|
|
/*++
Copyright (c) 1994-1999 Microsoft Corporation
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntexapi.dbg>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "gflags.h"
CHAR GflagsHelpText[] = " \n" "usage: GFLAGS [-r [<Flags>] | \n" " [-k [<Flags>]] | \n" " [-i <ImageFileName> [<Flags>]] | \n" " [-i <ImageFileName> -tracedb <SizeInMb>] | \n" " [-p <PageHeapOptions>] (use `-p ?' for help) \n" " \n" "where: <Flags> is a 32 bit hex number (0x12345678) that specifies \n" " one or more global flags to set. \n" " -r operates on system registry settings. \n" " -k operates on kernel settings of the running system. \n" " -i operates on settings for a specific image file. \n" " \n" " If only the switch is specified, then current settings \n" " are displayed, not modified. If flags specified for -i \n" " option are FFFFFFFF, then registry entry for that image \n" " is deleted \n" " \n" "The `-tracedb' option is used to set the size of the stack trace \n" "database used to store runtime stack traces. The actual database \n" "will be created if the `+ust' flag is set in a previous command. \n" "`-tracedb 0' will revert to the default size for the database. \n" " \n" "If no arguments are specified to GFLAGS then it displays \n" "a dialog box that allows the user to modify the global \n" "flag settings. \n" " \n" "Flags may either be a single hex number that specifies all \n" "32-bits of the GlobalFlags value, or it can be one or more \n" "arguments, each beginning with a + or -, where the + means \n" "to set the corresponding bit(s) in the GlobalFlags and a = \n" "means to clear the corresponding bit(s). After the + or = \n" "may be either a hex number or a three letter abbreviation \n" "for a GlobalFlag. Valid abbreviations are: \n" " \n";
#define _PART_OF_GFLAGS_ 1
#include "..\pageheap\pageheap.cxx"
#if defined(_X86_)
//
// Use function pointers for ntdll import functions so gflags
// can fail with a user friendly message on win9x.
//
#define RtlIntegerToChar pRtlIntegerToChar
#define NtQueryInformationProcess pNtQueryInformationProcess
#define RtlCharToInteger pRtlCharToInteger
#define NtSetSystemInformation pNtSetSystemInformation
#define NtQuerySystemInformation pNtQuerySystemInformation
typedef NTSTATUS (NTAPI *PRTLINTEGERTOCHAR)( ULONG, ULONG, LONG, PSZ );
typedef NTSTATUS (NTAPI *PNTQUERYINFORMATIONPROCESS) ( IN HANDLE, IN PROCESSINFOCLASS, OUT PVOID, IN ULONG, OUT PULONG );
typedef NTSTATUS (NTAPI * PRTLCHARTOINTEGER) ( PCSZ, ULONG, PULONG );
typedef NTSTATUS (NTAPI * PNTSETSYSTEMINFORMATION) ( IN SYSTEM_INFORMATION_CLASS, IN PVOID, IN ULONG );
typedef NTSTATUS (NTAPI * PNTQUERYSYSTEMINFORMATION) ( IN SYSTEM_INFORMATION_CLASS, OUT PVOID, IN ULONG, OUT PULONG );
PRTLINTEGERTOCHAR pRtlIntegerToChar; PNTQUERYINFORMATIONPROCESS pNtQueryInformationProcess; PRTLCHARTOINTEGER pRtlCharToInteger; PNTSETSYSTEMINFORMATION pNtSetSystemInformation; PNTQUERYSYSTEMINFORMATION pNtQuerySystemInformation;
#endif
BOOL GflagsSetTraceDatabaseSize ( PCHAR ApplicationName, ULONG SizeInMb, PULONG RealSize );
INT_PTR APIENTRY MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL EnableDebugPrivilege( VOID );
BOOL OkToEnablePagedHeap( VOID );
HWND hwndMain; HWND hwndPagedHeapDlg;
HKEY hSmKey, hMmKey; DWORD InitialSetFlags; DWORD LastSetFlags;
//
// Special pool management
//
#define SPECIAL_POOL_OVERRUNS_CHECK_FORWARD 1
#define SPECIAL_POOL_OVERRUNS_CHECK_BACKWARD 0
DWORD LastSetSpecialPoolTag; DWORD LastSetSpecialPoolOverruns = SPECIAL_POOL_OVERRUNS_CHECK_FORWARD;
TCHAR SpecialPoolRenderBuffer[8 + 1];
DWORD InitialMaxStackTraceDepth; CHAR LastDebuggerValue[ MAX_PATH ];
UINT SpecialPool[] = { ID_SPECIAL_POOL_GROUP, ID_SPECIAL_POOL_IS_TEXT, ID_SPECIAL_POOL_IS_NUMBER, ID_SPECIAL_POOL_TAG, ID_SPECIAL_POOL_VERIFY_START, ID_SPECIAL_POOL_VERIFY_END, ID_MAX_STACK_DEPTH, 0 };
UINT Debugger[] = { ID_IMAGE_DEBUGGER_GROUP, ID_IMAGE_DEBUGGER_VALUE, ID_IMAGE_DEBUGGER_BUTTON, 0 };
PCHAR SystemProcesses[] = { "csrss.exe", "winlogon.exe", "services.exe", "lsass.exe", "svchost.exe", "ntmssvc.exe", "rpcss.exe", "spoolsv.exe" };
EnableSetOfControls( HWND hDlg, UINT * Controls, BOOL Enable ) { UINT Control ; HWND hWnd ;
Control = *Controls++ ; while ( Control ) { hWnd = GetDlgItem( hDlg, Control );
EnableWindow( hWnd, Enable );
ShowWindow( hWnd, Enable ? SW_NORMAL : SW_HIDE );
Control = *Controls++ ; }
return 0; }
DWORD GetSystemRegistryFlags( VOID ) { DWORD cbKey; DWORD GFlags; DWORD type;
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager", 0, KEY_READ | KEY_WRITE, &hSmKey ) != ERROR_SUCCESS ) { MessageBox( hwndMain, "Open Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager", MB_OK ); ExitProcess( 0 ); }
cbKey = sizeof( GFlags ); if (RegQueryValueEx( hSmKey, "GlobalFlag", 0, &type, (LPBYTE)&GFlags, &cbKey ) != ERROR_SUCCESS || type != REG_DWORD ) { MessageBox( hwndMain, "Value Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\GlobalFlag", MB_OK ); RegCloseKey( hSmKey ); ExitProcess( 0 ); }
cbKey = sizeof( InitialMaxStackTraceDepth ); if (RegQueryValueEx( hSmKey, "MaxStackTraceDepth", 0, &type, (LPBYTE)&InitialMaxStackTraceDepth, &cbKey ) != ERROR_SUCCESS || type != REG_DWORD ) { InitialMaxStackTraceDepth = 16; }
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management", 0, KEY_READ | KEY_WRITE, &hMmKey ) != ERROR_SUCCESS ) { MessageBox( hwndMain, "Open Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management", MB_OK ); RegCloseKey( hSmKey ); ExitProcess( 0 ); }
cbKey = sizeof( LastSetSpecialPoolTag ); if (RegQueryValueEx( hMmKey, "PoolTag", 0, &type, (LPBYTE)&LastSetSpecialPoolTag, &cbKey ) == ERROR_SUCCESS ) {
if (type != REG_DWORD) { MessageBox( hwndMain, "Value Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management\\PoolTag", MB_OK ); RegCloseKey( hSmKey ); RegCloseKey( hMmKey ); ExitProcess( 0 ); } } else { LastSetSpecialPoolTag = 0; }
cbKey = sizeof( LastSetSpecialPoolOverruns ); if (RegQueryValueEx( hMmKey, "PoolTagOverruns", 0, &type, (LPBYTE)&LastSetSpecialPoolOverruns, &cbKey ) == ERROR_SUCCESS ) {
if (type != REG_DWORD) {
MessageBox( hwndMain, "Value Type Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management" "\\PoolTagOverruns", MB_OK ); RegCloseKey( hSmKey ); RegCloseKey( hMmKey ); ExitProcess( 0 ); }
//
// The only legal values are 0, 1.
//
if (LastSetSpecialPoolOverruns != SPECIAL_POOL_OVERRUNS_CHECK_BACKWARD && LastSetSpecialPoolOverruns != SPECIAL_POOL_OVERRUNS_CHECK_FORWARD) {
MessageBox( hwndMain, "Value Data Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management" "\\PoolTagOverruns", MB_OK ); RegCloseKey( hSmKey ); RegCloseKey( hMmKey ); ExitProcess( 0 ); }
} else { LastSetSpecialPoolOverruns = SPECIAL_POOL_OVERRUNS_CHECK_FORWARD; }
return GFlags; }
BOOLEAN SetSystemRegistryFlags( DWORD GFlags, DWORD MaxStackTraceDepth, DWORD SpecialPoolTag, DWORD SpecialPoolOverruns ) { if (RegSetValueEx( hSmKey, "GlobalFlag", 0, REG_DWORD, (LPBYTE)&GFlags, sizeof( GFlags ) ) != ERROR_SUCCESS ) { MessageBox( hwndMain, "Value Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\GlobalFlag", MB_OK ); RegCloseKey( hSmKey ); RegCloseKey( hMmKey ); ExitProcess( 0 ); }
if (RegSetValueEx( hSmKey, "MaxStackTraceDepth", 0, REG_DWORD, (LPBYTE)&MaxStackTraceDepth, sizeof( MaxStackTraceDepth ) ) != ERROR_SUCCESS ) { MessageBox( hwndMain, "Value Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\MaxStackTraceDepth", MB_OK ); RegCloseKey( hSmKey ); RegCloseKey( hMmKey ); ExitProcess( 0 ); }
//
// Only modify special pool if we went to GUI mode
//
if (hwndMain) {
if (SpecialPoolTag) {
if (RegSetValueEx( hMmKey, "PoolTag", 0, REG_DWORD, (LPBYTE)&SpecialPoolTag, sizeof( SpecialPoolTag ) ) != ERROR_SUCCESS ) { MessageBox( hwndMain, "Value Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager" "\\Memory Management\\PoolTag", MB_OK ); RegCloseKey( hSmKey ); RegCloseKey( hMmKey ); ExitProcess( 0 ); }
if (RegSetValueEx( hMmKey, "PoolTagOverruns", 0, REG_DWORD, (LPBYTE)&SpecialPoolOverruns, sizeof( SpecialPoolOverruns ) ) != ERROR_SUCCESS ) { MessageBox( hwndMain, "Value Error", "SYSTEM\\CurrentControlSet\\Control\\Session Manager" "\\Memory Management\\PoolTag", MB_OK ); RegCloseKey( hSmKey ); RegCloseKey( hMmKey ); ExitProcess( 0 ); }
} else {
RegDeleteValue( hMmKey, "PoolTag" );
RegDeleteValue( hMmKey, "PoolTagOverruns" ); } }
InitialMaxStackTraceDepth = MaxStackTraceDepth; LastSetFlags = GFlags;
LastSetSpecialPoolTag = SpecialPoolTag; LastSetSpecialPoolOverruns = SpecialPoolOverruns;
return TRUE; }
DWORD GetKernelModeFlags( VOID ) { NTSTATUS Status; SYSTEM_FLAGS_INFORMATION SystemInformation;
Status = NtQuerySystemInformation( SystemFlagsInformation, &SystemInformation, sizeof( SystemInformation ), NULL ); if (!NT_SUCCESS( Status )) { MessageBox( hwndMain, "Value Error", "Kernel Mode Flags", MB_OK ); ExitProcess( 0 ); }
return SystemInformation.Flags; }
BOOLEAN AddImageNameToUSTString( PCHAR ImageFileName ) { CHAR RegKey[ MAX_PATH ]; CHAR *Enabled = NULL; HKEY hKey; DWORD Result; DWORD Length;
if (strlen( ImageFileName ) == 0) return FALSE;
// Open the Key
Result = RegCreateKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );
if (Result == ERROR_SUCCESS) { // Get the current length of the registry key
Result = RegQueryValueEx( hKey, "USTEnabled", NULL, NULL, NULL, &Length );
if (Result == ERROR_SUCCESS){ // Get a buffer big enough for current key, a ';', and our new name.
Enabled = (PCHAR)malloc(Length + strlen(ImageFileName)+ 1);
if (Enabled) { // Get the current key value
Result = RegQueryValueEx( hKey, "USTEnabled", NULL, NULL, (PBYTE)Enabled, &Length );
if (Result == ERROR_SUCCESS) { // If we are not currently in there, let add ourselves
if (!strstr(Enabled, ImageFileName)) { //Watch for a trailing ';'
if (Enabled[strlen(Enabled) - 1] != ';') strcat(Enabled, ";");
strcat(Enabled, ImageFileName);
Result = RegSetValueEx( hKey, "USTEnabled", 0, REG_SZ, (PBYTE)Enabled, (strlen(Enabled) + 1)); } }
free(Enabled); } // if enabled
} // Result == ERROR_SUCCESS on RegQueryValue
else if (Result == ERROR_FILE_NOT_FOUND) { // Key doesnt currently exist so lets just set it.
Result = RegSetValueEx( hKey, "USTEnabled", 0, REG_SZ, (PBYTE)ImageFileName, (strlen(ImageFileName) + 1)); } // Result == ERROR_FILE_NOT_FOUND on RegQueryValue
RegCloseKey( hKey ); } // Result == ERROR_SUCCESS on RegCreateKeyEx
// Did we succeed or not
if (Result != ERROR_SUCCESS) { MessageBox( hwndMain, "Failure adding or accessing User Stack Trace Registry Key", ImageFileName, MB_OK );
return FALSE; }
return TRUE; }
BOOLEAN DelImageNameFromUSTString( PCHAR ImageFileName ) { CHAR RegKey[ MAX_PATH ]; CHAR *Enabled = NULL; CHAR *NameStart = NULL, *NameEnd = NULL; HKEY hKey; DWORD Result; DWORD Length;
if (strlen( ImageFileName ) == 0) return FALSE;
// Open the Key
Result = RegCreateKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );
if (Result == ERROR_SUCCESS) { // Get the current length of the registry key
Result = RegQueryValueEx( hKey, "USTEnabled", NULL, NULL, NULL, &Length );
if (Result == ERROR_SUCCESS) { if (Length != 0) { // Get a buffer big enough for current key
Enabled = (PCHAR)malloc(Length); if (Enabled) { // Get the current key value
Result = RegQueryValueEx( hKey, "USTEnabled", NULL, NULL, (PBYTE)Enabled, &Length );
if (Result == ERROR_SUCCESS) {
// If we are currently in there, delete ourselves
if (NameStart = strstr(Enabled, ImageFileName)) { NameEnd = NameStart + strlen(ImageFileName);
if (*NameEnd == ';'){ NameEnd++; strcpy(NameStart, NameEnd); } else *NameStart = '\0';
//Knock off any trailing ';'
if (Enabled[strlen(Enabled) - 1] == ';') Enabled[strlen(Enabled) - 1] = '\0';
if (strlen(Enabled)) { Result = RegSetValueEx( hKey, "USTEnabled", 0, REG_SZ, (PBYTE)Enabled, (strlen(Enabled) + 1)); } else{ Result = RegDeleteValue( hKey, "USTEnabled"); } } }
free(Enabled); } } } else if (Result == ERROR_FILE_NOT_FOUND) { // This is a case where the registry key does not already exist
Result = ERROR_SUCCESS; } RegCloseKey( hKey ); }
// Did we succeed or not
if (Result != ERROR_SUCCESS) { MessageBox( hwndMain, "Failure accessing or deleting User Stack Trace Registry Key", ImageFileName, MB_OK );
return FALSE; }
return TRUE; }
BOOLEAN SetKernelModeFlags( DWORD GFlags ) { NTSTATUS Status; SYSTEM_FLAGS_INFORMATION SystemInformation;
if (!EnableDebugPrivilege()) { MessageBox( hwndMain, "Access Denied", "Unable to enable debug privilege", MB_OK ); ExitProcess( 0 ); }
SystemInformation.Flags = GFlags; Status = NtSetSystemInformation( SystemFlagsInformation, &SystemInformation, sizeof( SystemInformation ) ); if (!NT_SUCCESS( Status )) { MessageBox( hwndMain, "Value Error", "Kernel Mode Flags", MB_OK ); ExitProcess( 0 ); }
LastSetFlags = GFlags; return TRUE; }
DWORD GetImageFileNameFlags( PCHAR ImageFileName ) { CHAR Buffer[ MAX_PATH ]; CHAR RegKey[ MAX_PATH ]; DWORD Length = MAX_PATH; DWORD GFlags; HKEY hKey;
GFlags = 0; if (strlen( ImageFileName ) != 0) { sprintf( RegKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s", ImageFileName );
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, RegKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS ) { if (RegQueryValueEx( hKey, "GlobalFlag", NULL, NULL, (PBYTE)Buffer, &Length ) == ERROR_SUCCESS ) { RtlCharToInteger( Buffer, 0, &GFlags ); }
RegCloseKey( hKey ); }
}
return GFlags; }
BOOL GetImageFileNameDebugger( PCHAR ImageFileName, PCHAR Debugger ) { CHAR RegKey[ MAX_PATH ]; DWORD Length = MAX_PATH; DWORD GFlags; HKEY hKey; BOOL Success = FALSE;
GFlags = 0; if (strlen( ImageFileName ) != 0) { sprintf( RegKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s", ImageFileName );
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, RegKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS ) {
if (RegQueryValueEx( hKey, "Debugger", NULL, NULL, (PBYTE)Debugger, &Length ) == ERROR_SUCCESS ) { Success = TRUE ; }
RegCloseKey( hKey ); }
}
return Success ; }
BOOLEAN SetImageFileNameFlags( PCHAR ImageFileName, DWORD GFlags ) { CHAR Buffer[ MAX_PATH ]; CHAR RegKey[ MAX_PATH ]; HKEY hKey; DWORD Result; DWORD Length; DWORD Disposition;
if (strlen( ImageFileName ) != 0) {
sprintf( RegKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s", ImageFileName );
Result = RegCreateKeyEx( HKEY_LOCAL_MACHINE, RegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &Disposition );
if (Result == ERROR_SUCCESS) { if (GFlags == (DWORD)-1) { Result = RegDeleteValue( hKey, "GlobalFlag" ); DelImageNameFromUSTString(ImageFileName); } else { Length = sprintf( Buffer, "0x%08x", GFlags ) + 1; Result = RegSetValueEx( hKey, "GlobalFlag", 0, REG_SZ, (PBYTE)Buffer, Length );
if (GFlags&FLG_USER_STACK_TRACE_DB) AddImageNameToUSTString(ImageFileName); else DelImageNameFromUSTString(ImageFileName);
//
// If we enable page heap for a single application
// then we will avoid default behavior which is
// page heap light (only normal allocations) and
// we will enable the page heap full power.
// Note that we do not do this for system wide
// settings because this will make the machine
// unbootable.
//
if ((GFlags & FLG_HEAP_PAGE_ALLOCS)) {
Length = sprintf( Buffer, "0x%08x", 0x03 ) + 1;
Result = RegSetValueEx( hKey, "PageHeapFlags", 0, REG_SZ, (PBYTE)Buffer, Length ); } }
RegCloseKey( hKey ); }
if (Result != ERROR_SUCCESS) { MessageBox( hwndMain, (GFlags == (DWORD)-1) ? "Failed to delete registry value" : "Failed to set registry value", ImageFileName, MB_OK ); return FALSE; }
LastSetFlags = GFlags; return TRUE; }
return FALSE; }
BOOLEAN SetImageFileNameDebugger( PCHAR ImageFileName, PCHAR Debugger ) { CHAR RegKey[ MAX_PATH ]; HKEY hKey; DWORD Result; DWORD Length; DWORD Disposition;
if (strlen( ImageFileName ) != 0) {
sprintf( RegKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s", ImageFileName );
Result = RegCreateKeyEx( HKEY_LOCAL_MACHINE, RegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &Disposition );
if (Result == ERROR_SUCCESS) { if ( *Debugger ) { Result = RegSetValueEx( hKey, "Debugger", 0, REG_SZ, (PBYTE)Debugger, strlen( Debugger ) + 1 );
} else { Result = RegDeleteValue( hKey, "Debugger" ); }
RegCloseKey( hKey ); }
if (Result != ERROR_SUCCESS) { MessageBox( hwndMain, ( *Debugger ) ? "Failed to delete registry value" : "Failed to set registry value", ImageFileName, MB_OK ); return FALSE; }
return TRUE; }
return FALSE; }
BOOLEAN fRegistrySettings; BOOLEAN fKernelSettings; BOOLEAN fImageFileSettings; BOOLEAN fDisplaySettings; BOOLEAN fLaunchCommand; BOOLEAN fFlushImageSettings; PUCHAR ImageFileName; DWORD GlobalFlagMask; DWORD GlobalFlagSetting; DWORD MaxDepthSetting; DWORD OldGlobalFlags; DWORD NewGlobalFlags; DWORD NewGlobalFlagsValidMask; DWORD NewGlobalFlagsIgnored;
void DisplayFlags( PCHAR Msg, DWORD Flags, DWORD FlagsIgnored ) { int i;
if (Flags == 0xFFFFFFFF) { printf( "No %s\n", Msg ); return; }
printf( "Current %s are: %08x\n", Msg, Flags ); for (i=0; i<32; i++) { if (GlobalFlagInfo[i].Abbreviation != NULL && (Flags & GlobalFlagInfo[i].Flag) ) {
if (_stricmp(GlobalFlagInfo[i].Abbreviation, "hpa") == 0) {
printf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation, "Enable page heap"); } else {
printf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation, GlobalFlagInfo[i].Description ); } } }
if (FlagsIgnored) { printf( "Following settings were ignored: %08x\n", FlagsIgnored ); for (i=0; i<32; i++) { if (GlobalFlagInfo[i].Abbreviation != NULL && (FlagsIgnored & GlobalFlagInfo[i].Flag) ) {
if (_stricmp(GlobalFlagInfo[i].Abbreviation, "hpa") == 0) {
printf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation, "Enable page heap"); } else {
printf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation, GlobalFlagInfo[i].Description ); } } } } }
BOOL IsCmdlineOption ( PCHAR Option, PCHAR Name, PCHAR NameEx ) { if (_stricmp (Option, Name) == 0 || _stricmp (Option, NameEx) == 0) { return TRUE; } else { return FALSE; } }
int __cdecl main( int argc, char **argv ) { MSG msg; CHAR c; PCHAR s; BOOLEAN fUsage, fExpectingFlags, fExpectingDepth; ULONG i; CHAR Settings[ 2*MAX_PATH ];
#if defined(_X86_)
OSVERSIONINFO VersionInfo; VersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); GetVersionEx( &VersionInfo ); if ( VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ) { MessageBox( NULL, "Global flags only runs on Windows NT and Windows 2000. The glfags command was ignored.", "Global Flags Error", 0 ); exit(0); } else { HMODULE hDll; hDll = GetModuleHandle("ntdll"); if (hDll != NULL) { pRtlIntegerToChar = ( PRTLINTEGERTOCHAR ) GetProcAddress( hDll, "RtlIntegerToChar" ); pNtQueryInformationProcess = ( PNTQUERYINFORMATIONPROCESS ) GetProcAddress( hDll, "NtQueryInformationProcess" ); pRtlCharToInteger = ( PRTLCHARTOINTEGER ) GetProcAddress( hDll, "RtlCharToInteger" ); pNtSetSystemInformation = ( PNTSETSYSTEMINFORMATION ) GetProcAddress( hDll, "NtSetSystemInformation" ); pNtQuerySystemInformation = ( PNTQUERYSYSTEMINFORMATION ) GetProcAddress( hDll, "NtQuerySystemInformation" ); } } #endif
//
// Check if we need to redirect the whole command line to the page heap
// command line parser.
//
if (argc >= 2 && IsCmdlineOption (argv[1], "/p", "-p")) {
PageHeapMain (argc - 1, argv + 1); exit(0); } //
// Check forst for `-i APP -tracedb SIZE' option
//
if (argc == 5 && IsCmdlineOption (argv[3], "/tracedb", "-tracedb") && IsCmdlineOption (argv[1], "/i", "-i")) { ULONG RealSize;
if (GflagsSetTraceDatabaseSize (argv[2], atoi (argv[4]), &RealSize) == FALSE) { printf("Failed to set the trace database size for `%s' \n", argv[2]); exit(5); } else {
if (RealSize > 0) { printf("Trace database size for `%s' set to %u Mb.\n", argv[2], RealSize); } else { printf("Will use default size for the trace database. \n"); } exit(0); } }
//
// Continue ...
//
hwndMain = NULL; fUsage = FALSE; fExpectingFlags = FALSE; fExpectingDepth = FALSE; GlobalFlagMask = 0xFFFFFFFF; GlobalFlagSetting = 0; while (--argc) { s = *++argv; if (!fExpectingFlags && (*s == '-' || *s == '/')) { while (*++s) { c = (char)tolower(*s); switch (c) { case 'r': case 'k': case 'i': if (fRegistrySettings || fKernelSettings || fImageFileSettings) { fprintf( stderr, "GFLAG: may only specify one of -r, -k or -i\n" ); fUsage = TRUE; } else { fExpectingFlags = TRUE; fDisplaySettings = TRUE; if (c == 'r') { fRegistrySettings = TRUE; fExpectingDepth = TRUE; OldGlobalFlags = GetSystemRegistryFlags(); NewGlobalFlagsValidMask = VALID_SYSTEM_REGISTRY_FLAGS; strcpy( Settings, "Boot Registry Settings" ); } else if (c == 'k') { fKernelSettings = TRUE; NewGlobalFlagsValidMask = VALID_KERNEL_MODE_FLAGS; OldGlobalFlags = GetKernelModeFlags(); strcpy( Settings, "Running Kernel Settings" ); } else { fImageFileSettings = TRUE; NewGlobalFlagsValidMask = VALID_IMAGE_FILE_NAME_FLAGS; if (!--argc) { fprintf( stderr, "GFLAGS: ImageFileName missing after -i switch\n" ); fUsage = TRUE; exit( 0 ); // 179741 - JHH
} else { ImageFileName = (PUCHAR)(*++argv); OldGlobalFlags = GetImageFileNameFlags( (PCHAR)ImageFileName ); sprintf( Settings, "Registry Settings for %s executable", ImageFileName ); } } } break;
case 'l': fLaunchCommand = TRUE; fExpectingFlags = TRUE; break;
default: fUsage = TRUE; break; } } } else { if (fExpectingFlags) {
fDisplaySettings = FALSE;
if (*s == '+' || *s == '-') {
if (strlen(s+1) == 3) {
for (i = 0; i < 32; i += 1) {
if ((NewGlobalFlagsValidMask & GlobalFlagInfo[i].Flag) && (GlobalFlagInfo[i].Abbreviation != NULL) && _stricmp( GlobalFlagInfo[i].Abbreviation, s+1 ) == NULL) {
if (fKernelSettings) {
if (_stricmp(GlobalFlagInfo[i].Abbreviation, "ptg") == NULL) { fprintf (stderr, "Ignoring `ptg' flag. It can be used only with registry " "settings (`-r') because it requires a reboot.\n"); continue; }
if (_stricmp(GlobalFlagInfo[i].Abbreviation, "kst") == NULL) { fprintf (stderr, "Ignoring `kst' flag. It can be used only with registry " "settings (`-r') because it requires a reboot.\n"); continue; } }
if (*s == '-') { GlobalFlagMask &= ~GlobalFlagInfo[i].Flag; } else { GlobalFlagSetting |= GlobalFlagInfo[i].Flag; }
s += 4; break; } } }
if (*s != '\0') { if (*s++ == '-') { GlobalFlagMask &= ~strtoul( s, &s, 16 ); } else { GlobalFlagSetting |= strtoul( s, &s, 16 ); } } } else { fExpectingFlags = FALSE; GlobalFlagSetting = strtoul( s, &s, 16 ); }
if (fLaunchCommand) { exit( 0 ); }
if (fImageFileSettings && OldGlobalFlags == 0xFFFFFFFF) { OldGlobalFlags = 0; } } else if (fExpectingDepth) { MaxDepthSetting = strtoul( s, &s, 10 ); fExpectingDepth = FALSE; } else { fprintf( stderr, "GFLAGS: Unexpected argument - '%s'\n", s ); fUsage = TRUE; } } }
if (fUsage) { fputs(GflagsHelpText, stderr);
for (i=0; i<32; i++) {
if (GlobalFlagInfo[i].Abbreviation != NULL) {
if (_stricmp(GlobalFlagInfo[i].Abbreviation, "hpa") == 0) {
fprintf( stderr, " %s - %s\n", GlobalFlagInfo[i].Abbreviation, "Enable page heap"); } else {
fprintf( stderr, " %s - %s\n", GlobalFlagInfo[i].Abbreviation, GlobalFlagInfo[i].Description); } } }
fprintf( stderr, "\nAll images with ust enabled can be accessed in the\n" ); fprintf( stderr, "USTEnabled key under 'Image File Options'.\n" ); exit( 1 ); }
NewGlobalFlags = (OldGlobalFlags & GlobalFlagMask) | GlobalFlagSetting; if (!fImageFileSettings || NewGlobalFlags != 0xFFFFFFFF) { NewGlobalFlagsIgnored = ~NewGlobalFlagsValidMask & NewGlobalFlags; NewGlobalFlags &= NewGlobalFlagsValidMask; }
if (fDisplaySettings) { DisplayFlags( Settings, NewGlobalFlags, NewGlobalFlagsIgnored ); exit( 0 ); }
if (fRegistrySettings) { SetSystemRegistryFlags( NewGlobalFlags, fExpectingDepth ? InitialMaxStackTraceDepth : MaxDepthSetting, 0, SPECIAL_POOL_OVERRUNS_CHECK_FORWARD ); DisplayFlags( Settings, NewGlobalFlags, NewGlobalFlagsIgnored ); exit( 0 ); }
else if (fKernelSettings) { SetKernelModeFlags( NewGlobalFlags ); DisplayFlags( Settings, NewGlobalFlags, NewGlobalFlagsIgnored ); exit( 0 ); } else if (fImageFileSettings) { SetImageFileNameFlags( (PCHAR)ImageFileName, NewGlobalFlags ); DisplayFlags( Settings, NewGlobalFlags, NewGlobalFlagsIgnored ); exit( 0 ); }
CreateDialog( NULL, (LPSTR)DID_GFLAGS, NULL, MainWndProc ); if (!hwndMain) { MessageBox( hwndMain, "Main Error", "Cant create dialog", MB_OK ); ExitProcess( 0 ); }
while (GetMessage( &msg, 0, 0, 0 )) { if (!IsDialogMessage( hwndMain, &msg )) { DispatchMessage( &msg ); } }
exit( 0 ); return 0; }
VOID SetCheckBoxesFromFlags( DWORD GFlags, DWORD ValidFlags ) { int iBit;
GFlags &= ValidFlags; LastSetFlags = GFlags; for (iBit=0; iBit < 32; iBit++) { CheckDlgButton( hwndMain, ID_FLAG_1 + iBit, (GFlags & (1 << iBit)) ? 1 : 0 );
ShowWindow( GetDlgItem( hwndMain, ID_FLAG_1 + iBit ), (ValidFlags & (1 << iBit)) ? SW_SHOWNORMAL : SW_HIDE ); } }
DWORD GetFlagsFromCheckBoxes( VOID ) { DWORD GFlags; int iBit;
GFlags = 0; for (iBit=0; iBit < 32; iBit++) { if (IsDlgButtonChecked( hwndMain, ID_FLAG_1 + iBit )) { GFlags |= (1 << iBit); } }
return GFlags; }
VOID DoLaunch( PCHAR CommandLine, DWORD GFlags ) { STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; NTSTATUS Status; PROCESS_BASIC_INFORMATION BasicInformation; BOOLEAN ReadImageFileExecOptions;
memset( &StartupInfo, 0, sizeof( StartupInfo ) ); StartupInfo.cb = sizeof( StartupInfo ); if (CreateProcess( NULL, CommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInformation ) ) { Status = NtQueryInformationProcess( ProcessInformation.hProcess, ProcessBasicInformation, &BasicInformation, sizeof( BasicInformation ), NULL ); if (NT_SUCCESS( Status )) { ReadImageFileExecOptions = TRUE; if (!WriteProcessMemory( ProcessInformation.hProcess, &BasicInformation.PebBaseAddress->ReadImageFileExecOptions, &ReadImageFileExecOptions, sizeof( ReadImageFileExecOptions ), NULL ) || !WriteProcessMemory( ProcessInformation.hProcess, &BasicInformation.PebBaseAddress->NtGlobalFlag, &GFlags, sizeof( GFlags ), NULL ) ) { Status = STATUS_UNSUCCESSFUL; } }
if (!NT_SUCCESS( Status )) { MessageBox( hwndMain, "Launch Command Line", "Unable to pass flags to process - terminating", MB_OK ); TerminateProcess( ProcessInformation.hProcess, 1 ); }
ResumeThread( ProcessInformation.hThread ); CloseHandle( ProcessInformation.hThread ); MsgWaitForMultipleObjects( 1, &ProcessInformation.hProcess, FALSE, NMPWAIT_WAIT_FOREVER, QS_ALLINPUT ); CloseHandle( ProcessInformation.hProcess ); } else { MessageBox( hwndMain, "Launch Command Line", "Unable to create process", MB_OK ); }
return; }
DWORD LastRadioButtonId; DWORD SpecialPoolModeId; DWORD SpecialPoolOverrunsId;
BOOLEAN CheckSpecialPoolTagItem( HWND hwnd, BOOLEAN ForApply ) { DWORD NumChars; DWORD i; BOOLEAN IsIllegal = FALSE; BOOLEAN IsAmbiguous = FALSE;
NumChars = GetDlgItemText( hwnd, ID_SPECIAL_POOL_TAG, SpecialPoolRenderBuffer, sizeof( SpecialPoolRenderBuffer ));
if (NumChars != 0) {
if (SpecialPoolModeId == ID_SPECIAL_POOL_IS_NUMBER) {
//
// Check for illegal characters.
//
if (NumChars > 8) {
IsIllegal = TRUE;
} else {
for (i = 0; i < NumChars; i++) {
if (!((SpecialPoolRenderBuffer[i] >= '0' && SpecialPoolRenderBuffer[i] <= '9') ||
(SpecialPoolRenderBuffer[i] >= 'a' && SpecialPoolRenderBuffer[i] <= 'f') ||
(SpecialPoolRenderBuffer[i] >= 'A' && SpecialPoolRenderBuffer[i] <= 'F'))) {
IsIllegal = TRUE; break; } } }
} else {
//
// Check for too many characters.
//
if (NumChars > sizeof(DWORD)) {
IsIllegal = TRUE; }
//
// We check a few more things when the user is really writing back.
//
if (!IsIllegal && ForApply) {
//
// If this is not four characters and does not end in a '*',
// it is usually the case that the user really wanted a space
// at the end of the tag 'Gh1 ', not 'Gh1'. Make sure they
// get a little feedback.
//
if (NumChars != sizeof(DWORD) && SpecialPoolRenderBuffer[NumChars - 1] != '*') {
MessageBox( hwnd, "The specified tag is less than 4 characters, but most\n" "are really padded out with spaces. Please check and\n" "add spaces if neccesary.", "Possibly ambiguous special pool tag", MB_OK );
} } } }
if (IsIllegal) {
MessageBox( hwnd, (SpecialPoolModeId == ID_SPECIAL_POOL_IS_NUMBER ? "Must be a hexadecimal DWORD" : "Must be at most 4 characters"), "Illegal characters in special pool tag", MB_OK ); }
return !IsIllegal; }
DWORD GetSpecialPoolTagItem( HWND hwnd ) { DWORD NumChars; DWORD Tag = 0;
//
// We assume that the field is has been retrieved and checked.
//
NumChars = strlen( SpecialPoolRenderBuffer );
if (NumChars != 0) {
if (SpecialPoolModeId == ID_SPECIAL_POOL_IS_NUMBER) {
RtlCharToInteger( SpecialPoolRenderBuffer, 16, &Tag );
} else {
//
// Just drop the bytes into the DWORD - endianess is correct as is.
//
RtlCopyMemory( &Tag, SpecialPoolRenderBuffer, NumChars ); } }
return Tag; }
DWORD GetSpecialPoolOverrunsItem( HWND hwnd ) { switch (SpecialPoolOverrunsId) {
case ID_SPECIAL_POOL_VERIFY_END: return SPECIAL_POOL_OVERRUNS_CHECK_FORWARD; case ID_SPECIAL_POOL_VERIFY_START: return SPECIAL_POOL_OVERRUNS_CHECK_BACKWARD;
default: return SPECIAL_POOL_OVERRUNS_CHECK_FORWARD; } }
VOID ReRenderSpecialPoolTagItem( HWND hwnd ) { DWORD NumChars; DWORD Tag = 0;
//
// We assume that the field is has been retrieved and checked.
//
NumChars = strlen( SpecialPoolRenderBuffer );
//
// Assume that the dialog contents are of the previous mode. Switch it.
//
if (NumChars != 0) {
if (SpecialPoolModeId == ID_SPECIAL_POOL_IS_NUMBER) {
RtlCopyMemory( &Tag, SpecialPoolRenderBuffer, NumChars ); RtlIntegerToChar( Tag, 16, sizeof( SpecialPoolRenderBuffer ), SpecialPoolRenderBuffer);
} else {
RtlCharToInteger( SpecialPoolRenderBuffer, 16, &Tag ); RtlCopyMemory( SpecialPoolRenderBuffer, &Tag, sizeof( Tag )); SpecialPoolRenderBuffer[sizeof( Tag )] = '\0'; } }
SetDlgItemText( hwnd, ID_SPECIAL_POOL_TAG, SpecialPoolRenderBuffer ); }
BOOLEAN CheckForUnsaved( HWND hwnd ) { BOOL b;
//
// Appropriate to the mode we are leaving, see if there were unsaved changes.
// Return TRUE if there are unsaved changes.
//
if (GetFlagsFromCheckBoxes() != LastSetFlags || (fFlushImageSettings && (LastRadioButtonId == ID_IMAGE_FILE_OPTIONS)) || (LastRadioButtonId == ID_SYSTEM_REGISTRY && (!CheckSpecialPoolTagItem( hwnd, FALSE ) || (GetSpecialPoolTagItem( hwnd ) != LastSetSpecialPoolTag) || (GetSpecialPoolOverrunsItem( hwnd ) != LastSetSpecialPoolOverruns)) || GetDlgItemInt( hwnd, ID_MAX_STACK_DEPTH, &b, FALSE ) != InitialMaxStackTraceDepth)) {
if (MessageBox( hwndMain, "You didn't click 'apply' - did you want to discard current changes??", "Warning", MB_YESNO ) == IDNO ) {
return TRUE; } }
return FALSE; }
INT_PTR APIENTRY MainWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { DWORD NewFlags; CHAR ImageFileName[ MAX_PATH ]; CHAR CommandLine[ MAX_PATH ]; BOOL b, bCancelDiscard; int i;
bCancelDiscard = FALSE;
switch (message) {
case WM_INITDIALOG:
hwndMain = hwnd; LastRadioButtonId = ID_SYSTEM_REGISTRY; CheckRadioButton( hwnd, ID_SYSTEM_REGISTRY, ID_IMAGE_FILE_OPTIONS, LastRadioButtonId );
EnableSetOfControls( hwnd, SpecialPool, TRUE ); EnableSetOfControls( hwnd, Debugger, FALSE );
SetCheckBoxesFromFlags( GetSystemRegistryFlags(), VALID_SYSTEM_REGISTRY_FLAGS ); SetDlgItemInt( hwnd, ID_MAX_STACK_DEPTH, InitialMaxStackTraceDepth, FALSE );
//
// Make a not so wild guess about what kind of tag it is.
//
if (LastSetSpecialPoolTag && LastSetSpecialPoolTag < 0x2000) {
SpecialPoolModeId = ID_SPECIAL_POOL_IS_NUMBER; RtlIntegerToChar( LastSetSpecialPoolTag, 16, sizeof( SpecialPoolRenderBuffer ), SpecialPoolRenderBuffer ); } else {
SpecialPoolModeId = ID_SPECIAL_POOL_IS_TEXT; RtlCopyMemory( SpecialPoolRenderBuffer, &LastSetSpecialPoolTag, sizeof( LastSetSpecialPoolTag )); SpecialPoolRenderBuffer[sizeof(LastSetSpecialPoolTag)] = '\0'; }
CheckRadioButton( hwnd, ID_SPECIAL_POOL_IS_TEXT, ID_SPECIAL_POOL_IS_NUMBER, SpecialPoolModeId ); SetDlgItemText( hwnd, ID_SPECIAL_POOL_TAG, SpecialPoolRenderBuffer );
//
// Initial state for the special pool overrun radio buttons.
//
switch (LastSetSpecialPoolOverruns) {
case SPECIAL_POOL_OVERRUNS_CHECK_FORWARD: SpecialPoolOverrunsId = ID_SPECIAL_POOL_VERIFY_END; break;
case SPECIAL_POOL_OVERRUNS_CHECK_BACKWARD: SpecialPoolOverrunsId = ID_SPECIAL_POOL_VERIFY_START; break;
default: SpecialPoolOverrunsId = ID_SPECIAL_POOL_VERIFY_END; break; }
CheckRadioButton( hwnd, ID_SPECIAL_POOL_VERIFY_START, ID_SPECIAL_POOL_VERIFY_END, SpecialPoolOverrunsId );
return(TRUE);
case WM_COMMAND:
switch ( LOWORD(wParam) ) {
case ID_LAUNCH:
GetDlgItemText( hwnd, ID_COMMAND_LINE, CommandLine, sizeof( CommandLine ) ); if (strlen( ImageFileName ) == 0) { MessageBox( hwndMain, "Launch Command Line", "Must fill in command line first", MB_OK ); SetFocus( GetDlgItem( hwnd, ID_COMMAND_LINE ) ); break; }
// fall through
case ID_APPLY:
if (IsDlgButtonChecked( hwnd, ID_SYSTEM_REGISTRY )) {
//
// System wide settings
//
if (CheckSpecialPoolTagItem( hwnd, TRUE )) {
NewFlags = GetFlagsFromCheckBoxes();
SetSystemRegistryFlags( NewFlags, GetDlgItemInt( hwnd, ID_MAX_STACK_DEPTH, &b, FALSE ), GetSpecialPoolTagItem( hwnd ), GetSpecialPoolOverrunsItem (hwnd)); } } else if (IsDlgButtonChecked( hwnd, ID_KERNEL_MODE )) {
//
// Kernel mode settings
//
// N.B. This will set flags on the fly. It does not touch
// the registry and does not require a reboot.
//
NewFlags = GetFlagsFromCheckBoxes();
SetKernelModeFlags( NewFlags ); } else if (IsDlgButtonChecked( hwnd, ID_IMAGE_FILE_OPTIONS )) {
//
// Application specific settings
//
GetDlgItemText( hwnd, ID_IMAGE_FILE_NAME, ImageFileName, sizeof( ImageFileName ) ); if (strlen( ImageFileName ) == 0) { MessageBox( hwnd, "Missing Image File Name", "Must set image file name", MB_OK ); SetFocus( GetDlgItem( hwnd, ID_IMAGE_FILE_NAME ) ); break; }
SetImageFileNameFlags( ImageFileName, GetFlagsFromCheckBoxes() ); if ( fFlushImageSettings ) {
GetDlgItemText( hwnd, ID_IMAGE_DEBUGGER_VALUE, LastDebuggerValue, MAX_PATH );
SetImageFileNameDebugger( ImageFileName, LastDebuggerValue );
fFlushImageSettings = FALSE ;
} }
if (LOWORD(wParam) == ID_LAUNCH) { DoLaunch( CommandLine, GetFlagsFromCheckBoxes() ); } break;
case IDOK: if (CheckForUnsaved( hwnd )) { break; }
// fall through
case IDCANCEL: PostQuitMessage(0); DestroyWindow( hwnd ); break;
case ID_SPECIAL_POOL_IS_TEXT: case ID_SPECIAL_POOL_IS_NUMBER:
if (CheckSpecialPoolTagItem( hwnd, FALSE )) {
if (LOWORD(wParam) != SpecialPoolModeId) {
SpecialPoolModeId = LOWORD(wParam); CheckRadioButton( hwnd, ID_SPECIAL_POOL_IS_TEXT, ID_SPECIAL_POOL_IS_NUMBER, SpecialPoolModeId );
ReRenderSpecialPoolTagItem( hwnd ); } } else {
//
// Always treat this as a cancel.
//
bCancelDiscard = TRUE; }
break;
case ID_SPECIAL_POOL_VERIFY_START: case ID_SPECIAL_POOL_VERIFY_END:
if (LOWORD(wParam) != SpecialPoolOverrunsId) {
SpecialPoolOverrunsId = LOWORD(wParam); CheckRadioButton( hwnd, ID_SPECIAL_POOL_VERIFY_START, ID_SPECIAL_POOL_VERIFY_END, SpecialPoolOverrunsId ); }
break;
case ID_IMAGE_DEBUGGER_BUTTON: if (IsDlgButtonChecked( hwnd, ID_IMAGE_DEBUGGER_BUTTON ) == BST_CHECKED ) { EnableWindow( GetDlgItem( hwnd, ID_IMAGE_DEBUGGER_VALUE ), TRUE );
GetDlgItemText( hwnd, ID_IMAGE_FILE_NAME, ImageFileName, MAX_PATH );
for ( i = 0 ; i < sizeof( SystemProcesses ) / sizeof( PCHAR ) ; i++ ) { if (_stricmp( ImageFileName, SystemProcesses[i] ) == 0 ) { SetDlgItemText( hwnd, ID_IMAGE_DEBUGGER_VALUE, "ntsd -d -g -G" ); break; } }
} else { SetDlgItemText( hwnd, ID_IMAGE_DEBUGGER_VALUE, "" ); EnableWindow( GetDlgItem( hwnd, ID_IMAGE_DEBUGGER_VALUE ), FALSE ); } fFlushImageSettings = TRUE ; break;
case ID_SYSTEM_REGISTRY: if (CheckForUnsaved( hwnd )) { bCancelDiscard = TRUE; break; }
LastRadioButtonId = ID_SYSTEM_REGISTRY; SetCheckBoxesFromFlags( GetSystemRegistryFlags(), VALID_SYSTEM_REGISTRY_FLAGS ); EnableSetOfControls( hwnd, SpecialPool, TRUE ); EnableSetOfControls( hwnd, Debugger, FALSE );
break;
case ID_KERNEL_MODE: if (CheckForUnsaved( hwnd )) { bCancelDiscard = TRUE; break; }
LastRadioButtonId = ID_KERNEL_MODE; SetCheckBoxesFromFlags( GetKernelModeFlags(), VALID_KERNEL_MODE_FLAGS ); EnableSetOfControls( hwnd, SpecialPool, FALSE ); EnableSetOfControls( hwnd, Debugger, FALSE );
break;
case ID_IMAGE_FILE_OPTIONS: if (CheckForUnsaved( hwnd )) { bCancelDiscard = TRUE; break; }
GetDlgItemText( hwnd, ID_IMAGE_FILE_NAME, ImageFileName, sizeof( ImageFileName ) ); if (strlen( ImageFileName ) == 0) { MessageBox( hwndMain, "Image File Name Missing", "Must fill in image file name first", MB_OK ); CheckRadioButton( hwnd, ID_SYSTEM_REGISTRY, ID_IMAGE_FILE_OPTIONS, LastRadioButtonId ); SetCheckBoxesFromFlags( GetSystemRegistryFlags(), VALID_SYSTEM_REGISTRY_FLAGS ); SetFocus( GetDlgItem( hwnd, ID_IMAGE_FILE_NAME ) ); break; } else { LastRadioButtonId = ID_IMAGE_FILE_OPTIONS; SetCheckBoxesFromFlags( GetImageFileNameFlags( ImageFileName ), VALID_IMAGE_FILE_NAME_FLAGS );
if ( GetImageFileNameDebugger( ImageFileName, LastDebuggerValue ) ) { SetDlgItemText( hwnd, ID_IMAGE_DEBUGGER_VALUE, LastDebuggerValue ); CheckDlgButton( hwnd, ID_IMAGE_DEBUGGER_BUTTON, 1 );
}
EnableSetOfControls( hwnd, SpecialPool, FALSE ); EnableSetOfControls( hwnd, Debugger, TRUE );
} break;
default: break; } break;
case WM_CLOSE: PostQuitMessage(0); DestroyWindow( hwnd ); break;
}
if (bCancelDiscard) {
//
// Recheck the right radio buttons 'cause the user didn't
// *really* mean it.
//
CheckRadioButton( hwnd, ID_SYSTEM_REGISTRY, ID_IMAGE_FILE_OPTIONS, LastRadioButtonId ); CheckRadioButton( hwnd, ID_SPECIAL_POOL_IS_TEXT, ID_SPECIAL_POOL_IS_NUMBER, SpecialPoolModeId );
CheckRadioButton( hwnd, ID_SPECIAL_POOL_VERIFY_START, ID_SPECIAL_POOL_VERIFY_END, SpecialPoolOverrunsId );
}
return 0; }
BOOL EnableDebugPrivilege( VOID ) { HANDLE Token; PTOKEN_PRIVILEGES NewPrivileges; BYTE OldPriv[ 1024 ]; PBYTE pbOldPriv; ULONG cbNeeded; BOOL fRc; LUID LuidPrivilege;
//
// Make sure we have access to adjust and to get the old token privileges
//
if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token ) ) { return FALSE; }
cbNeeded = 0;
//
// Initialize the privilege adjustment structure
//
LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &LuidPrivilege ); NewPrivileges = (PTOKEN_PRIVILEGES)HeapAlloc( GetProcessHeap(), 0, sizeof(TOKEN_PRIVILEGES) + (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES) ); if (NewPrivileges == NULL) { CloseHandle( Token ); return FALSE; }
NewPrivileges->PrivilegeCount = 1; NewPrivileges->Privileges[0].Luid = LuidPrivilege; NewPrivileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//
// Enable the privilege
//
pbOldPriv = OldPriv; fRc = AdjustTokenPrivileges( Token, FALSE, NewPrivileges, sizeof( OldPriv ), (PTOKEN_PRIVILEGES)pbOldPriv, &cbNeeded ); if (!fRc) { //
// If the stack was too small to hold the privileges
// then allocate off the heap
//
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { pbOldPriv = (PBYTE)HeapAlloc( GetProcessHeap(), 0, cbNeeded ); if (pbOldPriv == NULL) { CloseHandle( Token ); return FALSE; }
fRc = AdjustTokenPrivileges( Token, FALSE, NewPrivileges, cbNeeded, (PTOKEN_PRIVILEGES)pbOldPriv, &cbNeeded ); } }
return fRc; }
VOID CenterDialog( HWND hWndDialog ) { RECT rectWindow; POINT pointCenter; POINT pointNewCornerChild; INT nChildWidth; INT nChildHeight; HWND hWndParent;
hWndParent = GetParent( hWndDialog );
//
// parent window's rectangle
//
GetWindowRect( hWndParent, &rectWindow );
//
// the center, in screen coordinates
//
pointCenter.x = rectWindow.left + ( rectWindow.right - rectWindow.left ) / 2; pointCenter.y = rectWindow.top + ( rectWindow.bottom - rectWindow.top ) / 2;
//
// chils window's rectangle, in screen coordinates
//
GetWindowRect( hWndDialog, &rectWindow );
nChildWidth = rectWindow.right - rectWindow.left ; nChildHeight = rectWindow.bottom - rectWindow.top;
//
// the new top-left corner of the child
//
pointNewCornerChild.x = pointCenter.x - nChildWidth / 2; pointNewCornerChild.y = pointCenter.y - nChildHeight / 2;
//
// move the child window
//
MoveWindow( hWndDialog, pointNewCornerChild.x, pointNewCornerChild.y, nChildWidth, nChildHeight, TRUE ); }
INT_PTR APIENTRY PagedHeapDlgProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { INT_PTR nResult;
nResult = FALSE;
switch ( message ) {
case WM_INITDIALOG: hwndPagedHeapDlg = hwnd;
//
// center this dialog
//
CenterDialog( hwndPagedHeapDlg );
break;
case WM_COMMAND: switch( LOWORD(wParam) ) { case IDYES: EndDialog( hwndPagedHeapDlg, IDYES ); break;
case IDNO: EndDialog( hwndPagedHeapDlg, IDNO ); break; } break;
case WM_CLOSE: case WM_DESTROY: case WM_ENDSESSION: case WM_QUIT: EndDialog(hwndPagedHeapDlg,IDNO); nResult = TRUE; break;
default: break; }
return nResult; }
BOOL OkToEnablePagedHeap( VOID ) { MEMORYSTATUS MemoryStatus;
GlobalMemoryStatus( &MemoryStatus );
if( MemoryStatus.dwTotalPhys < 512 * 1024 * 1024 ) {
//
// less than 512 Mb of RAM
//
return ( DialogBoxParam( NULL, (LPCTSTR)( MAKEINTRESOURCE(DID_PAGED_HEAP_WARNING) ), hwndMain, PagedHeapDlgProc, 0 ) == IDYES ); }
return TRUE; }
BOOL GflagsSetTraceDatabaseSize ( PCHAR ApplicationName, ULONG SizeInMb, PULONG RealSize ) { HKEY ImageKey; CHAR ImageKeyName[ MAX_PATH ]; LONG Result;
CHAR Buffer[ MAX_PATH ]; DWORD Length = MAX_PATH; DWORD TraceDatabaseSize;
*RealSize = 0;
if (ApplicationName == NULL) { return FALSE; }
sprintf (ImageKeyName, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s", ApplicationName);
Result = RegOpenKeyEx (HKEY_LOCAL_MACHINE, ImageKeyName, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &ImageKey);
if (Result != ERROR_SUCCESS) { return FALSE; }
if (SizeInMb == 0) { Result = RegDeleteValue (ImageKey, "StackTraceDatabaseSizeInMb");
if (Result != ERROR_SUCCESS) { RegCloseKey (ImageKey); return FALSE; } } else {
if (SizeInMb < 8) { TraceDatabaseSize = 8; } else {
TraceDatabaseSize = SizeInMb; }
Result = RegSetValueEx (ImageKey, "StackTraceDatabaseSizeInMb", 0, REG_DWORD, (PBYTE)(&TraceDatabaseSize), sizeof TraceDatabaseSize);
if (Result != ERROR_SUCCESS) { RegCloseKey (ImageKey); return FALSE; }
*RealSize = TraceDatabaseSize; }
RegCloseKey (ImageKey); return TRUE; }
|