#include "tlhelp32.h"
DWORD GetPIDbyName(char *strName)
{
HANDLE hprocessSnap = NULL;
PROCESSENTRY32 pe32;
memset(&pe32, 0, sizeof(PROCESSENTRY32));
hprocessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//创建进程快照
// 如果创建快照失败就返回1;
if (hprocessSnap == INVALID_HANDLE_VALUE)
{
printf("\nCreateToolhelp32Snapshot()failed:%d",GetLastError());
return 0;
}
pe32.dwSize = sizeof(PROCESSENTRY32); //初始化pe32的dwsize值
//遍历快照
if (Process32First(hprocessSnap,&pe32))
{
do
{
//如果name(要查找的进程的名字)等于pe32.szExeFile(本进程的名字),就返pe32.the32ProcessID (进程ID)
if (!stricmp(strName, pe32.szExeFile))
{
return (DWORD)pe32.th32ProcessID;
}
}while (Process32Next(hprocessSnap,&pe32));
}
//如果没找到就返回0
CloseHandle (hprocessSnap);
return 0;
}
// Enable the SeDebugPrivilege
void EnableDebugPriv( void )
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
// enable the SeDebugPrivilege
if ( ! OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
{
_tprintf( _T("OpenProcessToken() failed, Error = %d SeDebugPrivilege is not available.\n") , GetLastError() );
return;
}
if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
{
_tprintf( _T("LookupPrivilegeValue() failed, Error = %d SeDebugPrivilege is not available.\n"), GetLastError() );
CloseHandle( hToken );
return;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
_tprintf( _T("AdjustTokenPrivileges() failed, Error = %d SeDebugPrivilege is not available.\n"), GetLastError() );
CloseHandle( hToken );
}
typedef struct _SYSTEM_HANDLE
{
DWORD ProcessID;
WORD HandleType;
WORD HandleNumber;
DWORD KernelAddress;
DWORD Flags;
} SYSTEM_HANDLE;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
DWORD Count;
SYSTEM_HANDLE Handles[1];
}SYSTEM_HANDLE_INFORMATION;
typedef DWORD (WINAPI *PNtQueryObject)( HANDLE, DWORD, VOID*, DWORD, VOID* );
typedef DWORD (__stdcall *PNtQuerySystemInformation)( DWORD, VOID*, DWORD, ULONG* );
typedef DWORD (WINAPI *PNtQueryInformationFile)(HANDLE, PVOID, PVOID, DWORD, DWORD );
PNtQuerySystemInformation NtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
_T("NtQuerySystemInformation") );
PNtQueryObject NtQueryObject = (PNtQueryObject)GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
_T("NtQueryObject") );
PNtQueryInformationFile NtQueryInformationFile = (PNtQueryInformationFile)
GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
_T("NtQueryInformationFile") );
BOOL IsSupportedHandle( SYSTEM_HANDLE& handle )
{
//Here you can filter the handles you don't want in the Handle list
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
// Try calling GetVersionEx using the OSVERSIONINFOEX structure,
// which is supported on Windows 2000.
//
// If that fails, try using the OSVERSIONINFO structure.
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi);
if( bOsVersionInfoEx == 0 )
{
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return FALSE;
}
// Windows 2000 supports everything :)
if ( osvi.dwMajorVersion >= 5 )
return TRUE;
//NT4 System process doesn't like if we bother his internal security :)
if ( handle.ProcessID == 2 && handle.HandleType == 16 )
return FALSE;
return TRUE;
}
void LPCWSTR2CString( LPCWSTR strW, CString& str )
{
#ifdef UNICODE
// if it is already UNICODE, no problem
str = strW;
#else
str = _T("");
TCHAR* actChar = (TCHAR*)strW;
if ( actChar == _T('\0') )
return;
ULONG len = wcslen(strW) + 1;
TCHAR* pBuffer = new TCHAR[ len ];
TCHAR* pNewStr = pBuffer;
while ( len-- )
{
*(pNewStr++) = *actChar;
actChar += 2;
}
str = pBuffer;
delete [] pBuffer;
#endif
}
//Information functions
BOOL GetTypeToken( HANDLE h, CString& str, DWORD processId )
{
ULONG size = 0x2000;
UCHAR* lpBuffer = NULL;
BOOL ret = FALSE;
HANDLE handle;
HANDLE hRemoteProcess = NULL;
BOOL remote = processId != GetCurrentProcessId();
if ( remote )
{
// Open the remote process
hRemoteProcess = OpenProcess(PROCESS_DUP_HANDLE, TRUE, processId );
if ( hRemoteProcess == NULL )
return FALSE;
// Duplicate the remote handle for our process
::DuplicateHandle( hRemoteProcess, h, GetCurrentProcess(), &handle, 0, FALSE, DUPLICATE_SAME_ACCESS );
}
else
handle = h;
// Query the info size
NtQueryObject( handle, 2, NULL, 0, &size );
lpBuffer = new UCHAR[size];
// Query the info size ( type )
if ( NtQueryObject( handle, 2, lpBuffer, size, NULL ) == 0 )
{
str = _T("");
LPCWSTR2CString( (LPCWSTR)(lpBuffer+0x60), str );
ret = TRUE;
}
if ( remote )
{
if ( hRemoteProcess != NULL )
CloseHandle( hRemoteProcess );
if ( handle != NULL )
CloseHandle( handle );
}
if ( lpBuffer != NULL )
delete [] lpBuffer;
return ret;
}
//由文件handle 得到其盘符
//成功 返回盘符大写字母 失败返回0
char GetHandleLetter(HANDLE h)
{
BY_HANDLE_FILE_INFORMATION lpFileInformation;
if(FALSE == GetFileInformationByHandle(h, &lpFileInformation))
return 0;
char szDisk[MAX_PATH] = {0};
DWORD dwLength = GetLogicalDriveStrings(MAX_PATH, szDisk);
for (DWORD i=0; i<dwLength; i++)
{
char szRealDisk[MAX_PATH] = {0};
lstrcpy(szRealDisk, szDisk+i);
DWORD dwSerial = 0;
GetVolumeInformation(szRealDisk, NULL, NULL, &dwSerial, NULL, NULL, NULL, NULL);
if (dwSerial == lpFileInformation.dwVolumeSerialNumber)
{
//这里确保返回的是大写盘符
return szRealDisk[0] & 0xDF;
}
}
return 0;
}
//查看进程文件占有用
void CGetProcFileUsedDlg::OnOK()
{
CListBox *p = (CListBox*)GetDlgItem(IDC_LIST1);
char szProName[MAX_PATH] = {0};
DWORD dwPID = 0;
DWORD i=0;
GetDlgItemText(IDC_EDIT1, szProName, MAX_PATH);
EnableDebugPriv();
dwPID = GetPIDbyName(szProName);
if (dwPID == 0)
{
AfxMessageBox("输入的进程名有误!");
return ;
}
DWORD size = 0x2000;
DWORD needed = 0;
SYSTEM_HANDLE_INFORMATION* pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*)
VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE );
if ( pSysHandleInformation == NULL )
return ;
//16表示查询 句柄信息
if (NtQuerySystemInformation(16, pSysHandleInformation, size, &needed) != 0)
{
if ( needed == 0 )
{
goto __exit;
}
// The size was not enough
VirtualFree( pSysHandleInformation, 0, MEM_RELEASE );
pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*)
VirtualAlloc( NULL, size = needed + 256, MEM_COMMIT, PAGE_READWRITE );
}
if ( pSysHandleInformation == NULL )
return ;
if (NtQuerySystemInformation( 16, pSysHandleInformation, size, NULL ) != 0 )
{
goto __exit;
}
// Iterating through the objects
for (i = 0; i < pSysHandleInformation->Count; i++ )
{
if ( !IsSupportedHandle( pSysHandleInformation->Handles[i] ) )
continue;
// ProcessId filtering check
if ( pSysHandleInformation->Handles[i].ProcessID == dwPID)
{
CString strType;
GetTypeToken( (HANDLE)pSysHandleInformation->Handles[i].HandleNumber, strType, dwPID );
if (strType == "File")
{
HANDLE handle;
HANDLE hTM = OpenProcess(PROCESS_DUP_HANDLE, TRUE, dwPID);
BOOL bRet = ::DuplicateHandle(hTM,
(HANDLE)pSysHandleInformation->Handles[i].HandleNumber, GetCurrentProcess(),
&handle, 0, TRUE, DUPLICATE_SAME_ACCESS);
UCHAR lpBuffer[0x1000] = {0};
DWORD iob[2];
//9表示查询文件路径
DWORD status = NtQueryInformationFile(handle, iob, lpBuffer, sizeof(lpBuffer), 9 );
if (status == 0)
{
CString str = GetHandleLetter(handle);
CString path = (wchar_t *)(lpBuffer+4);
if (str == "")
{
str = "_";
}
str += ":";
str += path;
p->AddString(str);
OutputDebugString(str);
}
CloseHandle(hTM);
CloseHandle(handle);
}
}
}
__exit:
if ( pSysHandleInformation != NULL )
VirtualFree( pSysHandleInformation, 0, MEM_RELEASE );
}