Sysinternals Homepage
Forum Home Forum Home > Windows Discussions > Internals
  New Posts New Posts RSS Feed: Enumerate opened files
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Enumerate opened files

 Post Reply Post Reply Page  <123
Author
Message Reverse Sort Order
Napalm View Drop Down
Groupie
Groupie
Avatar

Joined: 28 July 2005
Location: United Kingdom
Online Status: Offline
Posts: 91
Post Options Post Options   Quote Napalm Quote  Post ReplyReply Direct Link To This Post Topic: Enumerate opened files
    Posted: 21 April 2006 at 5:08am
Ok, not really looked into it in that much depth, since it was originally coded to display handles to \device\tcp and \device\udp.

I would very much like to see WalkObjects once its done. :)


Napalm

Napalm
That's the thing about people who think they hate computers. What they really hate is lousy programmers.
Back to Top
EP_X0FF View Drop Down
Senior Member
Senior Member
Avatar

Joined: 08 March 2006
Location: Russian Federation
Online Status: Offline
Posts: 4753
Post Options Post Options   Quote EP_X0FF Quote  Post ReplyReply Direct Link To This Post Posted: 21 April 2006 at 12:45am
Originally posted by Napalm


Let me know if it works..

It works fine. But not all process objects enumerated. Yes, program ignores unnamed handles, but many nammed too - for example [System] has file c:\hiberfil.sys that is not displayed by this enum. Look on ProcExp. It enums everything (but via driver). I am writting a function (called WalkObjects) that should try to return everything. I know it is possible in user mode.

Edited by EP_X0FF - 21 April 2006 at 12:47am
Ring0 - the source of inspiration
Back to Top
Napalm View Drop Down
Groupie
Groupie
Avatar

Joined: 28 July 2005
Location: United Kingdom
Online Status: Offline
Posts: 91
Post Options Post Options   Quote Napalm Quote  Post ReplyReply Direct Link To This Post Posted: 20 April 2006 at 9:11pm
I have not had a problem with my original code. Here is the project with a compiled version and a batch file to pipe the output to a text document.

2006-04-20_211055_HandleList.zip

Let me know if it works.. I would like to know if this rectifies the problem.

Napalm

Napalm
That's the thing about people who think they hate computers. What they really hate is lousy programmers.
Back to Top
EP_X0FF View Drop Down
Senior Member
Senior Member
Avatar

Joined: 08 March 2006
Location: Russian Federation
Online Status: Offline
Posts: 4753
Post Options Post Options   Quote EP_X0FF Quote  Post ReplyReply Direct Link To This Post Posted: 20 April 2006 at 8:11pm
Does somebody know how to enum ALL process objects? Not via driver - in user mode.

NtQueryObject hungs on opened named pipes
       
ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
        }

//So you will never get here

        if((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL))
Ring0 - the source of inspiration
Back to Top
Napalm View Drop Down
Groupie
Groupie
Avatar

Joined: 28 July 2005
Location: United Kingdom
Online Status: Offline
Posts: 91
Post Options Post Options   Quote Napalm Quote  Post ReplyReply Direct Link To This Post Posted: 20 April 2006 at 7:01pm
daniele_dll,
The problem stems from the code you have removed from my original. The call to NtQuerySystemInformation with a class of SystemHandleInformation means you get the Handles for all processes. Since that some of the Handles belong to other processes they wont be in your processes handle table. As so cannot query their names.

So this is why in my original code I used OpenProcess, DuplicateHandle, and then with the resulting duplicated handle to the current process we can then query its name with GetObjectInfo. Finally a little bit of cleanup with CloseHandle.


Napalm


Edited by Napalm - 20 April 2006 at 7:07pm

Napalm
That's the thing about people who think they hate computers. What they really hate is lousy programmers.
Back to Top
Guests View Drop Down
Guest Group
Guest Group
Post Options Post Options   Quote Guests Quote  Post ReplyReply Direct Link To This Post Posted: 20 April 2006 at 10:51am
Thanks you! Very helpful!
Back to Top
daniele_dll View Drop Down
Newbie
Newbie


