BOOLEAN CreateDirectoryPath(_In_ PWSTR DirPath) { BOOLEAN success = FALSE; PPH_STRING dirPathString = NULL; PWSTR dirPathDup = NULL; if (RtlDoesFileExists_U(DirPath)) return TRUE; if ((dirPathDup = PhDuplicateStringZ(DirPath)) == NULL) goto CleanupExit; for (PWSTR path = _wcstok(dirPathDup, L"\\"); path; path = _wcstok(NULL, L"\\")) { if (!dirPathString) dirPathString = PhCreateString(path); else { PPH_STRING tempPathString; tempPathString = PhConcatStrings( 3, dirPathString->Buffer, L"\\", path ); if (!RtlDoesFileExists_U(PhGetString(tempPathString))) { if (!CreateDirectory(PhGetString(tempPathString), NULL)) { PhDereferenceObject(tempPathString); goto CleanupExit; } } PhSwapReference(&dirPathString, tempPathString); PhDereferenceObject(tempPathString); } } success = TRUE; CleanupExit: if (dirPathString) { PhDereferenceObject(dirPathString); } if (dirPathDup) { PhFree(dirPathDup); } return success; }
VOID DotNetAsmShowContextMenu( _In_ PASMPAGE_CONTEXT Context, _In_ POINT Location ) { PDNA_NODE node; PPH_EMENU menu; PPH_EMENU_ITEM selectedItem; if (!(node = DotNetAsmGetSelectedEntry(Context))) return; menu = PhCreateEMenu(); PhLoadResourceEMenuItem(menu, PluginInstance->DllBase, MAKEINTRESOURCE(IDR_ASSEMBLY_MENU), 0); if (PhIsNullOrEmptyString(node->PathText) || !RtlDoesFileExists_U(node->PathText->Buffer)) { PhSetFlagsEMenuItem(menu, ID_CLR_OPENFILELOCATION, PH_EMENU_DISABLED, PH_EMENU_DISABLED); } selectedItem = PhShowEMenu( menu, Context->WindowHandle, PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, Location.x, Location.y ); if (selectedItem && selectedItem->Id != -1) { switch (selectedItem->Id) { case ID_CLR_OPENFILELOCATION: { if (!PhIsNullOrEmptyString(node->PathText) && RtlDoesFileExists_U(node->PathText->Buffer)) { PhShellExploreFile(Context->WindowHandle, node->PathText->Buffer); } } break; case ID_CLR_COPY: { PPH_STRING text; text = PhGetTreeNewText(Context->TnHandle, 0); PhSetClipboardString(Context->TnHandle, &text->sr); PhDereferenceObject(text); } break; } } PhDestroyEMenu(menu); }
VOID PhpInitializeSettings( VOID ) { NTSTATUS status; if (!PhStartupParameters.NoSettings) { static PH_STRINGREF settingsSuffix = PH_STRINGREF_INIT(L".settings.xml"); PPH_STRING settingsFileName; // There are three possible locations for the settings file: // 1. The file name given in the command line. // 2. A file named ProcessHacker.exe.settings.xml in the program directory. (This changes // based on the executable file name.) // 3. The default location. // 1. File specified in command line if (PhStartupParameters.SettingsFileName) { // Get an absolute path now. PhSettingsFileName = PhGetFullPath(PhStartupParameters.SettingsFileName->Buffer, NULL); } // 2. File in program directory if (!PhSettingsFileName) { settingsFileName = PhConcatStringRef2(&PhApplicationFileName->sr, &settingsSuffix); if (RtlDoesFileExists_U(settingsFileName->Buffer)) { PhSettingsFileName = settingsFileName; } else { PhDereferenceObject(settingsFileName); } } // 3. Default location if (!PhSettingsFileName) { PhSettingsFileName = PhGetKnownLocation(CSIDL_APPDATA, L"\\Process Hacker 2\\settings.xml"); } if (PhSettingsFileName) { status = PhLoadSettings(PhSettingsFileName->Buffer); // If we didn't find the file, it will be created. Otherwise, // there was probably a parsing error and we don't want to // change anything. if (status == STATUS_FILE_CORRUPT_ERROR) { if (PhShowMessage( NULL, MB_ICONWARNING | MB_YESNO, L"Process Hacker's settings file is corrupt. Do you want to reset it?\n" L"If you select No, the settings system will not function properly." ) == IDYES) { HANDLE fileHandle; IO_STATUS_BLOCK isb; CHAR data[] = "<settings></settings>"; // This used to delete the file. But it's better to keep the file there // and overwrite it with some valid XML, especially with case (2) above. if (NT_SUCCESS(PhCreateFileWin32( &fileHandle, PhSettingsFileName->Buffer, FILE_GENERIC_WRITE, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OVERWRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { NtWriteFile(fileHandle, NULL, NULL, NULL, &isb, data, sizeof(data) - 1, NULL, NULL); NtClose(fileHandle); } } else { // Pretend we don't have a settings store so bad things // don't happen. PhDereferenceObject(PhSettingsFileName); PhSettingsFileName = NULL; } } } } // Apply basic global settings. PhMaxSizeUnit = PhGetIntegerSetting(L"MaxSizeUnit"); if (PhGetIntegerSetting(L"SampleCountAutomatic")) { ULONG sampleCount; sampleCount = (GetSystemMetrics(SM_CXVIRTUALSCREEN) + 1) / 2; if (sampleCount > 2048) sampleCount = 2048; PhSetIntegerSetting(L"SampleCount", sampleCount); } }
VOID PeInitializeSettings( VOID ) { static PH_STRINGREF settingsSuffix = PH_STRINGREF_INIT(L".peview.xml"); NTSTATUS status; PPH_STRING appFileName; PPH_STRING tempFileName; // There are three possible locations for the settings file: // 1. A file named peview.exe.peview.xml in the program directory. (This changes // based on the executable file name.) // 2. The default location. // 1. File in program directory appFileName = PhGetApplicationFileName(); tempFileName = PhConcatStringRef2(&appFileName->sr, &settingsSuffix); PhDereferenceObject(appFileName); if (RtlDoesFileExists_U(tempFileName->Buffer)) { PeSettingsFileName = tempFileName; } else { PhDereferenceObject(tempFileName); } // 2. Default location if (!PeSettingsFileName) { PeSettingsFileName = PhGetKnownLocation(CSIDL_APPDATA, L"\\Process Hacker\\peview.xml"); } if (PeSettingsFileName) { status = PhLoadSettings(PeSettingsFileName->Buffer); // If we didn't find the file, it will be created. Otherwise, // there was probably a parsing error and we don't want to // change anything. if (status == STATUS_FILE_CORRUPT_ERROR) { if (PhShowMessage2( NULL, TDCBF_YES_BUTTON | TDCBF_NO_BUTTON, TD_WARNING_ICON, L"PE View's settings file is corrupt. Do you want to reset it?", L"If you select No, the settings system will not function properly." ) == IDYES) { HANDLE fileHandle; IO_STATUS_BLOCK isb; CHAR data[] = "<settings></settings>"; // This used to delete the file. But it's better to keep the file there // and overwrite it with some valid XML, especially with case (2) above. if (NT_SUCCESS(PhCreateFileWin32( &fileHandle, PeSettingsFileName->Buffer, FILE_GENERIC_WRITE, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OVERWRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { NtWriteFile(fileHandle, NULL, NULL, NULL, &isb, data, sizeof(data) - 1, NULL, NULL); NtClose(fileHandle); } } else { // Pretend we don't have a settings store so bad things don't happen. PhDereferenceObject(PeSettingsFileName); PeSettingsFileName = NULL; } } } // Apply basic global settings. PhMaxSizeUnit = PhGetIntegerSetting(L"MaxSizeUnit"); }
NTSTATUS KphConnect2Ex( _In_opt_ PWSTR DeviceName, _In_ PWSTR FileName, _In_opt_ PKPH_PARAMETERS Parameters ) { NTSTATUS status; WCHAR fullDeviceName[256]; PH_FORMAT format[2]; SC_HANDLE scmHandle; SC_HANDLE serviceHandle; BOOLEAN started = FALSE; BOOLEAN created = FALSE; if (!DeviceName) DeviceName = KPH_DEVICE_SHORT_NAME; PhInitFormatS(&format[0], L"\\Device\\"); PhInitFormatS(&format[1], DeviceName); if (!PhFormatToBuffer(format, 2, fullDeviceName, sizeof(fullDeviceName), NULL)) return STATUS_NAME_TOO_LONG; // Try to open the device. status = KphConnect(fullDeviceName); if (NT_SUCCESS(status) || status == STATUS_ADDRESS_ALREADY_EXISTS) return status; if ( status != STATUS_NO_SUCH_DEVICE && status != STATUS_NO_SUCH_FILE && status != STATUS_OBJECT_NAME_NOT_FOUND && status != STATUS_OBJECT_PATH_NOT_FOUND ) return status; // Load the driver, and try again. // Try to start the service, if it exists. scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (scmHandle) { serviceHandle = OpenService(scmHandle, DeviceName, SERVICE_START); if (serviceHandle) { if (StartService(serviceHandle, 0, NULL)) started = TRUE; CloseServiceHandle(serviceHandle); } CloseServiceHandle(scmHandle); } if (!started && RtlDoesFileExists_U(FileName)) { // Try to create the service. scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (scmHandle) { serviceHandle = CreateService( scmHandle, DeviceName, DeviceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, FileName, NULL, NULL, NULL, NULL, L"" ); if (serviceHandle) { created = TRUE; // Set parameters if the caller supplied them. // Note that we fail the entire function if this fails, // because failing to set parameters like SecurityLevel may // result in security vulnerabilities. if (Parameters) { status = KphSetParameters(DeviceName, Parameters); if (!NT_SUCCESS(status)) { // Delete the service and fail. goto CreateAndConnectEnd; } } if (StartService(serviceHandle, 0, NULL)) started = TRUE; } CloseServiceHandle(scmHandle); } } if (started) { // Try to open the device again. status = KphConnect(fullDeviceName); } CreateAndConnectEnd: if (created) { // "Delete" the service. Since we (may) have a handle to // the device, the SCM will delete the service automatically // when it is stopped (upon reboot). If we don't have a // handle to the device, the service will get deleted immediately, // which is a good thing anyway. DeleteService(serviceHandle); CloseServiceHandle(serviceHandle); } return status; }