From bc3b356ae6effeb57229e0339b63b484ce5f107a Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Sat, 13 Oct 2018 01:14:15 +0200 Subject: [PATCH] [GFLAGS] Move code around to handle multiple options --- .../cmdutils/gflags/CMakeLists.txt | 9 +- .../applications/cmdutils/gflags/gflags.c | 382 +----------------- .../applications/cmdutils/gflags/gflags.h | 26 ++ .../applications/cmdutils/gflags/pageheap.c | 355 ++++++++++++++++ 4 files changed, 409 insertions(+), 363 deletions(-) create mode 100644 modules/rosapps/applications/cmdutils/gflags/gflags.h create mode 100644 modules/rosapps/applications/cmdutils/gflags/pageheap.c diff --git a/modules/rosapps/applications/cmdutils/gflags/CMakeLists.txt b/modules/rosapps/applications/cmdutils/gflags/CMakeLists.txt index a6936de6eed..fd935e76e82 100644 --- a/modules/rosapps/applications/cmdutils/gflags/CMakeLists.txt +++ b/modules/rosapps/applications/cmdutils/gflags/CMakeLists.txt @@ -1,7 +1,14 @@ -add_executable(gflags gflags.c gflags.rc) + +list(APPEND SOURCE + gflags.c + pageheap.c + gflags.h) + +add_executable(gflags ${SOURCE} gflags.rc) set_module_type(gflags win32cui UNICODE) add_importlibs(gflags advapi32 user32 msvcrt kernel32) +add_pch(gflags gflags.h SOURCE) if(MSVC) add_importlibs(gflags ntdll) diff --git a/modules/rosapps/applications/cmdutils/gflags/gflags.c b/modules/rosapps/applications/cmdutils/gflags/gflags.c index 260c6d5794a..b0751a091f7 100644 --- a/modules/rosapps/applications/cmdutils/gflags/gflags.c +++ b/modules/rosapps/applications/cmdutils/gflags/gflags.c @@ -1,27 +1,17 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS ping utility - * FILE: applications/cmdutils/gflags/gflags.c - * PURPOSE: Global Flags utility - * PROGRAMMERS: Pierre Schweitzer + * PROJECT: Global Flags utility + * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0) + * PURPOSE: Global Flags utility entrypoint + * COPYRIGHT: Copyright 2017 Pierre Schweitzer (pierre@reactos.org) + * Copyright 2018 Mark Jansen (mark.jansen@reactos.org) */ -#define WIN32_NO_STATUS -#include -#include -#include -#include -#include -#include -#include +#include "gflags.h" -static BOOL Set = FALSE; -static BOOL Unset = FALSE; -static BOOL Full = FALSE; -static PWSTR Image = NULL; -static WCHAR ImageExecOptionsString[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"; +static BOOL UsePageHeap = FALSE; -static DWORD ReagFlagsFromRegistry(HKEY SubKey, PVOID Buffer, PWSTR Value, DWORD MaxLen) + +DWORD ReagFlagsFromRegistry(HKEY SubKey, PVOID Buffer, PWSTR Value, DWORD MaxLen) { DWORD Len, Flags, Type; @@ -35,299 +25,13 @@ static DWORD ReagFlagsFromRegistry(HKEY SubKey, PVOID Buffer, PWSTR Value, DWORD return Flags; } -static VOID ModifyStatus(VOID) -{ - LONG Ret; - DWORD MaxLen, GlobalFlags; - PVOID Buffer; - HKEY HandleKey, HandleSubKey; - - Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ImageExecOptionsString, 0, KEY_WRITE | KEY_READ, &HandleKey); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegOpenKeyEx failed (%d)\n", Ret); - return; - } - - Ret = RegCreateKeyEx(HandleKey, Image, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &HandleSubKey, NULL); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegCreateKeyEx failed (%d)\n", Ret); - return; - } - - Ret = RegQueryInfoKey(HandleSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegQueryInfoKey failed (%d)\n", Ret); - RegCloseKey(HandleSubKey); - RegCloseKey(HandleKey); - return; - } - - MaxLen = max(MaxLen, 11 * sizeof(WCHAR)); - Buffer = HeapAlloc(GetProcessHeap(), 0, MaxLen); - if (Buffer == NULL) - { - wprintf(L"MS: HeapAlloc failed\n"); - RegCloseKey(HandleSubKey); - RegCloseKey(HandleKey); - return; - } - - GlobalFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"GlobalFlag", MaxLen); - if (Set) - { - GlobalFlags |= 0x02000000; - } - else - { - GlobalFlags &= ~0x02000000; - } - - if (GlobalFlags != 0) - { - wsprintf(Buffer, L"0x%08x", GlobalFlags); - Ret = RegSetValueEx(HandleSubKey, L"GlobalFlag", 0, REG_SZ, Buffer, 11 * sizeof(WCHAR)); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret); - } - } - else - { - Ret = RegDeleteValue(HandleSubKey, L"GlobalFlag"); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegDeleteValue failed (%d)\n", Ret); - } - } - - if (Unset) - { - Ret = RegDeleteValue(HandleSubKey, L"PageHeapFlags"); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegDeleteValue failed (%d)\n", Ret); - } - } - else - { - DWORD PageHeapFlags; - - PageHeapFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"PageHeapFlags", MaxLen); - PageHeapFlags &= ~3; - - if (Full) - { - PageHeapFlags |= 1; - } - PageHeapFlags |= 2; - - wsprintf(Buffer, L"0x%x", PageHeapFlags); - Ret = RegSetValueEx(HandleSubKey, L"PageHeapFlags", 0, REG_SZ, Buffer, 11 * sizeof(WCHAR)); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret); - } - } - - if (Set) - { - DWORD Type, VerifierFlags, Len; - - VerifierFlags = 0; - Len = MaxLen; - if (RegQueryValueEx(HandleSubKey, L"VerifierFlags", NULL, &Type, Buffer, &Len) == ERROR_SUCCESS && - Type == REG_DWORD && Len == sizeof(DWORD)) - { - VerifierFlags = ((DWORD *)Buffer)[0]; - VerifierFlags &= ~0x8001; - } - - if (Full) - { - VerifierFlags |= 1; - } - else - { - VerifierFlags |= 0x8000; - } - - Ret = RegSetValueEx(HandleSubKey, L"VerifierFlags", 0, REG_DWORD, (const BYTE *)&VerifierFlags, sizeof(DWORD)); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret); - } - } - - wprintf(L"path: %s\n", ImageExecOptionsString); - wprintf(L"\t%s: page heap %s\n", Image, (Set ? L"enabled" : L"disabled")); - - HeapFree(GetProcessHeap(), 0, Buffer); - RegCloseKey(HandleSubKey); - RegCloseKey(HandleKey); -} - -static BOOL DisplayImageInfo(HKEY HandleKey, PWSTR SubKey, PBOOL Header) -{ - LONG Ret; - BOOL Handled; - DWORD MaxLen, GlobalFlags; - HKEY HandleSubKey; - PVOID Buffer; - - Ret = RegOpenKeyEx(HandleKey, SubKey, 0, KEY_READ, &HandleSubKey); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"DII: RegOpenKeyEx failed (%d)\n", Ret); - return FALSE; - } - - Ret = RegQueryInfoKey(HandleSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"DII: RegQueryInfoKey failed (%d)\n", Ret); - RegCloseKey(HandleSubKey); - return FALSE; - } - - Buffer = HeapAlloc(GetProcessHeap(), 0, MaxLen); - if (Buffer == NULL) - { - wprintf(L"DII: HeapAlloc failed\n"); - RegCloseKey(HandleSubKey); - return FALSE; - } - - Handled = FALSE; - GlobalFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"GlobalFlag", MaxLen); - if (GlobalFlags & 0x02000000) - { - DWORD PageHeapFlags; - - if (Image == NULL) - { - if (!*Header) - { - wprintf(L"path: %s\n", ImageExecOptionsString); - *Header = TRUE; - } - wprintf(L"\t%s: page heap enabled with flags (", SubKey); - } - else - { - wprintf(L"Page heap is enabled for %s with flags (", SubKey); - } - - PageHeapFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"PageHeapFlags", MaxLen); - if (PageHeapFlags & 0x1) - { - wprintf(L"full "); - } - - if (PageHeapFlags & 0x2) - { - wprintf(L"traces"); - } - - wprintf(L")\n"); - - Handled = TRUE; - } - - HeapFree(GetProcessHeap(), 0, Buffer); - RegCloseKey(HandleSubKey); - - return Handled; -} - -static VOID DisplayStatus(VOID) -{ - LONG Ret; - HKEY HandleKey; - DWORD Index, MaxLen, Handled; - TCHAR * SubKey; - BOOL Header; - - Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ImageExecOptionsString, 0, KEY_READ, &HandleKey); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"DS: RegOpenKeyEx failed (%d)\n", Ret); - return; - } - - Ret = RegQueryInfoKey(HandleKey, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL, NULL, NULL, NULL, NULL); - if (Ret != ERROR_SUCCESS) - { - wprintf(L"DS: RegQueryInfoKey failed (%d)\n", Ret); - RegCloseKey(HandleKey); - return; - } - - ++MaxLen; // NULL-char - SubKey = HeapAlloc(GetProcessHeap(), 0, MaxLen * sizeof(TCHAR)); - if (SubKey == NULL) - { - wprintf(L"DS: HeapAlloc failed\n"); - RegCloseKey(HandleKey); - return; - } - - Index = 0; - Handled = 0; - Header = FALSE; - do - { - Ret = RegEnumKey(HandleKey, Index, SubKey, MaxLen); - if (Ret != ERROR_NO_MORE_ITEMS) - { - if (Image == NULL || wcscmp(SubKey, Image) == 0) - { - if (DisplayImageInfo(HandleKey, SubKey, &Header)) - { - ++Handled; - } - } - - ++Index; - } - } while (Ret != ERROR_NO_MORE_ITEMS); - - if (Handled == 0) - { - if (Image == NULL) - { - wprintf(L"No application has page heap enabled.\n"); - } - else - { - wprintf(L"Page heap is not enabled for %s\n", Image); - } - } - - HeapFree(GetProcessHeap(), 0, SubKey); - RegCloseKey(HandleKey); -} - -static VOID Usage(VOID) -{ - wprintf(L"Usage: gflags /p [image.exe] [/enable|/disable [/full]]\n" - L"\timage.exe:\tImage you want to deal with\n" - L"\t/enable:\tenable page heap for the image\n" - L"\t/disable:\tdisable page heap for the image\n" - L"\t/full:\t\tactivate full debug page heap\n"); -} - static BOOL ParseCmdline(int argc, LPWSTR argv[]) { INT i; - BOOL UsePageHeap = FALSE; if (argc < 2) { - wprintf(L"Not enough args!\n", argc); - Usage(); + wprintf(L"Not enough args!\n"); return FALSE; } @@ -338,37 +42,12 @@ static BOOL ParseCmdline(int argc, LPWSTR argv[]) if (argv[i][1] == L'p' && argv[i][2] == UNICODE_NULL) { UsePageHeap = TRUE; + return PageHeap_ParseCmdline(i + 1, argc, argv); } - else if (argv[i][1] == L'p' && argv[i][2] != UNICODE_NULL) - { - wprintf(L"Invalid option: %s\n", argv[i]); - Usage(); - return FALSE; - } - else - { - if (wcscmp(argv[i], L"/enable") == 0) - { - Set = TRUE; - } - else if (wcscmp(argv[i], L"/disable") == 0) - { - Unset = TRUE; - } - else if (wcscmp(argv[i], L"/full") == 0) - { - Full = TRUE; - } - } - } - else if (Image == NULL) - { - Image = argv[i]; } else { wprintf(L"Invalid option: %s\n", argv[i]); - Usage(); return FALSE; } } @@ -376,49 +55,28 @@ static BOOL ParseCmdline(int argc, LPWSTR argv[]) if (!UsePageHeap) { wprintf(L"Only page heap flags are supported\n"); - Usage(); - return FALSE; - } - - if (Set && Unset) - { - wprintf(L"ENABLE and DISABLED cannot be set together\n"); - Usage(); - return FALSE; - } - - if (Image == NULL && (Set || Unset || Full)) - { - wprintf(L"Can't ENABLE or DISABLE with no image\n"); - Usage(); - return FALSE; - } - - if (!Set && !Unset && Full) - { - wprintf(L"Cannot deal with full traces with no other indication\n"); - Usage(); return FALSE; } return TRUE; } + int wmain(int argc, LPWSTR argv[]) { if (!ParseCmdline(argc, argv)) { + wprintf(L"Usage: gflags /p [image.exe] [/enable|/disable [/full]]\n" + L"\timage.exe:\tImage you want to deal with\n" + L"\t/enable:\tenable page heap for the image\n" + L"\t/disable:\tdisable page heap for the image\n" + L"\t/full:\t\tactivate full debug page heap\n"); return 1; } - if (!Set && !Unset) + if (UsePageHeap) { - DisplayStatus(); + return PageHeap_Execute(); } - else - { - ModifyStatus(); - } - - return 0; + return 2; } diff --git a/modules/rosapps/applications/cmdutils/gflags/gflags.h b/modules/rosapps/applications/cmdutils/gflags/gflags.h new file mode 100644 index 00000000000..740f6a77c7e --- /dev/null +++ b/modules/rosapps/applications/cmdutils/gflags/gflags.h @@ -0,0 +1,26 @@ +/* +* PROJECT: Global Flags utility +* LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0) +* PURPOSE: Global Flags utility page heap options +* COPYRIGHT: Copyright 2017 Pierre Schweitzer (pierre@reactos.org) +*/ + +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include +#include +#include + + +/* Option specific commandline parsing */ +BOOL PageHeap_ParseCmdline(INT i, int argc, LPWSTR argv[]); + +/* Execute parsed options */ +INT PageHeap_Execute(); + +/* Common functions */ +DWORD ReagFlagsFromRegistry(HKEY SubKey, PVOID Buffer, PWSTR Value, DWORD MaxLen); + diff --git a/modules/rosapps/applications/cmdutils/gflags/pageheap.c b/modules/rosapps/applications/cmdutils/gflags/pageheap.c new file mode 100644 index 00000000000..33d11b1c27a --- /dev/null +++ b/modules/rosapps/applications/cmdutils/gflags/pageheap.c @@ -0,0 +1,355 @@ +/* + * PROJECT: Global Flags utility + * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0) + * PURPOSE: Global Flags utility page heap options + * COPYRIGHT: Copyright 2017 Pierre Schweitzer (pierre@reactos.org) + */ + +#include "gflags.h" + +static BOOL Set = FALSE; +static BOOL Unset = FALSE; +static BOOL Full = FALSE; +static PWSTR Image = NULL; +static WCHAR ImageExecOptionsString[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"; + + +static VOID ModifyStatus(VOID) +{ + LONG Ret; + DWORD MaxLen, GlobalFlags; + PVOID Buffer; + HKEY HandleKey, HandleSubKey; + + Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ImageExecOptionsString, 0, KEY_WRITE | KEY_READ, &HandleKey); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegOpenKeyEx failed (%d)\n", Ret); + return; + } + + Ret = RegCreateKeyEx(HandleKey, Image, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &HandleSubKey, NULL); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegCreateKeyEx failed (%d)\n", Ret); + return; + } + + Ret = RegQueryInfoKey(HandleSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegQueryInfoKey failed (%d)\n", Ret); + RegCloseKey(HandleSubKey); + RegCloseKey(HandleKey); + return; + } + + MaxLen = max(MaxLen, 11 * sizeof(WCHAR)); + Buffer = HeapAlloc(GetProcessHeap(), 0, MaxLen); + if (Buffer == NULL) + { + wprintf(L"MS: HeapAlloc failed\n"); + RegCloseKey(HandleSubKey); + RegCloseKey(HandleKey); + return; + } + + GlobalFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"GlobalFlag", MaxLen); + if (Set) + { + GlobalFlags |= 0x02000000; + } + else + { + GlobalFlags &= ~0x02000000; + } + + if (GlobalFlags != 0) + { + wsprintf(Buffer, L"0x%08x", GlobalFlags); + Ret = RegSetValueEx(HandleSubKey, L"GlobalFlag", 0, REG_SZ, Buffer, 11 * sizeof(WCHAR)); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret); + } + } + else + { + Ret = RegDeleteValue(HandleSubKey, L"GlobalFlag"); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegDeleteValue failed (%d)\n", Ret); + } + } + + if (Unset) + { + Ret = RegDeleteValue(HandleSubKey, L"PageHeapFlags"); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegDeleteValue failed (%d)\n", Ret); + } + } + else + { + DWORD PageHeapFlags; + + PageHeapFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"PageHeapFlags", MaxLen); + PageHeapFlags &= ~3; + + if (Full) + { + PageHeapFlags |= 1; + } + PageHeapFlags |= 2; + + wsprintf(Buffer, L"0x%x", PageHeapFlags); + Ret = RegSetValueEx(HandleSubKey, L"PageHeapFlags", 0, REG_SZ, Buffer, 11 * sizeof(WCHAR)); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret); + } + } + + if (Set) + { + DWORD Type, VerifierFlags, Len; + + VerifierFlags = 0; + Len = MaxLen; + if (RegQueryValueEx(HandleSubKey, L"VerifierFlags", NULL, &Type, Buffer, &Len) == ERROR_SUCCESS && + Type == REG_DWORD && Len == sizeof(DWORD)) + { + VerifierFlags = ((DWORD *)Buffer)[0]; + VerifierFlags &= ~0x8001; + } + + if (Full) + { + VerifierFlags |= 1; + } + else + { + VerifierFlags |= 0x8000; + } + + Ret = RegSetValueEx(HandleSubKey, L"VerifierFlags", 0, REG_DWORD, (const BYTE *)&VerifierFlags, sizeof(DWORD)); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"MS: RegSetValueEx failed (%d)\n", Ret); + } + } + + wprintf(L"path: %s\n", ImageExecOptionsString); + wprintf(L"\t%s: page heap %s\n", Image, (Set ? L"enabled" : L"disabled")); + + HeapFree(GetProcessHeap(), 0, Buffer); + RegCloseKey(HandleSubKey); + RegCloseKey(HandleKey); +} + +static BOOL DisplayImageInfo(HKEY HandleKey, PWSTR SubKey, PBOOL Header) +{ + LONG Ret; + BOOL Handled; + DWORD MaxLen, GlobalFlags; + HKEY HandleSubKey; + PVOID Buffer; + + Ret = RegOpenKeyEx(HandleKey, SubKey, 0, KEY_READ, &HandleSubKey); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"DII: RegOpenKeyEx failed (%d)\n", Ret); + return FALSE; + } + + Ret = RegQueryInfoKey(HandleSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"DII: RegQueryInfoKey failed (%d)\n", Ret); + RegCloseKey(HandleSubKey); + return FALSE; + } + + Buffer = HeapAlloc(GetProcessHeap(), 0, MaxLen); + if (Buffer == NULL) + { + wprintf(L"DII: HeapAlloc failed\n"); + RegCloseKey(HandleSubKey); + return FALSE; + } + + Handled = FALSE; + GlobalFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"GlobalFlag", MaxLen); + if (GlobalFlags & 0x02000000) + { + DWORD PageHeapFlags; + + if (Image == NULL) + { + if (!*Header) + { + wprintf(L"path: %s\n", ImageExecOptionsString); + *Header = TRUE; + } + wprintf(L"\t%s: page heap enabled with flags (", SubKey); + } + else + { + wprintf(L"Page heap is enabled for %s with flags (", SubKey); + } + + PageHeapFlags = ReagFlagsFromRegistry(HandleSubKey, Buffer, L"PageHeapFlags", MaxLen); + if (PageHeapFlags & 0x1) + { + wprintf(L"full "); + } + + if (PageHeapFlags & 0x2) + { + wprintf(L"traces"); + } + + wprintf(L")\n"); + + Handled = TRUE; + } + + HeapFree(GetProcessHeap(), 0, Buffer); + RegCloseKey(HandleSubKey); + + return Handled; +} + +static VOID DisplayStatus(VOID) +{ + LONG Ret; + HKEY HandleKey; + DWORD Index, MaxLen, Handled; + TCHAR * SubKey; + BOOL Header; + + Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ImageExecOptionsString, 0, KEY_READ, &HandleKey); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"DS: RegOpenKeyEx failed (%d)\n", Ret); + return; + } + + Ret = RegQueryInfoKey(HandleKey, NULL, NULL, NULL, NULL, &MaxLen, NULL, NULL, NULL, NULL, NULL, NULL); + if (Ret != ERROR_SUCCESS) + { + wprintf(L"DS: RegQueryInfoKey failed (%d)\n", Ret); + RegCloseKey(HandleKey); + return; + } + + ++MaxLen; // NULL-char + SubKey = HeapAlloc(GetProcessHeap(), 0, MaxLen * sizeof(TCHAR)); + if (SubKey == NULL) + { + wprintf(L"DS: HeapAlloc failed\n"); + RegCloseKey(HandleKey); + return; + } + + Index = 0; + Handled = 0; + Header = FALSE; + do + { + Ret = RegEnumKey(HandleKey, Index, SubKey, MaxLen); + if (Ret != ERROR_NO_MORE_ITEMS) + { + if (Image == NULL || wcscmp(SubKey, Image) == 0) + { + if (DisplayImageInfo(HandleKey, SubKey, &Header)) + { + ++Handled; + } + } + + ++Index; + } + } while (Ret != ERROR_NO_MORE_ITEMS); + + if (Handled == 0) + { + if (Image == NULL) + { + wprintf(L"No application has page heap enabled.\n"); + } + else + { + wprintf(L"Page heap is not enabled for %s\n", Image); + } + } + + HeapFree(GetProcessHeap(), 0, SubKey); + RegCloseKey(HandleKey); +} + +BOOL PageHeap_ParseCmdline(INT i, int argc, LPWSTR argv[]) +{ + for (; i < argc; i++) + { + if (argv[i][0] == L'/') + { + if (wcscmp(argv[i], L"/enable") == 0) + { + Set = TRUE; + } + else if (wcscmp(argv[i], L"/disable") == 0) + { + Unset = TRUE; + } + else if (wcscmp(argv[i], L"/full") == 0) + { + Full = TRUE; + } + } + else if (Image == NULL) + { + Image = argv[i]; + } + else + { + wprintf(L"Invalid option: %s\n", argv[i]); + return FALSE; + } + } + + if (Set && Unset) + { + wprintf(L"ENABLE and DISABLED cannot be set together\n"); + return FALSE; + } + + if (Image == NULL && (Set || Unset || Full)) + { + wprintf(L"Can't ENABLE or DISABLE with no image\n"); + return FALSE; + } + + if (!Set && !Unset && Full) + { + wprintf(L"Cannot deal with full traces with no other indication\n"); + return FALSE; + } + + return TRUE; +} + +INT PageHeap_Execute() +{ + if (!Set && !Unset) + { + DisplayStatus(); + } + else + { + ModifyStatus(); + } + + return 0; +}