编写列举系统进程的程序,传统的方法为利用tlhelp api系统快照的方式进行列举。其实还用一种方法,即利用ntdll中的NtQuerySystemInformation函数。下面给出代码,很简单。
NTSTATUS NtStatus; DWORD dwReturnLength; DWORD dwBuffSize = 0x10000; // 缓冲区大小,存放进程信息 PSYSTEM_PROCESSES pSystemProcessInfo = NULL; // 存放返回的进程信息头指针地址 PSYSTEM_PROCESSES pSelectProcessInfo = NULL;
m_cListCtrl.InsertColumn( 0, _T("映像名称"), LVCFMT_LEFT, 100); m_cListCtrl.InsertColumn( 1, _T("PID"), LVCFMT_LEFT, 50);// m_cListCtrl.InsertColumn( 2, _T("优先级"), LVCFMT_LEFT, 50);
HMODULE hNtDll = LoadLibrary("Ntdll.dll"); NTQUERYSYSTEMINFOMATION NtQuerySystemInformation = (NTQUERYSYSTEMINFOMATION)GetProcAddress(hNtDll, "NtQuerySystemInformation"); RTLUNICODESTRINGTOANSISTRING RtlUnicodeStringToAnsiString = (RTLUNICODESTRINGTOANSISTRING)GetProcAddress(hNtDll, "RtlUnicodeStringToAnsiString");
pSystemProcessInfo = (PSYSTEM_PROCESSES)malloc(dwBuffSize);
NtStatus = NtQuerySystemInformation( QUERY_TYPE, pSystemProcessInfo, dwBuffSize, &dwReturnLength );
//缓冲区大小不够 while(NtStatus == 0xc0000004) { dwBuffSize += 0x1000; //在原来分配的堆上进行扩展 pSystemProcessInfo = (PSYSTEM_PROCESSES)realloc( pSystemProcessInfo, dwBuffSize ); if( pSystemProcessInfo == NULL ) { FreeLibrary(hNtDll); return FALSE; } }
NtStatus = NtQuerySystemInformation( QUERY_TYPE, pSystemProcessInfo, dwBuffSize, &dwReturnLength );
//函数NtQuerySystemInformation调用失败 if( NtStatus != 0x00000000L ) { free( pSystemProcessInfo ); FreeLibrary( hNtDll ); ::MessageBox(m_hWnd, "NATIVE API调用失败!", "错误", MB_OK); return FALSE; }
pSelectProcessInfo = pSystemProcessInfo;
CString szFormat; ANSI_STRING ansiProcessName;
do { int iCount = m_cListCtrl.GetItemCount();
if(pSelectProcessInfo->ProcessId == 0) { m_cListCtrl.InsertItem(iCount, "[System Idle Process]"); m_cListCtrl.SetItemText(iCount, 1, "0"); } else { RtlUnicodeStringToAnsiString(&ansiProcessName, &pSelectProcessInfo->ProcessName, 1); m_cListCtrl.InsertItem(iCount, ansiProcessName.Buffer); szFormat.Format("%d", pSelectProcessInfo->ProcessId); m_cListCtrl.SetItemText(iCount, 1, szFormat); }
// szFormat.Format("%d", pSelectProcessInfo->BasePriority);// m_cListCtrl.SetItemText(iCount, 2, szFormat);
//移动到下一个结构 pSelectProcessInfo = (PSYSTEM_PROCESSES)((LPBYTE)pSelectProcessInfo + pSelectProcessInfo->NextEntryDelta); }while(pSelectProcessInfo->NextEntryDelta != 0);
free(pSystemProcessInfo); FreeLibrary(hNtDll); return TRUE;