|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
Apitest.c
Abstract:
This module contains the function test for the Win32 Registry API.
Author:
David J. Gilman (davegi) 28-Dec-1991
Environment:
Windows, Crt - User Mode
Notes:
This test can be compiled for Unicode by defining the compiler symbol UNICODE.
Since this is a test program it relies on assertions for error checking rather than a more robust mechanism.
--*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "crtools.h"
#define HKEY_ROOT HKEY_CURRENT_USER
#define SAVE_RESTORE_FILE TEXT( "srkey.reg" )
#define KEY_PATH \
TEXT( "TestUser1\\TestUser1_1\\TestUser1_2" )
#define PREDEFINED_HANDLE HKEY_USERS
#define PREDEFINED_HANDLE_STRING \
TEXT( "HKEY_USERS\\.Default\\TestUser1" )
#define KEY_NAME_1 TEXT( "TestUser1" )
#define KEY_NAME_1_TITLE_INDEX ( 0 )
#define KEY_NAME_1_CLASS TEXT( "Test User Class" )
#define KEY_NAME_1_CLASS_LENGTH LENGTH( KEY_NAME_1_CLASS )
#define KEY_NAME_1_1 TEXT( "TestUser1_1" )
#define KEY_NAME_1_1_LENGTH LENGTH( KEY_NAME_1_1 )
#define KEY_NAME_1_1_TITLE_INDEX ( 0 )
#define KEY_NAME_1_1_CLASS TEXT( "Test User Class" )
#define KEY_NAME_1_1_CLASS_LENGTH LENGTH( KEY_NAME_1_1_CLASS )
#define KEY_NAME_1_2 TEXT( "TestUser1_2" )
#define KEY_NAME_1_2_LENGTH LENGTH( KEY_NAME_1_2 )
#define KEY_NAME_1_2_TITLE_INDEX (0 )
#define KEY_NAME_1_2_CLASS TEXT( "Test User Class" )
#define KEY_NAME_1_2_CLASS_LENGTH LENGTH( KEY_NAME_1_2_CLASS )
#define VALUE_NAME_1 TEXT( "One" )
#define VALUE_NAME_1_LENGTH LENGTH( VALUE_NAME_1 )
#define VALUE_NAME_1_TITLE_INDEX 0
#define VALUE_DATA_1 "Number One"
#define VALUE_DATA_1_LENGTH 11
#define VALUE_DATA_1_TYPE REG_SZ
#define VALUE_NAME_2 TEXT( "Second" )
#define VALUE_NAME_2_LENGTH LENGTH( VALUE_NAME_2 )
#define VALUE_NAME_2_TITLE_INDEX ( 0 )
#define VALUE_DATA_2 ( 2 )
#define VALUE_DATA_2_LENGTH ( sizeof( VALUE_DATA_2 ))
#define VALUE_DATA_2_TYPE REG_DWORD
#define MAX_DATA_LENGTH ( 32 )
//
// Root handle for apitest's nodes.
//
HKEY RootHandle;
//
// Error and informational messages.
//
PSTR UsageMessage =
"Usage: apitest [-?] [-q] [\\machinename]\n";
PSTR HelpMessage =
"\n where:\n" \ " -? - display this message.\n" \ " -q - quiet - suppresses all output\n" \ " machinename - remote machine.\n";
PSTR InvalidSwitchMessage =
"Invalid switch - %s\n";
PSTR InvalidMachineNameMessage =
"Invalid machine name - %s\n";
//
// Event handle used for synchronization.
//
HANDLE _EventHandle; HANDLE _EventHandle1; HANDLE _EventHandle2;
BOOL Quiet;
VOID DeleteTree( IN HKEY KeyHandle )
{ LONG Error; DWORD Index; HKEY ChildHandle;
TSTR KeyName[ MAX_PATH ]; DWORD KeyNameLength; TSTR ClassName[ MAX_PATH ]; DWORD ClassNameLength; DWORD TitleIndex; DWORD NumberOfSubKeys; DWORD MaxSubKeyLength; DWORD MaxClassLength; DWORD NumberOfValues; DWORD MaxValueNameLength; DWORD MaxValueDataLength; DWORD SecurityDescriptorLength; FILETIME LastWriteTime;
ClassNameLength = MAX_PATH;
Error = RegQueryInfoKey( KeyHandle, ClassName, &ClassNameLength, NULL, &NumberOfSubKeys, &MaxSubKeyLength, &MaxClassLength, &NumberOfValues, &MaxValueNameLength, &MaxValueDataLength, &SecurityDescriptorLength, &LastWriteTime ); REG_API_SUCCESS( RegQueryInfoKey );
for( Index = 0; Index < NumberOfSubKeys; Index++ ) {
KeyNameLength = MAX_PATH;
Error = RegEnumKey( KeyHandle, 0, // Index,
KeyName, KeyNameLength ); REG_API_SUCCESS( RegEnumKey );
Error = RegOpenKey( KeyHandle, KeyName, &ChildHandle );
REG_API_SUCCESS( RegOpenKey );
DeleteTree( ChildHandle );
Error = RegCloseKey( ChildHandle ); REG_API_SUCCESS( RegCloseKey );
Error = RegDeleteKey( KeyHandle, KeyName ); REG_API_SUCCESS( RegDeleteKey ); } } VOID DeleteTestTree( )
{ LONG Error; HKEY KeyHandle;
Error = RegOpenKey( RootHandle, KEY_NAME_1, &KeyHandle );
if( Error == ERROR_SUCCESS ) {
DeleteTree( KeyHandle );
Error = RegCloseKey( KeyHandle ); REG_API_SUCCESS( RegCloseKey );
Error = RegDeleteKey( RootHandle, KEY_NAME_1 ); REG_API_SUCCESS( RegDeleteKey ); } }
DWORD NotifyThread( LPVOID Parameters )
{ LONG Error; BOOL ErrorFlag; HANDLE EventHandle;
UNREFERENCED_PARAMETER( Parameters );
//
// Create the notification event.
//
EventHandle = CreateEvent( NULL, FALSE, FALSE, NULL ); ASSERT( EventHandle != NULL );
//
// Set-up an asynchronous notify.
//
Error = RegNotifyChangeKeyValue( RootHandle, FALSE, REG_LEGAL_CHANGE_FILTER, EventHandle, TRUE ); REG_API_SUCCESS( RegNotifyChangeKeyValue );
//
// Release the main thread.
//
ErrorFlag = SetEvent( _EventHandle ); ASSERT( ErrorFlag == TRUE );
//
// Wait for a notification.
//
Error = (LONG)WaitForSingleObject( EventHandle, (DWORD)-1 ); ASSERT( Error == 0 );
if( ! Quiet ) { printf( "First notification triggered\n" ); }
CloseHandle( EventHandle );
EventHandle = CreateEvent( NULL, FALSE, FALSE, NULL ); ASSERT( EventHandle != NULL );
//
// Set-up an asynchronous notify.
//
Error = RegNotifyChangeKeyValue( RootHandle, FALSE, REG_LEGAL_CHANGE_FILTER, EventHandle, TRUE ); REG_API_SUCCESS( RegNotifyChangeKeyValue );
//
// Release the main thread.
//
ErrorFlag = SetEvent( _EventHandle1 ); ASSERT( ErrorFlag == TRUE );
//
// Wait for a notification.
//
Error = (LONG)WaitForSingleObject( EventHandle, (DWORD)-1 ); ASSERT( Error == 0 );
if( ! Quiet ) { printf( "Second notification triggered\n" ); }
CloseHandle( EventHandle ); ErrorFlag = SetEvent( _EventHandle2 ); ASSERT( ErrorFlag == TRUE );
#endif
return ( DWORD ) TRUE; }
VOID main( INT argc, PCHAR argv[ ] )
{ LONG Error; BOOL ErrorFlag; DWORD Index;
PTSTR MachineName;
PKEY Key; TSTR NameString[ MAX_PATH ];
HANDLE NotifyThreadHandle; DWORD ThreadID;
HKEY PredefinedHandle; HKEY Handle1; HKEY Handle1_1; HKEY Handle1_2;
PSECURITY_DESCRIPTOR SecurityDescriptor; SECURITY_ATTRIBUTES SecurityAttributes;
DWORD Disposition; TSTR KeyName[ MAX_PATH ]; DWORD KeyNameLength; TSTR ClassName[ MAX_PATH ]; DWORD ClassNameLength; DWORD NumberOfSubKeys; DWORD MaxSubKeyLength; DWORD MaxClassLength; DWORD NumberOfValues; DWORD MaxValueNameLength; DWORD MaxValueDataLength; DWORD SecurityDescriptorLength; FILETIME LastWriteTime;
TSTR ValueName[ MAX_PATH ]; DWORD ValueNameLength;
BYTE Data[ MAX_DATA_LENGTH ]; DWORD DataLength;
BYTE Data_1[ ] = VALUE_DATA_1; DWORD Data_2 = VALUE_DATA_2;
DWORD TitleIndex; DWORD Type;
UNREFERENCED_PARAMETER( argc );
//
// By default, be verbose and operate on the local machine.
//
Quiet = FALSE; MachineName = NULL;
//
// Initialize options based on the command line.
//
while( *++argv ) {
//
// If the command line argument is a switch character...
//
if( isswitch(( *argv )[ 0 ] )) {
switch( tolower(( *argv )[ 1 ] )) {
//
// Display the detailed help message and quit.
//
case '?':
DisplayMessage( FALSE, UsageMessage ); DisplayMessage( TRUE, HelpMessage ); break;
//
// Quiet - no output.
//
case 'q':
Quiet = TRUE; break;
//
// Display invalid switch message and quit.
//
default:
DisplayMessage( FALSE, InvalidSwitchMessage, *argv ); DisplayMessage( TRUE, UsageMessage ); } } else {
MachineName = *argv; } }
//
// If a machine name was passed on the command line, connect to
// the Registry on that machine else use the local Registry.
// In either case construct a string representation of the
// test's main key (i.e. \\machine\HKEY_USERS\.Default\TestUser1 or
// HKEY_USERS\.Default\TestUser1.
//
if( MachineName ) {
Error = RegConnectRegistry( MachineName, PREDEFINED_HANDLE, &PredefinedHandle );
REG_API_SUCCESS( RegConnectRegistry );
strcpy( NameString, MachineName ); strcat( NameString, "\\\\" ); strcat( NameString, PREDEFINED_HANDLE_STRING );
} else {
PredefinedHandle = PREDEFINED_HANDLE; strcpy( NameString, PREDEFINED_HANDLE_STRING ); }
//
// Open ".Default" key as the root for the remainder of the test.
//
Error = RegOpenKeyEx( PredefinedHandle, ".Default", REG_OPTION_RESERVED, MAXIMUM_ALLOWED, &RootHandle ); REG_API_SUCCESS( RegOpenKeyEx );
//
// Predefined handle is no longer needed.
//
Error = RegCloseKey( PredefinedHandle ); REG_API_SUCCESS( RegCloseKey );
//
// Delete the save / restore file (in case it exists from a previous
// run of the test) as RegSaveKey requires a new file.
//
DeleteFile( SAVE_RESTORE_FILE );
//
// Remove any leftover keys from previous runs of this test.
//
DeleteTestTree( );
//
// Use the Win 3.1 API (which calls the Win32 API) to create a path.
//
Error = RegCreateKey( RootHandle, KEY_PATH, &Handle1 ); REG_API_SUCCESS( RegCreateKey );
//
// Close the key so the delete (DeleteTestTree) will work.
//
Error = RegCloseKey( Handle1 ); REG_API_SUCCESS( RegCloseKey );
//
// Remove the path.
//
DeleteTestTree( );
//
// Create the synchronization event.
//
_EventHandle = CreateEvent( NULL, FALSE, FALSE, NULL ); ASSERT( _EventHandle != NULL );
_EventHandle1 = CreateEvent( NULL, FALSE, FALSE, NULL ); ASSERT( _EventHandle1 != NULL );
_EventHandle2 = CreateEvent( NULL, FALSE, FALSE, NULL ); ASSERT( _EventHandle2 != NULL );
//
// Create the notify thread.
//
NotifyThreadHandle = CreateThread( NULL, 0, NotifyThread, NULL, 0, &ThreadID ); ASSERT( NotifyThreadHandle != NULL );
//
// Wait for the notify thread to create its event.
//
Error = (LONG)WaitForSingleObject( _EventHandle, (DWORD)-1 ); ASSERT( Error == 0 );
//
// Use Win 3.1 compatible APIs to create/close, open/close and delete
// the key TestUser1.
//
Error = RegCreateKey( RootHandle, KEY_NAME_1, &Handle1 ); REG_API_SUCCESS( RegCreateKey );
Error = RegCloseKey( Handle1 ); REG_API_SUCCESS( RegCloseKey );
//
// Wait for the notify thread to create its event.
//
Error = (LONG)WaitForSingleObject( _EventHandle1, (DWORD)-1 ); ASSERT( Error == 0 );
Error = RegOpenKey( RootHandle, KEY_NAME_1, &Handle1 ); REG_API_SUCCESS( RegOpenKey );
Error = RegCloseKey( Handle1 ); REG_API_SUCCESS( RegCloseKey );
Error = RegDeleteKey( RootHandle, KEY_NAME_1 ); REG_API_SUCCESS( RegDeleteKey );
//
// Use Win32 APIs to create/close, open/close and create (open) the
// key TestUser1.
//
//
// Allocate and initialize the SecurityDescriptor.
//
SecurityDescriptor = malloc( sizeof( SECURITY_DESCRIPTOR )); ASSERT( SecurityDescriptor != NULL ); ErrorFlag = InitializeSecurityDescriptor( SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); ASSERT( ErrorFlag == TRUE );
SecurityAttributes.nLength = sizeof( SECURITY_ATTRIBUTES ); SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor; SecurityAttributes.bInheritHandle = FALSE;
Error = RegCreateKeyEx( RootHandle, KEY_NAME_1, 0, KEY_NAME_1_CLASS, REG_OPTION_RESERVED, KEY_ALL_ACCESS, &SecurityAttributes, &Handle1, &Disposition ); REG_API_SUCCESS( RegCreateKeyEx );
ASSERT( Disposition == REG_CREATED_NEW_KEY );
Error = RegCloseKey( Handle1 ); REG_API_SUCCESS( RegCloseKey );
//
// Wait for the notify thread to create its event.
//
Error = RegOpenKeyEx( RootHandle, KEY_NAME_1, REG_OPTION_RESERVED, KEY_ALL_ACCESS, &Handle1 ); REG_API_SUCCESS( RegOpenKeyEx );
Error = RegCloseKey( Handle1 ); REG_API_SUCCESS( RegCloseKey );
Error = RegCreateKeyEx( RootHandle, KEY_NAME_1, 0, KEY_NAME_1_CLASS, REG_OPTION_RESERVED, KEY_ALL_ACCESS, NULL, &Handle1, &Disposition ); REG_API_SUCCESS( RegCreateKeyEx );
ASSERT( Disposition == REG_OPENED_EXISTING_KEY );
//
// Get and set the key's SECURITY_DESCRIPTOR. Setting will trigger
// a notification.
//
SecurityDescriptorLength = 0;
//
// Get the SECURITY_DESCRIPTOR's length.
//
Error = RegGetKeySecurity( Handle1, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, SecurityDescriptor, &SecurityDescriptorLength ); ASSERT( Error == ERROR_INSUFFICIENT_BUFFER );
SecurityDescriptor = realloc( SecurityDescriptor, SecurityDescriptorLength ); ASSERT( SecurityDescriptor != NULL ); ErrorFlag = InitializeSecurityDescriptor( SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); ASSERT( ErrorFlag == TRUE );
Error = RegSetKeySecurity( Handle1, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, SecurityDescriptor ); REG_API_SUCCESS( RegSetKeySecurity );
Error = (LONG)WaitForSingleObject( _EventHandle2, (DWORD)-1 ); ASSERT( Error == 0 );
//
// Reinitialize after the realloc.
//
SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor;
//
// Create two sub-keys.
//
Error = RegCreateKeyEx( Handle1, KEY_NAME_1_1, 0, KEY_NAME_1_1_CLASS, REG_OPTION_RESERVED, KEY_ALL_ACCESS, &SecurityAttributes, &Handle1_1, &Disposition ); REG_API_SUCCESS( RegCreateKeyEx );
ASSERT( Disposition == REG_CREATED_NEW_KEY );
Error = RegCreateKeyEx( Handle1, KEY_NAME_1_2, 0, KEY_NAME_1_2_CLASS, 0, KEY_ALL_ACCESS, &SecurityAttributes, &Handle1_2, &Disposition ); REG_API_SUCCESS( RegCreateKeyEx );
ASSERT( Disposition == REG_CREATED_NEW_KEY );
//
// Enumerate the two sub-keys using the Win 3.1 and the the Win32
// enumeration APIs.
//
KeyNameLength = MAX_PATH;
Error = RegEnumKey( Handle1, 0, KeyName, KeyNameLength ); REG_API_SUCCESS( RegEnumKey );
ASSERT( Compare( KeyName, KEY_NAME_1_1, KEY_NAME_1_1_LENGTH ));
KeyNameLength = MAX_PATH; ClassNameLength = MAX_PATH;
Error = RegEnumKeyEx( Handle1, 1, KeyName, &KeyNameLength, NULL, ClassName, &ClassNameLength, &LastWriteTime ); REG_API_SUCCESS( RegEnumKeyEx );
ASSERT( Compare( KeyName, KEY_NAME_1_2, KEY_NAME_1_2_LENGTH )); ASSERT( KeyNameLength == KEY_NAME_1_2_LENGTH ); //ASSERT( TitleIndex == KEY_NAME_1_2_TITLE_INDEX );
ASSERT( Compare( ClassName, KEY_NAME_1_2_CLASS, KEY_NAME_1_2_CLASS_LENGTH )); ASSERT( ClassNameLength == KEY_NAME_1_2_CLASS_LENGTH );
//
// If the Quiet command line option wasn't set, display the TestUser1 key.
//
if( ! Quiet ) { Key = ParseKey( NameString ); REG_API_SUCCESS( Key != NULL ); DisplayKeys( Key, TRUE, TRUE, TRUE ); FreeKey( Key ); }
//
// Close the two sub-keys.
//
Error = RegCloseKey( Handle1_1 ); REG_API_SUCCESS( RegCloseKey );
Error = RegCloseKey( Handle1_2 ); REG_API_SUCCESS( RegCloseKey );
Error = RegFlushKey( Handle1 );
REG_API_SUCCESS( RegFlushKey );
//
// Save the TestUser1 tree to a file.
//
#if 0
Error = RegSaveKey( Handle1, SAVE_RESTORE_FILE, SecurityDescriptor ); REG_API_SUCCESS( RegSaveKey );
RegCloseKey( Handle1 );
//
// Delete the TestUser1 tree.
//
DeleteTestTree( );
//
// Load TestUser1 from the file
//
Error = RegLoadKey( RootHandle, KEY_NAME_1, SAVE_RESTORE_FILE ); REG_API_SUCCESS( RegLoadKey );
//
// Unload TestUser1
//
Error = RegUnLoadKey( RootHandle, KEY_NAME_1 ); REG_API_SUCCESS( RegUnLoadKey );
//
// Restore the TestUser1 tree from a file.
//
Error = RegCreateKey( RootHandle, KEY_NAME_1, &Handle1 ); REG_API_SUCCESS( RegCreateKey );
Error = RegRestoreKey( Handle1, SAVE_RESTORE_FILE, 0 ); REG_API_SUCCESS( RegRestoreKey ); #endif
//
// Delete the two sub-keys.
//
Error = RegDeleteKey( Handle1, KEY_NAME_1_1 ); REG_API_SUCCESS( RegDeleteKey );
Error = RegDeleteKey( Handle1, KEY_NAME_1_2 ); REG_API_SUCCESS( RegDeleteKey );
//
// Set a value in the TestUser1 key using the Win 3.1 compatible API.
//
Error = RegSetValue( RootHandle, KEY_NAME_1, VALUE_DATA_1_TYPE, Data_1, VALUE_DATA_1_LENGTH ); REG_API_SUCCESS( RegSetValue );
//
// Set a value in the TestUser1 key using the Win32 API.
//
Error = RegSetValueEx( Handle1, VALUE_NAME_2, 0, VALUE_DATA_2_TYPE, ( PVOID ) &Data_2, VALUE_DATA_2_LENGTH ); REG_API_SUCCESS( RegSetValueEx );
//
// Commit the Key to the Registry.
//
Error = RegFlushKey( Handle1 ); REG_API_SUCCESS( RegFlushKey );
//
// If the Quiet command line option wasn't set, display the TestUser1 key.
//
if( ! Quiet ) { Key = ParseKey( NameString ); REG_API_SUCCESS( Key != NULL ); DisplayKeys( Key, TRUE, TRUE, TRUE ); FreeKey( Key ); }
//
// Query a value in the TestUser1 key using the Win 3.1 compatible API.
//
DataLength = MAX_DATA_LENGTH;
Error = RegQueryValue( RootHandle, KEY_NAME_1, Data, &DataLength ); REG_API_SUCCESS( RegQueryValue );
ASSERT( Compare( Data, &Data_1, VALUE_DATA_1_LENGTH )); ASSERT( DataLength == VALUE_DATA_1_LENGTH );
//
// Query a value in the TestUser1 key using the Win32 API.
//
DataLength = MAX_DATA_LENGTH;
Error = RegQueryValueEx( Handle1, VALUE_NAME_2, NULL, &Type, Data, &DataLength ); REG_API_SUCCESS( RegQueryValueEx );
//ASSERT( TitleIndex == VALUE_NAME_2_TITLE_INDEX );
ASSERT( Type == VALUE_DATA_2_TYPE ); ASSERT(( DWORD ) Data[ 0 ] == Data_2 ); ASSERT( DataLength == VALUE_DATA_2_LENGTH );
//
// Query information about the key.
//
ClassNameLength = MAX_PATH;
Error = RegQueryInfoKey( Handle1, ClassName, &ClassNameLength, NULL, &NumberOfSubKeys, &MaxSubKeyLength, &MaxClassLength, &NumberOfValues, &MaxValueNameLength, &MaxValueDataLength, &SecurityDescriptorLength, &LastWriteTime ); REG_API_SUCCESS( RegQueryInfoKey );
ASSERT( Compare( ClassName, KEY_NAME_1_CLASS, KEY_NAME_1_CLASS_LENGTH )); ASSERT( ClassNameLength == KEY_NAME_1_CLASS_LENGTH ); //ASSERT( TitleIndex == KEY_NAME_1_TITLE_INDEX );
ASSERT( NumberOfSubKeys == 0 );
ASSERT( MaxSubKeyLength == 0 ); ASSERT( MaxClassLength == 0 );
ASSERT( NumberOfValues == 2 );
ASSERT( MaxValueNameLength == VALUE_NAME_2_LENGTH * sizeof(WCHAR) ); ASSERT( MaxValueDataLength == VALUE_DATA_1_LENGTH * sizeof(WCHAR) );
//
// Enumerate the values.
//
for( Index = 0; Index < 2; Index++ ) {
ValueNameLength = MAX_PATH; DataLength = MAX_DATA_LENGTH;
Error = RegEnumValue( Handle1, Index, ValueName, &ValueNameLength, NULL, &Type, Data, &DataLength ); REG_API_SUCCESS( RegEnumValue );
//
// Check specifics depending on the value being queried.
//
switch( Index ) {
case 0:
//
// No name - win 3.1 compatible value.
//
ASSERT( ValueNameLength == 0 ); //ASSERT( TitleIndex == VALUE_NAME_1_TITLE_INDEX );
ASSERT( Type == VALUE_DATA_1_TYPE ); ASSERT( Compare( Data, Data_1, VALUE_DATA_1_LENGTH )); ASSERT( DataLength == VALUE_DATA_1_LENGTH ); break;
case 1:
ASSERT( Compare( ValueName, VALUE_NAME_2, VALUE_NAME_2_LENGTH )); ASSERT( ValueNameLength == VALUE_NAME_2_LENGTH ); //ASSERT( TitleIndex == VALUE_NAME_2_TITLE_INDEX );
ASSERT( Type == VALUE_DATA_2_TYPE ); ASSERT(( DWORD ) Data[ 0 ] == Data_2 ); ASSERT( DataLength == VALUE_DATA_2_LENGTH ); break;
default:
ASSERT_MESSAGE( FALSE, "Valid value enumeration index - " ); } }
//
// All done! Get rid of the key and close it.
//
Error = RegDeleteKey( RootHandle, KEY_NAME_1 ); REG_API_SUCCESS( RegDeleteKey );
Error = RegCloseKey( Handle1 ); REG_API_SUCCESS( RegCloseKey ); }
|