Click here to Skip to main content
15,887,135 members
Articles / Programming Languages / C++

Listing Used Files

Rate me:
Please Sign up or sign in to vote.
4.81/5 (95 votes)
29 Sep 2010CPOL11 min read 630.8K   23.2K   221   218
A ShellExtension that lists all the used files in a folder.

[The VC6 version of source code is kept just for reference in case if any one is still using VC6. Also, it does not include any modifications done after June-06-2008 mentioned in the Revision History section.]

Screenshot - Application.jpg

Introduction

This is a utility to display all the files that are opened under a specific folder.

Background

It often happens to me that when I try to rename or delete my current working folder of a project, it gives an error message like "Cannot rename BlaBlaBla: It is being used by another person or program". Almost at all times, I fail to find this other program/person, and end up restarting the machine. Since then, I have been searching for a method to find the list of files that an application uses. Even though the ProcessExplorer of SysInternals lists the files opened by each process, it is hard to find opened files in a particular folder. So I created one that does this, purely because of my necessity.

Using the Code

Download the application and register it using RegSvr32 (RegSvr32 OpenedFiles.dll). This application basically contains two components: an extension DLL and a driver. The extension DLL is responsible for showing the context menu in the shell and the GUI you see. I will explain the role of the driver later in this article.

This application will install a menu on folders, the background of a folder, and on a drive. I suggest you read The Complete Idiot's Guide to Writing Shell Extensions - Part I, article by Michael Dunn, if you are new to shell extensions. In fact, it was from there that I learned to write shell extensions.

Screenshot - context_menu.jpg

Enumerating Opened Files

When you click on the "List Opened Files" menu, it will first enumerate all of the opened files in the system. This is implemented in the following function:

C++
void EnumerateOpenedFiles( CString& csPath, OF_CALLBACL CallBackProc, UINT_PTR pUserContext, 
                           HANDLE hDriver, 
                           GetFinalPathNameByHandleDef pGetFinalPathNameByHandle ) 

