PPH_STRING NvGpuQueryDriverVersion(VOID) { if (NvAPI_SYS_GetDriverAndBranchVersion) { NvU32 driverVersion = 0; NvAPI_ShortString driverAndBranchString = ""; if (NvAPI_SYS_GetDriverAndBranchVersion(&driverVersion, driverAndBranchString) == NVAPI_OK) { return PhFormatString(L"%lu.%lu [%hs]", driverVersion / 100, driverVersion % 100, driverAndBranchString ); } } if (NvAPI_GetDisplayDriverVersion) { NV_DISPLAY_DRIVER_VERSION nvDisplayDriverVersion = { NV_DISPLAY_DRIVER_VERSION_VER }; if (NvAPI_GetDisplayDriverVersion(NvGpuDisplayHandleList->Items[0], &nvDisplayDriverVersion) == NVAPI_OK) { return PhFormatString(L"%lu.%lu [%hs]", nvDisplayDriverVersion.drvVersion / 100, nvDisplayDriverVersion.drvVersion % 100, nvDisplayDriverVersion.szBuildBranchString ); } } return PhCreateString(L"N/A"); }
PPH_STRING WepGetWindowTitleForSelector( _In_ PWE_WINDOW_SELECTOR Selector ) { switch (Selector->Type) { case WeWindowSelectorAll: { return PhCreateString(L"Windows - All"); } break; case WeWindowSelectorThread: { return PhFormatString(L"Windows - Thread %lu", HandleToUlong(Selector->Thread.ThreadId)); } break; case WeWindowSelectorProcess: { CLIENT_ID clientId; clientId.UniqueProcess = Selector->Process.ProcessId; clientId.UniqueThread = NULL; return PhConcatStrings2(L"Windows - ", PH_AUTO_T(PH_STRING, PhGetClientIdName(&clientId))->Buffer); } break; case WeWindowSelectorDesktop: { return PhFormatString(L"Windows - Desktop \"%s\"", Selector->Desktop.DesktopName->Buffer); } break; default: return PhCreateString(L"Windows"); } }
static BOOL CALLBACK PhpProcessMiniDumpCallback( _In_ PVOID CallbackParam, _In_ const PMINIDUMP_CALLBACK_INPUT CallbackInput, _Inout_ PMINIDUMP_CALLBACK_OUTPUT CallbackOutput ) { PPROCESS_MINIDUMP_CONTEXT context = CallbackParam; PPH_STRING message = NULL; // Don't try to send status updates if we're creating a dump of the current process. if (context->ProcessId == NtCurrentProcessId()) return TRUE; // MiniDumpWriteDump seems to get bored of calling the callback // after it begins dumping the process handles. The code is // still here in case they fix this problem in the future. switch (CallbackInput->CallbackType) { case CancelCallback: { if (context->Stop) CallbackOutput->Cancel = TRUE; } break; case ModuleCallback: { message = PhFormatString(L"Processing module %s...", CallbackInput->Module.FullPath); } break; case ThreadCallback: { message = PhFormatString(L"Processing thread %u...", CallbackInput->Thread.ThreadId); } break; } if (message) { SendMessage( context->WindowHandle, WM_PH_MINIDUMP_STATUS_UPDATE, PH_MINIDUMP_STATUS_UPDATE, (LPARAM)message->Buffer ); PhDereferenceObject(message); } return TRUE; }
PPH_STRING PhFormatLogEntry( _In_ PPH_LOG_ENTRY Entry ) { switch (Entry->Type) { case PH_LOG_ENTRY_PROCESS_CREATE: return PhFormatString( L"Process created: %s (%u) started by %s (%u)", Entry->Process.Name->Buffer, (ULONG)Entry->Process.ProcessId, PhGetStringOrDefault(Entry->Process.ParentName, L"Unknown Process"), (ULONG)Entry->Process.ParentProcessId ); case PH_LOG_ENTRY_PROCESS_DELETE: return PhFormatString(L"Process terminated: %s (%u)", Entry->Process.Name->Buffer, (ULONG)Entry->Process.ProcessId); case PH_LOG_ENTRY_SERVICE_CREATE: return PhFormatString(L"Service created: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_DELETE: return PhFormatString(L"Service deleted: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_START: return PhFormatString(L"Service started: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_STOP: return PhFormatString(L"Service stopped: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_CONTINUE: return PhFormatString(L"Service continued: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_PAUSE: return PhFormatString(L"Service paused: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_MESSAGE: PhReferenceObject(Entry->Message); return Entry->Message; default: return PhReferenceEmptyString(); } }
PPH_STRING NvGpuQueryFoundry(VOID) { if (NvAPI_GPU_GetFoundry) { NV_FOUNDRY nvFoundryType = NV_FOUNDRY_NONE; if (NvAPI_GPU_GetFoundry(NvGpuPhysicalHandleList->Items[0], &nvFoundryType) == NVAPI_OK) { switch (nvFoundryType) { case NV_FOUNDRY_TSMC: return PhCreateString(L"Taiwan Semiconductor Manufacturing Company (TSMC)"); case NV_FOUNDRY_UMC: return PhCreateString(L"United Microelectronics Corporation (UMC)"); case NV_FOUNDRY_IBM: return PhCreateString(L"IBM Microelectronics"); case NV_FOUNDRY_SMIC: return PhCreateString(L"Semiconductor Manufacturing International Corporation (SMIC)"); case NV_FOUNDRY_CSM: return PhCreateString(L"Chartered Semiconductor Manufacturing (CSM)"); case NV_FOUNDRY_TOSHIBA: return PhCreateString(L"Toshiba Corporation"); default: return PhFormatString(L"%lu", nvFoundryType); } } } return PhCreateString(L"N/A"); }
PPH_PROCESS_PROPCONTEXT PhCreateProcessPropContext( _In_ HWND ParentWindowHandle, _In_ PPH_PROCESS_ITEM ProcessItem ) { static PH_INITONCE initOnce = PH_INITONCE_INIT; PPH_PROCESS_PROPCONTEXT propContext; PROPSHEETHEADER propSheetHeader; if (PhBeginInitOnce(&initOnce)) { PhpProcessPropContextType = PhCreateObjectType(L"ProcessPropContext", 0, PhpProcessPropContextDeleteProcedure); PhpProcessPropPageContextType = PhCreateObjectType(L"ProcessPropPageContext", 0, PhpProcessPropPageContextDeleteProcedure); PhEndInitOnce(&initOnce); } propContext = PhCreateObjectZero(sizeof(PH_PROCESS_PROPCONTEXT), PhpProcessPropContextType); propContext->PropSheetPages = PhAllocateZero(sizeof(HPROPSHEETPAGE) * PH_PROCESS_PROPCONTEXT_MAXPAGES); if (!PH_IS_FAKE_PROCESS_ID(ProcessItem->ProcessId)) { propContext->Title = PhFormatString( L"%s (%u)", ProcessItem->ProcessName->Buffer, HandleToUlong(ProcessItem->ProcessId) ); } else { PhSetReference(&propContext->Title, ProcessItem->ProcessName); } memset(&propSheetHeader, 0, sizeof(PROPSHEETHEADER)); propSheetHeader.dwSize = sizeof(PROPSHEETHEADER); propSheetHeader.dwFlags = PSH_MODELESS | PSH_NOAPPLYNOW | PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_USECALLBACK | PSH_USEHICON; propSheetHeader.hInstance = PhInstanceHandle; propSheetHeader.hwndParent = ParentWindowHandle; propSheetHeader.hIcon = ProcessItem->SmallIcon; propSheetHeader.pszCaption = propContext->Title->Buffer; propSheetHeader.pfnCallback = PhpPropSheetProc; propSheetHeader.nPages = 0; propSheetHeader.nStartPage = 0; propSheetHeader.phpage = propContext->PropSheetPages; if (PhCsForceNoParent) propSheetHeader.hwndParent = NULL; memcpy(&propContext->PropSheetHeader, &propSheetHeader, sizeof(PROPSHEETHEADER)); PhSetReference(&propContext->ProcessItem, ProcessItem); return propContext; }
PPH_STRING PhGetThreadPriorityWin32String( __in LONG PriorityWin32 ) { switch (PriorityWin32) { case THREAD_PRIORITY_TIME_CRITICAL: return PhCreateString(L"Time Critical"); case THREAD_PRIORITY_HIGHEST: return PhCreateString(L"Highest"); case THREAD_PRIORITY_ABOVE_NORMAL: return PhCreateString(L"Above Normal"); case THREAD_PRIORITY_NORMAL: return PhCreateString(L"Normal"); case THREAD_PRIORITY_BELOW_NORMAL: return PhCreateString(L"Below Normal"); case THREAD_PRIORITY_LOWEST: return PhCreateString(L"Lowest"); case THREAD_PRIORITY_IDLE: return PhCreateString(L"Idle"); case THREAD_PRIORITY_ERROR_RETURN: return NULL; default: return PhFormatString(L"%d", PriorityWin32); } }
static PPH_STRING UpdateVersionString( VOID ) { ULONG majorVersion; ULONG minorVersion; ULONG revisionVersion; PPH_STRING currentVersion = NULL; PPH_STRING versionHeader = NULL; PhGetPhVersionNumbers( &majorVersion, &minorVersion, NULL, &revisionVersion ); currentVersion = PhFormatString( L"%lu.%lu.%lu", majorVersion, minorVersion, revisionVersion ); if (currentVersion) { versionHeader = PhConcatStrings2(L"ProcessHacker-Build: ", currentVersion->Buffer); PhDereferenceObject(currentVersion); } return versionHeader; }
static BOOL ConnectionAvailable( VOID ) { if (WindowsVersion > WINDOWS_XP) { INetworkListManager *pNetworkListManager; // Create an instance of the INetworkListManger COM object. if (SUCCEEDED(CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, &IID_INetworkListManager, &pNetworkListManager))) { VARIANT_BOOL isConnected = VARIANT_FALSE; VARIANT_BOOL isConnectedInternet = VARIANT_FALSE; // Query the relevant properties. INetworkListManager_get_IsConnected(pNetworkListManager, &isConnected); INetworkListManager_get_IsConnectedToInternet(pNetworkListManager, &isConnectedInternet); // Cleanup the INetworkListManger COM object. INetworkListManager_Release(pNetworkListManager); pNetworkListManager = NULL; // Check if Windows is connected to a network and it's connected to the internet. if (isConnected == VARIANT_TRUE && isConnectedInternet == VARIANT_TRUE) { // We're online and connected to the internet. return TRUE; } // We're not connected to anything. return FALSE; } // If we reached here, we were unable to init the INetworkListManager, fall back to InternetGetConnectedState. goto NOT_SUPPORTED; } else NOT_SUPPORTED: { DWORD dwType; if (InternetGetConnectedState(&dwType, 0)) { return TRUE; } else { LogEvent(NULL, PhFormatString(L"Updater: (ConnectionAvailable) InternetGetConnectedState failed to detect an active Internet connection (%d)", GetLastError())); } //if (!InternetCheckConnection(NULL, FLAG_ICC_FORCE_CONNECTION, 0)) //{ // LogEvent(PhFormatString(L"Updater: (ConnectionAvailable) InternetCheckConnection failed connection to Sourceforge.net (%d)", GetLastError())); // return FALSE; //} } return FALSE; }
static BOOLEAN NTAPI PhpWalkThreadStackCallback( _In_ PPH_THREAD_STACK_FRAME StackFrame, _In_opt_ PVOID Context ) { PTHREAD_STACK_CONTEXT threadStackContext = (PTHREAD_STACK_CONTEXT)Context; PPH_STRING symbol; PTHREAD_STACK_ITEM item; if (threadStackContext->StopWalk) return FALSE; PhAcquireQueuedLockExclusive(&threadStackContext->StatusLock); PhMoveReference(&threadStackContext->StatusMessage, PhFormatString(L"Processing frame %u...", threadStackContext->NewList->Count)); PhReleaseQueuedLockExclusive(&threadStackContext->StatusLock); PostMessage(threadStackContext->ProgressWindowHandle, WM_PH_STATUS_UPDATE, 0, 0); symbol = PhGetSymbolFromAddress( threadStackContext->SymbolProvider, (ULONG64)StackFrame->PcAddress, NULL, NULL, NULL, NULL ); if (symbol && (StackFrame->Flags & PH_THREAD_STACK_FRAME_I386) && !(StackFrame->Flags & PH_THREAD_STACK_FRAME_FPO_DATA_PRESENT)) { PhMoveReference(&symbol, PhConcatStrings2(symbol->Buffer, L" (No unwind info)")); } item = PhAllocate(sizeof(THREAD_STACK_ITEM)); item->StackFrame = *StackFrame; item->Index = threadStackContext->NewList->Count; if (PhPluginsEnabled) { PH_PLUGIN_THREAD_STACK_CONTROL control; control.Type = PluginThreadStackResolveSymbol; control.UniqueKey = threadStackContext; control.u.ResolveSymbol.StackFrame = StackFrame; control.u.ResolveSymbol.Symbol = symbol; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackThreadStackControl), &control); symbol = control.u.ResolveSymbol.Symbol; } item->Symbol = symbol; PhAddItemList(threadStackContext->NewList, item); return TRUE; }
PPH_STRING WepGetWindowTitleForSelector( _In_ PWE_WINDOW_SELECTOR Selector ) { PPH_STRING title; CLIENT_ID clientId; PPH_STRING clientIdName; switch (Selector->Type) { case WeWindowSelectorAll: { return PhCreateString(L"Windows - All"); } break; case WeWindowSelectorThread: { return PhFormatString(L"Windows - Thread %u", (ULONG)Selector->Thread.ThreadId); } break; case WeWindowSelectorProcess: { clientId.UniqueProcess = Selector->Process.ProcessId; clientId.UniqueThread = NULL; clientIdName = PhGetClientIdName(&clientId); title = PhConcatStrings2(L"Windows - ", clientIdName->Buffer); PhDereferenceObject(clientIdName); return title; } break; case WeWindowSelectorDesktop: { return PhFormatString(L"Windows - Desktop \"%s\"", Selector->Desktop.DesktopName->Buffer); } break; default: return PhCreateString(L"Windows"); } }
static PPH_STRING PhpSettingToString( _In_ PH_SETTING_TYPE Type, _In_ PPH_SETTING Setting ) { switch (Type) { case StringSettingType: { if (!Setting->u.Pointer) return PhReferenceEmptyString(); PhReferenceObject(Setting->u.Pointer); return (PPH_STRING)Setting->u.Pointer; } case IntegerSettingType: { return PhFormatString(L"%x", Setting->u.Integer); } case IntegerPairSettingType: { PPH_INTEGER_PAIR integerPair = &Setting->u.IntegerPair; return PhFormatString(L"%d,%d", integerPair->X, integerPair->Y); } case ScalableIntegerPairSettingType: { PPH_SCALABLE_INTEGER_PAIR scalableIntegerPair = Setting->u.Pointer; if (!scalableIntegerPair) return PhReferenceEmptyString(); return PhFormatString(L"@%u|%d,%d", scalableIntegerPair->Scale, scalableIntegerPair->X, scalableIntegerPair->Y); } } return PhReferenceEmptyString(); }
PPH_STRING NvGpuQueryRopsCount(VOID) { if (NvAPI_GPU_GetPartitionCount) { NvU32 value = 0; if (NvAPI_GPU_GetPartitionCount(NvGpuPhysicalHandleList->Items[0], &value) == NVAPI_OK) { if (GpuArchType >= 0x120) { return PhFormatString(L"%lu", value * 16); } else if (GpuArchType >= 0x0c0) { return PhFormatString(L"%lu", value * 8); } return PhFormatString(L"%lu", value * 4); } } return PhCreateString(L"N/A"); }
PPH_STRING NvGpuQueryShaderCount(VOID) { if (NvAPI_GPU_GetGpuCoreCount) { NvU32 value = 0; if (NvAPI_GPU_GetGpuCoreCount(NvGpuPhysicalHandleList->Items[0], &value) == NVAPI_OK) { return PhFormatString(L"%lu Unified", value); } } return PhCreateString(L"N/A"); }
PPH_STRING NvGpuQueryFanSpeed(VOID) { NvU32 tachValue = 0; NV_GPU_COOLER_SETTINGS coolerInfo = { NV_GPU_COOLER_SETTINGS_VER }; if (NvAPI_GPU_GetTachReading && NvAPI_GPU_GetTachReading(NvGpuPhysicalHandleList->Items[0], &tachValue) == NVAPI_OK) { if (NvAPI_GPU_GetCoolerSettings && NvAPI_GPU_GetCoolerSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_COOLER_TARGET_ALL, &coolerInfo) == NVAPI_OK) { return PhFormatString(L"%lu RPM (%lu%%)", tachValue, coolerInfo.cooler[0].currentLevel); } return PhFormatString(L"%lu RPM", tachValue); } else { if (NvAPI_GPU_GetCoolerSettings && NvAPI_GPU_GetCoolerSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_COOLER_TARGET_ALL, &coolerInfo) == NVAPI_OK) { return PhFormatString(L"%lu%%", coolerInfo.cooler[0].currentLevel); } } return PhCreateString(L"N/A"); }
PPH_STRING NvGpuQueryBusWidth(VOID) { if (NvAPI_GPU_GetFBWidthAndLocation) { NvU32 width = 0; NvU32 location = 0; if (NvAPI_GPU_GetFBWidthAndLocation(NvGpuPhysicalHandleList->Items[0], &width, &location) == NVAPI_OK) { return PhFormatString(L"%lu Bit", width); } } return PhCreateString(L"N/A"); }
PPH_STRING NvGpuQueryRevision(VOID) { if (NvAPI_GPU_GetArchInfo) { NV_ARCH_INFO nvArchInfo = { NV_ARCH_INFO_VER }; if (NvAPI_GPU_GetArchInfo(NvGpuPhysicalHandleList->Items[0], &nvArchInfo) == NVAPI_OK) { GpuArchType = nvArchInfo.unknown[0]; return PhFormatString(L"%02X", nvArchInfo.unknown[2]); } } return PhCreateString(L"N/A"); }
VOID PhpRefreshProcessMemoryList( _In_ HWND hwndDlg, _In_ PPH_PROCESS_PROPPAGECONTEXT PropPageContext ) { PPH_MEMORY_CONTEXT memoryContext = PropPageContext->Context; if (memoryContext->MemoryItemListValid) { PhDeleteMemoryItemList(&memoryContext->MemoryItemList); memoryContext->MemoryItemListValid = FALSE; } memoryContext->LastRunStatus = PhQueryMemoryItemList( memoryContext->ProcessId, PH_QUERY_MEMORY_REGION_TYPE | PH_QUERY_MEMORY_WS_COUNTERS, &memoryContext->MemoryItemList ); if (NT_SUCCESS(memoryContext->LastRunStatus)) { if (PhPluginsEnabled) { PH_PLUGIN_MEMORY_ITEM_LIST_CONTROL control; control.Type = PluginMemoryItemListInitialized; control.u.Initialized.List = &memoryContext->MemoryItemList; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackMemoryItemListControl), &control); } memoryContext->MemoryItemListValid = TRUE; TreeNew_SetEmptyText(memoryContext->ListContext.TreeNewHandle, &EmptyMemoryText, 0); PhReplaceMemoryList(&memoryContext->ListContext, &memoryContext->MemoryItemList); } else { PPH_STRING message; message = PhGetStatusMessage(memoryContext->LastRunStatus, 0); PhMoveReference(&memoryContext->ErrorMessage, PhFormatString(L"Unable to query memory information:\n%s", PhGetStringOrDefault(message, L"Unknown error."))); PhClearReference(&message); TreeNew_SetEmptyText(memoryContext->ListContext.TreeNewHandle, &memoryContext->ErrorMessage->sr, 0); PhReplaceMemoryList(&memoryContext->ListContext, NULL); } }
PPH_STRING NvGpuQueryPciInfo(VOID) { if (NvAPI_GPU_GetPCIEInfo) { NV_PCIE_INFO pciInfo = { NV_PCIE_INFO_VER }; if (NvAPI_GPU_GetPCIEInfo(NvGpuPhysicalHandleList->Items[0], &pciInfo) == NVAPI_OK) { return PhFormatString(L"%lu @ %lu %lu", pciInfo.info[1].unknown1, pciInfo.info[0].unknown5, pciInfo.info[0].unknown6 ); } } return PhCreateString(L"N/A"); }
PPH_STRING NvGpuQueryPcbValue(VOID) { if (NvAPI_GPU_ClientPowerTopologyGetStatus) { NV_POWER_TOPOLOGY_STATUS nvPowerTopologyStatus = { NV_POWER_TOPOLOGY_STATUS_VER }; if (NvAPI_GPU_ClientPowerTopologyGetStatus(NvGpuPhysicalHandleList->Items[0], &nvPowerTopologyStatus) == NVAPI_OK) { for (NvU32 i = 0; i < nvPowerTopologyStatus.count; i++) { NV_POWER_TOPOLOGY_2 powerTopology = nvPowerTopologyStatus.unknown[i]; return PhFormatString(L"%lu", powerTopology.unknown.unknown2); } } } return PhCreateString(L"N/A"); }
VOID LogEvent(__in PWSTR str, __in int status) { switch (GraphicsType) { case NvidiaGraphics: { if (NvAPI_GetErrorMessage != NULL) { PPH_STRING nvPhString = NULL; PPH_STRING statusString = NULL; NvAPI_ShortString nvString = { 0 }; NvAPI_GetErrorMessage((NvStatus)status, nvString); nvPhString = PhCreateStringFromAnsi(nvString); statusString = PhFormatString(str, nvPhString->Buffer); PhLogMessageEntry(PH_LOG_ENTRY_MESSAGE, statusString); PhDereferenceObject(statusString); PhDereferenceObject(nvPhString); } else { PPH_STRING string = PhCreateString(L"gfxinfo: (LogEvent) NvAPI_GetErrorMessage was not initialized."); PhLogMessageEntry(PH_LOG_ENTRY_MESSAGE, string); PhDereferenceObject(string); } } break; case AtiGraphics: { //PPH_STRING string = PhFormatString(str, status); //PhLogMessageEntry(PH_LOG_ENTRY_MESSAGE, string); //PhDereferenceObject(string); } break; } }
PPH_STRING GetGfxFanSpeed(VOID) { NvStatus status = NVAPI_ERROR; NV_COOLER_INFO_V2 v2 = { 0 }; v2.Version = NV_COOLER_INFO_VER; status = NvAPI_GetCoolerSettings(physHandle, 0, &v2); if (NV_SUCCESS(status)) { return PhFormatString(L"Fan Speed: %d%%", v2.Values[0].CurrentLevel); } else { LogEvent(L"gfxinfo: (GetGfxFanSpeed) NvAPI_GetCoolerSettings failed (%s)", status); } return NULL; }
static PPH_STRING GenerateCacheName( _In_ PDNS_RECORD Record ) { PDNS_RECORD record = Record; PPH_STRING result; result = PhCreateString(record->pName); record = record->pNext; while (record) { PhMoveReference( &result, PhFormatString(L"%s, %s", result->Buffer, record->pName) ); record = record->pNext; } return result; }
PPH_STRING PhpGetGdiHandleInformation( _In_ ULONG Handle ) { HGDIOBJ handle; handle = (HGDIOBJ)UlongToPtr(Handle); switch (GDI_CLIENT_TYPE_FROM_HANDLE(Handle)) { case GDI_CLIENT_BITMAP_TYPE: case GDI_CLIENT_DIBSECTION_TYPE: { BITMAP bitmap; if (GetObject(handle, sizeof(BITMAP), &bitmap)) { return PhFormatString( L"Width: %u, Height: %u, Depth: %u", bitmap.bmWidth, bitmap.bmHeight, bitmap.bmBitsPixel ); } } break; case GDI_CLIENT_BRUSH_TYPE: { LOGBRUSH brush; if (GetObject(handle, sizeof(LOGBRUSH), &brush)) { return PhFormatString( L"Style: %u, Color: 0x%08x, Hatch: 0x%Ix", brush.lbStyle, _byteswap_ulong(brush.lbColor), brush.lbHatch ); } } break; case GDI_CLIENT_EXTPEN_TYPE: { EXTLOGPEN pen; if (GetObject(handle, sizeof(EXTLOGPEN), &pen)) { return PhFormatString( L"Style: 0x%x, Width: %u, Color: 0x%08x", pen.elpPenStyle, pen.elpWidth, _byteswap_ulong(pen.elpColor) ); } } break; case GDI_CLIENT_FONT_TYPE: { LOGFONT font; if (GetObject(handle, sizeof(LOGFONT), &font)) { return PhFormatString( L"Face: %s, Height: %d", font.lfFaceName, font.lfHeight ); } } break; case GDI_CLIENT_PALETTE_TYPE: { USHORT count; if (GetObject(handle, sizeof(USHORT), &count)) { return PhFormatString( L"Entries: %u", (ULONG)count ); } } break; case GDI_CLIENT_PEN_TYPE: { LOGPEN pen; if (GetObject(handle, sizeof(LOGPEN), &pen)) { return PhFormatString( L"Style: %u, Width: %u, Color: 0x%08x", pen.lopnStyle, pen.lopnWidth.x, _byteswap_ulong(pen.lopnColor) ); } } break; } return NULL; }
VOID StatusBarUpdate( _In_ BOOLEAN ResetMaxWidths ) { static ULONG64 lastTickCount = 0; ULONG count; ULONG i; HDC hdc; BOOLEAN resetMaxWidths = FALSE; PPH_STRING text[MAX_STATUSBAR_ITEMS]; ULONG widths[MAX_STATUSBAR_ITEMS]; if (ProcessesUpdatedCount < 2) return; if (ResetMaxWidths) resetMaxWidths = TRUE; if (!StatusBarItemList || StatusBarItemList->Count == 0) { // The status bar doesn't cope well with 0 parts. widths[0] = -1; SendMessage(StatusBarHandle, SB_SETPARTS, 1, (LPARAM)widths); SendMessage(StatusBarHandle, SB_SETTEXT, 0, (LPARAM)L""); return; } hdc = GetDC(StatusBarHandle); SelectObject(hdc, (HFONT)SendMessage(StatusBarHandle, WM_GETFONT, 0, 0)); // Reset max. widths for Max. CPU Process and Max. I/O Process parts once in a while. { LARGE_INTEGER tickCount; PhQuerySystemTime(&tickCount); if (tickCount.QuadPart - lastTickCount >= 10 * PH_TICKS_PER_SEC) { resetMaxWidths = TRUE; lastTickCount = tickCount.QuadPart; } } count = 0; for (i = 0; i < StatusBarItemList->Count; i++) { SIZE size; ULONG width; PSTATUSBAR_ITEM statusItem; statusItem = StatusBarItemList->Items[i]; switch (statusItem->Id) { case ID_STATUS_CPUUSAGE: { text[count] = PhFormatString( L"CPU Usage: %.2f%%", (SystemStatistics.CpuKernelUsage + SystemStatistics.CpuUserUsage) * 100 ); } break; case ID_STATUS_COMMITCHARGE: { ULONG commitUsage = SystemStatistics.Performance->CommittedPages; FLOAT commitFraction = (FLOAT)commitUsage / SystemStatistics.Performance->CommitLimit * 100; text[count] = PhFormatString( L"Commit Charge: %s (%.2f%%)", PhaFormatSize(UInt32x32To64(commitUsage, PAGE_SIZE), -1)->Buffer, commitFraction ); } break; case ID_STATUS_PHYSICALMEMORY: { ULONG physicalUsage = PhSystemBasicInformation.NumberOfPhysicalPages - SystemStatistics.Performance->AvailablePages; FLOAT physicalFraction = (FLOAT)physicalUsage / PhSystemBasicInformation.NumberOfPhysicalPages * 100; text[count] = PhFormatString( L"Physical Memory: %s (%.2f%%)", PhaFormatSize(UInt32x32To64(physicalUsage, PAGE_SIZE), -1)->Buffer, physicalFraction ); } break; case ID_STATUS_FREEMEMORY: { ULONG physicalFree = SystemStatistics.Performance->AvailablePages; FLOAT physicalFreeFraction = (FLOAT)physicalFree / PhSystemBasicInformation.NumberOfPhysicalPages * 100; text[count] = PhFormatString( L"Free Memory: %s (%.2f%%)", PhaFormatSize(UInt32x32To64(physicalFree, PAGE_SIZE), -1)->Buffer, physicalFreeFraction ); } break; case ID_STATUS_NUMBEROFPROCESSES: { text[count] = PhConcatStrings2( L"Processes: ", PhaFormatUInt64(SystemStatistics.NumberOfProcesses, TRUE)->Buffer ); } break; case ID_STATUS_NUMBEROFTHREADS: { text[count] = PhConcatStrings2( L"Threads: ", PhaFormatUInt64(SystemStatistics.NumberOfThreads, TRUE)->Buffer ); } break; case ID_STATUS_NUMBEROFHANDLES: { text[count] = PhConcatStrings2( L"Handles: ", PhaFormatUInt64(SystemStatistics.NumberOfHandles, TRUE)->Buffer ); } break; case ID_STATUS_IO_RO: { text[count] = PhConcatStrings2( L"I/O R+O: ", PhaFormatSize(SystemStatistics.IoReadDelta.Delta + SystemStatistics.IoOtherDelta.Delta, -1)->Buffer ); } break; case ID_STATUS_IO_W: { text[count] = PhConcatStrings2( L"I/O W: ", PhaFormatSize(SystemStatistics.IoWriteDelta.Delta, -1)->Buffer ); } break; case ID_STATUS_MAX_CPU_PROCESS: { PPH_PROCESS_ITEM processItem; if (SystemStatistics.MaxCpuProcessId && (processItem = PhReferenceProcessItem(SystemStatistics.MaxCpuProcessId))) { if (!PH_IS_FAKE_PROCESS_ID(processItem->ProcessId)) { text[count] = PhFormatString( L"%s (%lu): %.2f%%", processItem->ProcessName->Buffer, HandleToUlong(processItem->ProcessId), processItem->CpuUsage * 100 ); } else { text[count] = PhFormatString( L"%s: %.2f%%", processItem->ProcessName->Buffer, processItem->CpuUsage * 100 ); } PhDereferenceObject(processItem); } else { text[count] = PhCreateString(L"-"); } } break; case ID_STATUS_MAX_IO_PROCESS: { PPH_PROCESS_ITEM processItem; if (SystemStatistics.MaxIoProcessId && (processItem = PhReferenceProcessItem(SystemStatistics.MaxIoProcessId))) { if (!PH_IS_FAKE_PROCESS_ID(processItem->ProcessId)) { text[count] = PhFormatString( L"%s (%lu): %s", processItem->ProcessName->Buffer, HandleToUlong(processItem->ProcessId), PhaFormatSize(processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta, -1)->Buffer ); } else { text[count] = PhFormatString( L"%s: %s", processItem->ProcessName->Buffer, PhaFormatSize(processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta, -1)->Buffer ); } PhDereferenceObject(processItem); } else { text[count] = PhCreateString(L"-"); } } break; case ID_STATUS_NUMBEROFVISIBLEITEMS: { HWND tnHandle = NULL; tnHandle = GetCurrentTreeNewHandle(); if (tnHandle) { ULONG visibleCount = 0; visibleCount = TreeNew_GetFlatNodeCount(tnHandle); text[count] = PhFormatString( L"Visible: %lu", visibleCount ); } else { text[count] = PhCreateString( L"Visible: N/A" ); } } break; case ID_STATUS_NUMBEROFSELECTEDITEMS: { HWND tnHandle = NULL; tnHandle = GetCurrentTreeNewHandle(); if (tnHandle) { ULONG visibleCount = 0; ULONG selectedCount = 0; visibleCount = TreeNew_GetFlatNodeCount(tnHandle); for (ULONG i = 0; i < visibleCount; i++) { if (TreeNew_GetFlatNode(tnHandle, i)->Selected) selectedCount++; } text[count] = PhFormatString( L"Selected: %lu", selectedCount ); } else { text[count] = PhCreateString( L"Selected: N/A" ); } } break; case ID_STATUS_INTERVALSTATUS: { ULONG interval; interval = PhGetIntegerSetting(L"UpdateInterval"); if (UpdateAutomatically) { switch (interval) { case 500: text[count] = PhCreateString(L"Interval: Fast"); break; case 1000: text[count] = PhCreateString(L"Interval: Normal"); break; case 2000: text[count] = PhCreateString(L"Interval: Below Normal"); break; case 5000: text[count] = PhCreateString(L"Interval: Slow"); break; case 10000: text[count] = PhCreateString(L"Interval: Very Slow"); break; } } else { text[count] = PhCreateString(L"Interval: Paused"); } } break; } if (resetMaxWidths) StatusBarMaxWidths[count] = 0; if (!GetTextExtentPoint32(hdc, text[count]->Buffer, (ULONG)text[count]->Length / sizeof(WCHAR), &size)) size.cx = 200; if (count != 0) widths[count] = widths[count - 1]; else widths[count] = 0; width = size.cx + 10; if (width <= StatusBarMaxWidths[count]) { width = StatusBarMaxWidths[count]; } else { StatusBarMaxWidths[count] = width; } widths[count] += width; count++; } ReleaseDC(StatusBarHandle, hdc); SendMessage(StatusBarHandle, SB_SETPARTS, count, (LPARAM)widths); for (i = 0; i < count; i++) { SendMessage(StatusBarHandle, SB_SETTEXT, i, (LPARAM)text[i]->Buffer); PhDereferenceObject(text[i]); } }
PVIRUSTOTAL_API_RESPONSE VirusTotalRequestIpAddressReport( _In_ PPH_STRING IpAddress ) { PVIRUSTOTAL_API_RESPONSE result = NULL; PPH_BYTES jsonString = NULL; PPH_HTTP_CONTEXT httpContext = NULL; PPH_STRING versionString = NULL; PPH_STRING userAgentString = NULL; PPH_STRING urlPathString = NULL; PVOID jsonRootObject = NULL; versionString = PhGetPhVersion(); userAgentString = PhConcatStrings2(L"ProcessHacker_", versionString->Buffer); if (!PhHttpSocketCreate( &httpContext, PhGetString(userAgentString) )) { goto CleanupExit; } if (!PhHttpSocketConnect( httpContext, L"www.virustotal.com", PH_HTTP_DEFAULT_HTTPS_PORT )) { goto CleanupExit; } { PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlPathString = PhFormatString( L"%s%s%s%s%s%S%s%s", L"/vtapi", L"/v2", L"/ip-address", L"/report", L"?\x0061\x0070\x0069\x006B\x0065\x0079=", resourceString->Buffer, L"&ip=", IpAddress->Buffer ); PhClearReference(&resourceString); } if (!PhHttpSocketBeginRequest( httpContext, L"POST", PhGetString(urlPathString), PH_HTTP_FLAG_REFRESH | PH_HTTP_FLAG_SECURE )) { goto CleanupExit; } if (!PhHttpSocketAddRequestHeaders(httpContext, L"Content-Type: application/json", 0)) goto CleanupExit; if (!PhHttpSocketSendRequest(httpContext, NULL, 0)) goto CleanupExit; if (!PhHttpSocketEndRequest(httpContext)) goto CleanupExit; if (!(jsonString = PhHttpSocketDownloadString(httpContext, FALSE))) goto CleanupExit; if (!(jsonRootObject = PhCreateJsonParser(jsonString->Buffer))) goto CleanupExit; result = PhAllocate(sizeof(VIRUSTOTAL_API_RESPONSE)); memset(result, 0, sizeof(VIRUSTOTAL_API_RESPONSE)); //result->ResponseCode = PhGetJsonValueAsLong64(jsonRootObject, "response_code"); //result->StatusMessage = PhGetJsonValueAsString(jsonRootObject, "verbose_msg"); //result->PermaLink = PhGetJsonValueAsString(jsonRootObject, "permalink"); //result->ScanId = PhGetJsonValueAsString(jsonRootObject, "scan_id"); CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); if (jsonRootObject) PhFreeJsonParser(jsonRootObject); PhClearReference(&jsonString); PhClearReference(&versionString); PhClearReference(&userAgentString); return result; }
PVIRUSTOTAL_FILE_REPORT VirusTotalRequestFileReport( _In_ PPH_STRING FileHash ) { PVIRUSTOTAL_FILE_REPORT result = NULL; PPH_BYTES jsonString = NULL; PPH_HTTP_CONTEXT httpContext = NULL; PPH_STRING versionString = NULL; PPH_STRING userAgentString = NULL; PPH_STRING urlPathString = NULL; PVOID jsonRootObject = NULL; PVOID jsonScanObject; versionString = PhGetPhVersion(); userAgentString = PhConcatStrings2(L"ProcessHacker_", versionString->Buffer); if (!PhHttpSocketCreate( &httpContext, PhGetString(userAgentString) )) { goto CleanupExit; } if (!PhHttpSocketConnect( httpContext, L"www.virustotal.com", PH_HTTP_DEFAULT_HTTPS_PORT )) { goto CleanupExit; } { PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlPathString = PhFormatString( L"%s%s%s%s%s%S%s%s", L"/vtapi", L"/v2", L"/file", L"/report", L"?\x0061\x0070\x0069\x006B\x0065\x0079=", resourceString->Buffer, L"&resource=", FileHash->Buffer ); PhClearReference(&resourceString); } if (!PhHttpSocketBeginRequest( httpContext, L"POST", PhGetString(urlPathString), PH_HTTP_FLAG_REFRESH | PH_HTTP_FLAG_SECURE )) { goto CleanupExit; } if (!PhHttpSocketAddRequestHeaders(httpContext, L"Content-Type: application/json", 0)) goto CleanupExit; if (!PhHttpSocketSendRequest(httpContext, NULL, 0)) goto CleanupExit; if (!PhHttpSocketEndRequest(httpContext)) goto CleanupExit; if (!(jsonString = PhHttpSocketDownloadString(httpContext, FALSE))) goto CleanupExit; if (!(jsonRootObject = PhCreateJsonParser(jsonString->Buffer))) goto CleanupExit; result = PhAllocate(sizeof(VIRUSTOTAL_FILE_REPORT)); memset(result, 0, sizeof(VIRUSTOTAL_FILE_REPORT)); result->ResponseCode = PhGetJsonValueAsLong64(jsonRootObject, "response_code"); result->StatusMessage = PhGetJsonValueAsString(jsonRootObject, "verbose_msg"); result->PermaLink = PhGetJsonValueAsString(jsonRootObject, "permalink"); result->ScanDate = PhGetJsonValueAsString(jsonRootObject, "scan_date"); result->ScanId = PhGetJsonValueAsString(jsonRootObject, "scan_id"); result->Total = PhFormatUInt64(PhGetJsonValueAsLong64(jsonRootObject, "total"), FALSE); result->Positives = PhFormatUInt64(PhGetJsonValueAsLong64(jsonRootObject, "positives"), FALSE); //result->Md5 = PhGetJsonValueAsString(jsonRootObject, "md5"); //result->Sha1 = PhGetJsonValueAsString(jsonRootObject, "sha1"); //result->Sha256 = PhGetJsonValueAsString(jsonRootObject, "sha256"); if (jsonScanObject = PhGetJsonObject(jsonRootObject, "scans")) { PPH_LIST jsonArrayList; if (jsonArrayList = PhGetJsonObjectAsArrayList(jsonScanObject)) { result->ScanResults = PhCreateList(jsonArrayList->Count); for (ULONG i = 0; i < jsonArrayList->Count; i++) { PVIRUSTOTAL_FILE_REPORT_RESULT entry; PJSON_ARRAY_LIST_OBJECT object = jsonArrayList->Items[i]; entry = PhAllocate(sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); memset(entry, 0, sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); entry->Vendor = PhConvertUtf8ToUtf16(object->Key); entry->Detected = PhGetJsonObjectBool(object->Entry, "detected"); entry->EngineVersion = PhGetJsonValueAsString(object->Entry, "version"); entry->DetectionName = PhGetJsonValueAsString(object->Entry, "result"); entry->DatabaseDate = PhGetJsonValueAsString(object->Entry, "update"); PhAddItemList(result->ScanResults, entry); PhFree(object); } PhDereferenceObject(jsonArrayList); } } CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); if (jsonRootObject) PhFreeJsonParser(jsonRootObject); PhClearReference(&jsonString); PhClearReference(&versionString); PhClearReference(&userAgentString); return result; }
PPH_BYTES VirusTotalSendHttpRequest( _In_ PPH_BYTES JsonArray ) { PPH_BYTES subRequestBuffer = NULL; PPH_HTTP_CONTEXT httpContext = NULL; PPH_STRING versionString = NULL; PPH_STRING userAgentString = NULL; PPH_STRING urlPathString = NULL; versionString = PhGetPhVersion(); userAgentString = PhConcatStrings2(L"ProcessHacker_", versionString->Buffer); if (!PhHttpSocketCreate(&httpContext, PhGetString(userAgentString))) goto CleanupExit; if (!PhHttpSocketConnect(httpContext, L"www.virustotal.com", PH_HTTP_DEFAULT_HTTPS_PORT)) goto CleanupExit; { PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlPathString = PhFormatString( L"%s%s%s%s%S", L"/partners", L"/sysinternals", L"/file-reports", L"?\x0061\x0070\x0069\x006B\x0065\x0079=", resourceString->Buffer ); PhClearReference(&resourceString); } if (!PhHttpSocketBeginRequest( httpContext, L"POST", urlPathString->Buffer, PH_HTTP_FLAG_REFRESH | PH_HTTP_FLAG_SECURE )) { goto CleanupExit; } if (!PhHttpSocketAddRequestHeaders(httpContext, L"Content-Type: application/json", 0)) goto CleanupExit; if (!PhHttpSocketSendRequest(httpContext, JsonArray->Buffer, (ULONG)JsonArray->Length)) goto CleanupExit; if (!PhHttpSocketEndRequest(httpContext)) goto CleanupExit; if (!(subRequestBuffer = PhHttpSocketDownloadString(httpContext, FALSE))) goto CleanupExit; CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); PhClearReference(&urlPathString); PhClearReference(&versionString); PhClearReference(&userAgentString); if (JsonArray) PhDereferenceObject(JsonArray); return subRequestBuffer; }
static NTSTATUS DownloadUpdateThreadStart( __in PVOID Parameter ) { PPH_STRING downloadUrlPath = NULL; HANDLE tempFileHandle = NULL; HINTERNET hInitialize = NULL, hConnection = NULL, hRequest = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; HWND hwndDlg = (HWND)Parameter; Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), FALSE); SetDlgItemText(hwndDlg, IDC_STATUS, L"Initializing"); // Reset the progress state on Vista and above. if (WindowsVersion > WINDOWS_XP) SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETSTATE, PBST_NORMAL, 0L); if (!ConnectionAvailable()) return status; __try { // Get temp dir. WCHAR tempPathString[MAX_PATH]; DWORD tempPathLength = GetTempPath(MAX_PATH, tempPathString); if (tempPathLength == 0 || tempPathLength > MAX_PATH) { LogEvent(hwndDlg, PhFormatString(L"CreateFile failed (%d)", GetLastError())); __leave; } // create the download path string. downloadUrlPath = PhFormatString( L"/projects/processhacker/files/processhacker2/processhacker-%u.%u-setup.exe/download?use_mirror=autoselect", /* ?use_mirror=waix" */ UpdateData.MajorVersion, UpdateData.MinorVersion ); // Append the tempath to our string: %TEMP%processhacker-%u.%u-setup.exe // Example: C:\\Users\\dmex\\AppData\\Temp\\processhacker-2.10-setup.exe SetupFilePath = PhFormatString( L"%sprocesshacker-%u.%u-setup.exe", tempPathString, UpdateData.MajorVersion, UpdateData.MinorVersion ); // Create output file status = PhCreateFileWin32( &tempFileHandle, SetupFilePath->Buffer, FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_TEMPORARY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (!NT_SUCCESS(status)) { LogEvent(hwndDlg, PhFormatString(L"PhCreateFileWin32 failed (%s)", ((PPH_STRING)PHA_DEREFERENCE(PhGetNtMessage(status)))->Buffer)); __leave; } { // Create a user agent string. PPH_STRING phVersion = PhGetPhVersion(); PPH_STRING userAgent = PhConcatStrings2(L"PH Updater v", phVersion->Buffer); // Initialize the wininet library. if (!(hInitialize = InternetOpen( userAgent->Buffer, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ))) { LogEvent(hwndDlg, PhFormatString(L"Updater: (InitializeConnection) InternetOpen failed (%d)", GetLastError())); PhDereferenceObject(userAgent); PhDereferenceObject(phVersion); __leave; } PhDereferenceObject(userAgent); PhDereferenceObject(phVersion); } // Connect to the server. if (!(hConnection = InternetConnect( hInitialize, L"sourceforge.net", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0))) { LogEvent(hwndDlg, PhFormatString(L"InternetConnect failed (%d)", GetLastError())); __leave; } // Open the HTTP request. if (!(hRequest = HttpOpenRequest( hConnection, NULL, downloadUrlPath->Buffer, NULL, NULL, NULL, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RESYNCHRONIZE, 0 ))) { LogEvent(hwndDlg, PhFormatString(L"HttpOpenRequest failed (%d)", GetLastError())); __leave; } SetDlgItemText(hwndDlg, IDC_STATUS, L"Connecting"); // Send the HTTP request. if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) { LogEvent(hwndDlg, PhFormatString(L"HttpSendRequest failed (%d)", GetLastError())); // Enable the 'Retry' button. Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), TRUE); SetDlgItemText(hwndDlg, IDC_DOWNLOAD, L"Retry"); // Reset the state and let user retry the download. PhUpdaterState = Download; } else { BYTE hashBuffer[20]; DWORD contentLengthSize = sizeof(DWORD); PH_HASH_CONTEXT hashContext; // Initialize hash algorithm. PhInitializeHash(&hashContext, Sha1HashAlgorithm); if (!HttpQueryInfoW(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &contentLengthSize, 0)) { // No content length...impossible to calculate % complete... // we can read the data, BUT in this instance Sourceforge always returns the content length // so instead we'll exit here instead of downloading the file. LogEvent(hwndDlg, PhFormatString(L"HttpQueryInfo failed (%d)", GetLastError())); __leave; } else { BYTE buffer[PAGE_SIZE]; DWORD bytesRead = 0, startTick = 0; IO_STATUS_BLOCK isb; // Zero the buffer. ZeroMemory(buffer, PAGE_SIZE); // Reset the counters. bytesDownloaded = 0, timeTransferred = 0, LastUpdateTime = 0; IsUpdating = FALSE; // Start the clock. startTick = GetTickCount(); timeTransferred = startTick; // Download the data. while (InternetReadFile(hRequest, buffer, PAGE_SIZE, &bytesRead)) { // If we get zero bytes, the file was uploaded or there was an error. if (bytesRead == 0) break; // If window closed and thread handle was closed, just dispose and exit. // (This also skips error checking/prompts and updating the disposed UI) if (!DownloadThreadHandle) __leave; // Update the hash of bytes we downloaded. PhUpdateHash(&hashContext, buffer, bytesRead); // Write the downloaded bytes to disk. status = NtWriteFile( tempFileHandle, NULL, NULL, NULL, &isb, buffer, bytesRead, NULL, NULL ); if (!NT_SUCCESS(status)) { PPH_STRING message = PhGetNtMessage(status); LogEvent(hwndDlg, PhFormatString(L"NtWriteFile failed (%s)", message->Buffer)); PhDereferenceObject(message); break; } // Check dwBytesRead are the same dwBytesWritten length returned by WriteFile. if (bytesRead != isb.Information) { PPH_STRING message = PhGetNtMessage(status); LogEvent(hwndDlg, PhFormatString(L"NtWriteFile failed (%s)", message->Buffer)); PhDereferenceObject(message); break; } // Update our total bytes downloaded PhAcquireQueuedLockExclusive(&Lock); bytesDownloaded += (DWORD)isb.Information; PhReleaseQueuedLockExclusive(&Lock); AsyncUpdate(); } // Check if we downloaded the entire file. assert(bytesDownloaded == contentLength); // Compute our hash result. if (PhFinalHash(&hashContext, &hashBuffer, 20, NULL)) { // Allocate our hash string, hex the final hash result in our hashBuffer. PPH_STRING hexString = PhBufferToHexString(hashBuffer, 20); if (PhEqualString(hexString, UpdateData.Hash, TRUE)) { // If PH is not elevated, set the UAC shield for the install button as the setup requires elevation. if (!PhElevated) SendMessage(GetDlgItem(hwndDlg, IDC_DOWNLOAD), BCM_SETSHIELD, 0, TRUE); // Set the download result, don't include hash status since it succeeded. //SetDlgItemText(hwndDlg, IDC_STATUS, L"Download Complete"); // Set button text for next action Button_SetText(GetDlgItem(hwndDlg, IDC_DOWNLOAD), L"Install"); // Enable the Install button Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), TRUE); // Hash succeeded, set state as ready to install. PhUpdaterState = Install; } else { if (WindowsVersion > WINDOWS_XP) SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETSTATE, PBST_ERROR, 0L); SetDlgItemText(hwndDlg, IDC_STATUS, L"Download complete, SHA1 Hash failed."); // Set button text for next action Button_SetText(GetDlgItem(hwndDlg, IDC_DOWNLOAD), L"Retry"); // Enable the Install button Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), TRUE); // Hash failed, reset state to downloading so user can redownload the file. PhUpdaterState = Download; } PhDereferenceObject(hexString); } else { //SetDlgItemText(hwndDlg, IDC_STATUS, L"PhFinalHash failed"); // Show fancy Red progressbar if hash failed on Vista and above. if (WindowsVersion > WINDOWS_XP) SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETSTATE, PBST_ERROR, 0L); } } } status = STATUS_SUCCESS; } __finally { if (hInitialize) { InternetCloseHandle(hInitialize); hInitialize = NULL; } if (hConnection) { InternetCloseHandle(hConnection); hConnection = NULL; } if (hRequest) { InternetCloseHandle(hRequest); hRequest = NULL; } if (tempFileHandle) { NtClose(tempFileHandle); tempFileHandle = NULL; } if (downloadUrlPath) { PhDereferenceObject(downloadUrlPath); downloadUrlPath = NULL; } } return status; }
static NTSTATUS CheckUpdateThreadStart( __in PVOID Parameter ) { HWND hwndDlg = (HWND)Parameter; if (ConnectionAvailable()) { if (QueryXmlData()) { INT result = 0; PhGetPhVersionNumbers( &UpdateData.PhMajorVersion, &UpdateData.PhMinorVersion, NULL, &UpdateData.PhRevisionVersion ); result = 1;/*CompareVersions( UpdateData.MajorVersion, UpdateData.MinorVersion, UpdateData.PhMajorVersion, UpdateData.PhMinorVersion );*/ if (result > 0) { PPH_STRING summaryText = PhFormatString( L"Process Hacker %u.%u", UpdateData.MajorVersion, UpdateData.MinorVersion ); PPH_STRING releaseDateText = PhFormatString( L"Released: %s", UpdateData.RelDate->Buffer ); PPH_STRING releaseSizeText = PhFormatString( L"Size: %s", UpdateData.Size->Buffer ); SetDlgItemText(hwndDlg, IDC_MESSAGE, summaryText->Buffer); SetDlgItemText(hwndDlg, IDC_RELDATE, releaseDateText->Buffer); SetDlgItemText(hwndDlg, IDC_STATUS, releaseSizeText->Buffer); // Set the state for the button to know it can preform the download action. PhUpdaterState = Download; // Enable the download button. Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), TRUE); // Use the Scrollbar macro to enable the other controls. ScrollBar_Show(GetDlgItem(hwndDlg, IDC_PROGRESS), TRUE); ScrollBar_Show(GetDlgItem(hwndDlg, IDC_RELDATE), TRUE); ScrollBar_Show(GetDlgItem(hwndDlg, IDC_STATUS), TRUE); PhDereferenceObject(releaseSizeText); PhDereferenceObject(releaseDateText); PhDereferenceObject(summaryText); } else if (result == 0) { PPH_STRING summaryText = PhCreateString( L"No updates available" ); PPH_STRING versionText = PhFormatString( L"You're running the latest stable version: v%u.%u", UpdateData.MajorVersion, UpdateData.MinorVersion ); SetDlgItemText(hwndDlg, IDC_MESSAGE, summaryText->Buffer); SetDlgItemText(hwndDlg, IDC_RELDATE, versionText->Buffer); PhDereferenceObject(versionText); PhDereferenceObject(summaryText); } else if (result < 0) { PPH_STRING summaryText = PhCreateString( L"No updates available" ); PPH_STRING versionText = PhFormatString( L"You're running SVN build: v%u.%u (r%u)", UpdateData.PhMajorVersion, UpdateData.PhMinorVersion, UpdateData.PhRevisionVersion ); //swprintf_s( // szReleaseText, // _countof(szReleaseText), // L"Released: %s", // xmlData.RelDate // ); SetDlgItemText(hwndDlg, IDC_RELDATE, versionText->Buffer); SetDlgItemText(hwndDlg, IDC_MESSAGE, summaryText->Buffer); PhDereferenceObject(versionText); PhDereferenceObject(summaryText); } } } return STATUS_SUCCESS; }