Joined: 16 January 2006
Location: Italy
Online Status: Offline
Posts: 26
Post Options Post Options   Quote daniele_dll Quote  Post ReplyReply Direct Link To This Post Posted: 01 February 2006 at 9:29am
Originally posted by xuthus

I tried to use NtQueryInformationFile to retrieve a file name.

Sorry, in Object Pascal:

  if ObjType=FileType then begin
    NTQFI:= GetProcAddress(GetModuleHandle('NTDLL.DLL'), 'NtQueryInformationFile');
    if Addr(NTQFI)<>nil then begin
      dwSize:= sizeof(FILE_NAME_INFORMATION);
      New(pFileInfo);
      ntRet:= NTQFI(h, @Status, pFileInfo, dwSize, FileNameInformation);
      if (ntRet = STATUS_SUCCESS) then begin
        strRes:= pFileInfo^.FileName;
      end
      else begin
        ShowMessage('fail');
      end;
      FreeMem(pFileInfo);
    end;
  end
  else begin
    // ... code from daniele_dll for all other handle types
  end;

FileType = 26 for win2k, other values for other OSes.

But NtQueryInformationFile always returns STATUS_INVALID_DEVICE_REQUEST

Why?



hi,

the answer to your pvt is: yes, i've founded an answer :)

for first i want to say that the code i posted isin't mine, but it was written by napalm, i only getted it, modified it and posted it here (saying that it is napalm's source code)

for secondo i've founded a really complete article that explain all that you need to do the stuff:
1- you need to call Nt/ZwQueryInformationFile passing a zero buffer to acquire the necessary size
2- you need to recall the same api passing a buffer that has the correct size
3- data recived are in unicode, so you need to use an unicode-aware type or you'll get strange strings :D
4- sometimes this api hang so is necessary to use a thread with a timeout to stop it after, at example, 30 milliseconds
5- all the entire process is REALLY slow, many times my app need between 3 and 7 seconds to found the filename so it is a slow process
6- pay attention to memory leaks ... my application checks a lot of files and after ten minutes of backup my windows crashed for low memory ... in another test, checking the memory, i noticed that my application was using more than 700mb of memory ... not a good thing :) for this reason i preferred to do an executable and recall it to do the stuff (if you want i can send the executable)

here there is some useful stuff:
http://www.codeguru.com/Cpp/W-P/system/processesmodules/arti cle.php/c2827/

take a look to the source code, it is really well written :)

my little app is really similiar to WhoUses.exe but insted to return an human comprensible stuff return only a process id


Edited by daniele_dll
Back to Top
xuthus View Drop Down
Newbie
Newbie


Joined: 01 February 2006
Location: Russian Federation
Online Status: Offline
Posts: 6
Post Options Post Options   Quote xuthus Quote  Post ReplyReply Direct Link To This Post Posted: 01 February 2006 at 8:58am

I tried to use NtQueryInformationFile to retrieve a file name.

Sorry, in Object Pascal:

  if ObjType=FileType then begin
    NTQFI:= GetProcAddress(GetModuleHandle('NTDLL.DLL'), 'NtQueryInformationFile');
    if Addr(NTQFI)<>nil then begin
      dwSize:= sizeof(FILE_NAME_INFORMATION);
      New(pFileInfo);
      ntRet:= NTQFI(h, @Status, pFileInfo, dwSize, FileNameInformation);
      if (ntRet = STATUS_SUCCESS) then begin
        strRes:= pFileInfo^.FileName;
      end
      else begin
        ShowMessage('fail');
      end;
      FreeMem(pFileInfo);
    end;
  end
  else begin
    // ... code from daniele_dll for all other handle types
  end;

FileType = 26 for win2k, other values for other OSes.

But NtQueryInformationFile always returns STATUS_INVALID_DEVICE_REQUEST

Why?



Edited by xuthus
Back to Top
daniele_dll View Drop Down
Newbie
Newbie


Joined: 16 January 2006
Location: Italy
Online Status: Offline
Posts: 26
Post Options Post Options   Quote daniele_dll Quote  Post ReplyReply Direct Link To This Post Posted: 16 January 2006 at 12:48pm
hi to all,

