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.

256 lines
6.2 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. Crdump.c
  5. Abstract:
  6. Author:
  7. David J. Gilman (davegi) 20-Dec-1991
  8. Environment:
  9. Windows, Crt - User Mode
  10. --*/
  11. #include <ctype.h>
  12. #include <stdlib.h>
  13. #include <windows.h>
  14. #include "crtools.h"
  15. //
  16. // KEY_ELEMENT is used to maintain a list of KEYs.
  17. //
  18. typedef struct _KEY_ELEMENT
  19. KEY_ELEMENT,
  20. *PKEY_ELEMENT;
  21. struct _KEY_ELEMENT {
  22. PKEY Key;
  23. PKEY_ELEMENT NextKeyElement;
  24. };
  25. //
  26. // Error and informational messages.
  27. //
  28. PSTR UsageMessage =
  29. "Usage: crdump [-?] [-d] [-v] [-r] key...\n";
  30. PSTR HelpMessage =
  31. "\n where:\n" \
  32. " -? - display this message.\n" \
  33. " -d - dump all data (implies -v).\n" \
  34. " -v - dump all values.\n" \
  35. " -r - recurse through sub keys.\n" \
  36. " key - name(s) of the key(s) to dump.\n" \
  37. "\n A key is formed by specifying one of the predefined handles:\n" \
  38. "\n - HKEY_LOCAL_MACHINE\n" \
  39. " - HKEY_CLASSES_ROOT\n" \
  40. " - HKEY_CURRENT_USER\n" \
  41. " - HKEY_USERS\n" \
  42. "\n followed by a sub-key name.\n" \
  43. "\n An environment variable can be used as shorthand for the\n" \
  44. " predefined handles. For example,\n" \
  45. "\n crdump HKEY_USERS\\davegi\n" \
  46. "\n is equivalent to\n" \
  47. "\n set HKEY_USERS=hu\n" \
  48. " crdump hu\\davegi\n";
  49. PSTR InvalidKeyMessage =
  50. "Invalid key - %s\n";
  51. PSTR InvalidSwitchMessage =
  52. "Invalid switch - %s\n";
  53. PSTR DisplayKeyFailMessage =
  54. "Could not display key %s\n";
  55. VOID
  56. main(
  57. INT argc,
  58. PCHAR argv[ ]
  59. )
  60. /*++
  61. Routine Description:
  62. Arguments:
  63. Return Value:
  64. None.
  65. --*/
  66. {
  67. BOOL Values;
  68. BOOL Data;
  69. BOOL Recurse;
  70. PKEY ParsedKey;
  71. PKEY_ELEMENT ParsedKeyElement;
  72. PKEY_ELEMENT ParsedKeysHead;
  73. PKEY_ELEMENT ParsedKeysTail;
  74. KEY_ELEMENT Dummy = { NULL, NULL };
  75. //
  76. // If CrDump is invoked without any command line options, display
  77. // the usage message.
  78. //
  79. if( argc < 2 ) {
  80. DisplayMessage( TRUE, UsageMessage );
  81. }
  82. //
  83. // By default, no sub keys, values or data are displayed.
  84. //
  85. Recurse = FALSE;
  86. Values = FALSE;
  87. Data = FALSE;
  88. //
  89. // Use a Dummy KEY structure to simplify the list management.
  90. // Initialize the head and tail pointers to point to the Dummy.
  91. //
  92. ParsedKeysHead = &Dummy;
  93. ParsedKeysTail = &Dummy;
  94. //
  95. // Initialize options based on the command line.
  96. //
  97. while( *++argv ) {
  98. //
  99. // If the command line argument is a switch character...
  100. //
  101. if( isswitch(( *argv )[ 0 ] )) {
  102. switch( tolower(( *argv )[ 1 ] )) {
  103. //
  104. // Display the detailed help message and quit.
  105. //
  106. case '?':
  107. DisplayMessage( FALSE, UsageMessage );
  108. DisplayMessage( TRUE, HelpMessage );
  109. break;
  110. //
  111. // Display data - implies display values.
  112. case 'd':
  113. Values = TRUE;
  114. Data = TRUE;
  115. break;
  116. //
  117. // Display sub keys.
  118. //
  119. case 'r':
  120. Recurse = TRUE;
  121. break;
  122. //
  123. // Display values.
  124. //
  125. case 'v':
  126. Values = TRUE;
  127. break;
  128. //
  129. // Display invalid switch message and quit.
  130. //
  131. default:
  132. DisplayMessage( FALSE, InvalidSwitchMessage, *argv );
  133. DisplayMessage( TRUE, UsageMessage );
  134. }
  135. } else {
  136. //
  137. // The command line argument was not a switch so attempt to parse
  138. // it into a predefined handle and a sub key.
  139. //
  140. ParsedKey = ParseKey( *argv );
  141. if( ParsedKey ) {
  142. //
  143. // If the command line argument was succesfully parsed,
  144. // allocate and initialize a KEY_ELEMENT, add it to the
  145. // list and update the tail pointer.
  146. //
  147. ParsedKeyElement = ( PKEY_ELEMENT ) malloc(
  148. sizeof( KEY_ELEMENT )
  149. );
  150. ASSERT( ParsedKeyElement );
  151. ParsedKeyElement->Key = ParsedKey;
  152. ParsedKeyElement->NextKeyElement = NULL;
  153. ParsedKeysTail->NextKeyElement = ParsedKeyElement;
  154. ParsedKeysTail = ParsedKeyElement;
  155. } else {
  156. //
  157. // The command line argument was not succesfully parsed,
  158. // so display an invalid key message and continue.
  159. //
  160. DisplayMessage( FALSE, InvalidKeyMessage, *argv );
  161. }
  162. }
  163. }
  164. //
  165. // Command line parsing is complete. Display the requested keys
  166. // skipping the Dummy KEY_ELEMENT structure.
  167. //
  168. while( ParsedKeysHead = ParsedKeysHead->NextKeyElement ) {
  169. DisplayKeys( ParsedKeysHead->Key, Values, Data, Recurse );
  170. //
  171. // Once the KEY structure's Key is displayed both the KEY and
  172. // KEY_ELEMENT can be freed.
  173. //
  174. FreeKey( ParsedKeysHead->Key );
  175. free( ParsedKeysHead );
  176. }
  177. }