[GFLAGS] Move code around to handle multiple options
[reactos.git] / modules / rosapps / applications / cmdutils / gflags / gflags.c
index 260c6d5..b0751a0 100644 (file)
@@ -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 <pierre@reactos.org>
+ * 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 <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <winuser.h>
-#include <winreg.h>
-#include <stdio.h>
-#include <stdlib.h>
+#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;
-            }
-            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;
-                }
+                return PageHeap_ParseCmdline(i + 1, argc, argv);
             }
         }
-        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)
-    {
-        DisplayStatus();
-    }
-    else
+    if (UsePageHeap)
     {
-        ModifyStatus();
+        return PageHeap_Execute();
     }
-
-    return 0;
+    return 2;
 }