VOID FormatSizeInKB(DWORD dwSize, DWORD nCharacters, LPTSTR szSize, size_t cchSize) { TCHAR szFormattedSize[64]; if (StrFormatKBSize(dwSize, szFormattedSize, _countof(szFormattedSize)) == NULL) { StringCchPrintf(szFormattedSize, _countof(szFormattedSize), TEXT("%8u"), dwSize); } // Format to the right nCharacter width if needed. if (_tcslen(szFormattedSize) < nCharacters) { DWORD current = 0; for(current = 0; current < (nCharacters - _tcslen(szFormattedSize)); current++) { szSize[current] = TEXT(' '); } szSize[current] = TEXT('\0'); _tcscat_s(szSize, cchSize - current, szFormattedSize); } }
VOID WINAPI WorkerThreadHashFile( PCOMMONCONTEXT pcmnctx, PCTSTR pszPath, PBOOL pbSuccess, PWHCTXEX pwhctx, PWHRESULTEX pwhres, PBYTE pbuffer, PFILESIZE pFileSize, LPARAM lParam, PCRITICAL_SECTION pUpdateCritSec, volatile ULONGLONG* pcbCurrentMaxSize #ifdef _TIMED , PDWORD pdwElapsed #endif ) { HANDLE hFile; *pbSuccess = FALSE; // If the worker thread is working so fast that the UI cannot catch up, // pause for a bit to let things settle down while (pcmnctx->cSentMsgs > pcmnctx->cHandledMsgs + 50) { Sleep(50); if (pcmnctx->status == PAUSED) WaitForSingleObject(pcmnctx->hUnpauseEvent, INFINITE); if (pcmnctx->status == CANCEL_REQUESTED) return; } // Indicate that we want lower-case results (TODO: make this an option) pwhctx->uCaseMode = WHFMT_LOWERCASE; if ((hFile = OpenFileForReading(pszPath)) != INVALID_HANDLE_VALUE) { ULONGLONG cbFileSize, cbFileRead = 0; DWORD cbBufferRead; UINT lastProgress = 0; UINT8 cInner = 0; if (GetFileSizeEx(hFile, (PLARGE_INTEGER)&cbFileSize)) { // The progress bar is updates only once every 4 buffer reads; if // the file is small enough that it requires only one such cycle, // then do not bother with updating the progress bar; this improves // performance when working with large numbers of small files BOOL bUpdateProgress = cbFileSize >= READ_BUFFER_SIZE * 4, bCurrentlyUpdating = FALSE; // If the caller provides a way to return the file size, then set // the file size; send a SETSIZE notification only if it was "big" if (pFileSize) { pFileSize->ui64 = cbFileSize; StrFormatKBSize(cbFileSize, pFileSize->sz, countof(pFileSize->sz)); if (cbFileSize > READ_BUFFER_SIZE) PostMessage(pcmnctx->hWnd, HM_WORKERTHREAD_SETSIZE, (WPARAM)pcmnctx, lParam != -1 ? lParam : (LPARAM)pFileSize); } #ifdef _TIMED DWORD dwStarted; if (pdwElapsed) dwStarted = GetTickCount(); #endif // Finally, read the file and calculate the checksum; the // progress bar is updated only once every 4 buffer reads (512K) WHInitEx(pwhctx); do // Outer loop: keep going until the end { do // Inner loop: break every 4 cycles or if the end is reached { if (pcmnctx->status == PAUSED) WaitForSingleObject(pcmnctx->hUnpauseEvent, INFINITE); if (pcmnctx->status == CANCEL_REQUESTED) { CloseHandle(hFile); return; } ReadFile(hFile, pbuffer, READ_BUFFER_SIZE, &cbBufferRead, NULL); WHUpdateEx(pwhctx, pbuffer, cbBufferRead); cbFileRead += cbBufferRead; } while (cbBufferRead == READ_BUFFER_SIZE && (++cInner & 0x03)); if (bUpdateProgress) UpdateProgressBar(pcmnctx->hWndPBFile, pUpdateCritSec, &bCurrentlyUpdating, pcbCurrentMaxSize, cbFileSize, cbFileRead, &lastProgress); } while (cbBufferRead == READ_BUFFER_SIZE); WHFinishEx(pwhctx, pwhres); #ifdef _TIMED if (pdwElapsed) *pdwElapsed = GetTickCount() - dwStarted; #endif if (cbFileRead == cbFileSize) *pbSuccess = TRUE; if (bUpdateProgress) UpdateProgressBar(pcmnctx->hWndPBFile, pUpdateCritSec, &bCurrentlyUpdating, pcbCurrentMaxSize, cbFileSize, 0, &lastProgress); } CloseHandle(hFile); } }
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); } } }