Beispiel #1
0
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);
    }
}
Beispiel #3
0
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);
        }
    }
}