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);
   }
}
Exemple #2
0
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);
      }
   }
}