NTSTATUS SaveDb( VOID ) { PH_AUTO_POOL autoPool; NTSTATUS status; HANDLE fileHandle; mxml_node_t *topNode; ULONG enumerationKey = 0; PDB_OBJECT *object; PhInitializeAutoPool(&autoPool); topNode = mxmlNewElement(MXML_NO_PARENT, "objects"); LockDb(); while (PhEnumHashtable(ObjectDb, (PVOID*)&object, &enumerationKey)) { CreateObjectElement( topNode, &UInt64ToBase10String((*object)->Tag)->sr, &(*object)->Name->sr, &UInt64ToBase10String((*object)->PriorityClass)->sr, &UInt64ToBase10String((*object)->IoPriorityPlusOne)->sr, &(*object)->Comment->sr, &UInt64ToBase10String((*object)->BackColor)->sr, &UInt64ToBase10String((*object)->Collapse)->sr, &UInt64ToBase10String((*object)->AffinityMask)->sr ); PhDrainAutoPool(&autoPool); } UnlockDb(); // Create the directory if it does not exist. { PPH_STRING fullPath; ULONG indexOfFileName; if (fullPath = PH_AUTO(PhGetFullPath(ObjectDbPath->Buffer, &indexOfFileName))) { if (indexOfFileName != -1) SHCreateDirectoryEx(NULL, PhaSubstring(fullPath, 0, indexOfFileName)->Buffer, NULL); } } PhDeleteAutoPool(&autoPool); status = PhCreateFileWin32( &fileHandle, ObjectDbPath->Buffer, FILE_GENERIC_WRITE, 0, FILE_SHARE_READ, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (!NT_SUCCESS(status)) { mxmlDelete(topNode); return status; } mxmlSaveFd(topNode, fileHandle, MXML_NO_CALLBACK); mxmlDelete(topNode); NtClose(fileHandle); return STATUS_SUCCESS; }
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); } }
PPH_STRING FiFormatFileName( _In_ PPH_STRING FileName ) { if (!FiArgNative) { PPH_STRING fileName; PPH_STRING fullPath; UNICODE_STRING fileNameUs; // Get the full path first so we can detect long file names. fullPath = PhGetFullPath(FileName->Buffer, NULL); if (fullPath) { if (fullPath->Length / 2 > MAX_PATH) { wprintf(L"Warning: Detected long file name \"%s\".\n", fullPath->Buffer); fileName = PhConcatStrings2(L"\\??\\", fullPath->Buffer); PhDereferenceObject(fullPath); return fileName; } PhDereferenceObject(fullPath); } if (RtlDosPathNameToNtPathName_U( FileName->Buffer, &fileNameUs, NULL, NULL )) { fileName = PhCreateStringFromUnicodeString(&fileNameUs); RtlFreeHeap(RtlProcessHeap(), 0, fileNameUs.Buffer); return fileName; } else { wprintf(L"Warning: Unable to convert the file name \"%s\" to a NT file name.\n", FileName->Buffer); // Fallback method. return PhConcatStrings2(L"\\??\\", FileName->Buffer); } } else { // Some limited conversions are applied for convenience. if (FileName->Length >= 2 * 2 && iswalpha(FileName->Buffer[0]) && FileName->Buffer[1] == ':') { return PhConcatStrings2(L"\\??\\", FileName->Buffer); } else if (FileName->Buffer[0] != '\\') { return PhFormatString( L"\\??\\%s%s", NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer, FileName->Buffer ); } else { return PhReferenceObject(FileName); } } }