void ShowExplorerCmdLine() // this demo shows us the command line of the explorer // this is not possible when using normal win32 APIs { HWND wnd; DWORD pid; HANDLE ph; char arrCh [MAX_PATH + 1]; // first we ask the taskbar's window handle and the corresponding process ID wnd = FindWindow("Shell_TrayWnd", ""); GetWindowThreadProcessId(wnd, &pid); // then we open the process, which is the explorer, of course ph = OpenProcess(PROCESS_ALL_ACCESS, false, pid); // next we ask the command line of the explorer GetProcessCmdLine(ph, arrCh); // and finally we show it's command line MessageBox(0, arrCh, "explorer's command line...", 0); // I like it the clean style CloseHandle(ph); }
BOOL GetProcessCmdLine(DWORD PID, LPTSTR szCmdLine, DWORD Size) { // Sanity checks if ((PID <= 0) || (szCmdLine == NULL)) return(FALSE); // Check if we can get information for this process HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID); if (hProcess == NULL) return(FALSE); BOOL bReturn = GetProcessCmdLine(hProcess, szCmdLine, Size); // Don't forget to release the process handle CloseHandle(hProcess); return(bReturn); }
VOID ShowProcessInfo(HWND hwnd, DWORD dwProcessID) { SetWindowText(hwnd, TEXT("")); // Clear the output box CToolhelp th(TH32CS_SNAPALL, dwProcessID); // Show Process details PROCESSENTRY32 pe = { sizeof(pe) }; BOOL fOk = th.ProcessFirst(&pe); for (; fOk; fOk = th.ProcessNext(&pe)) { if (pe.th32ProcessID == dwProcessID) { TCHAR szCmdLine[1024]; if (GetProcessCmdLine(dwProcessID, szCmdLine, _countof(szCmdLine))) { AddText(hwnd, TEXT("Command line: %s %s\r\n"), pe.szExeFile, szCmdLine); } else { AddText(hwnd, TEXT("Filename: %s\r\n"), pe.szExeFile); } AddText(hwnd, TEXT(" PID=%08X, ParentPID=%08X, ") TEXT("PriorityClass=%d, Threads=%d, Heaps=%d\r\n"), pe.th32ProcessID, pe.th32ParentProcessID, pe.pcPriClassBase, pe.cntThreads, th.HowManyHeaps()); TCHAR szOwner[MAX_PATH+1]; if (GetProcessOwner(dwProcessID, szOwner, MAX_PATH)) { AddText(hwnd, TEXT("Owner: %s\r\n"), szOwner); } break; // No need to continue looping } } // Show Modules in the Process // Number of characters to display an address AddText(hwnd, TEXT("\r\nModules Information:\r\n") TEXT(" Usage %-*s(%-*s) %10s Module\r\n"), s_cchAddress, TEXT("BaseAddr"), s_cchAddress, TEXT("ImagAddr"), TEXT("Size")); MODULEENTRY32 me = { sizeof(me) }; fOk = th.ModuleFirst(&me); for (; fOk; fOk = th.ModuleNext(&me)) { if (me.ProccntUsage == 65535) { // Module was implicitly loaded and cannot be unloaded AddText(hwnd, TEXT(" Fixed")); } else { AddText(hwnd, TEXT(" %5d"), me.ProccntUsage); } // Try to format the size in kb. TCHAR szFormattedSize[64]; if (StrFormatKBSize(me.modBaseSize, szFormattedSize, _countof(szFormattedSize)) == NULL) { StringCchPrintf(szFormattedSize, _countof(szFormattedSize), TEXT("%10u"), me.modBaseSize); } PVOID pvPreferredBaseAddr = GetModulePreferredBaseAddr(pe.th32ProcessID, me.modBaseAddr); if (me.modBaseAddr == pvPreferredBaseAddr) { AddText(hwnd, TEXT(" %p %*s %10s %s\r\n"), me.modBaseAddr, s_cchAddress, TEXT(""), szFormattedSize, me.szExePath); } else { AddText(hwnd, TEXT(" %p(%p) %10s %s\r\n"), me.modBaseAddr, pvPreferredBaseAddr, szFormattedSize, me.szExePath); } } // Show threads in the process AddText(hwnd, TEXT("\r\nThread Information:\r\n") TEXT(" TID Priority\r\n")); THREADENTRY32 te = { sizeof(te) }; fOk = th.ThreadFirst(&te); for (; fOk; fOk = th.ThreadNext(&te)) { if (te.th32OwnerProcessID == dwProcessID) { int nPriority = te.tpBasePri + te.tpDeltaPri; if ((te.tpBasePri < 16) && (nPriority > 15)) nPriority = 15; if ((te.tpBasePri > 15) && (nPriority > 31)) nPriority = 31; if ((te.tpBasePri < 16) && (nPriority < 1)) nPriority = 1; if ((te.tpBasePri > 15) && (nPriority < 16)) nPriority = 16; AddText(hwnd, TEXT(" %08X %2d\r\n"), te.th32ThreadID, nPriority); } } }