PPH_STRING PhUnescapeStringForDelimiter( __in PPH_STRING String, __in WCHAR Delimiter ) { PH_STRING_BUILDER stringBuilder; SIZE_T length; SIZE_T i; length = String->Length / 2; PhInitializeStringBuilder(&stringBuilder, String->Length / 2 * 3); for (i = 0; i < length; i++) { if (String->Buffer[i] == '\\') { if (i != length - 1) { PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i + 1]); i++; } else { // Trailing backslash. Just ignore it. break; } } else { PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i]); } } return PhFinalStringBuilderString(&stringBuilder); }
PPH_STRING PhEscapeStringForDelimiter( __in PPH_STRING String, __in WCHAR Delimiter ) { PH_STRING_BUILDER stringBuilder; SIZE_T length; SIZE_T i; WCHAR temp[2]; length = String->Length / 2; PhInitializeStringBuilder(&stringBuilder, String->Length / 2 * 3); temp[0] = '\\'; for (i = 0; i < length; i++) { if (String->Buffer[i] == '\\' || String->Buffer[i] == Delimiter) { temp[1] = String->Buffer[i]; PhAppendStringBuilderEx(&stringBuilder, temp, 4); } else { PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i]); } } return PhFinalStringBuilderString(&stringBuilder); }
VOID LoadCounterList( _Inout_ PPH_LIST FilterList, _In_ PPH_STRING String ) { PH_STRING_BUILDER stringBuilder; PPH_PERFMON_ENTRY entry = NULL; PH_STRINGREF part; PH_STRINGREF remaining = String->sr; while (remaining.Length != 0) { entry = (PPH_PERFMON_ENTRY)PhAllocate(sizeof(PH_PERFMON_ENTRY)); memset(entry, 0, sizeof(PH_PERFMON_ENTRY)); PhInitializeStringBuilder(&stringBuilder, 20); PhSplitStringRefAtChar(&remaining, ',', &part, &remaining); for (SIZE_T i = 0; i < part.Length / sizeof(WCHAR); i++) { if (part.Buffer[i] == '\\') { if (i != part.Length - 1) { i++; PhAppendCharStringBuilder(&stringBuilder, part.Buffer[i]); } else { // Unescape backslashes - Just ignore chars. break; } } else { PhAppendCharStringBuilder(&stringBuilder, part.Buffer[i]); } } entry->Name = PhCreateString(stringBuilder.String->Buffer); PhDeleteStringBuilder(&stringBuilder); PhAddItemList(FilterList, entry); } }
static PPH_STRING SaveCounterList( _Inout_ PPH_LIST FilterList ) { PH_STRING_BUILDER stringBuilder; WCHAR temp[2]; PhInitializeStringBuilder(&stringBuilder, 100); temp[0] = '\\'; for (SIZE_T i = 0; i < FilterList->Count; i++) { PPH_PERFMON_ENTRY entry = (PPH_PERFMON_ENTRY)FilterList->Items[i]; SIZE_T length = entry->Name->Length / 2; for (SIZE_T ii = 0; ii < length; ii++) { if (entry->Name->Buffer[ii] == '\\') // escape backslashes { temp[1] = entry->Name->Buffer[ii]; PhAppendStringBuilderEx(&stringBuilder, temp, 4); } else { PhAppendCharStringBuilder(&stringBuilder, entry->Name->Buffer[ii]); } } PhAppendCharStringBuilder(&stringBuilder, ','); } if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 1, 1); return PhFinalStringBuilderString(&stringBuilder); }
PPH_STRING SaveFilterList( _Inout_ PPH_LIST FilterList ) { PH_STRING_BUILDER stringBuilder; SIZE_T i; SIZE_T j; WCHAR temp[2]; PhInitializeStringBuilder(&stringBuilder, 100); temp[0] = '\\'; for (i = 0; i < FilterList->Count; i++) { PFILTER_ENTRY entry = FilterList->Items[i]; SIZE_T length; // Write the entry type. temp[1] = entry->Type == FilterInclude ? 'i' : 'e'; PhAppendStringBuilderEx(&stringBuilder, temp, 4); // Write the filter string. length = entry->Filter->Length / 2; for (j = 0; j < length; j++) { if (entry->Filter->Buffer[j] == '\\') // escape backslashes { temp[1] = entry->Filter->Buffer[j]; PhAppendStringBuilderEx(&stringBuilder, temp, 4); } else { PhAppendCharStringBuilder(&stringBuilder, entry->Filter->Buffer[j]); } } } return PhFinalStringBuilderString(&stringBuilder); }
VOID PhpAppendStringWithLineBreaks( _Inout_ PPH_STRING_BUILDER StringBuilder, _In_ PPH_STRINGREF String, _In_ ULONG CharactersPerLine, _In_opt_ PPH_STRINGREF IndentAfterFirstLine ) { PH_STRINGREF line; SIZE_T bytesPerLine; BOOLEAN afterFirstLine; SIZE_T bytesToAppend; line = *String; bytesPerLine = CharactersPerLine * sizeof(WCHAR); afterFirstLine = FALSE; while (line.Length != 0) { bytesToAppend = line.Length; if (bytesToAppend > bytesPerLine) bytesToAppend = bytesPerLine; if (afterFirstLine) { PhAppendCharStringBuilder(StringBuilder, '\n'); if (IndentAfterFirstLine) PhAppendStringBuilder(StringBuilder, IndentAfterFirstLine); } PhAppendStringBuilderEx(StringBuilder, line.Buffer, bytesToAppend); afterFirstLine = TRUE; PhSkipStringRef(&line, bytesToAppend); } }
static INT_PTR CALLBACK NetworkOutputDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PNETWORK_OUTPUT_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PNETWORK_OUTPUT_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) { PhSaveWindowPlacementToSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg); PhDeleteLayoutManager(&context->LayoutManager); if (context->ProcessHandle) { // Terminate the child process. PhTerminateProcess(context->ProcessHandle, STATUS_SUCCESS); // Close the child process handle. NtClose(context->ProcessHandle); } // Close the pipe handle. if (context->PipeReadHandle) NtClose(context->PipeReadHandle); RemoveProp(hwndDlg, L"Context"); PhFree(context); } } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PH_RECTANGLE windowRectangle; context->WindowHandle = hwndDlg; context->OutputHandle = GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, context->OutputHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_MORE_INFO), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT); windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_POSITION); windowRectangle.Size = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_SIZE); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 190; rect.bottom = 120; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } // Check for first-run default position. if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0) { PhCenterWindow(hwndDlg, GetParent(hwndDlg)); } else { PhLoadWindowPlacementFromSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg); } if (context->IpAddress.Type == PH_IPV4_NETWORK_TYPE) { RtlIpv4AddressToString(&context->IpAddress.InAddr, context->IpAddressString); } else { RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->IpAddressString); } switch (context->Action) { case NETWORK_ACTION_TRACEROUTE: { HANDLE dialogThread = INVALID_HANDLE_VALUE; Static_SetText(context->WindowHandle, PhaFormatString(L"Tracing route to %s...", context->IpAddressString)->Buffer ); if (dialogThread = PhCreateThread(0, NetworkTracertThreadStart, (PVOID)context)) NtClose(dialogThread); } break; case NETWORK_ACTION_WHOIS: { HANDLE dialogThread = INVALID_HANDLE_VALUE; Static_SetText(context->WindowHandle, PhaFormatString(L"Whois %s...", context->IpAddressString)->Buffer ); ShowWindow(GetDlgItem(hwndDlg, IDC_MORE_INFO), SW_SHOW); if (dialogThread = PhCreateThread(0, NetworkWhoisThreadStart, (PVOID)context)) NtClose(dialogThread); } break; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: PostQuitMessage(0); break; } } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case WM_SIZING: PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); break; case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; HWND hwndChild = (HWND)lParam; // Check if old graph colors are enabled. if (!PhGetIntegerSetting(L"GraphColorMode")) break; // Set a transparent background for the control backcolor. SetBkMode(hDC, TRANSPARENT); // Check for our edit control and change the color. if (hwndChild == context->OutputHandle) { // Set text color as the Green PH graph text color. SetTextColor(hDC, RGB(124, 252, 0)); // Set a black control backcolor. return (INT_PTR)GetStockBrush(BLACK_BRUSH); } } break; case WM_NOTIFY: { switch (((LPNMHDR)lParam)->code) { case NM_CLICK: case NM_RETURN: { PNMLINK syslink = (PNMLINK)lParam; if (syslink->hdr.idFrom == IDC_MORE_INFO) { PhShellExecute( PhMainWndHandle, PhaConcatStrings2(L"http://wq.apnic.net/apnic-bin/whois.pl?searchtext=", context->IpAddressString)->Buffer, NULL ); } } break; } } break; case NTM_RECEIVEDTRACE: { OEM_STRING inputString; UNICODE_STRING convertedString; PH_STRING_BUILDER receivedString; if (wParam != 0) { inputString.Buffer = (PCHAR)lParam; inputString.Length = (USHORT)wParam; if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE))) { PPH_STRING windowText = NULL; PhInitializeStringBuilder(&receivedString, PAGE_SIZE); // Get the current output text. windowText = PhGetWindowText(context->OutputHandle); // Append the current output text to the New string. if (!PhIsNullOrEmptyString(windowText)) PhAppendStringBuilder(&receivedString, &windowText->sr); PhAppendFormatStringBuilder(&receivedString, L"%s", convertedString.Buffer); // Remove leading newlines. if (receivedString.String->Length >= 2 * 2 && receivedString.String->Buffer[0] == '\r' && receivedString.String->Buffer[1] == '\n') { PhRemoveStringBuilder(&receivedString, 0, 2); } SetWindowText(context->OutputHandle, receivedString.String->Buffer); SendMessage( context->OutputHandle, EM_SETSEL, receivedString.String->Length / 2 - 1, receivedString.String->Length / 2 - 1 ); SendMessage(context->OutputHandle, WM_VSCROLL, SB_BOTTOM, 0); PhDereferenceObject(windowText); PhDeleteStringBuilder(&receivedString); RtlFreeUnicodeString(&convertedString); } } } break; case NTM_RECEIVEDWHOIS: { OEM_STRING inputString; UNICODE_STRING convertedString; PH_STRING_BUILDER receivedString; if (lParam != 0) { inputString.Buffer = (PCHAR)lParam; inputString.Length = (USHORT)wParam; if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE))) { USHORT i; PhInitializeStringBuilder(&receivedString, PAGE_SIZE); // Convert carriage returns. for (i = 0; i < convertedString.Length; i++) { if (convertedString.Buffer[i] == '\n') { PhAppendStringBuilder2(&receivedString, L"\r\n"); } else { PhAppendCharStringBuilder(&receivedString, convertedString.Buffer[i]); } } // Remove leading newlines. if (receivedString.String->Length >= 2 * 2 && receivedString.String->Buffer[0] == '\r' && receivedString.String->Buffer[1] == '\n') { PhRemoveStringBuilder(&receivedString, 0, 2); } SetWindowText(context->OutputHandle, receivedString.String->Buffer); SendMessage( context->OutputHandle, EM_SETSEL, receivedString.String->Length / 2 - 1, receivedString.String->Length / 2 - 1 ); SendMessage(context->OutputHandle, WM_VSCROLL, SB_TOP, 0); PhDeleteStringBuilder(&receivedString); RtlFreeUnicodeString(&convertedString); } PhFree((PVOID)lParam); } } break; case NTM_RECEIVEDFINISH: { PPH_STRING windowText = PhGetWindowText(context->WindowHandle); if (windowText) { Static_SetText( context->WindowHandle, PhaFormatString(L"%s Finished.", windowText->Buffer)->Buffer ); PhDereferenceObject(windowText); } } break; } return FALSE; }
/** * Formats a text table to a list of lines. * * \param Table A pointer to the text table. * \param Rows The number of rows in the table. * \param Columns The number of columns in the table. * \param Mode The export formatting mode. * * \return A list of strings for each line in the output. The list object and * string objects are not auto-dereferenced. */ PPH_LIST PhaFormatTextTable( __in PPH_STRING **Table, __in ULONG Rows, __in ULONG Columns, __in ULONG Mode ) { PPH_LIST lines; // The tab count array contains the number of tabs need to fill the biggest // row cell in each column. PULONG tabCount; ULONG i; ULONG j; if (Mode == PH_EXPORT_MODE_TABS || Mode == PH_EXPORT_MODE_SPACES) { // Create the tab count array. PhCreateAlloc(&tabCount, sizeof(ULONG) * Columns); PhaDereferenceObject(tabCount); memset(tabCount, 0, sizeof(ULONG) * Columns); // zero all values for (i = 0; i < Rows; i++) { for (j = 0; j < Columns; j++) { ULONG newCount; if (Table[i][j]) newCount = (ULONG)(Table[i][j]->Length / sizeof(WCHAR) / TAB_SIZE); else newCount = 0; // Replace the existing count if this tab count is bigger. if (tabCount[j] < newCount) tabCount[j] = newCount; } } } // Create the final list of lines by going through each cell and appending // the proper tab count (if we are using tabs). This will make sure each column // is properly aligned. lines = PhCreateList(Rows); for (i = 0; i < Rows; i++) { PH_STRING_BUILDER stringBuilder; PhInitializeStringBuilder(&stringBuilder, 100); switch (Mode) { case PH_EXPORT_MODE_TABS: { for (j = 0; j < Columns; j++) { ULONG k; if (Table[i][j]) { // Calculate the number of tabs needed. k = (ULONG)(tabCount[j] + 1 - Table[i][j]->Length / sizeof(WCHAR) / TAB_SIZE); PhAppendStringBuilder(&stringBuilder, Table[i][j]); } else { k = tabCount[j] + 1; } PhAppendCharStringBuilder2(&stringBuilder, '\t', k); } } break; case PH_EXPORT_MODE_SPACES: { for (j = 0; j < Columns; j++) { ULONG k; if (Table[i][j]) { // Calculate the number of spaces needed. k = (ULONG)((tabCount[j] + 1) * TAB_SIZE - Table[i][j]->Length / sizeof(WCHAR)); PhAppendStringBuilder(&stringBuilder, Table[i][j]); } else { k = (tabCount[j] + 1) * TAB_SIZE; } PhAppendCharStringBuilder2(&stringBuilder, ' ', k); } } break; case PH_EXPORT_MODE_CSV: { for (j = 0; j < Columns; j++) { PhAppendCharStringBuilder(&stringBuilder, '\"'); if (Table[i][j]) { PhpEscapeStringForCsv(&stringBuilder, Table[i][j]); } PhAppendCharStringBuilder(&stringBuilder, '\"'); if (j != Columns - 1) PhAppendCharStringBuilder(&stringBuilder, ','); } } break; } PhAddItemList(lines, PhFinalStringBuilderString(&stringBuilder)); } return lines; }
VOID LoadFilterList( _Inout_ PPH_LIST FilterList, _In_ PPH_STRING String ) { PH_STRING_BUILDER stringBuilder; SIZE_T length; SIZE_T i; PFILTER_ENTRY entry; length = String->Length / 2; PhInitializeStringBuilder(&stringBuilder, 20); entry = NULL; for (i = 0; i < length; i++) { if (String->Buffer[i] == '\\') { if (i != length - 1) { i++; switch (String->Buffer[i]) { case 'i': case 'e': if (entry) { entry->Filter = PhFinalStringBuilderString(&stringBuilder); PhAddItemList(FilterList, entry); PhInitializeStringBuilder(&stringBuilder, 20); } entry = PhAllocate(sizeof(FILTER_ENTRY)); entry->Type = String->Buffer[i] == 'i' ? FilterInclude : FilterExclude; break; default: PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i]); break; } } else { // Trailing backslash. Just ignore it. break; } } else { PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i]); } } if (entry) { entry->Filter = PhFinalStringBuilderString(&stringBuilder); PhAddItemList(FilterList, entry); } else { PhDeleteStringBuilder(&stringBuilder); } }
PPH_STRING PhGetProcessTooltipText( __in PPH_PROCESS_ITEM Process ) { PH_STRING_BUILDER stringBuilder; PPH_STRING tempString; PhInitializeStringBuilder(&stringBuilder, 200); // Command line if (Process->CommandLine) { PhAppendStringBuilder(&stringBuilder, Process->CommandLine); PhAppendCharStringBuilder(&stringBuilder, '\n'); } // File information tempString = PhFormatImageVersionInfo( Process->FileName, &Process->VersionInfo, L" ", 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"File:\n"); PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); // Known command line information if (Process->CommandLine && Process->QueryHandle) { PH_KNOWN_PROCESS_TYPE knownProcessType; PH_KNOWN_PROCESS_COMMAND_LINE knownCommandLine; if (NT_SUCCESS(PhGetProcessKnownType( Process->QueryHandle, &knownProcessType )) && PhaGetProcessKnownCommandLine( Process->CommandLine, knownProcessType, &knownCommandLine )) { switch (knownProcessType & KnownProcessTypeMask) { case ServiceHostProcessType: PhAppendStringBuilder2(&stringBuilder, L"Service group name:\n "); PhAppendStringBuilder(&stringBuilder, knownCommandLine.ServiceHost.GroupName); PhAppendCharStringBuilder(&stringBuilder, '\n'); break; case RunDllAsAppProcessType: { PH_IMAGE_VERSION_INFO versionInfo; if (PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.RunDllAsApp.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.RunDllAsApp.FileName, &versionInfo, L" ", 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"Run DLL target file:\n"); PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; case ComSurrogateProcessType: { PH_IMAGE_VERSION_INFO versionInfo; PPH_STRING guidString; PhAppendStringBuilder2(&stringBuilder, L"COM target:\n"); if (knownCommandLine.ComSurrogate.Name) { PhAppendStringBuilder2(&stringBuilder, L" "); PhAppendStringBuilder(&stringBuilder, knownCommandLine.ComSurrogate.Name); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (guidString = PhFormatGuid(&knownCommandLine.ComSurrogate.Guid)) { PhAppendStringBuilder2(&stringBuilder, L" "); PhAppendStringBuilder(&stringBuilder, guidString); PhDereferenceObject(guidString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (knownCommandLine.ComSurrogate.FileName && PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.ComSurrogate.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.ComSurrogate.FileName, &versionInfo, L" ", 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"COM target file:\n"); PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; } } } // Services if (Process->ServiceList && Process->ServiceList->Count != 0) { ULONG enumerationKey = 0; PPH_SERVICE_ITEM serviceItem; PPH_LIST serviceList; ULONG i; // Copy the service list into our own list so we can sort it. serviceList = PhCreateList(Process->ServiceList->Count); PhAcquireQueuedLockShared(&Process->ServiceListLock); while (PhEnumPointerList( Process->ServiceList, &enumerationKey, &serviceItem )) { PhReferenceObject(serviceItem); PhAddItemList(serviceList, serviceItem); } PhReleaseQueuedLockShared(&Process->ServiceListLock); qsort(serviceList->Items, serviceList->Count, sizeof(PPH_SERVICE_ITEM), ServiceForTooltipCompare); PhAppendStringBuilder2(&stringBuilder, L"Services:\n"); // Add the services. for (i = 0; i < serviceList->Count; i++) { serviceItem = serviceList->Items[i]; PhAppendStringBuilder2(&stringBuilder, L" "); PhAppendStringBuilder(&stringBuilder, serviceItem->Name); PhAppendStringBuilder2(&stringBuilder, L" ("); PhAppendStringBuilder(&stringBuilder, serviceItem->DisplayName); PhAppendStringBuilder2(&stringBuilder, L")\n"); } PhDereferenceObjects(serviceList->Items, serviceList->Count); PhDereferenceObject(serviceList); } // Tasks if (PhEqualString2(Process->ProcessName, L"taskeng.exe", TRUE) || PhEqualString2(Process->ProcessName, L"taskhost.exe", TRUE)) { PH_STRING_BUILDER tasks; PhInitializeStringBuilder(&tasks, 40); PhpFillRunningTasks(Process, &tasks); if (tasks.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Tasks:\n"); PhAppendStringBuilder(&stringBuilder, tasks.String); } PhDeleteStringBuilder(&tasks); } // Plugin if (PhPluginsEnabled) { PH_PLUGIN_GET_TOOLTIP_TEXT getTooltipText; getTooltipText.Parameter = Process; getTooltipText.StringBuilder = &stringBuilder; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackGetProcessTooltipText), &getTooltipText); } // Notes { PH_STRING_BUILDER notes; PhInitializeStringBuilder(¬es, 40); if (Process->FileName) { if (Process->VerifyResult == VrTrusted) { if (!PhIsNullOrEmptyString(Process->VerifySignerName)) PhAppendFormatStringBuilder(¬es, L" Signer: %s\n", Process->VerifySignerName->Buffer); else PhAppendStringBuilder2(¬es, L" Signed.\n"); } else if (Process->VerifyResult == VrUnknown) { // Nothing } else if (Process->VerifyResult != VrNoSignature) { PhAppendStringBuilder2(¬es, L" Signature invalid.\n"); } } if (Process->IsPacked) { PhAppendFormatStringBuilder( ¬es, L" Image is probably packed (%u imports over %u modules).\n", Process->ImportFunctions, Process->ImportModules ); } if (Process->ConsoleHostProcessId) { CLIENT_ID clientId; PPH_STRING clientIdString; clientId.UniqueProcess = Process->ConsoleHostProcessId; clientId.UniqueThread = NULL; clientIdString = PhGetClientIdName(&clientId); PhAppendFormatStringBuilder(¬es, L" Console host: %s\n", clientIdString->Buffer); PhDereferenceObject(clientIdString); } if (Process->IsDotNet) PhAppendStringBuilder2(¬es, L" Process is managed (.NET).\n"); if (Process->IsElevated) PhAppendStringBuilder2(¬es, L" Process is elevated.\n"); if (Process->IsInJob) PhAppendStringBuilder2(¬es, L" Process is in a job.\n"); if (Process->IsPosix) PhAppendStringBuilder2(¬es, L" Process is POSIX.\n"); if (Process->IsWow64) PhAppendStringBuilder2(¬es, L" Process is 32-bit (WOW64).\n"); if (notes.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Notes:\n"); PhAppendStringBuilder(&stringBuilder, notes.String); } PhDeleteStringBuilder(¬es); } // Remove the trailing newline. if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 1, 1); return PhFinalStringBuilderString(&stringBuilder); }
PPH_STRING PhGetServiceTooltipText( __in PPH_SERVICE_ITEM Service ) { PH_STRING_BUILDER stringBuilder; PPH_STRING tempString; SC_HANDLE serviceHandle; PhInitializeStringBuilder(&stringBuilder, 200); if (serviceHandle = PhOpenService(Service->Name->Buffer, SERVICE_QUERY_CONFIG)) { //LPQUERY_SERVICE_CONFIG config; // File information // (Disabled for now because of file name resolution issues) /*if (config = PhGetServiceConfig(serviceHandle)) { PPH_STRING fileName; PPH_STRING newFileName; PH_IMAGE_VERSION_INFO versionInfo; fileName = PhCreateString(config->lpBinaryPathName); newFileName = PhGetFileName(fileName); PhDereferenceObject(fileName); fileName = newFileName; if (PhInitializeImageVersionInfo( &versionInfo, fileName->Buffer )) { tempString = PhFormatImageVersionInfo( fileName, &versionInfo, L" ", 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"File:\n"); PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } PhDereferenceObject(fileName); PhFree(config); }*/ // Description if (tempString = PhGetServiceDescription(serviceHandle)) { PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); PhDereferenceObject(tempString); } CloseServiceHandle(serviceHandle); } // Remove the trailing newline. if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 1, 1); return PhFinalStringBuilderString(&stringBuilder); }
BOOLEAN PhShellProcessHacker( __in HWND hWnd, __in_opt PWSTR Parameters, __in ULONG ShowWindowType, __in ULONG Flags, __in ULONG AppFlags, __in_opt ULONG Timeout, __out_opt PHANDLE ProcessHandle ) { BOOLEAN result; PH_STRING_BUILDER sb; PWSTR parameters; PPH_STRING temp; if (AppFlags & PH_SHELL_APP_PROPAGATE_PARAMETERS) { PhInitializeStringBuilder(&sb, 128); if (Parameters) PhAppendStringBuilder2(&sb, Parameters); // Propagate parameters. if (PhStartupParameters.NoSettings) { PhAppendStringBuilder2(&sb, L" -nosettings"); } else if (PhStartupParameters.SettingsFileName && PhSettingsFileName) { PhAppendStringBuilder2(&sb, L" -settings \""); temp = PhEscapeCommandLinePart(&PhSettingsFileName->sr); PhAppendStringBuilder(&sb, temp); PhDereferenceObject(temp); PhAppendCharStringBuilder(&sb, '\"'); } if (PhStartupParameters.NoKph) { PhAppendStringBuilder2(&sb, L" -nokph"); } if (PhStartupParameters.NoPlugins) { PhAppendStringBuilder2(&sb, L" -noplugins"); } if (PhStartupParameters.NewInstance) { PhAppendStringBuilder2(&sb, L" -newinstance"); } if (!(AppFlags & PH_SHELL_APP_PROPAGATE_PARAMETERS_IGNORE_VISIBILITY)) { if (PhStartupParameters.ShowVisible) { PhAppendStringBuilder2(&sb, L" -v"); } if (PhStartupParameters.ShowHidden) { PhAppendStringBuilder2(&sb, L" -hide"); } } parameters = sb.String->Buffer; } else { parameters = Parameters; } result = PhShellExecuteEx( hWnd, PhApplicationFileName->Buffer, parameters, ShowWindowType, Flags, Timeout, ProcessHandle ); if (AppFlags & PH_SHELL_APP_PROPAGATE_PARAMETERS) PhDeleteStringBuilder(&sb); return result; }
BOOLEAN QueryUpdateData( _Inout_ PPH_UPDATER_CONTEXT Context ) { BOOLEAN success = FALSE; PPH_HTTP_CONTEXT httpContext = NULL; PPH_BYTES jsonString = NULL; PVOID jsonObject = NULL; if (!PhHttpSocketCreate(&httpContext, NULL)) { Context->ErrorCode = GetLastError(); goto CleanupExit; } if (!PhHttpSocketConnect( httpContext, L"wj32.org", PH_HTTP_DEFAULT_HTTPS_PORT )) { Context->ErrorCode = GetLastError(); goto CleanupExit; } if (!PhHttpSocketBeginRequest( httpContext, NULL, L"/processhacker/nightly.php?phupdater", PH_HTTP_FLAG_REFRESH | PH_HTTP_FLAG_SECURE )) { Context->ErrorCode = GetLastError(); goto CleanupExit; } { PPH_STRING versionHeader; PPH_STRING windowsHeader; if (versionHeader = UpdateVersionString()) { PhHttpSocketAddRequestHeaders(httpContext, versionHeader->Buffer, (ULONG)versionHeader->Length / sizeof(WCHAR)); PhDereferenceObject(versionHeader); } if (windowsHeader = UpdateWindowsString()) { PhHttpSocketAddRequestHeaders(httpContext, windowsHeader->Buffer, (ULONG)windowsHeader->Length / sizeof(WCHAR)); PhDereferenceObject(windowsHeader); } } if (!PhHttpSocketSendRequest(httpContext, NULL, 0)) { Context->ErrorCode = GetLastError(); goto CleanupExit; } if (!PhHttpSocketEndRequest(httpContext)) { Context->ErrorCode = GetLastError(); goto CleanupExit; } if (!(jsonString = PhHttpSocketDownloadString(httpContext, FALSE))) { Context->ErrorCode = GetLastError(); goto CleanupExit; } if (!(jsonObject = PhCreateJsonParser(jsonString->Buffer))) goto CleanupExit; Context->Version = PhGetJsonValueAsString(jsonObject, "version"); Context->RelDate = PhGetJsonValueAsString(jsonObject, "updated"); Context->SetupFileDownloadUrl = PhGetJsonValueAsString(jsonObject, "setup_url"); Context->SetupFileLength = PhFormatSize(PhGetJsonValueAsLong64(jsonObject, "setup_length"), 2); Context->SetupFileHash = PhGetJsonValueAsString(jsonObject, "setup_hash"); Context->SetupFileSignature = PhGetJsonValueAsString(jsonObject, "setup_sig"); Context->BuildMessage = PhGetJsonValueAsString(jsonObject, "changelog"); PhFreeJsonParser(jsonObject); if (PhIsNullOrEmptyString(Context->Version)) goto CleanupExit; if (PhIsNullOrEmptyString(Context->RelDate)) goto CleanupExit; if (PhIsNullOrEmptyString(Context->SetupFileDownloadUrl)) goto CleanupExit; if (PhIsNullOrEmptyString(Context->SetupFileLength)) goto CleanupExit; if (PhIsNullOrEmptyString(Context->SetupFileHash)) goto CleanupExit; if (PhIsNullOrEmptyString(Context->SetupFileSignature)) goto CleanupExit; if (PhIsNullOrEmptyString(Context->BuildMessage)) goto CleanupExit; success = TRUE; CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); if (jsonString) PhDereferenceObject(jsonString); if (success && !PhIsNullOrEmptyString(Context->BuildMessage)) { PH_STRING_BUILDER sb; PhInitializeStringBuilder(&sb, 0x100); for (SIZE_T i = 0; i < Context->BuildMessage->Length / sizeof(WCHAR); i++) { if (Context->BuildMessage->Data[i] == '\n') PhAppendStringBuilder2(&sb, L"\r\n"); else PhAppendCharStringBuilder(&sb, Context->BuildMessage->Data[i]); } PhMoveReference(&Context->BuildMessage, PhFinalStringBuilderString(&sb)); } return success; }
INT_PTR CALLBACK EspServiceOtherDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_OTHER_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_OTHER_CONTEXT)); memset(context, 0, sizeof(SERVICE_OTHER_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_OTHER_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; HWND privilegesLv; context->ServiceItem = serviceItem; context->PrivilegesLv = privilegesLv = GetDlgItem(hwndDlg, IDC_PRIVILEGES); PhSetListViewStyle(privilegesLv, FALSE, TRUE); PhSetControlTheme(privilegesLv, L"explorer"); PhAddListViewColumn(privilegesLv, 0, 0, 0, LVCFMT_LEFT, 140, L"Name"); PhAddListViewColumn(privilegesLv, 1, 1, 1, LVCFMT_LEFT, 220, L"Display Name"); PhSetExtendedListView(privilegesLv); context->PrivilegeList = PhCreateList(32); if (context->ServiceItem->Type == SERVICE_KERNEL_DRIVER || context->ServiceItem->Type == SERVICE_FILE_SYSTEM_DRIVER) { // Drivers don't support required privileges. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); } EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_SIDTYPE), EspServiceSidTypeStrings, sizeof(EspServiceSidTypeStrings) / sizeof(PWSTR)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_PROTECTION), EspServiceLaunchProtectedStrings, sizeof(EspServiceLaunchProtectedStrings) / sizeof(PWSTR)); if (WindowsVersion < WINDOWS_8_1) EnableWindow(GetDlgItem(hwndDlg, IDC_PROTECTION), FALSE); SetDlgItemText(hwndDlg, IDC_SERVICESID, PhGetStringOrDefault(PH_AUTO(EspGetServiceSidString(&serviceItem->Name->sr)), L"N/A")); status = EspLoadOtherInfo(hwndDlg, context); if (!NT_SUCCESS(status)) { PhShowWarning(hwndDlg, L"Unable to query service information: %s", ((PPH_STRING)PH_AUTO(PhGetNtMessage(status)))->Buffer); } context->Ready = TRUE; } break; case WM_DESTROY: { if (context->PrivilegeList) { PhDereferenceObjects(context->PrivilegeList->Items, context->PrivilegeList->Count); PhDereferenceObject(context->PrivilegeList); } PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD: { NTSTATUS status; LSA_HANDLE policyHandle; LSA_ENUMERATION_HANDLE enumContext; PPOLICY_PRIVILEGE_DEFINITION buffer; ULONG count; ULONG i; PPH_LIST choices; PPH_STRING selectedChoice = NULL; choices = PH_AUTO(PhCreateList(100)); if (!NT_SUCCESS(status = PhOpenLsaPolicy(&policyHandle, POLICY_VIEW_LOCAL_INFORMATION, NULL))) { PhShowStatus(hwndDlg, L"Unable to open LSA policy", status, 0); break; } enumContext = 0; while (TRUE) { status = LsaEnumeratePrivileges( policyHandle, &enumContext, &buffer, 0x100, &count ); if (status == STATUS_NO_MORE_ENTRIES) break; if (!NT_SUCCESS(status)) break; for (i = 0; i < count; i++) { PhAddItemList(choices, PhaCreateStringEx(buffer[i].Name.Buffer, buffer[i].Name.Length)->Buffer); } LsaFreeMemory(buffer); } LsaClose(policyHandle); qsort(choices->Items, choices->Count, sizeof(PWSTR), PrivilegeNameCompareFunction); while (PhaChoiceDialog( hwndDlg, L"Add privilege", L"Select a privilege to add:", (PWSTR *)choices->Items, choices->Count, NULL, PH_CHOICE_DIALOG_CHOICE, &selectedChoice, NULL, NULL )) { BOOLEAN found = FALSE; PPH_STRING privilegeString; INT lvItemIndex; PPH_STRING displayName; // Check for duplicates. for (i = 0; i < context->PrivilegeList->Count; i++) { if (PhEqualString(context->PrivilegeList->Items[i], selectedChoice, FALSE)) { found = TRUE; break; } } if (found) { if (PhShowMessage( hwndDlg, MB_OKCANCEL | MB_ICONERROR, L"The selected privilege has already been added." ) == IDOK) { continue; } else { break; } } PhSetReference(&privilegeString, selectedChoice); PhAddItemList(context->PrivilegeList, privilegeString); lvItemIndex = PhAddListViewItem(context->PrivilegesLv, MAXINT, privilegeString->Buffer, privilegeString); if (PhLookupPrivilegeDisplayName(&privilegeString->sr, &displayName)) { PhSetListViewSubItem(context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer); PhDereferenceObject(displayName); } ExtendedListView_SortItems(context->PrivilegesLv); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; break; } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_STRING privilegeString; ULONG index; lvItemIndex = ListView_GetNextItem(context->PrivilegesLv, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->PrivilegesLv, lvItemIndex, (PVOID *)&privilegeString)) { index = PhFindItemList(context->PrivilegeList, privilegeString); if (index != -1) { PhDereferenceObject(privilegeString); PhRemoveItemList(context->PrivilegeList, index); PhRemoveListViewItem(context->PrivilegesLv, lvItemIndex); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; } } } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) { context->Dirty = TRUE; switch (LOWORD(wParam)) { case IDC_PRESHUTDOWNTIMEOUT: context->PreshutdownTimeoutValid = TRUE; break; case IDC_SIDTYPE: context->SidTypeValid = TRUE; break; case IDC_PROTECTION: context->LaunchProtectedValid = TRUE; break; } } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { SC_HANDLE serviceHandle = NULL; ULONG win32Result = 0; BOOLEAN connectedToPhSvc = FALSE; PPH_STRING launchProtectedString; ULONG launchProtected; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); launchProtectedString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_PROTECTION))); launchProtected = EspGetServiceLaunchProtectedInteger(launchProtectedString->Buffer); if (context->LaunchProtectedValid && launchProtected != 0 && launchProtected != context->OriginalLaunchProtected) { if (PhShowMessage( hwndDlg, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2, L"Setting service protection will prevent the service from being controlled, modified, or deleted. Do you want to continue?" ) == IDNO) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; } } if (context->Dirty) { SERVICE_PRESHUTDOWN_INFO preshutdownInfo; SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo; SERVICE_SID_INFO sidInfo; SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo; if (!(serviceHandle = PhOpenService(context->ServiceItem->Name->Buffer, SERVICE_CHANGE_CONFIG))) { win32Result = GetLastError(); if (win32Result == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { win32Result = 0; connectedToPhSvc = TRUE; } else { // User cancelled elevation. win32Result = ERROR_CANCELLED; goto Done; } } else { goto Done; } } if (context->PreshutdownTimeoutValid) { preshutdownInfo.dwPreshutdownTimeout = GetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, NULL, FALSE); if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_PRESHUTDOWN_INFO, &preshutdownInfo)) { win32Result = GetLastError(); } } if (context->RequiredPrivilegesValid) { PH_STRING_BUILDER sb; ULONG i; PhInitializeStringBuilder(&sb, 100); for (i = 0; i < context->PrivilegeList->Count; i++) { PhAppendStringBuilder(&sb, &((PPH_STRING)context->PrivilegeList->Items[i])->sr); PhAppendCharStringBuilder(&sb, 0); } requiredPrivilegesInfo.pmszRequiredPrivileges = sb.String->Buffer; if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivilegesInfo)) { win32Result = GetLastError(); } PhDeleteStringBuilder(&sb); } if (context->SidTypeValid) { PPH_STRING sidTypeString; sidTypeString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_SIDTYPE))); sidInfo.dwServiceSidType = EspGetServiceSidTypeInteger(sidTypeString->Buffer); if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo)) { win32Result = GetLastError(); } } if (context->LaunchProtectedValid) { launchProtectedInfo.dwLaunchProtected = launchProtected; if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_LAUNCH_PROTECTED, &launchProtectedInfo)) { // For now, ignore errors here. // win32Result = GetLastError(); } } Done: if (connectedToPhSvc) PhUiDisconnectFromPhSvc(); if (serviceHandle) CloseServiceHandle(serviceHandle); if (win32Result != 0) { if (win32Result == ERROR_CANCELLED || PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service information: %s", ((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } } return TRUE; } break; case LVN_ITEMCHANGED: { if (header->hwndFrom == context->PrivilegesLv) { EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), ListView_GetSelectedCount(context->PrivilegesLv) == 1); } } break; } } break; } return FALSE; }
PPH_STRING PhGetProcessTooltipText( _In_ PPH_PROCESS_ITEM Process, _Out_opt_ PULONG ValidToTickCount ) { PH_STRING_BUILDER stringBuilder; ULONG validForMs = 60 * 60 * 1000; // 1 hour PPH_STRING tempString; PH_KNOWN_PROCESS_TYPE knownProcessType = UnknownProcessType; PhInitializeStringBuilder(&stringBuilder, 200); // Command line if (Process->CommandLine) { tempString = PhEllipsisString(Process->CommandLine, 100 * 10); // This is necessary because the tooltip control seems to use some kind of O(n^9999) word-wrapping // algorithm. PhpAppendStringWithLineBreaks(&stringBuilder, &tempString->sr, 100, NULL); PhAppendCharStringBuilder(&stringBuilder, '\n'); PhDereferenceObject(tempString); } // File information tempString = PhFormatImageVersionInfo( Process->FileName, &Process->VersionInfo, &StandardIndent, 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"File:\n"); PhAppendStringBuilder(&stringBuilder, &tempString->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); // Known command line information if (Process->QueryHandle) PhGetProcessKnownType(Process->QueryHandle, &knownProcessType); if (Process->CommandLine && Process->QueryHandle) { PH_KNOWN_PROCESS_COMMAND_LINE knownCommandLine; if (knownProcessType != UnknownProcessType && PhaGetProcessKnownCommandLine( Process->CommandLine, knownProcessType, &knownCommandLine )) { switch (knownProcessType & KnownProcessTypeMask) { case ServiceHostProcessType: PhAppendStringBuilder2(&stringBuilder, L"Service group name:\n "); PhAppendStringBuilder(&stringBuilder, &knownCommandLine.ServiceHost.GroupName->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); break; case RunDllAsAppProcessType: { PH_IMAGE_VERSION_INFO versionInfo; if (PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.RunDllAsApp.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.RunDllAsApp.FileName, &versionInfo, &StandardIndent, 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"Run DLL target file:\n"); PhAppendStringBuilder(&stringBuilder, &tempString->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; case ComSurrogateProcessType: { PH_IMAGE_VERSION_INFO versionInfo; PPH_STRING guidString; PhAppendStringBuilder2(&stringBuilder, L"COM target:\n"); if (knownCommandLine.ComSurrogate.Name) { PhAppendStringBuilder(&stringBuilder, &StandardIndent); PhAppendStringBuilder(&stringBuilder, &knownCommandLine.ComSurrogate.Name->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (guidString = PhFormatGuid(&knownCommandLine.ComSurrogate.Guid)) { PhAppendStringBuilder(&stringBuilder, &StandardIndent); PhAppendStringBuilder(&stringBuilder, &guidString->sr); PhDereferenceObject(guidString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (knownCommandLine.ComSurrogate.FileName && PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.ComSurrogate.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.ComSurrogate.FileName, &versionInfo, &StandardIndent, 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"COM target file:\n"); PhAppendStringBuilder(&stringBuilder, &tempString->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; } } } // Services if (Process->ServiceList && Process->ServiceList->Count != 0) { ULONG enumerationKey = 0; PPH_SERVICE_ITEM serviceItem; PPH_LIST serviceList; ULONG i; // Copy the service list into our own list so we can sort it. serviceList = PhCreateList(Process->ServiceList->Count); PhAcquireQueuedLockShared(&Process->ServiceListLock); while (PhEnumPointerList( Process->ServiceList, &enumerationKey, &serviceItem )) { PhReferenceObject(serviceItem); PhAddItemList(serviceList, serviceItem); } PhReleaseQueuedLockShared(&Process->ServiceListLock); qsort(serviceList->Items, serviceList->Count, sizeof(PPH_SERVICE_ITEM), ServiceForTooltipCompare); PhAppendStringBuilder2(&stringBuilder, L"Services:\n"); // Add the services. for (i = 0; i < serviceList->Count; i++) { serviceItem = serviceList->Items[i]; PhAppendStringBuilder(&stringBuilder, &StandardIndent); PhAppendStringBuilder(&stringBuilder, &serviceItem->Name->sr); PhAppendStringBuilder2(&stringBuilder, L" ("); PhAppendStringBuilder(&stringBuilder, &serviceItem->DisplayName->sr); PhAppendStringBuilder2(&stringBuilder, L")\n"); } PhDereferenceObjects(serviceList->Items, serviceList->Count); PhDereferenceObject(serviceList); } // Tasks, Drivers switch (knownProcessType & KnownProcessTypeMask) { case TaskHostProcessType: { PH_STRING_BUILDER tasks; PhInitializeStringBuilder(&tasks, 40); PhpFillRunningTasks(Process, &tasks); if (tasks.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Tasks:\n"); PhAppendStringBuilder(&stringBuilder, &tasks.String->sr); } PhDeleteStringBuilder(&tasks); } break; case UmdfHostProcessType: { PH_STRING_BUILDER drivers; PhInitializeStringBuilder(&drivers, 40); PhpFillUmdfDrivers(Process, &drivers); if (drivers.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Drivers:\n"); PhAppendStringBuilder(&stringBuilder, &drivers.String->sr); } PhDeleteStringBuilder(&drivers); validForMs = 10 * 1000; // 10 seconds } break; } // Plugin if (PhPluginsEnabled) { PH_PLUGIN_GET_TOOLTIP_TEXT getTooltipText; getTooltipText.Parameter = Process; getTooltipText.StringBuilder = &stringBuilder; getTooltipText.ValidForMs = validForMs; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackGetProcessTooltipText), &getTooltipText); validForMs = getTooltipText.ValidForMs; } // Notes { PH_STRING_BUILDER notes; PhInitializeStringBuilder(¬es, 40); if (Process->FileName) { if (Process->VerifyResult == VrTrusted) { if (!PhIsNullOrEmptyString(Process->VerifySignerName)) PhAppendFormatStringBuilder(¬es, L" Signer: %s\n", Process->VerifySignerName->Buffer); else PhAppendStringBuilder2(¬es, L" Signed.\n"); } else if (Process->VerifyResult == VrUnknown) { // Nothing } else if (Process->VerifyResult != VrNoSignature) { PhAppendStringBuilder2(¬es, L" Signature invalid.\n"); } } if (Process->IsPacked) { PhAppendFormatStringBuilder( ¬es, L" Image is probably packed (%u imports over %u modules).\n", Process->ImportFunctions, Process->ImportModules ); } if ((ULONG_PTR)Process->ConsoleHostProcessId & ~3) { CLIENT_ID clientId; PWSTR description = L"Console host"; PPH_STRING clientIdString; clientId.UniqueProcess = (HANDLE)((ULONG_PTR)Process->ConsoleHostProcessId & ~3); clientId.UniqueThread = NULL; if ((ULONG_PTR)Process->ConsoleHostProcessId & 2) description = L"Console application"; clientIdString = PhGetClientIdName(&clientId); PhAppendFormatStringBuilder(¬es, L" %s: %s\n", description, clientIdString->Buffer); PhDereferenceObject(clientIdString); } if (Process->PackageFullName) { PhAppendFormatStringBuilder(¬es, L" Package name: %s\n", Process->PackageFullName->Buffer); } if (Process->IsDotNet) PhAppendStringBuilder2(¬es, L" Process is managed (.NET).\n"); if (Process->IsElevated) PhAppendStringBuilder2(¬es, L" Process is elevated.\n"); if (Process->IsImmersive) PhAppendStringBuilder2(¬es, L" Process is a Modern UI app.\n"); if (Process->IsInJob) PhAppendStringBuilder2(¬es, L" Process is in a job.\n"); if (Process->IsPosix) PhAppendStringBuilder2(¬es, L" Process is POSIX.\n"); if (Process->IsWow64) PhAppendStringBuilder2(¬es, L" Process is 32-bit (WOW64).\n"); if (notes.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Notes:\n"); PhAppendStringBuilder(&stringBuilder, ¬es.String->sr); } PhDeleteStringBuilder(¬es); } if (ValidToTickCount) *ValidToTickCount = GetTickCount() + validForMs; // Remove the trailing newline. if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); return PhFinalStringBuilderString(&stringBuilder); }
PPH_STRING PhGetServiceTooltipText( _In_ PPH_SERVICE_ITEM Service ) { PH_STRING_BUILDER stringBuilder; SC_HANDLE serviceHandle; PhInitializeStringBuilder(&stringBuilder, 200); if (serviceHandle = PhOpenService(Service->Name->Buffer, SERVICE_QUERY_CONFIG)) { PPH_STRING fileName; PPH_STRING description; // File information if (fileName = PhGetServiceRelevantFileName(&Service->Name->sr, serviceHandle)) { PH_IMAGE_VERSION_INFO versionInfo; PPH_STRING versionInfoText; if (PhInitializeImageVersionInfo( &versionInfo, fileName->Buffer )) { versionInfoText = PhFormatImageVersionInfo( fileName, &versionInfo, &StandardIndent, 0 ); if (!PhIsNullOrEmptyString(versionInfoText)) { PhAppendStringBuilder2(&stringBuilder, L"File:\n"); PhAppendStringBuilder(&stringBuilder, &versionInfoText->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } PhClearReference(&versionInfoText); PhDeleteImageVersionInfo(&versionInfo); } PhDereferenceObject(fileName); } // Description if (description = PhGetServiceDescription(serviceHandle)) { PhAppendStringBuilder2(&stringBuilder, L"Description:\n "); PhAppendStringBuilder(&stringBuilder, &description->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); PhDereferenceObject(description); } CloseServiceHandle(serviceHandle); } // Remove the trailing newline. if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); return PhFinalStringBuilderString(&stringBuilder); }
VOID PhpFillUmdfDrivers( _In_ PPH_PROCESS_ITEM Process, _Inout_ PPH_STRING_BUILDER Drivers ) { static PH_STRINGREF activeDevices = PH_STRINGREF_INIT(L"ACTIVE_DEVICES"); static PH_STRINGREF currentControlSetEnum = PH_STRINGREF_INIT(L"System\\CurrentControlSet\\Enum\\"); HANDLE processHandle; ULONG flags = 0; PVOID environment; ULONG environmentLength; ULONG enumerationKey; PH_ENVIRONMENT_VARIABLE variable; if (!NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, Process->ProcessId ))) return; #ifdef _WIN64 // Just in case. if (Process->IsWow64) flags |= PH_GET_PROCESS_ENVIRONMENT_WOW64; #endif if (NT_SUCCESS(PhGetProcessEnvironment( processHandle, flags, &environment, &environmentLength ))) { enumerationKey = 0; while (PhEnumProcessEnvironmentVariables(environment, environmentLength, &enumerationKey, &variable)) { PH_STRINGREF part; PH_STRINGREF remainingPart; if (!PhEqualStringRef(&variable.Name, &activeDevices, TRUE)) continue; remainingPart = variable.Value; while (remainingPart.Length != 0) { PhSplitStringRefAtChar(&remainingPart, ';', &part, &remainingPart); if (part.Length != 0) { HANDLE driverKeyHandle; PPH_STRING driverKeyPath; driverKeyPath = PhConcatStringRef2(¤tControlSetEnum, &part); if (NT_SUCCESS(PhOpenKey( &driverKeyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &driverKeyPath->sr, 0 ))) { PPH_STRING deviceDesc; PH_STRINGREF deviceName; PPH_STRING hardwareId; if (deviceDesc = PhQueryRegistryString(driverKeyHandle, L"DeviceDesc")) { PH_STRINGREF firstPart; PH_STRINGREF secondPart; if (PhSplitStringRefAtLastChar(&deviceDesc->sr, ';', &firstPart, &secondPart)) deviceName = secondPart; else deviceName = deviceDesc->sr; } else { PhInitializeStringRef(&deviceName, L"Unknown Device"); } hardwareId = PhQueryRegistryString(driverKeyHandle, L"HardwareID"); PhAppendStringBuilder(Drivers, &StandardIndent); PhAppendStringBuilder(Drivers, &deviceName); if (hardwareId) { PhTrimToNullTerminatorString(hardwareId); if (hardwareId->Length != 0) { PhAppendStringBuilder2(Drivers, L" ("); PhAppendStringBuilder(Drivers, &hardwareId->sr); PhAppendCharStringBuilder(Drivers, ')'); } } PhAppendCharStringBuilder(Drivers, '\n'); PhClearReference(&hardwareId); PhClearReference(&deviceDesc); NtClose(driverKeyHandle); } PhDereferenceObject(driverKeyPath); } } } PhFreePage(environment); } NtClose(processHandle); }