Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.1 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include <ntexapi.dbg>
  4. DECLARE_API( gflag )
  5. /*++
  6. Routine Description:
  7. This function is called as an NTSD extension to dump or modify
  8. the contents of the NtGlobalFlag variable in NTDLL
  9. Called as:
  10. !gflag [value]
  11. If a value is not given then displays the current bits set in
  12. NTDLL!NtGlobalFlag variable. Otherwise value can be one of the
  13. following:
  14. -? - displays a list of valid flag abbreviations
  15. number - 32-bit number that becomes the new value stored into
  16. NtGlobalFlag
  17. +number - specifies one or more bits to set in NtGlobalFlag
  18. +abbrev - specifies a single bit to set in NtGlobalFlag
  19. -number - specifies one or more bits to clear in NtGlobalFlag
  20. -abbrev - specifies a single bit to clear in NtGlobalFlag
  21. Return Value:
  22. None.
  23. --*/
  24. {
  25. ULONG gflagOffset;
  26. ULONG64 pebAddress;
  27. ULONG64 pNtGlobalFlag = 0;
  28. ULONG ValidBits = FLG_USERMODE_VALID_BITS;
  29. ULONG i;
  30. ULONG OldGlobalFlags;
  31. ULONG NewGlobalFlagsClear;
  32. ULONG NewGlobalFlagsSet;
  33. ULONG NewGlobalFlags;
  34. LPSTR s, Arg;
  35. pNtGlobalFlag = GetExpression("nt!NtGlobalFlag");
  36. ValidBits = FLG_VALID_BITS;
  37. //
  38. // If we could not get the global variable from the kernel, try from the
  39. // PEB for user mode
  40. //
  41. if (!pNtGlobalFlag)
  42. {
  43. GetPebAddress(0, &pebAddress);
  44. if (pebAddress)
  45. {
  46. if (GetFieldOffset("nt!_PEB", "NtGlobalFlag", &gflagOffset))
  47. {
  48. dprintf("Could not find NtGlobalFlag in nt!_PEB\n");
  49. return E_FAIL;
  50. }
  51. pNtGlobalFlag = gflagOffset + pebAddress;
  52. ValidBits = FLG_USERMODE_VALID_BITS;
  53. }
  54. }
  55. if (!pNtGlobalFlag)
  56. {
  57. dprintf( "Unable to get address of NtGlobalFlag variable" );
  58. return E_FAIL;
  59. }
  60. if (!ReadMemory(pNtGlobalFlag,
  61. &OldGlobalFlags,
  62. sizeof(OldGlobalFlags),
  63. NULL))
  64. {
  65. dprintf( "Unable to read contents of NtGlobalFlag variable at %p\n", pNtGlobalFlag );
  66. return E_FAIL;
  67. }
  68. OldGlobalFlags &= ValidBits;
  69. s = (LPSTR)args;
  70. if (!s)
  71. {
  72. s = "";
  73. }
  74. NewGlobalFlagsClear = 0;
  75. NewGlobalFlagsSet = 0;
  76. while (*s)
  77. {
  78. while (*s && *s <= ' ')
  79. {
  80. s += 1;
  81. }
  82. Arg = s;
  83. if (!*s)
  84. {
  85. break;
  86. }
  87. while (*s && *s > ' ')
  88. {
  89. s += 1;
  90. }
  91. if (*s)
  92. {
  93. *s++ = '\0';
  94. }
  95. if (!strcmp( Arg, "-?" ))
  96. {
  97. dprintf( "usage: !gflag [-? | flags]\n" );
  98. dprintf( "Flags may either be a single hex number that specifies all\n" );
  99. dprintf( "32-bits of the GlobalFlags value, or it can be one or more\n" );
  100. dprintf( "arguments, each beginning with a + or -, where the + means\n" );
  101. dprintf( "to set the corresponding bit(s) in the GlobalFlags and a -\n" );
  102. dprintf( "means to clear the corresponding bit(s). After the + or -\n" );
  103. dprintf( "may be either a hex number or a three letter abbreviation\n" );
  104. dprintf( "for a GlobalFlag. Valid abbreviations are:\n" );
  105. for (i=0; i<32; i++) {
  106. if ((GlobalFlagInfo[i].Flag & ValidBits) &&
  107. GlobalFlagInfo[i].Abbreviation != NULL)
  108. {
  109. dprintf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation,
  110. GlobalFlagInfo[i].Description
  111. );
  112. }
  113. }
  114. return E_FAIL;
  115. }
  116. if (*Arg == '+' || *Arg == '-')
  117. {
  118. if (strlen(Arg+1) == 3)
  119. {
  120. for (i=0; i<32; i++)
  121. {
  122. if ((GlobalFlagInfo[i].Flag & ValidBits) &&
  123. !_stricmp( GlobalFlagInfo[i].Abbreviation, Arg+1 ))
  124. {
  125. if (*Arg == '-')
  126. {
  127. NewGlobalFlagsClear |= GlobalFlagInfo[i].Flag;
  128. }
  129. else
  130. {
  131. NewGlobalFlagsSet |= GlobalFlagInfo[i].Flag;
  132. }
  133. Arg += 4;
  134. break;
  135. }
  136. }
  137. if (*Arg != '\0')
  138. {
  139. dprintf( "Invalid flag abbreviation - '%s'\n", Arg );
  140. return E_FAIL;
  141. }
  142. }
  143. if (*Arg != '\0')
  144. {
  145. if (*Arg++ == '-')
  146. {
  147. NewGlobalFlagsClear |= strtoul( Arg, &Arg, 16 );
  148. }
  149. else
  150. {
  151. NewGlobalFlagsSet |= strtoul( Arg, &Arg, 16 );
  152. }
  153. }
  154. }
  155. else
  156. {
  157. NewGlobalFlagsSet = strtoul( Arg, &Arg, 16 );
  158. break;
  159. }
  160. }
  161. NewGlobalFlags = (OldGlobalFlags & ~NewGlobalFlagsClear) | NewGlobalFlagsSet;
  162. NewGlobalFlags &= ValidBits;
  163. if (NewGlobalFlags != OldGlobalFlags)
  164. {
  165. if (!WriteMemory( pNtGlobalFlag,
  166. &NewGlobalFlags,
  167. sizeof( NewGlobalFlags ),
  168. NULL))
  169. {
  170. dprintf( "Unable to store new global flag settings.\n" );
  171. return E_FAIL;
  172. }
  173. dprintf( "New NtGlobalFlag contents: 0x%08x\n", NewGlobalFlags );
  174. OldGlobalFlags = NewGlobalFlags;
  175. }
  176. else
  177. {
  178. dprintf( "Current NtGlobalFlag contents: 0x%08x\n", OldGlobalFlags );
  179. }
  180. for (i=0; i<32; i++)
  181. {
  182. if (OldGlobalFlags & GlobalFlagInfo[i].Flag)
  183. {
  184. dprintf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation, GlobalFlagInfo[i].Description );
  185. }
  186. }
  187. return S_OK;
  188. }