Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

rtdmp.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 rtdmp.c 00008 00009 Abstract: 00010 00011 NT level registry api test program #3, basic non-error paths. 00012 00013 Dump out a sub-tree of the registry. 00014 00015 rtdmp <KeyPath> 00016 00017 Will ennumerate and dump out the subkeys and values of KeyPath, 00018 and then apply itself recursively to each subkey it finds. 00019 00020 It assumes data values are null terminated strings. 00021 00022 Example: 00023 00024 rtdmp \REGISTRY\MACHINE\TEST\bigkey 00025 00026 00027 \REGISTRY\MACHINE\TEST\bigkey:: 00028 00029 ValueTest1_01 type=0 ti=1 00030 "This is a test string" 00031 00032 ValueTest1_01 type=0 ti=2 00033 "This is a test string" 00034 00035 \REGISTRY\MACHCINE\TEST\bigkey\child_key_1:: 00036 00037 ValueTest1_01 type=0 ti=1 00038 "This is a test string" 00039 00040 ValueTest1_01 type=0 ti=2 00041 "This is a test string" 00042 Author: 00043 00044 Bryan Willman (bryanwi) 10-Dec-91 00045 00046 Revision History: 00047 00048 --*/ 00049 00050 #include "cmp.h" 00051 #include <stdio.h> 00052 #include <stdlib.h> 00053 #include <string.h> 00054 00055 #define WORK_SIZE 16384 00056 00057 void __cdecl main(int, char *); 00058 void processargs(); 00059 00060 void print(PUNICODE_STRING); 00061 00062 void 00063 DumpValues( 00064 HANDLE Handle 00065 ); 00066 00067 void 00068 Dump( 00069 HANDLE Handle 00070 ); 00071 00072 UNICODE_STRING WorkName; 00073 WCHAR workbuffer[WORK_SIZE]; 00074 00075 void 00076 __cdecl main( 00077 int argc, 00078 char *argv[] 00079 ) 00080 { 00081 NTSTATUS status; 00082 OBJECT_ATTRIBUTES ObjectAttributes; 00083 HANDLE BaseHandle; 00084 00085 // 00086 // Process args 00087 // 00088 00089 WorkName.MaximumLength = WORK_SIZE; 00090 WorkName.Length = 0L; 00091 WorkName.Buffer = &(workbuffer[0]); 00092 00093 processargs(argc, argv); 00094 00095 00096 // 00097 // Set up and open KeyPath 00098 // 00099 00100 printf("rtdmp: starting\n"); 00101 00102 InitializeObjectAttributes( 00103 &ObjectAttributes, 00104 &WorkName, 00105 0, 00106 (HANDLE)NULL, 00107 NULL 00108 ); 00109 ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; 00110 00111 status = NtOpenKey( 00112 &BaseHandle, 00113 MAXIMUM_ALLOWED, 00114 &ObjectAttributes 00115 ); 00116 if (!NT_SUCCESS(status)) { 00117 printf("rtdmp: t0: %08lx\n", status); 00118 exit(1); 00119 } 00120 00121 Dump(BaseHandle); 00122 } 00123 00124 00125 void 00126 Dump( 00127 HANDLE Handle 00128 ) 00129 { 00130 NTSTATUS status; 00131 PKEY_BASIC_INFORMATION KeyInformation; 00132 OBJECT_ATTRIBUTES ObjectAttributes; 00133 ULONG NamePos; 00134 ULONG index; 00135 STRING enumname; 00136 HANDLE WorkHandle; 00137 ULONG ResultLength; 00138 static char buffer[WORK_SIZE]; 00139 PUCHAR p; 00140 00141 KeyInformation = (PKEY_BASIC_INFORMATION)buffer; 00142 NamePos = WorkName.Length; 00143 00144 // 00145 // Print name of node we are about to dump out 00146 // 00147 print(&WorkName); 00148 printf("::\n\n"); 00149 00150 // 00151 // Print out node's values 00152 // 00153 DumpValues(Handle); 00154 00155 // 00156 // Enumerate node's children and apply ourselves to each one 00157 // 00158 00159 for (index = 0; TRUE; index++) { 00160 00161 RtlZeroMemory(KeyInformation, WORK_SIZE); 00162 status = NtEnumerateKey( 00163 Handle, 00164 index, 00165 KeyBasicInformation, 00166 KeyInformation, 00167 WORK_SIZE, 00168 &ResultLength 00169 ); 00170 00171 if (status == STATUS_NO_MORE_ENTRIES) { 00172 00173 WorkName.Length = NamePos; 00174 return; 00175 00176 } else if (!NT_SUCCESS(status)) { 00177 00178 printf("rtdmp: dump1: status = %08lx\n", status); 00179 exit(1); 00180 00181 } 00182 00183 enumname.Buffer = &(KeyInformation->Name[0]); 00184 enumname.Length = KeyInformation->NameLength; 00185 enumname.MaximumLength = KeyInformation->NameLength; 00186 00187 p = WorkName.Buffer; 00188 p += WorkName.Length; 00189 *p = '\\'; 00190 p++; 00191 *p = '\0'; 00192 WorkName.Length += 2; 00193 00194 RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&enumname); 00195 00196 InitializeObjectAttributes( 00197 &ObjectAttributes, 00198 &enumname, 00199 0, 00200 Handle, 00201 NULL 00202 ); 00203 ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; 00204 00205 status = NtOpenKey( 00206 &WorkHandle, 00207 MAXIMUM_ALLOWED, 00208 &ObjectAttributes 00209 ); 00210 if (!NT_SUCCESS(status)) { 00211 printf("rtdmp: dump2: %08lx\n", status); 00212 exit(1); 00213 } 00214 00215 Dump(WorkHandle); 00216 NtClose(WorkHandle); 00217 WorkName.Length = NamePos; 00218 } 00219 } 00220 00221 00222 void 00223 DumpValues( 00224 HANDLE Handle 00225 ) 00226 { 00227 NTSTATUS status; 00228 static char tempbuffer[WORK_SIZE]; 00229 PKEY_VALUE_FULL_INFORMATION KeyValueInformation; 00230 ULONG index; 00231 ULONG ResultLength; 00232 PULONG p; 00233 ULONG i; 00234 UNICODE_STRING valname; 00235 00236 KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)tempbuffer; 00237 00238 for (index = 0; TRUE; index++) { 00239 00240 RtlZeroMemory(KeyValueInformation, WORK_SIZE); 00241 status = NtEnumerateValueKey( 00242 Handle, 00243 index, 00244 KeyValueFullInformation, 00245 KeyValueInformation, 00246 WORK_SIZE, 00247 &ResultLength 00248 ); 00249 if (status == STATUS_NO_MORE_ENTRIES) { 00250 00251 return; 00252 00253 } else if (!NT_SUCCESS(status)) { 00254 00255 printf("rtdmp: dumpvalues: status = %08lx\n", status); 00256 exit(1); 00257 00258 } 00259 00260 printf("\t"); 00261 valname.Length = KeyValueInformation->NameLength; 00262 valname.MaximumLength = KeyValueInformation->NameLength; 00263 valname.Buffer = (PWSTR)&(KeyValueInformation->Name[0]); 00264 printf("'"); 00265 print(&valname); 00266 printf("'\n"); 00267 printf( 00268 "\ttitle index = %d\ttype = ", 00269 KeyValueInformation->TitleIndex 00270 ); 00271 switch( KeyValueInformation->Type ) { 00272 case REG_NONE: 00273 printf("NONE\n\tValue = 0x%x", 00274 *((PULONG)KeyValueInformation + KeyValueInformation->DataOffset)); 00275 break; 00276 00277 case REG_SZ: 00278 printf("REG_SZ\n\tValue = '%ws'", 00279 ((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset)); 00280 break; 00281 00282 case REG_BINARY: 00283 printf("REG_BINARY\n\tValue = (%lx)\n", KeyValueInformation->DataLength); 00284 p = (PULONG)KeyValueInformation + KeyValueInformation->DataOffset; 00285 i = 1; 00286 while (i <= KeyValueInformation->DataLength) { 00287 printf( " %08lx", *p++ ); 00288 if ((i % 8) == 0) { 00289 printf( "\n" ); 00290 } 00291 i += sizeof( ULONG ); 00292 } 00293 break; 00294 00295 // case REG_DWORD: 00296 case REG_DWORD_LITTLE_ENDIAN: 00297 printf("REG_DWORD\n\tValue = 0x%lx", 00298 *((PULONG)KeyValueInformation + KeyValueInformation->DataOffset)); 00299 break; 00300 00301 case REG_DWORD_BIG_ENDIAN: 00302 printf("REG_DWORD_BIG_ENDIAN\n\tValue = 0x%lx", 00303 *((PULONG)KeyValueInformation + KeyValueInformation->DataOffset)); 00304 break; 00305 00306 } 00307 printf("\n\n"); 00308 } 00309 } 00310 00311 00312 void 00313 print( 00314 PUNICODE_STRING String 00315 ) 00316 { 00317 static ANSI_STRING temp; 00318 static char tempbuffer[WORK_SIZE]; 00319 00320 temp.MaximumLength = WORK_SIZE; 00321 temp.Length = 0L; 00322 temp.Buffer = tempbuffer; 00323 00324 RtlUnicodeStringToAnsiString(&temp, String, FALSE); 00325 printf("%s", temp.Buffer); 00326 return; 00327 } 00328 00329 00330 void 00331 processargs( 00332 int argc, 00333 char *argv[] 00334 ) 00335 { 00336 ANSI_STRING temp; 00337 00338 if ( (argc != 2) ) 00339 { 00340 printf("Usage: %s <KeyPath>\n", 00341 argv[0]); 00342 exit(1); 00343 } 00344 00345 RtlInitAnsiString( 00346 &temp, 00347 argv[1] 00348 ); 00349 00350 RtlAnsiStringToUnicodeString( 00351 &WorkName, 00352 &temp, 00353 FALSE 00354 ); 00355 00356 return; 00357 }

Generated on Sat May 15 19:41:40 2004 for test by doxygen 1.3.7