00001
#include <stdio.h>
00002
#include <stdlib.h>
00003
#include <memory.h>
00004
#include "windows.h"
00005
00006 #define MSG_ERROR_VALUE_INCORRECT_SIZE "\tERROR: Value entry data has incorrect size \n\t\tValueName = %ls \n\t\tNameSize = %d \n\t\tValueType = %s \n\t\tValueSize = %d\n"
00007 #define MSG_ERROR_VALUE_NOT_NUL_TERMINATED "\tERROR: Value entry data is not NUL terminated \n\t\tValueName = %ls \n\t\tNameSize = %d \n\t\tValueType = %s\n"
00008 #define MSG_ERROR_VALUE_UNKNOWN_DATA "\tERROR: Value entry contains unknown data \n\t\tValueName = %ls \n\t\tNameSize = %d \n\t\tValueType = %#x \n\t\tValueSize = %d\n"
00009 #define MSG_ERROR_REG_ENUM_VALUE "\tERROR: RegEnumValue() failed, iValue = %d, Status = %d \n"
00010 #define MSG_ERROR_REG_OPEN_KEY_EX "\tERROR: RegOpenKeyEx() failed, Status = %d \n"
00011 #define MSG_ERROR_REG_QUERY_INFO_KEY "\tERROR: RegQueryInfoKey() failed, Status = %d \n"
00012 #define MSG_ERROR_REG_ENUM_KEY_EX "ERROR: RegEnumKeyEx() failed, \n\t Status = %d \n\t, SubKey = %d"
00013 #define MSG_ERROR_REG_CONNECT_REGISTRY "ERROR: Unable to connect to %s, Status = %d \n"
00014 #define MSG_COMPLETE_KEY_NAME "%ls\\%ls \n"
00015
00016
VOID
00017 ExamineValueEntries( IN HKEY Key,
00018 IN LPCWSTR CompleteKeyName,
00019 IN DWORD cchMaxValueName,
00020 IN DWORD cbMaxValueData,
00021 IN DWORD cValues,
00022 IN LPCWSTR PredefinedKeyName )
00023
00024
00025 {
00026 LONG
Status;
00027
DWORD iValue;
00028 LPWSTR lpszValue;
00029
DWORD cchValue;
00030
DWORD dwType;
00031
PBYTE lpbData;
00032
DWORD cbData;
00033 BOOLEAN KeyNameAlreadyPrinted;
00034
00035
00036
00037
00038
00039 lpszValue = ( LPWSTR )malloc( (cchMaxValueName + 1)*
sizeof( WCHAR ) );
00040 lpbData = ( LPBYTE )malloc( cbMaxValueData );
00041
if( ( lpszValue ==
NULL ) ||
00042 ( lpbData ==
NULL ) ) {
00043 printf(
"ERROR: Unable to allocate memory, cchMaxValueName = %d, cbMaxValuedata = %d \n",
00044 cchMaxValueName, cbMaxValueData );
00045
if( lpszValue !=
NULL ) {
00046 free( lpszValue );
00047 }
00048
if( lpbData !=
NULL ) {
00049 free( lpbData );
00050 }
00051
return;
00052 }
00053
00054
00055
00056
00057
00058 KeyNameAlreadyPrinted =
FALSE;
00059
for( iValue = 0; iValue < cValues; iValue++ ) {
00060 cchValue = cchMaxValueName + 1;
00061 cbData = cbMaxValueData;
00062
Status = RegEnumValueW(
Key,
00063 iValue,
00064 lpszValue,
00065 &cchValue,
00066 0,
00067 &dwType,
00068 lpbData,
00069 &cbData );
00070
00071
if(
Status != ERROR_SUCCESS ) {
00072
if( !KeyNameAlreadyPrinted ) {
00073 KeyNameAlreadyPrinted =
TRUE;
00074 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00075 }
00076 printf(
MSG_ERROR_REG_ENUM_VALUE, iValue,
Status );
00077
continue;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
switch( dwType ) {
00087
00088
case REG_BINARY:
00089
00090
if( cbData == 0 ) {
00091
if( !KeyNameAlreadyPrinted ) {
00092 KeyNameAlreadyPrinted =
TRUE;
00093 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00094 }
00095 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00096 lpszValue, cchValue,
"REG_BINARY", cbData );
00097 }
00098
break;
00099
00100
case REG_DWORD:
00101
00102
if( cbData !=
sizeof(
DWORD ) ) {
00103
if( !KeyNameAlreadyPrinted ) {
00104 KeyNameAlreadyPrinted =
TRUE;
00105 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00106 }
00107 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00108 lpszValue, cchValue,
"REG_DWORD", cbData );
00109 }
00110
break;
00111
00112
case REG_DWORD_BIG_ENDIAN:
00113
00114
if( cbData !=
sizeof(
DWORD ) ) {
00115
if( !KeyNameAlreadyPrinted ) {
00116 KeyNameAlreadyPrinted =
TRUE;
00117 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00118 }
00119 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00120 lpszValue, cchValue,
"REG_DWORD_BIG_ENDIAN", cbData );
00121 }
00122
break;
00123
00124
case REG_EXPAND_SZ:
00125
00126
if( ( cbData != 0 ) && ( ( cbData %
sizeof( WCHAR ) ) == 0 )) {
00127
if( *( ( PWCHAR )( lpbData + cbData -
sizeof( WCHAR ) ) ) != ( WCHAR )
'\0' ) {
00128
if( !KeyNameAlreadyPrinted ) {
00129 KeyNameAlreadyPrinted =
TRUE;
00130 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00131 }
00132 printf(
MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
00133 lpszValue, cchValue,
"REG_EXPAND_SZ" );
00134 }
00135 }
else {
00136
if( !KeyNameAlreadyPrinted ) {
00137 KeyNameAlreadyPrinted =
TRUE;
00138 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00139 }
00140 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00141 lpszValue, cchValue,
"REG_EXPAND_SZ", cbData );
00142 }
00143
break;
00144
00145
case REG_LINK:
00146
00147
if( cbData == 0 ) {
00148
if( !KeyNameAlreadyPrinted ) {
00149 KeyNameAlreadyPrinted =
TRUE;
00150 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00151 }
00152 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00153 lpszValue, cchValue,
"REG_LINK", cbData );
00154 }
00155
break;
00156
00157
case REG_MULTI_SZ:
00158
00159
if( ( cbData != 0 ) && ( ( cbData %
sizeof( WCHAR ) ) == 0 )) {
00160
if( *( ( PWCHAR )( lpbData + cbData -
sizeof( WCHAR ) ) ) != ( WCHAR )
'\0' ) {
00161
if( !KeyNameAlreadyPrinted ) {
00162 KeyNameAlreadyPrinted =
TRUE;
00163 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00164 }
00165 printf(
MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
00166 lpszValue, cchValue,
"REG_MULTI_SZ" );
00167 }
00168 }
else {
00169
if( !KeyNameAlreadyPrinted ) {
00170 KeyNameAlreadyPrinted =
TRUE;
00171 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00172 }
00173 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00174 lpszValue, cchValue,
"REG_MULTI_SZ", cbData );
00175 }
00176
break;
00177
00178
case REG_NONE:
00179
00180
if( cbData != 0 ) {
00181
if( !KeyNameAlreadyPrinted ) {
00182 KeyNameAlreadyPrinted =
TRUE;
00183 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00184 }
00185 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00186 lpszValue, cchValue,
"REG_NONE", cbData );
00187 }
00188
break;
00189
00190
case REG_RESOURCE_LIST:
00191
00192
if( cbData == 0 ) {
00193
if( !KeyNameAlreadyPrinted ) {
00194 KeyNameAlreadyPrinted =
TRUE;
00195 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00196 }
00197 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00198 lpszValue, cchValue,
"REG_RESOURCE_LIST", cbData );
00199 }
00200
break;
00201
00202
00203
case REG_SZ:
00204
00205
if( ( cbData != 0 ) && ( ( cbData %
sizeof( WCHAR ) ) == 0 ) ) {
00206
if( *( ( PWCHAR )( lpbData + cbData -
sizeof( WCHAR ) ) ) != ( WCHAR )
'\0' ) {
00207
if( !KeyNameAlreadyPrinted ) {
00208 KeyNameAlreadyPrinted =
TRUE;
00209 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00210 }
00211 printf(
MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
00212 lpszValue, cchValue,
"REG_SZ" );
00213 }
00214 }
else {
00215
if( !KeyNameAlreadyPrinted ) {
00216 KeyNameAlreadyPrinted =
TRUE;
00217 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00218 }
00219 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00220 lpszValue, cchValue,
"REG_SZ", cbData );
00221 }
00222
break;
00223
00224
case REG_FULL_RESOURCE_DESCRIPTOR:
00225
00226
if( cbData == 0 ) {
00227
if( !KeyNameAlreadyPrinted ) {
00228 KeyNameAlreadyPrinted =
TRUE;
00229 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00230 }
00231 printf(
MSG_ERROR_VALUE_INCORRECT_SIZE,
00232 lpszValue, cchValue,
"REG_FULL_RESOURCE_DESCRIPTOR", cbData );
00233 }
00234
break;
00235
00236
default:
00237
00238
if( !KeyNameAlreadyPrinted ) {
00239 KeyNameAlreadyPrinted =
TRUE;
00240 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00241 }
00242 printf(
MSG_ERROR_VALUE_UNKNOWN_DATA,
00243 lpszValue, cchValue, dwType, cbData );
00244
break;
00245
00246 }
00247 }
00248
00249
00250
00251
00252 free( lpszValue );
00253 free( lpbData );
00254 }
00255
00256
00257
00258
00259
00260
VOID
00261 ExamineKey(
00262 IN HKEY PredefinedKey,
00263 IN LPCWSTR ParentName,
00264 IN LPCWSTR KeyName,
00265 IN LPCWSTR PredefinedKeyName
00266 )
00267
00268 {
00269 LPWSTR CompleteKeyName;
00270
00271 HKEY
Key;
00272
00273 LONG
Status;
00274
00275 WCHAR szClass[
MAX_PATH + 1 ];
00276
DWORD cchClass;
00277
DWORD cSubKeys;
00278
DWORD cchMaxSubKey;
00279
DWORD cchMaxClass;
00280
DWORD cValues;
00281
DWORD cchMaxValueName;
00282
DWORD cbMaxValueData;
00283
DWORD cbSecurityDescriptor;
00284 FILETIME ftLastWriteTime;
00285
00286 WCHAR szSubKeyName[
MAX_PATH + 1 ];
00287
DWORD cchSubKeyNameLength;
00288
00289
DWORD iSubKey;
00290 BOOLEAN KeyNameAlreadyPrinted;
00291
00292
00293
00294
00295
00296
00297
if( wcslen( ParentName ) == 0 ) {
00298 CompleteKeyName = wcsdup(
KeyName );
00299
if( CompleteKeyName ==
NULL ) {
00300 printf(
"ERROR: wcsdup( KeyName ) failed \n" );
00301
return;
00302 }
00303 }
else {
00304 CompleteKeyName = wcsdup( ParentName );
00305
if( CompleteKeyName ==
NULL ) {
00306 printf(
"ERROR: wcsdup( ParentName ) failed \n" );
00307
return;
00308 }
00309
if( wcslen(
KeyName ) != 0 ) {
00310 CompleteKeyName = realloc( CompleteKeyName,
00311 ( wcslen( CompleteKeyName ) +
00312 wcslen(
L"\\" ) +
00313 wcslen(
KeyName ) + 1 )*
sizeof( WCHAR ) );
00314 wcscat( CompleteKeyName,
L"\\" );
00315 wcscat( CompleteKeyName,
KeyName );
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
Status = RegOpenKeyExW( PredefinedKey,
00330 CompleteKeyName,
00331 0,
00332 MAXIMUM_ALLOWED,
00333 &
Key );
00334
00335
00336
if(
Status != ERROR_SUCCESS ) {
00337 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00338 printf(
MSG_ERROR_REG_OPEN_KEY_EX,
Status );
00339 free( CompleteKeyName );
00340
return;
00341 }
00342
00343
00344
00345
00346
00347
00348 cchClass =
sizeof( szClass ) /
sizeof( WCHAR );
00349
Status = RegQueryInfoKeyW(
Key,
00350 szClass,
00351 &cchClass,
00352 0,
00353 &cSubKeys,
00354 &cchMaxSubKey,
00355 &cchMaxClass,
00356 &cValues,
00357 &cchMaxValueName,
00358 &cbMaxValueData,
00359 &cbSecurityDescriptor,
00360 &ftLastWriteTime );
00361
00362
if(
Status != ERROR_SUCCESS ) {
00363 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00364 printf(
MSG_ERROR_REG_QUERY_INFO_KEY,
Status );
00365 free( CompleteKeyName );
00366 RegCloseKey(
Key );
00367
return;
00368 }
00369
00370
00371
if( cValues != 0 ) {
00372
00373
00374
00375
00376
00377
ExamineValueEntries(
Key,
00378 CompleteKeyName,
00379 cchMaxValueName,
00380 cbMaxValueData,
00381 cValues,
00382 PredefinedKeyName );
00383
00384 }
00385
00386
00387
00388
00389
if( cSubKeys != 0 ) {
00390 KeyNameAlreadyPrinted =
FALSE;
00391
for( iSubKey = 0; iSubKey < cSubKeys; iSubKey++ ) {
00392 cchSubKeyNameLength =
sizeof( szSubKeyName )/
sizeof( WCHAR );
00393 cchClass =
sizeof( szClass ) /
sizeof( WCHAR );
00394
Status = RegEnumKeyExW(
Key,
00395 iSubKey,
00396 szSubKeyName,
00397 &cchSubKeyNameLength,
00398 0,
00399
NULL,
00400
NULL,
00401 &ftLastWriteTime );
00402
00403
if(
Status != ERROR_SUCCESS ) {
00404
if( !KeyNameAlreadyPrinted ) {
00405 KeyNameAlreadyPrinted =
TRUE;
00406 printf(
MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
00407 }
00408 printf(
MSG_ERROR_REG_ENUM_KEY_EX,
Status, iSubKey );
00409
continue;
00410 }
00411
ExamineKey( PredefinedKey,
00412 CompleteKeyName,
00413 szSubKeyName,
00414 PredefinedKeyName );
00415 }
00416 }
00417 RegCloseKey(
Key );
00418
00419 free( CompleteKeyName );
00420 }
00421
00422
00423
00424
00425 main(
int argc,
char* argv[] )
00426 {
00427
DWORD i;
00428 HKEY RemoteUsers;
00429 HKEY RemoteLocalMachine;
00430 LONG
Status;
00431
00432
if( argc <= 1 ) {
00433 printf(
"\n******* Examining HKEY_LOCAL_MACHINE on local machine\n\n" );
00434
ExamineKey( HKEY_LOCAL_MACHINE,
00435
L"",
00436
L"",
00437
L"HKEY_LOCAL_MACHINE" );
00438
00439 printf(
"\n******* Examining HKEY_USERS on local machine\n\n" );
00440
ExamineKey( HKEY_USERS,
00441
L"",
00442
L"",
00443
L"HKEY_USERS" );
00444
00445 printf(
"\n******* Examining HKEY_CLASSES_ROOT on local machine\n\n" );
00446
ExamineKey( HKEY_CLASSES_ROOT,
00447
L"",
00448
L"",
00449
L"HKEY_CLASSES_ROOT" );
00450
00451 printf(
"\n******* Examining HKEY_CURRENT_USER on local machine\n\n" );
00452
ExamineKey( HKEY_CURRENT_USER,
00453
L"",
00454
L"",
00455
L"HKEY_CURRENT_USER" );
00456 }
else {
00457
for( i = 1; i < argc; i++ ) {
00458
00459
00460
00461
00462
Status = RegConnectRegistry( argv[ i ],
00463 HKEY_LOCAL_MACHINE,
00464 &RemoteLocalMachine );
00465
00466
if(
Status != ERROR_SUCCESS ) {
00467 printf(
MSG_ERROR_REG_CONNECT_REGISTRY, argv[i],
Status );
00468
continue;
00469 }
00470
00471
Status = RegConnectRegistry( argv[ i ],
00472 HKEY_USERS,
00473 &RemoteUsers );
00474
00475
if(
Status != ERROR_SUCCESS ) {
00476 RegCloseKey( RemoteLocalMachine );
00477 printf(
MSG_ERROR_REG_CONNECT_REGISTRY, argv[i],
Status );
00478
continue;
00479 }
00480
00481 printf(
"\n******* Examining HKEY_LOCAL_MACHINE on %s \n\n", argv[i] );
00482
ExamineKey( RemoteLocalMachine,
00483
L"",
00484
L"",
00485
L"HKEY_LOCAL_MACHINE" );
00486
00487 printf(
"\n******* Examining HKEY_USERS on %s \n\n", argv[i] );
00488
ExamineKey( RemoteUsers,
00489
L"",
00490
L"",
00491
L"HKEY_USERS" );
00492
00493 RegCloseKey( RemoteLocalMachine );
00494 RegCloseKey( RemoteUsers );
00495 }
00496 }
00497 }