diff --git a/2.x/trunk/CHANGELOG.txt b/2.x/trunk/CHANGELOG.txt index bb2cf3ad3..380d1fa69 100644 --- a/2.x/trunk/CHANGELOG.txt +++ b/2.x/trunk/CHANGELOG.txt @@ -6,6 +6,8 @@ Process Hacker * Updated WindowExplorer plugin * Added support for setting page priority * Added elevation support for setting priority + * Added support for automatically using a settings file in + the program directory (e.g. ProcessHacker.exe.settings.xml) * Improved Run As mechanism * FIXED: * Handle leak diff --git a/2.x/trunk/ProcessHacker/include/phapp.h b/2.x/trunk/ProcessHacker/include/phapp.h index beb55609b..1a0a4832b 100644 --- a/2.x/trunk/ProcessHacker/include/phapp.h +++ b/2.x/trunk/ProcessHacker/include/phapp.h @@ -94,20 +94,10 @@ VOID PhApplyUpdateInterval( __in ULONG Interval ); -VOID PhActivatePreviousInstance(); - -VOID PhInitializeCommonControls(); - VOID PhInitializeFont( __in HWND hWnd ); -VOID PhInitializeKph(); - -BOOLEAN PhInitializeAppSystem(); - -ATOM PhRegisterWindowClass(); - // appsup PHAPPAPI diff --git a/2.x/trunk/ProcessHacker/main.c b/2.x/trunk/ProcessHacker/main.c index 895ee0e41..e91957f6c 100644 --- a/2.x/trunk/ProcessHacker/main.c +++ b/2.x/trunk/ProcessHacker/main.c @@ -28,7 +28,20 @@ #include #include +VOID PhActivatePreviousInstance(); + +VOID PhInitializeCommonControls(); + +VOID PhInitializeKph(); + +BOOLEAN PhInitializeAppSystem(); + +ATOM PhRegisterWindowClass(); + +VOID PhpInitializeSettings(); + VOID PhpProcessStartupParameters(); + VOID PhpEnablePrivileges(); PPH_STRING PhApplicationDirectory; @@ -107,60 +120,7 @@ INT WINAPI WinMain( PhpProcessStartupParameters(); - // Load settings. - { - PhSettingsInitialization(); - - if (!PhStartupParameters.NoSettings) - { - // Use the settings file name given in the command line, - // otherwise use the default location. - - if (PhStartupParameters.SettingsFileName) - { - // Get an absolute path now. - PhSettingsFileName = PhGetFullPath(PhStartupParameters.SettingsFileName->Buffer, NULL); - } - - if (!PhSettingsFileName) - { - PhSettingsFileName = PhGetKnownLocation(CSIDL_APPDATA, L"\\Process Hacker 2\\settings.xml"); - } - - if (PhSettingsFileName) - { - NTSTATUS status; - - 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) - { - PhDeleteFileWin32(PhSettingsFileName->Buffer); - } - else - { - // Pretend we don't have a settings store so bad things - // don't happen. - PhDereferenceObject(PhSettingsFileName); - PhSettingsFileName = NULL; - } - } - } - } - - // Apply the settings. - PhMaxSizeUnit = PhGetIntegerSetting(L"MaxSizeUnit"); - } + PhpInitializeSettings(); PhpEnablePrivileges(); @@ -526,6 +486,102 @@ ATOM PhRegisterWindowClass() return RegisterClassEx(&wcex); } +VOID PhpInitializeSettings() +{ + NTSTATUS status; + + PhSettingsInitialization(); + + 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[] = ""; + + // 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"); +} + #define PH_ARG_SETTINGS 1 #define PH_ARG_NOSETTINGS 2 #define PH_ARG_SHOWVISIBLE 3 diff --git a/2.x/trunk/ProcessHacker/settings.c b/2.x/trunk/ProcessHacker/settings.c index f94fdd0a0..e740010b1 100644 --- a/2.x/trunk/ProcessHacker/settings.c +++ b/2.x/trunk/ProcessHacker/settings.c @@ -729,7 +729,7 @@ NTSTATUS PhLoadSettings( if (!topNode) return STATUS_FILE_CORRUPT_ERROR; - if (!topNode->child) + if (topNode->type != MXML_ELEMENT) { mxmlDelete(topNode); return STATUS_FILE_CORRUPT_ERROR; diff --git a/2.x/trunk/phlib/basesup.c b/2.x/trunk/phlib/basesup.c index 3168f7c46..5e05bdbdb 100644 --- a/2.x/trunk/phlib/basesup.c +++ b/2.x/trunk/phlib/basesup.c @@ -1533,7 +1533,7 @@ PPH_STRING PhConcatStrings_V( stringLength = wcslen(arg) * sizeof(WCHAR); memcpy( - &string->Buffer[totalLength / sizeof(WCHAR)], + (PCHAR)string->Buffer + totalLength, arg, stringLength ); @@ -1567,7 +1567,7 @@ PPH_STRING PhConcatStrings2( length1 ); memcpy( - &string->Buffer[length1 / sizeof(WCHAR)], + (PCHAR)string->Buffer + length1, String2, length2 ); @@ -1588,9 +1588,12 @@ PPH_STRING PhConcatStringRef2( { PPH_STRING string; + assert(!(String1->Length & 1)); + assert(!(String2->Length & 1)); + string = PhCreateStringEx(NULL, String1->Length + String2->Length); memcpy(string->Buffer, String1->Buffer, String1->Length); - memcpy(&string->Buffer[String1->Length / sizeof(WCHAR)], String2->Buffer, String2->Length); + memcpy((PCHAR)string->Buffer + String1->Length, String2->Buffer, String2->Length); return string; } @@ -1609,17 +1612,21 @@ PPH_STRING PhConcatStringRef3( ) { PPH_STRING string; - PWSTR buffer; + PCHAR buffer; + + assert(!(String1->Length & 1)); + assert(!(String2->Length & 1)); + assert(!(String3->Length & 1)); string = PhCreateStringEx(NULL, String1->Length + String2->Length + String3->Length); - buffer = string->Buffer; + buffer = (PCHAR)string->Buffer; memcpy(buffer, String1->Buffer, String1->Length); - buffer += String1->Length / sizeof(WCHAR); + buffer += String1->Length; memcpy(buffer, String2->Buffer, String2->Length); - buffer += String2->Length / sizeof(WCHAR); + buffer += String2->Length; memcpy(buffer, String3->Buffer, String3->Length); return string;