Author: pschweitzer
Date: Sat Jun 17 12:34:08 2017
New Revision: 75073
URL:
http://svn.reactos.org/svn/reactos?rev=75073&view=rev
Log:
[GFLAGS]
Add a quick'n'dirty implementation of gflags utility.
It only covers some page heap usage (enough to enable/disable DPH :-)).
It's syntax compatible with MS one, and with what's written down in ROS wiki.
See:
https://www.reactos.org/wiki/Debugging#Debug_Page_Heap_.28DPH.29
Added:
trunk/rosapps/applications/cmdutils/gflags/
trunk/rosapps/applications/cmdutils/gflags/CMakeLists.txt (with props)
trunk/rosapps/applications/cmdutils/gflags/gflags.c (with props)
trunk/rosapps/applications/cmdutils/gflags/gflags.rc (with props)
Modified:
trunk/rosapps/applications/cmdutils/CMakeLists.txt
Modified: trunk/rosapps/applications/cmdutils/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/CMak…
==============================================================================
--- trunk/rosapps/applications/cmdutils/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rosapps/applications/cmdutils/CMakeLists.txt [iso-8859-1] Sat Jun 17 12:34:08
2017
@@ -1,6 +1,7 @@
add_subdirectory(appwiz)
add_subdirectory(arping)
add_subdirectory(cat)
+add_subdirectory(gflags)
add_subdirectory(ntfsinfo)
add_subdirectory(tee)
add_subdirectory(touch)
Added: trunk/rosapps/applications/cmdutils/gflags/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/gfla…
==============================================================================
--- trunk/rosapps/applications/cmdutils/gflags/CMakeLists.txt (added)
+++ trunk/rosapps/applications/cmdutils/gflags/CMakeLists.txt [iso-8859-1] Sat Jun 17
12:34:08 2017
@@ -0,0 +1,10 @@
+
+add_executable(gflags gflags.c gflags.rc)
+set_module_type(gflags win32cui UNICODE)
+add_importlibs(gflags advapi32 user32 msvcrt kernel32)
+
+if(MSVC)
+ add_importlibs(gflags ntdll)
+endif()
+
+add_cd_file(TARGET gflags DESTINATION reactos/bin FOR all)
Propchange: trunk/rosapps/applications/cmdutils/gflags/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/gflags/gflags.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/gfla…
==============================================================================
--- trunk/rosapps/applications/cmdutils/gflags/gflags.c (added)
+++ trunk/rosapps/applications/cmdutils/gflags/gflags.c [iso-8859-1] Sat Jun 17 12:34:08
2017
@@ -0,0 +1,421 @@
+/*
+ * 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 <pierre(a)reactos.org>
+ */
+
+#define WIN32_NO_STATUS
+#include <stdarg.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winuser.h>
+#include <winreg.h>
+#include <stdio.h>
+#include <stdlib.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 DWORD ReagFlagsFromRegistry(HKEY SubKey, PVOID Buffer, PWSTR Value, DWORD MaxLen)
+{
+ DWORD Len, Flags, Type;
+
+ Len = MaxLen;
+ Flags = 0;
+ if (RegQueryValueEx(SubKey, Value, NULL, &Type, Buffer, &Len) ==
ERROR_SUCCESS && Type == REG_SZ)
+ {
+ Flags = wcstoul(Buffer, NULL, 16);
+ }
+
+ 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)
+{
+ // FIXME
+ wprintf(L"Usage\n");
+}
+
+static BOOL ParseCmdline(int argc, LPWSTR argv[])
+{
+ INT i;
+ BOOL UsePageHeap = FALSE;
+
+ if (argc < 2)
+ {
+ wprintf(L"Not enough args!\n", argc);
+ Usage();
+ return FALSE;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] == L'/')
+ {
+ if (argv[i][1] == L'p' && argv[i][2] == UNICODE_NULL)
+ {
+ UsePageHeap = TRUE;
+ }
+ 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;
+ }
+ }
+
+ 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))
+ {
+ return 1;
+ }
+
+ if (!Set && !Unset)
+ {
+ DisplayStatus();
+ }
+ else
+ {
+ ModifyStatus();
+ }
+
+ return 0;
+}
Propchange: trunk/rosapps/applications/cmdutils/gflags/gflags.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/gflags/gflags.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/gfla…
==============================================================================
--- trunk/rosapps/applications/cmdutils/gflags/gflags.rc (added)
+++ trunk/rosapps/applications/cmdutils/gflags/gflags.rc [iso-8859-1] Sat Jun 17 12:34:08
2017
@@ -0,0 +1,6 @@
+#include <windef.h>
+
+#define REACTOS_STR_FILE_DESCRIPTION "Global Flags utility"
+#define REACTOS_STR_INTERNAL_NAME "gflags"
+#define REACTOS_STR_ORIGINAL_FILENAME "gflags.exe"
+#include <reactos/version.rc>
Propchange: trunk/rosapps/applications/cmdutils/gflags/gflags.rc
------------------------------------------------------------------------------
svn:eol-style = native