i'm developing a backup applications and i need to show the name of the applications that have files opened

to do the stuff i've looking around to see if there is a way to do this and after a log research i've founded a way (and this forum): I must use NtQuerySystemInformation to enumerate opened handles, filter the result using the property ObjectType of the struct _SYSTEM_HANDLE and get the object name using NtQueryObject

After a lot of tests i've founded this forum and the Napalm's source code and doing some modifications i getted the list of handles but i think that there is some kind of problem: I get a really SHORT list of handles, removing the filter that check for the object type too!

Here there is his modified code:


LPWSTR GetObjectName(HANDLE hObject)
{
    LPWSTR lpwsReturn = NULL;
    if(pNTQO != NULL){
        DWORD dwSize = sizeof(OBJECT_NAME_INFORMATION);
        POBJECT_NAME_INFORMATION pObjectInfo = (POBJECT_NAME_INFORMATION) new BYTE[dwSize];
        NTSTATUS ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
        if(ntReturn == STATUS_BUFFER_OVERFLOW){
              delete pObjectInfo;
              pObjectInfo = (POBJECT_NAME_INFORMATION) new BYTE[dwSize];
              ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
        }
        if((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL))
        {
              lpwsReturn = (LPWSTR) new BYTE[pObjectInfo->Length + sizeof(WCHAR)];
              ZeroMemory(lpwsReturn, pObjectInfo->Length + sizeof(WCHAR));
              CopyMemory(lpwsReturn, pObjectInfo->Buffer, pObjectInfo->Length);
        }
        delete pObjectInfo;
    }
    return lpwsReturn;
}

int main(int argc, char *argv[])
{
    EnableDebugPrivilege();

    pNTQO = (tNTQO)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQueryObject");
    pNTQSI = (tNTQSI)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation");

    if(pNTQSI != NULL)
    {
        DWORD dwSize = sizeof(SYSTEM_HANDLE_INFORMATION);
        PSYSTEM_HANDLE_INFORMATION pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) new BYTE[dwSize];
        NTSTATUS ntReturn = pNTQSI(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
        if(ntReturn == STATUS_INFO_LENGTH_MISMATCH)
        {
              delete pHandleInfo;
              pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) new BYTE[dwSize];
              ntReturn = pNTQSI(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
        }
        if(ntReturn == STATUS_SUCCESS)
        {
              printf(" Found %d Handles. Listing File Handles...\n\n", pHandleInfo->uCount);
              printf(" PID\tHandle\tObject Type\tObject Name\n");
              for(DWORD dwIdx = 0; dwIdx < pHandleInfo->uCount; dwIdx++)
              {
                 printf("%5d\t%6d\t%ws",
                     pHandleInfo->Handles[dwIdx].uIdProcess,
                     pHandleInfo->Handles[dwIdx].Handle,
                     GetObjectType(pHandleInfo->Handles[dwIdx].ObjectType));

                LPWSTR lpwsName = GetObjectName((HANDLE)pHandleInfo->Handles[dwIdx].Handle);
                 if(lpwsName != NULL)
                {
                    printf("\t%ws", lpwsName);
                     delete lpwsName;
                }

                printf("\n", lpwsName);
              }
              printf("\n\n");
        }
        else
        {
              printf("Error while trying to allocate memory for System Handle Information.\n");
        }
        delete pHandleInfo;
    }
    else
    {
        printf("Cannot find NtQuerySystemInformation API... Is this system not Win2K and above?");
    }

    return 0;
}


The main problem is that GetObjectName return a lot of times null values and i don't understand why!
And another thing strange that happen: when i enumerate all the handles the object type is, in ALL results, 28, but this can't be ... i've seen that the higher value is 23 and indicate a file object

note: i'm not an expert C/C++ coder and, when all will run correctly, i'll convert all this code to C# code or, however, i'll need to write a library that do the work and i'll need to interface this library with C#

thanks to all!
Back to Top
 Post Reply Post Reply Page  <123

Forum Jump Forum Permissions View Drop Down