{
    ...............
    // Get the list of all handles in the system
    PSYSTEM_HANDLE_INFORMATION pSysHandleInformation = new SYSTEM_HANDLE_INFORMATION;
    DWORD size = sizeof(SYSTEM_HANDLE_INFORMATION);
    DWORD needed = 0;
    NTSTATUS status = NtQuerySystemInformation( SystemHandleInformation, 
                      pSysHandleInformation, size, &needed );
    if( !NT_SUCCESS(status))
    {
        if( 0 == needed )
        {
            return;// some other error
        }
        // The previously supplied buffer wasn't enough.
        delete pSysHandleInformation;
        size = needed + 1024;
        pSysHandleInformation = (PSYSTEM_HANDLE_INFORMATION)new BYTE[size];
        status = NtQuerySystemInformation( SystemHandleInformation, 
                                           pSysHandleInformation, size, &needed );
        if( !NT_SUCCESS(status))
        {
            // some other error so quit.
            delete pSysHandleInformation;
            return;
        }
    }
    .....................
    .....................
    .....................
        for ( DWORD i = 0; i < pSysHandleInformation->dwCount; i++ )
    {
        SYSTEM_HANDLE& sh = pSysHandleInformation->Handles[i];
        if( sh.bObjectType != nFileType )// Under windows XP file handle is of type 28
        {
            continue;
        }

        CString csFileName;
        CString csDir;
        if( hDriver )
        {
            HANDLE_INFO stHandle = {0};
            ADDRESS_INFO stAddress;
            stAddress.pAddress = sh.pAddress;
            DWORD dwReturn = 0;
            BOOL bSuccess = DeviceIoControl( hDriver, IOCTL_LISTDRV_BUFFERED_IO, 
                                             &stAddress, sizeof(ADDRESS_INFO), 
                                             &stHandle, 
                                             sizeof(HANDLE_INFO), &dwReturn, NULL );

            
            if( bSuccess && stHandle.tcFileName[0] != 0 && 
                stHandle.uType != FILE_DEVICE_SOUND && 
                stHandle.uType != FILE_DEVICE_NAMED_PIPE )
            {

                if( stHandle.uType != FILE_DEVICE_NETWORK_FILE_SYSTEM  )
                {
                    // Get the drive name from the dos device name
                    if( !GetDrive( (LPCTSTR)stHandle.tcDeviceName, csFileName, true ))
                    {
                        OutputDebugString( L"GetDrive failed" );
                    }
                    csFileName += (LPCTSTR)stHandle.tcFileName;
                }
                else
                {
                    csFileName = _T("\\");
                    csFileName += (LPCTSTR)stHandle.tcFileName;
                }
            }
        }    
        ...

For every file opened in the system, there will be a handle associated with it. With the NtQuerySystemInformation API, we can retrieve all the handles in the system. This includes file handles, Mutex handles, Event handles, etc. Actually, the NtQuerySystemInformation function returns an array of the structure SYSTEM_HANDLE.

C++
typedef struct _SYSTEM_HANDLE
{
    DWORD    dwProcessId;
    BYTE     bObjectType;
    BYTE     bFlags;
    WORD     wValue;
    PVOID    pAddress;
    DWORD    GrantedAccess;
}
SYSTEM_HANDLE;

For an object of type file, the value bObjectType in SYSTEM_HANDLE is 28 in Windows XP, Windows 2000, and Window 7; 25 in Windows Vista; and 26 in Windows 2000. Since this application supports only XP/Windows 7, Windows 2000, and Vista, we can ignore all the items with values other than 28/25. In SYSTEM_HANDLE, there is another important member for us, the pAddress. For each file handle, there is a FILE_OBJECT associated with it, and the pAddress is a pointer to that structure. Unfortunately, this address points to kernel memory space, and a user mode application cannot access this memory. Here comes the driver part. This application accesses this memory using the driver "ListOpenedFileDrv_XX.sys". The only thing the driver does is copy the file name in the kernel memory and pass it to the user mode. Using the function DeviceIoControl, the pAddress is passed to the driver. The driver accepts this address and copies the file name from FILE_OBJECT, setting it in the out parameter of the DeviceIoControl function.

As I mentioned earlier, the Process Explorer shows the information about all the handles used by the application. However, the Process Explorer is a stand-alone application. So where is the driver? Or is it doing all this without the driver? This question puzzled me for many days until someone told me that the driver is added in the resource of the Process Explorer. Nice trick, isn't it? So I thought of implementing the same feature in my application too. The function given below performs this task. [Note: The new version of the application is not keeping the driver in the resource, but it directly uses the driver from the application folder. The below code is kept only for those who refer to the VC6 version of the source code.]

C++
HANDLE ExtractAndInstallDrv()
{
    SC_HANDLE hSCManager =
        OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
    SC_HANDLE hService = OpenService
        ( hSCManager , DRV_NAME, SERVICE_ALL_ACCESS);
    CString csPath;
    if( 0 == hService )
    {
        // Service not installed. So install the service.
        // First extract the resource
        HINSTANCE hModule= AfxGetInstanceHandle();
        HRSRC hRsrc = FindResource
            (hModule, MAKEINTRESOURCE(IDR_XPDRIVER),_T("BINARY"));
        HGLOBAL hDrvRsrc = LoadResource(hModule, hRsrc);
        DWORD dwDriverSize = SizeofResource(hModule, hRsrc);
        LPVOID lpvDriver = LockResource(hDrvRsrc);
        CFile File;
        if( !File.Open( DRV_FILE_NAME, CFile::modeCreate|CFile::modeWrite ))
        {
            return 0;
        }
        File.Write( lpvDriver, dwDriverSize );
        csPath = File.GetFilePath();
        File.Close();
        ...
    }

I made an application that does the above things and started using it. Some days later, again that rename problem occurred, and my application listed nothing. When I looked in the Task Manager, I found out that this time it was because of the applications that were running from my folder. So my next step was to enumerate the EXEs and any DLLs that have been loaded from my folder.

Enumerating Loaded Modules

Enumerating the modules loaded by applications was somewhat easy compared to the above task. It just made use of the following APIs. The EnumerateLoadedModules function handles this task in the application.

C++
EnumProcesses()
CreateToolhelp32Snapshot()
Module32First()
Module32Next()

Compatibility with UAC

As you have seen, this application makes use of many API calls that need Administrative privilege. But the Explorer.exe in Vista and later runs with restricted privilege so that the shell extension loaded by the explorer also cannot make any API calls that need Administrative privilege. Which means my current implementation, which had only one DLL that does all the job, is no longer going to work. So the only way is to spool another EXE from the shell extension in Administrative mode. So now, when you click on "List Opened Files", it launches OpenFileFinder.exe using ShellExecute, and the rest of the things are taken care by this process. But I was so lazy to move all the existing feature of in the shell extension DLL to the exe or another DLL. So what I did is I kept the functionality in the DLL itself and exported the function ShowOpenedFiles from the DLL, which when called, shows the opened files dialog. The diagram below show this architecture:

Screenshot - Application.jpg

The Problem with Vista 64 Bit and Windows-7 64 Bit

In 64 bit versions of Windows, starting from Vista, Microsoft has enforced that any program that is supposed to be loaded into the kernel space should be digitally signed by Microsoft. This enforcement affect lots of free software and unfortunately to this software also. The core thing in this application is done by our tiny driver which I no longer will be able to load in those versions of Windows. So my initial plan was to discontinue this application in 64 bit Vista and later. However, because of the new APIs which are introduced from Windows Vista, there is still an option to make this work without the driver also. So this application still works in 64 bit Vista and Windows with limited results. The new API that I was talking about is GetFinalPathNameByHandle. However, using the API instead of our driver has some problems like:

  • This function accepts HANDLE, but the handles are not unique among all processes.
  • To solve the above problem, we have to duplicate the handle. To duplicate the handle, I have to get the process handle using OpenProcess. But OpenProcess fails for some processes like SYSTEM because of lack of access. Even if we successfully duplicate some other handles, the API still fails saying Access Denied.
  • Last and the worst, it hangs for certain kinds of handles. You can read mode about this problem in here: GetFinalPathNameByHandle API Hungs. At the time when I was checking this problem in Windows Vista, I remember atleast the GetFileInformationByHandleEx worked in all cases. But now I experience the same problem in Windows 7.

The only workaround to prevent the entire application from hanging is to call the API from a separate thread. So what I did in this application is, if the driver installation fails, it will switch to Plan B, which is actually to use the GetFinalPathNameByHandle in a separate thread. Meanwhile, the main thread will keep on checking whether the worker thread has hung or not using some events. After a time out period, if the main thread does not receive the event, it will terminate the worked thread and spool another worker thread. This is continued until all the the handles have been enumerated.

The following code shows how the API is called from the thread:

C++
DWORD WINAPI ThreadProc( LPVOID lParam )
{
    THREAD_PARAMS* pThreadParam = (THREAD_PARAMS*)lParam;    
    GetFinalPathNameByHandleDef pGetFinalPathNameByHandle = 
                       pThreadParam->pGetFinalPathNameByHandle;
    for( g_CurrentIndex; g_CurrentIndex < pThreadParam->pSysHandleInformation->dwCount;  )
    {
        WaitForSingleObject( pThreadParam->hStartEvent, INFINITE );
        ResetEvent( pThreadParam->hStartEvent ). 
        pThreadParam->bStatus = false;
        SYSTEM_HANDLE& sh = pThreadParam->pSysHandleInformation->Handles[g_CurrentIndex];
        g_CurrentIndex++;
        // First try to duplicate the handle,
        // if the duplicate handle failed, we will coninue with the
        // original handle. But calling the API
        // with the orginal handle is least likly to success
        HANDLE hDup = (HANDLE)sh.wValue;
        HANDLE hProcess = OpenProcess( PROCESS_DUP_HANDLE , FALSE, sh.dwProcessId );
        if( hProcess )
        {
            BOOL b = DuplicateHandle( hProcess, (HANDLE)sh.wValue, 
                       GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );
            if( !b )
            {
                hDup = (HANDLE)sh.wValue;
            }
            CloseHandle( hProcess );
        }
        DWORD dwRet = pGetFinalPathNameByHandle( hDup, pThreadParam->lpPath, MAX_PATH, 0 );
        if( hDup && (hDup != (HANDLE)sh.wValue))
        {
            CloseHandle( hDup );
        }
        if(dwRet)
        {
            pThreadParam->bStatus = true;
        }
        SetEvent( pThreadParam->hFinishedEvent );
        
    }
    return 0;
}

And this is how the main thread delegates its work to the thread procedure:

C++
void EnumerateOpenedFiles( CString& csPath, OF_CALLBACL CallBackProc, 
                           UINT_PTR pUserContext, HANDLE hDriver,
                           GetFinalPathNameByHandleDef pGetFinalPathNameByHandle ) 
{
    ................
    ................
    if( pGetFinalPathNameByHandle )// there is no driver, we have do it ugly way
    {
        g_CurrentIndex = 0;
        TCHAR tcFileName[MAX_PATH+1];
        THREAD_PARAMS ThreadParams;
        ThreadParams.lpPath = tcFileName;
        ThreadParams.nFileType = nFileType;
        ThreadParams.pGetFinalPathNameByHandle = pGetFinalPathNameByHandle;
        ThreadParams.pSysHandleInformation = pSysHandleInformation;
        ThreadParams.hStartEvent = ::CreateEvent( 0, TRUE, FALSE, 0 );
        ThreadParams.hFinishedEvent = ::CreateEvent( 0, TRUE, FALSE, 0 );
        HANDLE ThreadHandle = 0;
        while( g_CurrentIndex < pSysHandleInformation->dwCount )
        {
            if( !ThreadHandle )
            {
                ThreadHandle = CreateThread( 0, 0, ThreadProc, &ThreadParams, 0, 0 );    
            }
            ResetEvent( ThreadParams.hFinishedEvent );
            SetEvent( ThreadParams.hStartEvent );
            if( WAIT_TIMEOUT == WaitForSingleObject( ThreadParams.hFinishedEvent, 100 ))
            {
                CString csError;
                csError.Format(L"Query hang for handle %d", 
                   (int)pSysHandleInformation->Handles[g_CurrentIndex - 1].wValue);
                OutputDebugString(csError );
                TerminateThread( ThreadHandle, 0 );
                CloseHandle( ThreadHandle );
                ThreadHandle = 0;
                continue;
            }
            if( !ThreadParams.bStatus )
            {
                continue;
            }
    ................
    ................
}

Compared to the driver method, this one is much slower and returns less results. You have to switch off the diver signature enforcement in 64 bit Vista if you still want this application to work using the driver.

How Third Party Applications Can Make Use of This Application

After the initial version of this application, I received many requests from people to export some functions so that other applications can also make use of this functionality. Starting from this release, OpenFileFinder.dll exports two C functions, which can be called from other binaries:

  • void ShowOpenedFiles( LPCWSTR lpPath )
  • You can call this function if you want to show the dialog and display the opened files in it.

  • void GetOpenedFiles( LPCWSTR lpPath, OF_TYPE Filter,OF_CALLBACK CallBackProc,UINT_PTR pUserContext );
  • If you call this function and pass a callback pointer, for each file handle that matches the input path, the callback function will be called.

The above functions plus the OF_TYPE enum and the OF_CALLBACK function pointer is defined in OpenedFiles.h.

Close Handle Option

During the initial development of this utility, I purposefully ignored the option for closing any file handles opened by another process. I though it was unsafe if it provides such an option because closing the handle may lead to unexpected results in that application. However, I later got into some situations like the folder I wanted to rename was used by service.exe. And if I wanted to rename the folder, the only option was to terminate the process. But terminating service.exe will make the entire system unstable. And so I was forced to include a Close Handle option too.

So how this option basically works is, it duplicates the handle using the DuplicateHandle() function with the DUPLICATE_CLOSE_SOURCE flag specified. After that, it closes the duplicate handle also using the CloseHandle() function. This option will work only for loaded files; i.e., using this option on a DLL used by another process is just ignored.

C++
HANDLE hDup = 0;
BOOL b = DuplicateHandle( hProcess, hFile, GetCurrentProcess(), 
    &hDup, DUPLICATE_SAME_ACCESS , FALSE, DUPLICATE_CLOSE_SOURCE );
if( hDup )
{
    CloseHandle( hDup );
}
CloseHandle( hProcess );

Basically, with the above code, we can close the handles created by another process. After closing the handle, we can rename or delete that file or directory. But there are cases where after closing the handle, we can rename the folder but deleting is not possible. For example, consider the file C:\WINDOWS\system32\config\CstEvent.Evt. Normally, this file is used by Service.exe for event logging purposes. So if we try to close this file handle using the above option, the handle will be closed and we can rename too, but cannot delete!! I tried many ways to solve this, but couldn't come up with a working solution. If anybody knows any options to solve this, please let me know.

Miscellaneous Features

Auto Complete in Combobox

Screenshot - AutoComplete.jpg

You have probably noticed that when we type some paths in the Run dialog of Windows, it will list the files and folders under that path. Similarly, when you type a path in the combobox of this application, it will list the files and folders under that path. SHAutoComplete takes care of this feature. This function needs a handle of the edit control. But I only have a combobox - how do I take the edit control inside it? Well, the edit control inside the combobox has a control ID 1001. Use the GetDlgItem() function with this ID to get the handle of the edit control. You can also specify a filename in that combobox.

C++
BOOL MainDlg::OnInitDialog()
{
    .....
    CWnd* pEdit =  m_combobox.GetDlgItem( 1001 );
    if( pEdit )
    {
        SHAutoComplete( pEdit->m_hWnd, SHACF_FILESYSTEM );
    }
}

Find Target Option

When you right click on one item in the list control of this application, you will find a menu called "Find Target". This option is something like the Find Target option in Windows Explorer. It opens a Windows Explorer window with a specified file selected in its folder. SHOpenFolderAndSelectItems() is used for implementing this feature.

C++
void MainDlg::OnMainFindtarget()
{
    ....
    CString csPath;
    csPath = m_list.GetItemText( nItem,2 );
    LPITEMIDLIST stId = 0;
    SFGAOF stSFGAOFIn = 0;
    SFGAOF stSFGAOFOut = 0;
    if( !FAILED(SHParseDisplayName( csPath, 0, &stId,stSFGAOFIn, &stSFGAOFOut )))
    {
        SHOpenFolderAndSelectItems( stId, 0, 0, 0 );
    }
}

Show Loaded Modules and Show Loaded Files - Options

As mentioned above, the list control in the application list includes two types of items - loaded files and loaded modules (DLLs, OCX, EXE etc.). This option is to Show/Hide one type of item from the list.

Note

This application uses a driver built for Windows XP/Win2003/Vista/Window 7, and so it will run only on those versions. If you want, you can add support for other OS versions as well by building the driver and making the necessary changes to the application.

Revision History

September-29-2010

  • Added 64 bit support
  • Added modifications mentioned in the section "Compatibility with UAC"
  • Added modifications mentioned in the section "The problem with Vista 64 bit and Windows-7 64 bit"

June-06-2008

  • The bug described in the below post[^] has been fixed
  • Close Handle and Close All Handle options added
  • "Show Loaded Modules" and "Show Loaded Files" options added

October-12-2007

  • Application icon is displayed along with process
  • Miscellaneous Features section added

September-27-2007

  • "Find Target" menu added
  • Added driver for Windows Vista
  • Added VC8 solution

June-30-2007

  • Article moved

June-4-2007

  • Article updated

May-28-2007

  • Original version posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionsolved Pin
fdsfsfsfds17-Jan-12 18:51
fdsfsfsfds17-Jan-12 18:51 
Questionhow to get name of current media player file Pin
fdsfsfsfds17-Jan-12 17:55
fdsfsfsfds17-Jan-12 17:55 
AnswerRe: how to get name of current media player file Pin
Naveen17-Jan-12 18:23
Naveen17-Jan-12 18:23 
QuestionUse in VB Pin
blindguyinanorgy4-Jan-12 5:27
blindguyinanorgy4-Jan-12 5:27 
AnswerRe: Use in VB Pin
Naveen10-Jan-12 19:21
Naveen10-Jan-12 19:21 
QuestionNot working on services Pin
LiorO6-Nov-11 7:41
LiorO6-Nov-11 7:41 
AnswerRe: Not working on services Pin
Naveen6-Nov-11 17:38
Naveen6-Nov-11 17:38 
QuestionTHIS CODE IS NOT WORKIN IN VISTA Pin
ronimanojk15-Sep-11 4:37
ronimanojk15-Sep-11 4:37 
VB
  Private Const DUPLICATE_SAME_ACCESS           As Long = &H2
Private Const DUPLICATE_CLOSE_SOURCE          As Long = &H1
Private Const STATUS_INFO_LENGTH_MISMATCH     As Long = &HC0000004
Private Const PROCESS_ALL_ACCESS              As Long = &H1F0FFF
Private Const FILE_MAP_READ                   As Long = &H4
Private Const PAGE_READONLY                   As Long = &H2
Private Const HEAP_ZERO_MEMORY                As Long = &H8
Private Const TOKEN_ADJUST_PRIVILEGES         As Long = &H20
Private Const SE_PRIVILEGE_ENABLED            As Long = &H2
Private Const SE_PRIVILEGE_NAME               As String = "SeDebugPrivilege"
Private Const TOKEN_QUERY                     As Long = &H8
 
Private Const SystemHandleInformation         As Long = &H10
' 16 bytes.
Private Type SYSTEM_HANDLE_INFORMATION
  ProcessID           As Long
  ObjectTypeNumber    As Byte
  Flags               As Byte
  Handle              As Integer
  Object_Pointer      As Long
  GrantedAccess       As Long
End Type
 
Private Type LUID
    LowPart             As Long
    HighPart            As Long
End Type
 
Private Type TOKEN_PRIVILEGES
    PrivilegeCount      As Long
    LuidUDT             As LUID
    Attributes          As Long
End Type
 
Private Declare Function GetProcessHeap Lib "kernel32.dll" () As Long
Private Declare Function HeapAlloc Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function HeapFree Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal lpMem As Long) As Long
Private Declare Function HeapDestroy Lib "kernel32.dll" (ByVal hHeap As Long) As Long
Private Declare Function NtQuerySystemInformation Lib "ntdll.dll" (ByVal SystemInformationClass As Long, ByVal pSystemInformation As Long, ByVal SystemInformationLength As Long, ByRef ReturnLength As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function DuplicateHandle Lib "kernel32.dll" (ByVal hSourceProcessHandle As Long, ByVal hSourceHandle As Long, ByVal hTargetProcessHandle As Long, ByRef lpTargetHandle As Long, ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwOptions As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function CreateFileMappingW Lib "kernel32" (ByVal hFile As Long, ByVal lpFileMappigAttributes As Long, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long
Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long
Private Declare Function GetMappedFileNameW Lib "Psapi.dll" (ByVal hProcess As Long, ByVal lpv As Long, ByVal lpFileName As Long, ByVal nSize As Long) As Long
Private Declare Function UnmapViewOfFile Lib "kernel32" (ByVal lpBaseAddress As Long) As Long
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValueA Lib "advapi32" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As Any, ReturnLength As Any) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Sub RtlZeroMemory Lib "kernel32.dll" (Destination As Any, ByVal Length As Long)
Private Declare Function GetModuleFileNameExW Lib "Psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpFileName As Long, ByVal nSize As Long) As Long
 
Dim HandleInfo()    As SYSTEM_HANDLE_INFORMATION
Dim m_cHandles      As Long
Dim hProcess        As Long
Dim hHandle         As Long
Dim szName          As String
Dim szAppName       As String
 
Public Sub QueryHandlesBuffer()
 
  ' The following method obtains all the handles on the system
  ' followed by an array of SYSTEM_HANDLE_INFORMATION structs
  ' that can be used to obtain information.
  
  ' Need to be admin on XP
  ' Need to be admin and elevated on vista and above.
  ' Need to have SE_DEBUG_PRIVS
  
  ' Use DUPLICATE_CLOSE_SOURCE to close the handle to the remote
  ' process and local process when passed to DuplicateHandle.
  
  Dim lpBufferHandles   As Long
  Dim Length            As Long
  Dim ret               As Long
  Dim n                 As Long
  
  ' 256 byte offset
  Length = &H100
  
  ' Allocate block of memory
  lpBufferHandles = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, Length)
  
  ' Check if valid buffer
  If lpBufferHandles = 0 Then
    Exit Sub
  End If
  
  ' Obtain the size required for SystemHandleInformation class
  While (NtQuerySystemInformation(SystemHandleInformation, lpBufferHandles, Length, ret) = STATUS_INFO_LENGTH_MISMATCH)
    Length = Length * 2
    ' free memory
    HeapFree GetProcessHeap, 0, lpBufferHandles
    ' allocate memory
    lpBufferHandles = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, Length)
  Wend
  
  ' Check if valid buffer
  If lpBufferHandles = 0 Then
    Exit Sub
  End If
  
  ' The number of system handles first 4 bytes.
  m_cHandles = ReadLong(lpBufferHandles)
  ' Resize array to system handle count.
  ReDim HandleInfo(m_cHandles) As SYSTEM_HANDLE_INFORMATION
  ' Initialize memory
  RtlZeroMemory HandleInfo(0), LenB(HandleInfo(0)) * m_cHandles
  ' Copy the information into the array
  RtlMoveMemory HandleInfo(0), ByVal lpBufferHandles + 4, LenB(HandleInfo(0)) * m_cHandles
  ' free memory
  HeapFree GetProcessHeap, 0, lpBufferHandles
  
  ' Get information from the SYSTEM_HANDLE_INFORMATION arrays
  
  For n = 0 To m_cHandles - 1
  ' Check if the object is a type FILE.
    If HandleInfo(n).ObjectTypeNumber = 28 Then ' 26 for Win2K
  ' Get real process handle.
      OpenProcessForHandle HandleInfo(n).ProcessID
  ' Have to duplicate the file handle so it's valid in our process context.
    
    
    
      DuplicateHandle hProcess, HandleInfo(n).Handle, GetCurrentProcess, hHandle, 0, 0, DUPLICATE_SAME_ACCESS
      
  ' Checksum
      If hHandle <> 0 Then
  ' Get DOS path,filename and process name.
        szName = GetObjectName(hHandle)
        szAppName = GetProcessName(hProcess)
  ' // TODO: SOME FILTERING GOES HERE. if szName Like "pewpew" Then return results.
        If LenB(szName) > 0 Then
            If InStr(1, szName, ".tax", vbTextCompare) > 0 Then
                List1.AddItem "hProcess = " & hProcess
                List1.AddItem "File = " & szName
                List1.AddItem "Process = " & szAppName
                List1.AddItem "handle= " & HandleInfo(n).Handle
                List1.AddItem HandleInfo(n).ProcessID
''                Dim hdup As Long
''                Call DuplicateHandle(hProcess, HandleInfo(n).Handle, GetCurrentProcess, hdup, DUPLICATE_SAME_ACCESS, 0, DUPLICATE_CLOSE_SOURCE)
''                If hdup > 0 Then
''                    CloseHandle (hdup)
''                End If
            End If
        End If
    '//
  ' Free handle
        CloseHandle hHandle
         
      End If
    End If
  Next n
  
End Sub
Private Function GetObjectName(ByVal dwHandle As Long) As String
 
' This method gets a filename from a file handle. Only if the file
' in question is atleast one byte. If a file is zero bytes
' it can't be mapped and the function fails. Choose to use this method
' instead of NtQueryObject because it's more stable and typically if
' the file is zero bytes it's used by an application that the user
' doesn't care about.
 
  Dim hFileMap        As Long
  Dim pMem            As Long
  Dim cbLength        As Long
  Dim bName(8192)     As Byte
  
  ' Create a file mapping in our process.
  hFileMap = CreateFileMappingW(dwHandle, 0, PAGE_READONLY, 0, 1, 0)
  
  ' Check valid handle
  If hFileMap = 0 Then
    Exit Function
  End If
  
  ' Map the file into memory
  pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1)
  
  ' Check valid memory pointer to file.
  If pMem = 0 Then
    CloseHandle hFileMap
    Exit Function
  End If
  
  ' Obtain the name from the mapped file.
  cbLength = GetMappedFileNameW(GetCurrentProcess, pMem, VarPtr(bName(0)), 8192)
  
  ' Check buffer for valid data.
  If cbLength <> 0 Then
    GetObjectName = Left$(bName, cbLength)
  Else
    GetObjectName = vbNullString
  End If
  
  ' free handles free mapping
  CloseHandle hFileMap
  UnmapViewOfFile pMem
  ' free memory
  Erase bName
  
End Function
 
Private Function GetProcessName(ByVal dwProcess As Long) As String
 
' The method obtains the process name associated with the real
' process handle.
 
  Dim bProcess(8192)  As Byte
  Dim cbLength        As Long
  
  cbLength = GetModuleFileNameExW(dwProcess, 0, VarPtr(bProcess(0)), 8192)
  
  ' check return buffer length
  If cbLength <> 0 Then
      GetProcessName = Left$(bProcess, cbLength)
    Else
      GetProcessName = vbNullString
  End If
  
  ' free memory
  Erase bProcess
  
End Function
 
 
Private Sub OpenProcessForHandle(ByVal ProcessID As Long)
 
' The method obtains a real process handle that can be used
' to get additional information about a process.
' If the PID is the same don't open the handle again. Only
' open the handle if the PID has changed.
 
  Dim LastPID   As Long
 
  If ProcessID <> LastPID Then
  ' free handle
    CloseHandle hProcess
  ' get real process handle.
    hProcess = OpenProcess( _
      PROCESS_ALL_ACCESS, _
      0, _
      ProcessID)
    ' checksum
    LastPID = ProcessID
    
  End If
 
End Sub
 
Public Sub SeDebugPrivilege()
 
' The following method gives SE_DEBUG_PRIVS.
 
    Dim Success     As Long
    Dim hToken      As Long
    Dim TokenPriv   As TOKEN_PRIVILEGES
' Do work.
    Success = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken)
    Success = LookupPrivilegeValueA(vbNullString, SE_PRIVILEGE_NAME, TokenPriv.LuidUDT)
    TokenPriv.PrivilegeCount = 1
    TokenPriv.Attributes = SE_PRIVILEGE_ENABLED
    Success = AdjustTokenPrivileges(hToken, 0, TokenPriv, 0, ByVal 0&, ByVal 0&)
    CloseHandle hToken
 
End Sub
 
Private Function ReadLong(ByVal Ptr As Long) As Long
 
' Helper function reads 4 bytes from memory address.
 
  Dim Bogus As Long
  RtlMoveMemory Bogus, ByVal Ptr, 4
  ReadLong = Bogus
  
End Function 





this is working fine in xp but.. not workin in vista!!
Can u tell why?
AnswerRe: THIS CODE IS NOT WORKIN IN VISTA Pin
Naveen15-Sep-11 15:39
Naveen15-Sep-11 15:39 
GeneralRe: THIS CODE IS NOT WORKIN IN VISTA Pin
ronimanojk15-Sep-11 19:25
ronimanojk15-Sep-11 19:25 
QuestionProblem with multiple usage on Windows7, 64bit Pin
abxd8-Aug-11 1:54
abxd8-Aug-11 1:54 
AnswerRe: Problem with multiple usage on Windows7, 64bit Pin
Naveen11-Aug-11 2:32
Naveen11-Aug-11 2:32 
QuestionConvert to C# application for x64 Windows Pin
CeccoCQ27-Jul-11 2:08
CeccoCQ27-Jul-11 2:08 
AnswerRe: Convert to C# application for x64 Windows Pin
Naveen27-Jul-11 15:10
Naveen27-Jul-11 15:10 
QuestionUsage of GetOpenedFiles Pin
abxd21-Jul-11 3:11
abxd21-Jul-11 3:11 
AnswerRe: Usage of GetOpenedFiles Pin
Naveen21-Jul-11 15:28
Naveen21-Jul-11 15:28 
QuestionUsing GetOpenedFiles from VB.Net project Pin
abxd26-Jun-11 23:04
abxd26-Jun-11 23:04 
AnswerRe: Using GetOpenedFiles from VB.Net project Pin
Naveen26-Jun-11 23:28
Naveen26-Jun-11 23:28 
GeneralRe: Using GetOpenedFiles from VB.Net project Pin
abxd27-Jun-11 1:16
abxd27-Jun-11 1:16 
QuestionProblems with Windows2003, 64bit Pin
abxd22-Jun-11 3:13
abxd22-Jun-11 3:13 
AnswerRe: Problems with Windows2003, 64bit Pin
Naveen23-Jun-11 5:23
Naveen23-Jun-11 5:23 
GeneralRe: Problems with Windows2003, 64bit Pin
abxd24-Jun-11 1:46
abxd24-Jun-11 1:46 
GeneralRe: Problems with Windows2003, 64bit Pin
Naveen26-Jun-11 14:57
Naveen26-Jun-11 14:57 
GeneralRe: Problems with Windows2003, 64bit Pin
abxd26-Jun-11 21:01
abxd26-Jun-11 21:01 
GeneralMy vote of 5 Pin
iye1526-Apr-11 8:35
iye1526-Apr-11 8:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.