windows-nt/Source/XPSP1/NT/base/ntos/config/test/chkreg.c
2020-09-26 16:20:57 +08:00

498 lines
17 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "windows.h"
#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"
#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"
#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"
#define MSG_ERROR_REG_ENUM_VALUE "\tERROR: RegEnumValue() failed, iValue = %d, Status = %d \n"
#define MSG_ERROR_REG_OPEN_KEY_EX "\tERROR: RegOpenKeyEx() failed, Status = %d \n"
#define MSG_ERROR_REG_QUERY_INFO_KEY "\tERROR: RegQueryInfoKey() failed, Status = %d \n"
#define MSG_ERROR_REG_ENUM_KEY_EX "ERROR: RegEnumKeyEx() failed, \n\t Status = %d \n\t, SubKey = %d"
#define MSG_ERROR_REG_CONNECT_REGISTRY "ERROR: Unable to connect to %s, Status = %d \n"
#define MSG_COMPLETE_KEY_NAME "%ls\\%ls \n"
VOID
ExamineValueEntries( IN HKEY Key,
IN LPCWSTR CompleteKeyName,
IN DWORD cchMaxValueName,
IN DWORD cbMaxValueData,
IN DWORD cValues,
IN LPCWSTR PredefinedKeyName )
{
LONG Status;
DWORD iValue;
LPWSTR lpszValue;
DWORD cchValue;
DWORD dwType;
PBYTE lpbData;
DWORD cbData;
BOOLEAN KeyNameAlreadyPrinted;
//
// Allocate the buffers for the value name and value data
//
lpszValue = ( LPWSTR )malloc( (cchMaxValueName + 1)*sizeof( WCHAR ) );
lpbData = ( LPBYTE )malloc( cbMaxValueData );
if( ( lpszValue == NULL ) ||
( lpbData == NULL ) ) {
printf( "ERROR: Unable to allocate memory, cchMaxValueName = %d, cbMaxValuedata = %d \n",
cchMaxValueName, cbMaxValueData );
if( lpszValue != NULL ) {
free( lpszValue );
}
if( lpbData != NULL ) {
free( lpbData );
}
return;
}
//
// Examine all value entries
//
KeyNameAlreadyPrinted = FALSE;
for( iValue = 0; iValue < cValues; iValue++ ) {
cchValue = cchMaxValueName + 1;
cbData = cbMaxValueData;
Status = RegEnumValueW( Key,
iValue,
lpszValue,
&cchValue,
0,
&dwType,
lpbData,
&cbData );
if( Status != ERROR_SUCCESS ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_REG_ENUM_VALUE, iValue, Status );
continue;
}
//
// For debugging only
//
// printf( "\tValueName = %ls \n", lpszValue );
//
switch( dwType ) {
case REG_BINARY:
if( cbData == 0 ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_BINARY", cbData );
}
break;
case REG_DWORD:
if( cbData != sizeof( DWORD ) ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_DWORD", cbData );
}
break;
case REG_DWORD_BIG_ENDIAN:
if( cbData != sizeof( DWORD ) ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_DWORD_BIG_ENDIAN", cbData );
}
break;
case REG_EXPAND_SZ:
if( ( cbData != 0 ) && ( ( cbData % sizeof( WCHAR ) ) == 0 )) {
if( *( ( PWCHAR )( lpbData + cbData - sizeof( WCHAR ) ) ) != ( WCHAR )'\0' ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
lpszValue, cchValue, "REG_EXPAND_SZ" );
}
} else {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_EXPAND_SZ", cbData );
}
break;
case REG_LINK:
if( cbData == 0 ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_LINK", cbData );
}
break;
case REG_MULTI_SZ:
if( ( cbData != 0 ) && ( ( cbData % sizeof( WCHAR ) ) == 0 )) {
if( *( ( PWCHAR )( lpbData + cbData - sizeof( WCHAR ) ) ) != ( WCHAR )'\0' ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
lpszValue, cchValue, "REG_MULTI_SZ" );
}
} else {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_MULTI_SZ", cbData );
}
break;
case REG_NONE:
if( cbData != 0 ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_NONE", cbData );
}
break;
case REG_RESOURCE_LIST:
if( cbData == 0 ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_RESOURCE_LIST", cbData );
}
break;
case REG_SZ:
if( ( cbData != 0 ) && ( ( cbData % sizeof( WCHAR ) ) == 0 ) ) {
if( *( ( PWCHAR )( lpbData + cbData - sizeof( WCHAR ) ) ) != ( WCHAR )'\0' ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_NOT_NUL_TERMINATED,
lpszValue, cchValue, "REG_SZ" );
}
} else {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_SZ", cbData );
}
break;
case REG_FULL_RESOURCE_DESCRIPTOR:
if( cbData == 0 ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_INCORRECT_SIZE,
lpszValue, cchValue, "REG_FULL_RESOURCE_DESCRIPTOR", cbData );
}
break;
default:
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_VALUE_UNKNOWN_DATA,
lpszValue, cchValue, dwType, cbData );
break;
}
}
//
// Free buffers for value name and value data
//
free( lpszValue );
free( lpbData );
}
VOID
ExamineKey(
IN HKEY PredefinedKey,
IN LPCWSTR ParentName,
IN LPCWSTR KeyName,
IN LPCWSTR PredefinedKeyName
)
{
LPWSTR CompleteKeyName;
HKEY Key;
LONG Status;
WCHAR szClass[ MAX_PATH + 1 ];
DWORD cchClass;
DWORD cSubKeys;
DWORD cchMaxSubKey;
DWORD cchMaxClass;
DWORD cValues;
DWORD cchMaxValueName;
DWORD cbMaxValueData;
DWORD cbSecurityDescriptor;
FILETIME ftLastWriteTime;
WCHAR szSubKeyName[ MAX_PATH + 1 ];
DWORD cchSubKeyNameLength;
DWORD iSubKey;
BOOLEAN KeyNameAlreadyPrinted;
//
// Build the complete key name
//
if( wcslen( ParentName ) == 0 ) {
CompleteKeyName = wcsdup( KeyName );
if( CompleteKeyName == NULL ) {
printf( "ERROR: wcsdup( KeyName ) failed \n" );
return;
}
} else {
CompleteKeyName = wcsdup( ParentName );
if( CompleteKeyName == NULL ) {
printf( "ERROR: wcsdup( ParentName ) failed \n" );
return;
}
if( wcslen( KeyName ) != 0 ) {
CompleteKeyName = realloc( CompleteKeyName,
( wcslen( CompleteKeyName ) +
wcslen( L"\\" ) +
wcslen( KeyName ) + 1 )*sizeof( WCHAR ) );
wcscat( CompleteKeyName, L"\\" );
wcscat( CompleteKeyName, KeyName );
}
}
//
// For debugging only
//
// printf( "%ls\\%ls \n", PredefinedKeyName, CompleteKeyName );
//
//
// Open the key
//
Status = RegOpenKeyExW( PredefinedKey,
CompleteKeyName,
0,
MAXIMUM_ALLOWED,
&Key );
if( Status != ERROR_SUCCESS ) {
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
printf( MSG_ERROR_REG_OPEN_KEY_EX, Status );
free( CompleteKeyName );
return;
}
//
// Determine the number of value entries, the maximum length of a value
// entry name, the maximum data size, and the number of subkeys
//
cchClass = sizeof( szClass ) / sizeof( WCHAR );
Status = RegQueryInfoKeyW( Key,
szClass,
&cchClass,
0,
&cSubKeys,
&cchMaxSubKey,
&cchMaxClass,
&cValues,
&cchMaxValueName,
&cbMaxValueData,
&cbSecurityDescriptor,
&ftLastWriteTime );
if( Status != ERROR_SUCCESS ) {
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
printf( MSG_ERROR_REG_QUERY_INFO_KEY, Status );
free( CompleteKeyName );
RegCloseKey( Key );
return;
}
if( cValues != 0 ) {
//
// Examine the value entries
//
ExamineValueEntries( Key,
CompleteKeyName,
cchMaxValueName,
cbMaxValueData,
cValues,
PredefinedKeyName );
}
//
// Traverse each subkey
//
if( cSubKeys != 0 ) {
KeyNameAlreadyPrinted = FALSE;
for( iSubKey = 0; iSubKey < cSubKeys; iSubKey++ ) {
cchSubKeyNameLength = sizeof( szSubKeyName )/sizeof( WCHAR );
cchClass = sizeof( szClass ) / sizeof( WCHAR );
Status = RegEnumKeyExW( Key,
iSubKey,
szSubKeyName,
&cchSubKeyNameLength,
0,
NULL,
NULL,
&ftLastWriteTime );
if( Status != ERROR_SUCCESS ) {
if( !KeyNameAlreadyPrinted ) {
KeyNameAlreadyPrinted = TRUE;
printf( MSG_COMPLETE_KEY_NAME, PredefinedKeyName, CompleteKeyName );
}
printf( MSG_ERROR_REG_ENUM_KEY_EX, Status, iSubKey );
continue;
}
ExamineKey( PredefinedKey,
CompleteKeyName,
szSubKeyName,
PredefinedKeyName );
}
}
RegCloseKey( Key );
free( CompleteKeyName );
}
main( int argc, char* argv[] )
{
DWORD i;
HKEY RemoteUsers;
HKEY RemoteLocalMachine;
LONG Status;
if( argc <= 1 ) {
printf( "\n******* Examining HKEY_LOCAL_MACHINE on local machine\n\n" );
ExamineKey( HKEY_LOCAL_MACHINE,
L"",
L"",
L"HKEY_LOCAL_MACHINE" );
printf( "\n******* Examining HKEY_USERS on local machine\n\n" );
ExamineKey( HKEY_USERS,
L"",
L"",
L"HKEY_USERS" );
printf( "\n******* Examining HKEY_CLASSES_ROOT on local machine\n\n" );
ExamineKey( HKEY_CLASSES_ROOT,
L"",
L"",
L"HKEY_CLASSES_ROOT" );
printf( "\n******* Examining HKEY_CURRENT_USER on local machine\n\n" );
ExamineKey( HKEY_CURRENT_USER,
L"",
L"",
L"HKEY_CURRENT_USER" );
} else {
for( i = 1; i < argc; i++ ) {
//
// printf( "Machine name = %s \n", argv[ i ] );
//
Status = RegConnectRegistry( argv[ i ],
HKEY_LOCAL_MACHINE,
&RemoteLocalMachine );
if( Status != ERROR_SUCCESS ) {
printf( MSG_ERROR_REG_CONNECT_REGISTRY, argv[i], Status );
continue;
}
Status = RegConnectRegistry( argv[ i ],
HKEY_USERS,
&RemoteUsers );
if( Status != ERROR_SUCCESS ) {
RegCloseKey( RemoteLocalMachine );
printf( MSG_ERROR_REG_CONNECT_REGISTRY, argv[i], Status );
continue;
}
printf( "\n******* Examining HKEY_LOCAL_MACHINE on %s \n\n", argv[i] );
ExamineKey( RemoteLocalMachine,
L"",
L"",
L"HKEY_LOCAL_MACHINE" );
printf( "\n******* Examining HKEY_USERS on %s \n\n", argv[i] );
ExamineKey( RemoteUsers,
L"",
L"",
L"HKEY_USERS" );
RegCloseKey( RemoteLocalMachine );
RegCloseKey( RemoteUsers );
}
}
}