static BOOLEAN NTAPI EnumModulesCallback( __in PPH_MODULE_INFO Module, __in_opt PVOID Context ) { PPH_STRING upperFileName; upperFileName = PhDuplicateString(Module->FileName); PhUpperString(upperFileName); if ( PhFindStringInString(upperFileName, 0, SearchString->Buffer) != -1 || (UseSearchPointer && Module->BaseAddress == (PVOID)SearchPointer) ) { PPHP_OBJECT_SEARCH_RESULT searchResult; PWSTR typeName; switch (Module->Type) { case PH_MODULE_TYPE_MAPPED_FILE: typeName = L"Mapped File"; break; case PH_MODULE_TYPE_MAPPED_IMAGE: typeName = L"Mapped Image"; break; default: typeName = L"DLL"; break; } searchResult = PhAllocate(sizeof(PHP_OBJECT_SEARCH_RESULT)); searchResult->ProcessId = (HANDLE)Context; searchResult->ResultType = (Module->Type == PH_MODULE_TYPE_MAPPED_FILE || Module->Type == PH_MODULE_TYPE_MAPPED_IMAGE) ? MappedFileSearchResult : ModuleSearchResult; searchResult->Handle = (HANDLE)Module->BaseAddress; searchResult->TypeName = PhCreateString(typeName); PhReferenceObject(Module->FileName); searchResult->Name = Module->FileName; PhPrintPointer(searchResult->HandleString, Module->BaseAddress); memset(&searchResult->Info, 0, sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)); PhAcquireQueuedLockExclusive(&SearchResultsLock); PhAddItemList(SearchResults, searchResult); // Update the search results in batches of 40. if (SearchResults->Count % 40 == 0) PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_UPDATE, 0, 0); PhReleaseQueuedLockExclusive(&SearchResultsLock); } PhDereferenceObject(upperFileName); return TRUE; }
PPH_STRING PhpGetX500Value( __in PPH_STRING String, __in PPH_STRINGREF KeyName ) { WCHAR keyNamePlusEquals[10]; SIZE_T keyNameLength; ULONG_PTR startIndex; ULONG_PTR endIndex; keyNameLength = KeyName->Length / sizeof(WCHAR); assert(!(keyNameLength > sizeof(keyNamePlusEquals) / sizeof(WCHAR) - 2)); memcpy(keyNamePlusEquals, KeyName->Buffer, KeyName->Length); keyNamePlusEquals[keyNameLength] = '='; keyNamePlusEquals[keyNameLength + 1] = 0; // Find "Key=". startIndex = PhFindStringInString(String, 0, keyNamePlusEquals); if (startIndex == -1) return NULL; startIndex += keyNameLength + 1; if (startIndex * sizeof(WCHAR) >= String->Length) return NULL; // Is the value quoted? if (String->Buffer[startIndex] == '"') { startIndex++; if (startIndex * sizeof(WCHAR) >= String->Length) return NULL; endIndex = PhFindCharInString(String, startIndex, '"'); // It's an error if we didn't find the matching quotation mark. if (endIndex == -1) return NULL; } else { endIndex = PhFindCharInString(String, startIndex, ','); // If we didn't find a comma, it means the key/value pair is // the last one in the string. if (endIndex == -1) endIndex = String->Length / sizeof(WCHAR); } return PhSubstring(String, startIndex, endIndex - startIndex); }
BOOLEAN NTAPI PhpCommandLineOptionCallback( _In_opt_ PPH_COMMAND_LINE_OPTION Option, _In_opt_ PPH_STRING Value, _In_opt_ PVOID Context ) { ULONG64 integer; if (Option) { switch (Option->Id) { case PH_ARG_SETTINGS: PhSwapReference(&PhStartupParameters.SettingsFileName, Value); break; case PH_ARG_NOSETTINGS: PhStartupParameters.NoSettings = TRUE; break; case PH_ARG_SHOWVISIBLE: PhStartupParameters.ShowVisible = TRUE; break; case PH_ARG_SHOWHIDDEN: PhStartupParameters.ShowHidden = TRUE; break; case PH_ARG_COMMANDMODE: PhStartupParameters.CommandMode = TRUE; break; case PH_ARG_COMMANDTYPE: PhSwapReference(&PhStartupParameters.CommandType, Value); break; case PH_ARG_COMMANDOBJECT: PhSwapReference(&PhStartupParameters.CommandObject, Value); break; case PH_ARG_COMMANDACTION: PhSwapReference(&PhStartupParameters.CommandAction, Value); break; case PH_ARG_COMMANDVALUE: PhSwapReference(&PhStartupParameters.CommandValue, Value); break; case PH_ARG_RUNASSERVICEMODE: PhSwapReference(&PhStartupParameters.RunAsServiceMode, Value); break; case PH_ARG_NOKPH: PhStartupParameters.NoKph = TRUE; break; case PH_ARG_INSTALLKPH: PhStartupParameters.InstallKph = TRUE; break; case PH_ARG_UNINSTALLKPH: PhStartupParameters.UninstallKph = TRUE; break; case PH_ARG_DEBUG: PhStartupParameters.Debug = TRUE; break; case PH_ARG_HWND: if (PhStringToInteger64(&Value->sr, 16, &integer)) PhStartupParameters.WindowHandle = (HWND)(ULONG_PTR)integer; break; case PH_ARG_POINT: { PH_STRINGREF xString; PH_STRINGREF yString; if (PhSplitStringRefAtChar(&Value->sr, ',', &xString, &yString)) { LONG64 x; LONG64 y; if (PhStringToInteger64(&xString, 10, &x) && PhStringToInteger64(&yString, 10, &y)) { PhStartupParameters.Point.x = (LONG)x; PhStartupParameters.Point.y = (LONG)y; } } } break; case PH_ARG_SHOWOPTIONS: PhStartupParameters.ShowOptions = TRUE; break; case PH_ARG_PHSVC: PhStartupParameters.PhSvc = TRUE; break; case PH_ARG_NOPLUGINS: PhStartupParameters.NoPlugins = TRUE; break; case PH_ARG_NEWINSTANCE: PhStartupParameters.NewInstance = TRUE; break; case PH_ARG_ELEVATE: PhStartupParameters.Elevate = TRUE; break; case PH_ARG_SILENT: PhStartupParameters.Silent = TRUE; break; case PH_ARG_HELP: PhStartupParameters.Help = TRUE; break; case PH_ARG_SELECTPID: if (PhStringToInteger64(&Value->sr, 0, &integer)) PhStartupParameters.SelectPid = (ULONG)integer; break; case PH_ARG_PRIORITY: if (PhEqualString2(Value, L"r", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME; else if (PhEqualString2(Value, L"h", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; else if (PhEqualString2(Value, L"n", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; else if (PhEqualString2(Value, L"l", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE; break; case PH_ARG_PLUGIN: if (!PhStartupParameters.PluginParameters) PhStartupParameters.PluginParameters = PhCreateList(3); PhReferenceObject(Value); PhAddItemList(PhStartupParameters.PluginParameters, Value); break; case PH_ARG_SELECTTAB: PhSwapReference(&PhStartupParameters.SelectTab, Value); break; } } else { PPH_STRING upperValue; upperValue = PhDuplicateString(Value); _wcsupr(upperValue->Buffer); if (PhFindStringInString(upperValue, 0, L"TASKMGR.EXE") != -1) { // User probably has Process Hacker replacing Task Manager. Force // the main window to start visible. PhStartupParameters.ShowVisible = TRUE; } PhDereferenceObject(upperValue); } return TRUE; }
INT_PTR CALLBACK PhpChoiceDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PCHOICE_DIALOG_CONTEXT context = (PCHOICE_DIALOG_CONTEXT)lParam; ULONG type; SIZE_T i; HWND comboBoxHandle; HWND checkBoxHandle; RECT checkBoxRect; RECT rect; ULONG diff; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); PhCenterWindow(hwndDlg, GetParent(hwndDlg)); SetWindowText(hwndDlg, context->Title); SetWindowText(GetDlgItem(hwndDlg, IDC_MESSAGE), context->Message); type = context->Flags & PH_CHOICE_DIALOG_TYPE_MASK; // Select the control to show, depending on the type. This is // because it is impossible to change the style of the combo box // after it is created. switch (type) { case PH_CHOICE_DIALOG_USER_CHOICE: comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICEUSER); ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICEUSER), SW_SHOW); break; case PH_CHOICE_DIALOG_PASSWORD: comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICESIMPLE); ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICESIMPLE), SW_SHOW); // Disable combo box features since it isn't a combo box. context->SavedChoicesSettingName = NULL; break; case PH_CHOICE_DIALOG_CHOICE: default: comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICE); ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICE), SW_SHOW); break; } context->ComboBoxHandle = comboBoxHandle; checkBoxHandle = GetDlgItem(hwndDlg, IDC_OPTION); if (type == PH_CHOICE_DIALOG_PASSWORD) { // Nothing } else if (type == PH_CHOICE_DIALOG_USER_CHOICE && context->SavedChoicesSettingName) { PPH_STRING savedChoices = PhGetStringSetting(context->SavedChoicesSettingName); ULONG_PTR indexOfDelim; PPH_STRING savedChoice; i = 0; // Split the saved choices using the delimiter. while (i < savedChoices->Length / 2) { // BUG BUG BUG - what if the user saves "\s"? indexOfDelim = PhFindStringInString(savedChoices, i, L"\\s"); if (indexOfDelim == -1) indexOfDelim = savedChoices->Length / 2; savedChoice = PhSubstring(savedChoices, i, indexOfDelim - i); if (savedChoice->Length != 0) { PPH_STRING unescaped; unescaped = PhUnescapeStringForDelimiter(savedChoice, '\\'); ComboBox_InsertString(comboBoxHandle, -1, unescaped->Buffer); PhDereferenceObject(unescaped); } PhDereferenceObject(savedChoice); i = indexOfDelim + 2; } PhDereferenceObject(savedChoices); } else { for (i = 0; i < context->NumberOfChoices; i++) { ComboBox_AddString(comboBoxHandle, context->Choices[i]); } context->SavedChoicesSettingName = NULL; // make sure we don't try to save the choices } if (type == PH_CHOICE_DIALOG_PASSWORD) { if (*context->SelectedChoice) SetWindowText(comboBoxHandle, (*context->SelectedChoice)->Buffer); Edit_SetSel(comboBoxHandle, 0, -1); } else if (type == PH_CHOICE_DIALOG_USER_CHOICE || type == PH_CHOICE_DIALOG_CHOICE) { // If we failed to choose a default choice based on what was specified, // select the first one if possible, or set the text directly. if (!(*context->SelectedChoice) || PhSelectComboBoxString( comboBoxHandle, (*context->SelectedChoice)->Buffer, FALSE) == CB_ERR) { if (type == PH_CHOICE_DIALOG_USER_CHOICE && *context->SelectedChoice) { SetWindowText(comboBoxHandle, (*context->SelectedChoice)->Buffer); } else if (type == PH_CHOICE_DIALOG_CHOICE && context->NumberOfChoices != 0) { ComboBox_SetCurSel(comboBoxHandle, 0); } } if (type == PH_CHOICE_DIALOG_USER_CHOICE) ComboBox_SetEditSel(comboBoxHandle, 0, -1); } if (context->Option) { SetWindowText(checkBoxHandle, context->Option); if (context->SelectedOption) Button_SetCheck(checkBoxHandle, *context->SelectedOption ? BST_CHECKED : BST_UNCHECKED); } else { // Hide the check box and move the buttons up. ShowWindow(checkBoxHandle, SW_HIDE); GetWindowRect(checkBoxHandle, &checkBoxRect); MapWindowPoints(NULL, hwndDlg, (POINT *)&checkBoxRect, 2); GetWindowRect(GetDlgItem(hwndDlg, IDOK), &rect); MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2); diff = rect.top - checkBoxRect.top; // OK rect.top -= diff; rect.bottom -= diff; SetWindowPos(GetDlgItem(hwndDlg, IDOK), NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); // Cancel GetWindowRect(GetDlgItem(hwndDlg, IDCANCEL), &rect); MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2); rect.top -= diff; rect.bottom -= diff; SetWindowPos(GetDlgItem(hwndDlg, IDCANCEL), NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); // Window GetWindowRect(hwndDlg, &rect); rect.bottom -= diff; SetWindowPos(hwndDlg, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); } SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)comboBoxHandle, TRUE); } break; case WM_DESTROY: { RemoveProp(hwndDlg, PhMakeContextAtom()); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: { PCHOICE_DIALOG_CONTEXT context = (PCHOICE_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); PPH_STRING selectedChoice; if ((context->Flags & PH_CHOICE_DIALOG_TYPE_MASK) != PH_CHOICE_DIALOG_PASSWORD) { selectedChoice = PH_AUTO(PhGetWindowText(context->ComboBoxHandle)); *context->SelectedChoice = selectedChoice; } else { // Password values are never auto-dereferenced. selectedChoice = PhGetWindowText(context->ComboBoxHandle); *context->SelectedChoice = selectedChoice; } if (context->Option && context->SelectedOption) *context->SelectedOption = Button_GetCheck(GetDlgItem(hwndDlg, IDC_OPTION)) == BST_CHECKED; if (context->SavedChoicesSettingName) { PH_STRING_BUILDER savedChoices; ULONG i; ULONG choicesToSave = PH_CHOICE_DIALOG_SAVED_CHOICES; PPH_STRING choice; PPH_STRING escaped; PhInitializeStringBuilder(&savedChoices, 100); // Push the selected choice to the top, then save the others. if (selectedChoice->Length != 0) { escaped = PhEscapeStringForDelimiter(selectedChoice, '\\'); PhAppendStringBuilder(&savedChoices, &escaped->sr); PhDereferenceObject(escaped); PhAppendStringBuilder2(&savedChoices, L"\\s"); } for (i = 1; i < choicesToSave; i++) { choice = PhGetComboBoxString(context->ComboBoxHandle, i - 1); if (!choice) break; // Don't save the choice if it's the same as the one // entered by the user (since we already saved it above). if (PhEqualString(choice, selectedChoice, FALSE)) { PhDereferenceObject(choice); choicesToSave++; // useless for now, but may be needed in the future continue; } escaped = PhEscapeStringForDelimiter(choice, '\\'); PhAppendStringBuilder(&savedChoices, &escaped->sr); PhDereferenceObject(escaped); PhDereferenceObject(choice); PhAppendStringBuilder2(&savedChoices, L"\\s"); } if (PhEndsWithString2(savedChoices.String, L"\\s", FALSE)) PhRemoveEndStringBuilder(&savedChoices, 2); PhSetStringSetting2(context->SavedChoicesSettingName, &savedChoices.String->sr); PhDeleteStringBuilder(&savedChoices); } EndDialog(hwndDlg, IDOK); } break; } } break; } return FALSE; }
static NTSTATUS PhpFindObjectsThreadStart( __in PVOID Parameter ) { PSYSTEM_HANDLE_INFORMATION_EX handles; PPH_HASHTABLE processHandleHashtable; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; ULONG i; // Refuse to search with no filter. if (SearchString->Length == 0) goto Exit; // Try to get a search pointer from the search string. UseSearchPointer = PhStringToInteger64(&SearchString->sr, 0, &SearchPointer); PhUpperString(SearchString); if (NT_SUCCESS(PhEnumHandlesEx(&handles))) { processHandleHashtable = PhCreateSimpleHashtable(8); for (i = 0; i < handles->NumberOfHandles; i++) { PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = &handles->Handles[i]; PPVOID processHandlePtr; HANDLE processHandle; PPH_STRING typeName; PPH_STRING bestObjectName; if (SearchStop) break; // Open a handle to the process if we don't already have one. processHandlePtr = PhFindItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId ); if (processHandlePtr) { processHandle = (HANDLE)*processHandlePtr; } else { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, (HANDLE)handleInfo->UniqueProcessId ))) { PhAddItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId, processHandle ); } else { continue; } } // Get handle information. if (NT_SUCCESS(PhGetHandleInformation( processHandle, (HANDLE)handleInfo->HandleValue, handleInfo->ObjectTypeIndex, NULL, &typeName, NULL, &bestObjectName ))) { PPH_STRING upperBestObjectName; upperBestObjectName = PhDuplicateString(bestObjectName); PhUpperString(upperBestObjectName); if ( PhFindStringInString(upperBestObjectName, 0, SearchString->Buffer) != -1 || (UseSearchPointer && handleInfo->Object == (PVOID)SearchPointer) ) { PPHP_OBJECT_SEARCH_RESULT searchResult; searchResult = PhAllocate(sizeof(PHP_OBJECT_SEARCH_RESULT)); searchResult->ProcessId = (HANDLE)handleInfo->UniqueProcessId; searchResult->ResultType = HandleSearchResult; searchResult->Handle = (HANDLE)handleInfo->HandleValue; searchResult->TypeName = typeName; searchResult->Name = bestObjectName; PhPrintPointer(searchResult->HandleString, (PVOID)searchResult->Handle); searchResult->Info = *handleInfo; PhAcquireQueuedLockExclusive(&SearchResultsLock); PhAddItemList(SearchResults, searchResult); // Update the search results in batches of 40. if (SearchResults->Count % 40 == 0) PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_UPDATE, 0, 0); PhReleaseQueuedLockExclusive(&SearchResultsLock); } else { PhDereferenceObject(typeName); PhDereferenceObject(bestObjectName); } PhDereferenceObject(upperBestObjectName); } } { PPH_KEY_VALUE_PAIR entry; i = 0; while (PhEnumHashtable(processHandleHashtable, &entry, &i)) NtClose((HANDLE)entry->Value); } PhDereferenceObject(processHandleHashtable); PhFree(handles); } if (NT_SUCCESS(PhEnumProcesses(&processes))) { process = PH_FIRST_PROCESS(processes); do { PhEnumGenericModules( process->UniqueProcessId, NULL, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, (PVOID)process->UniqueProcessId ); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); } Exit: PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_FINISHED, 0, 0); return STATUS_SUCCESS; }
BOOLEAN PhaGetProcessKnownCommandLine( __in PPH_STRING CommandLine, __in PH_KNOWN_PROCESS_TYPE KnownProcessType, __out PPH_KNOWN_PROCESS_COMMAND_LINE KnownCommandLine ) { switch (KnownProcessType & KnownProcessTypeMask) { case ServiceHostProcessType: { // svchost.exe -k <GroupName> static PH_COMMAND_LINE_OPTION options[] = { { 1, L"k", MandatoryArgumentType } }; KnownCommandLine->ServiceHost.GroupName = NULL; PhParseCommandLine( &CommandLine->sr, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS, PhpSvchostCommandLineCallback, KnownCommandLine ); if (KnownCommandLine->ServiceHost.GroupName) { PhaDereferenceObject(KnownCommandLine->ServiceHost.GroupName); return TRUE; } else { return FALSE; } } break; case RunDllAsAppProcessType: { // rundll32.exe <DllName>,<ProcedureName> ... SIZE_T i; ULONG_PTR lastIndexOfComma; PPH_STRING dllName; PPH_STRING procedureName; i = 0; // Get the rundll32.exe part. dllName = PhParseCommandLinePart(&CommandLine->sr, &i); if (!dllName) return FALSE; PhDereferenceObject(dllName); // Get the DLL name part. while (i < CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ') i++; dllName = PhParseCommandLinePart(&CommandLine->sr, &i); if (!dllName) return FALSE; PhaDereferenceObject(dllName); // The procedure name begins after the last comma. lastIndexOfComma = PhFindLastCharInString(dllName, 0, ','); if (lastIndexOfComma == -1) return FALSE; procedureName = PhaSubstring( dllName, lastIndexOfComma + 1, dllName->Length / 2 - lastIndexOfComma - 1 ); dllName = PhaSubstring(dllName, 0, lastIndexOfComma); // If the DLL name isn't an absolute path, assume it's in system32. // TODO: Use a proper search function. if (RtlDetermineDosPathNameType_U(dllName->Buffer) == RtlPathTypeRelative) { dllName = PhaConcatStrings( 3, ((PPH_STRING)PHA_DEREFERENCE(PhGetSystemDirectory()))->Buffer, L"\\", dllName->Buffer ); } KnownCommandLine->RunDllAsApp.FileName = dllName; KnownCommandLine->RunDllAsApp.ProcedureName = procedureName; } break; case ComSurrogateProcessType: { // dllhost.exe /processid:<Guid> static PH_STRINGREF inprocServer32Name = PH_STRINGREF_INIT(L"InprocServer32"); SIZE_T i; ULONG_PTR indexOfProcessId; PPH_STRING argPart; PPH_STRING guidString; UNICODE_STRING guidStringUs; GUID guid; HANDLE clsidKeyHandle; HANDLE inprocServer32KeyHandle; PPH_STRING fileName; i = 0; // Get the dllhost.exe part. argPart = PhParseCommandLinePart(&CommandLine->sr, &i); if (!argPart) return FALSE; PhDereferenceObject(argPart); // Get the argument part. while (i < (ULONG)CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ') i++; argPart = PhParseCommandLinePart(&CommandLine->sr, &i); if (!argPart) return FALSE; PhaDereferenceObject(argPart); // Find "/processid:"; the GUID is just after that. PhUpperString(argPart); indexOfProcessId = PhFindStringInString(argPart, 0, L"/PROCESSID:"); if (indexOfProcessId == -1) return FALSE; guidString = PhaSubstring( argPart, indexOfProcessId + 11, (ULONG)argPart->Length / 2 - indexOfProcessId - 11 ); PhStringRefToUnicodeString(&guidString->sr, &guidStringUs); if (!NT_SUCCESS(RtlGUIDFromString( &guidStringUs, &guid ))) return FALSE; KnownCommandLine->ComSurrogate.Guid = guid; KnownCommandLine->ComSurrogate.Name = NULL; KnownCommandLine->ComSurrogate.FileName = NULL; // Lookup the GUID in the registry to determine the name and file name. if (NT_SUCCESS(PhOpenKey( &clsidKeyHandle, KEY_READ, PH_KEY_CLASSES_ROOT, &PhaConcatStrings2(L"CLSID\\", guidString->Buffer)->sr, 0 ))) { KnownCommandLine->ComSurrogate.Name = PHA_DEREFERENCE(PhQueryRegistryString(clsidKeyHandle, NULL)); if (NT_SUCCESS(PhOpenKey( &inprocServer32KeyHandle, KEY_READ, clsidKeyHandle, &inprocServer32Name, 0 ))) { KnownCommandLine->ComSurrogate.FileName = PHA_DEREFERENCE(PhQueryRegistryString(inprocServer32KeyHandle, NULL)); if (fileName = PHA_DEREFERENCE(PhExpandEnvironmentStrings( &KnownCommandLine->ComSurrogate.FileName->sr ))) { KnownCommandLine->ComSurrogate.FileName = fileName; } NtClose(inprocServer32KeyHandle); } NtClose(clsidKeyHandle); } } break; default: return FALSE; } return TRUE; }