[GFLAGS] Implement imagefile options
[reactos.git] / modules / rosapps / applications / cmdutils / gflags / gflags.c
1 /*
2 * PROJECT: Global Flags utility
3 * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0)
4 * PURPOSE: Global Flags utility entrypoint
5 * COPYRIGHT: Copyright 2017 Pierre Schweitzer (pierre@reactos.org)
6 * Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
7 */
8
9 #include "gflags.h"
10
11 static BOOL UsePageHeap = FALSE;
12 static BOOL UseImageFile = FALSE;
13
14 const WCHAR ImageExecOptionsString[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options";
15
16 BOOL OpenImageFileExecOptions(IN REGSAM SamDesired, IN OPTIONAL PCWSTR ImageName, OUT HKEY* Key)
17 {
18 LONG Ret;
19 HKEY HandleKey, HandleSubKey;
20
21 Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ImageExecOptionsString, 0, KEY_WRITE | KEY_READ, &HandleKey);
22 if (Ret != ERROR_SUCCESS)
23 {
24 wprintf(L"OpenIFEO: RegOpenKeyEx failed (%d)\n", Ret);
25 return FALSE;
26 }
27
28 if (ImageName == NULL)
29 {
30 *Key = HandleKey;
31 return TRUE;
32 }
33
34 Ret = RegCreateKeyExW(HandleKey, ImageName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &HandleSubKey, NULL);
35 CloseHandle(HandleKey);
36
37 if (Ret != ERROR_SUCCESS)
38 {
39 wprintf(L"OpenIFEO: RegCreateKeyEx failed (%d)\n", Ret);
40 return FALSE;
41 }
42 *Key = HandleSubKey;
43 return TRUE;
44 }
45
46
47 DWORD ReadSZFlagsFromRegistry(HKEY SubKey, PWSTR Value)
48 {
49 WCHAR Buffer[20] = { 0 };
50 DWORD Len, Flags, Type;
51
52 Len = sizeof(Buffer) - sizeof(WCHAR);
53 Flags = 0;
54 if (RegQueryValueExW(SubKey, Value, NULL, &Type, (BYTE*)Buffer, &Len) == ERROR_SUCCESS && Type == REG_SZ)
55 {
56 Flags = wcstoul(Buffer, NULL, 16);
57 }
58
59 return Flags;
60 }
61
62 static BOOL ParseCmdline(int argc, LPWSTR argv[])
63 {
64 INT i;
65
66 if (argc < 2)
67 {
68 wprintf(L"Not enough args!\n");
69 return FALSE;
70 }
71
72 for (i = 1; i < argc; i++)
73 {
74 if (argv[i][0] == L'/')
75 {
76 if (argv[i][1] == L'p' && argv[i][2] == UNICODE_NULL)
77 {
78 UsePageHeap = TRUE;
79 return PageHeap_ParseCmdline(i + 1, argc, argv);
80 }
81 if (argv[i][1] == L'i' && argv[i][2] == UNICODE_NULL)
82 {
83 UseImageFile = TRUE;
84 return ImageFile_ParseCmdline(i + 1, argc, argv);
85 }
86 }
87 else
88 {
89 wprintf(L"Invalid option: %s\n", argv[i]);
90 return FALSE;
91 }
92 }
93
94 if (!UsePageHeap && !UseImageFile)
95 {
96 wprintf(L"Only page heap / image file flags are supported\n");
97 return FALSE;
98 }
99
100 return TRUE;
101 }
102
103
104 int wmain(int argc, LPWSTR argv[])
105 {
106 if (!ParseCmdline(argc, argv))
107 {
108 wprintf(L"Usage: gflags [/p [image.exe] [/enable|/disable [/full]]]\n"
109 L" [/i <image.exe> [<Flags>]]\n"
110 L" image.exe: Image you want to deal with\n"
111 L" /enable: enable page heap for the image\n"
112 L" /disable: disable page heap for the image\n"
113 L" /full: activate full debug page heap\n"
114 L" <Flags>: A 32 bit hex number (0x00000001) that specifies\n"
115 L" one or more global flags to set.\n"
116 L" Without any flags, the current settings are shown.\n"
117 L" Specify FFFFFFFF to delete the GlobalFlags entry.\n"
118 L" Additionally, instead of a single hex number,\n"
119 L" specify a list of abbreviations prefixed with\n"
120 L" a '+' to add, and '-' to remove a bit.\n"
121 L" Valid abbreviations:\n");
122 PrintFlags(~0, DEST_IMAGE);
123 return 1;
124 }
125
126 if (UsePageHeap)
127 {
128 return PageHeap_Execute();
129 }
130 else if (UseImageFile)
131 {
132 return ImageFile_Execute();
133 }
134 return 2;
135 }