编写列举系统进程的程序,传统的方法为利用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;
|