808 lines
20 KiB
C
808 lines
20 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ctreg.c
|
||
|
||
Abstract:
|
||
|
||
Configuration Registry component test
|
||
|
||
Needs to move from here
|
||
|
||
Author:
|
||
|
||
Scott Birrell (ScottBi) June 5, 1991
|
||
|
||
Environment:
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include <string.h>
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
|
||
|
||
#define CT_REG_INITIAL_KEY_COUNT 8L
|
||
#define CT_REG_INITIAL_LEVEL_COUNT 4L
|
||
#define CT_REG_KEY_VALUE_MAX_LENGTH 0x00000100L
|
||
|
||
//
|
||
// List of initial Registry keys to be set up. The list must be
|
||
// kept so that moving linearly through it visits key nodes with top
|
||
// to bottom key traversal taking precedence over left-to-right.
|
||
//
|
||
|
||
typedef struct _CT_TEST_REGISTRY_KEY {
|
||
ULONG KeyLevel;
|
||
PUCHAR KeyName;
|
||
ULONG KeyValueType;
|
||
PUCHAR KeyValue;
|
||
ULONG KeyValueLengthToQuery;
|
||
ULONG KeyValueLengthToSet;
|
||
NTSTATUS ExpectedStatus;
|
||
HANDLE KeyHandle;
|
||
HANDLE ParentKeyHandle;
|
||
} CT_TEST_REGISTRY_KEY, *PCT_TEST_REGISTRY_KEY;
|
||
|
||
CT_TEST_REGISTRY_KEY RegistryKeys[ CT_REG_INITIAL_KEY_COUNT ];
|
||
|
||
UCHAR KeyValue[CT_REG_KEY_VALUE_MAX_LENGTH];
|
||
ULONG KeyValueLengthToQuery;
|
||
ULONG KeyValueType;
|
||
LARGE_INTEGER LastWriteTime;
|
||
|
||
HANDLE ParentKeyHandle[CT_REG_INITIAL_LEVEL_COUNT + 1] =
|
||
{ NULL, NULL, NULL, NULL, NULL };
|
||
|
||
VOID
|
||
InitTestKey(
|
||
IN ULONG KeyNumber,
|
||
IN ULONG KeyLevel,
|
||
IN PUCHAR KeyName,
|
||
IN ULONG KeyNameLength,
|
||
IN ULONG KeyValueType,
|
||
IN PUCHAR KeyValue,
|
||
IN ULONG KeyValueLengthToQuery,
|
||
IN ULONG KeyValueLengthToSet,
|
||
IN NTSTATUS ExpectedStatus
|
||
);
|
||
|
||
|
||
VOID
|
||
CtRegExamineResult(
|
||
IN ULONG KeyNumber,
|
||
IN ULONG KeyValueType,
|
||
IN PUCHAR KeyValue,
|
||
IN ULONG KeyValueLength,
|
||
IN NTSTATUS ReturnedStatus
|
||
);
|
||
|
||
|
||
VOID
|
||
CtCreateSetQueryKey();
|
||
|
||
VOID
|
||
CtOpenMakeTempCloseKey();
|
||
|
||
|
||
VOID
|
||
main ()
|
||
{
|
||
CtCreateSetQueryKey();
|
||
|
||
CtOpenMakeTempCloseKey();
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
CtCreateSetQueryKey(
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function tests the RtlpNtOpenKey RtlpNtCreateKey and NtClose API.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status;
|
||
|
||
//
|
||
// Set up a test hierarchy of keys
|
||
//
|
||
|
||
ULONG KeyNumber;
|
||
ULONG ZeroLength;
|
||
STRING Name;
|
||
UNICODE_STRING UnicodeName;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
|
||
ZeroLength = 0L;
|
||
|
||
DbgPrint("Start of Create, Set, Query Registry Key Test\n");
|
||
|
||
//
|
||
// Initialize the test array. I did it this way because a statically
|
||
// initialized table is harder to read.
|
||
//
|
||
|
||
InitTestKey(
|
||
0,
|
||
0,
|
||
"\\Registry\\RLM",
|
||
sizeof ("\\Registry\\RLM"),
|
||
0,
|
||
"Level 0 - RLM",
|
||
sizeof ("\\Registry\\RLM") - 1,
|
||
sizeof ("\\Registry\\RLM") - 1,
|
||
STATUS_SUCCESS
|
||
);
|
||
|
||
InitTestKey(
|
||
1,
|
||
1,
|
||
"Test",
|
||
sizeof ("Test"),
|
||
1,
|
||
"Keyname Test - this value too big",
|
||
6,
|
||
sizeof ("Keyname Test - this value too big") -1,
|
||
STATUS_BUFFER_OVERFLOW
|
||
);
|
||
|
||
InitTestKey(
|
||
2,
|
||
2,
|
||
"SubTestA",
|
||
sizeof("SubTestA"),
|
||
2,
|
||
"Keyname SubTestA - value small",
|
||
30,
|
||
sizeof ("Keyname SubTestA - value small") - 1,
|
||
STATUS_SUCCESS
|
||
);
|
||
|
||
|
||
InitTestKey(
|
||
3,
|
||
3,
|
||
"SSTestA",
|
||
sizeof("SSTestA"),
|
||
3,
|
||
"Keyname SSTestA - zero length buffer",
|
||
30,
|
||
sizeof("Keyname SSTestA - zero length buffer") - 1,
|
||
STATUS_BUFFER_OVERFLOW
|
||
);
|
||
|
||
InitTestKey(
|
||
4,
|
||
3,
|
||
"SSTestB",
|
||
sizeof("SSTestB"),
|
||
4,
|
||
"Keyname SSTestB - value exact fit",
|
||
sizeof ("Keyname SSTestB - value exact fit") -1,
|
||
sizeof ("Keyname SSTestB - value exact fit") -1,
|
||
STATUS_SUCCESS
|
||
);
|
||
|
||
InitTestKey(
|
||
5,
|
||
3,
|
||
"SSTestC",
|
||
sizeof("SSTestC"),
|
||
5,
|
||
"Keyname SSTestC - value small",
|
||
40,
|
||
sizeof ("Keyname SSTestC - value small") -1,
|
||
STATUS_SUCCESS
|
||
);
|
||
|
||
InitTestKey(
|
||
6,
|
||
3,
|
||
"SSTestD",
|
||
sizeof("SSTestD"),
|
||
6,
|
||
"Keyname SSTestD - value small",
|
||
40,
|
||
sizeof ("Keyname SSTestD - value small") -1,
|
||
STATUS_SUCCESS
|
||
);
|
||
|
||
InitTestKey(
|
||
7,
|
||
3,
|
||
"SSTestE",
|
||
sizeof("SSTestD"),
|
||
0,
|
||
"Keyname SSTestD - no value set",
|
||
40,
|
||
0,
|
||
STATUS_SUCCESS
|
||
);
|
||
|
||
DbgPrint("Start of Registry Test\n");
|
||
|
||
//
|
||
// Create all of the initial test registry keys
|
||
//
|
||
|
||
|
||
for (KeyNumber = 0; KeyNumber < CT_REG_INITIAL_KEY_COUNT; KeyNumber++) {
|
||
|
||
RtlInitString(
|
||
&Name,
|
||
RegistryKeys[KeyNumber].KeyName
|
||
);
|
||
|
||
Status = RtlAnsiStringToUnicodeString(
|
||
&UnicodeName,
|
||
&Name,
|
||
TRUE );
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
DbgPrint("Security: Registry Init Ansi to Unicode failed 0x%lx\n",
|
||
Status);
|
||
return;
|
||
}
|
||
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&UnicodeName,
|
||
OBJ_CASE_INSENSITIVE,
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel],
|
||
NULL
|
||
);
|
||
|
||
//
|
||
// Remember the Parent Key handle
|
||
//
|
||
|
||
RegistryKeys[KeyNumber].ParentKeyHandle =
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel];
|
||
|
||
//
|
||
// Create the key if it does not already exist. If key does exist,
|
||
// continue trying to create all of the other keys needed (for now).
|
||
// Store the returned key handle as the parent key handle for the
|
||
// next higher (child) level.
|
||
//
|
||
|
||
Status = RtlpNtCreateKey(
|
||
&RegistryKeys[KeyNumber].KeyHandle,
|
||
(KEY_READ | KEY_WRITE),
|
||
&ObjectAttributes,
|
||
0L, // No options
|
||
NULL, // Default provider
|
||
NULL
|
||
);
|
||
|
||
//
|
||
// Save the Key's handle as the next level's parent handle.
|
||
//
|
||
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1] =
|
||
RegistryKeys[KeyNumber].KeyHandle;
|
||
|
||
//
|
||
// Free the memory allocated for the Unicode name
|
||
//
|
||
|
||
RtlFreeUnicodeString( &UnicodeName );
|
||
|
||
if (NT_SUCCESS(Status) || Status == STATUS_OBJECT_NAME_COLLISION) {
|
||
|
||
//
|
||
// Set the key's value unless the length to set is zero.
|
||
//
|
||
|
||
if (RegistryKeys[KeyNumber].KeyValueLengthToSet != 0) {
|
||
|
||
Status=RtlpNtSetValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel+1],
|
||
RegistryKeys[KeyNumber].KeyValueType,
|
||
RegistryKeys[KeyNumber].KeyValue,
|
||
RegistryKeys[KeyNumber].KeyValueLengthToSet
|
||
);
|
||
}
|
||
|
||
//
|
||
// Read the key's value back
|
||
//
|
||
|
||
KeyValueLengthToQuery =
|
||
RegistryKeys[KeyNumber].KeyValueLengthToQuery;
|
||
|
||
Status = RtlpNtQueryValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1],
|
||
&KeyValueType,
|
||
KeyValue,
|
||
&KeyValueLengthToQuery,
|
||
&LastWriteTime
|
||
);
|
||
|
||
//
|
||
// Verify that the expected KeyValue, KeyLength and Status
|
||
// were returned.
|
||
//
|
||
|
||
CtRegExamineResult(
|
||
KeyNumber,
|
||
KeyValueType,
|
||
KeyValue,
|
||
KeyValueLengthToQuery,
|
||
Status
|
||
);
|
||
|
||
//
|
||
// Test null pointer cases don't crash NtQueryValueKey
|
||
//
|
||
|
||
Status = RtlpNtQueryValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1],
|
||
NULL, // No type
|
||
KeyValue,
|
||
&KeyValueLengthToQuery,
|
||
&LastWriteTime
|
||
);
|
||
|
||
Status = RtlpNtQueryValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1],
|
||
&KeyValueType,
|
||
NULL, // No value
|
||
&KeyValueLengthToQuery,
|
||
&LastWriteTime
|
||
);
|
||
|
||
Status = RtlpNtQueryValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1],
|
||
&KeyValueType,
|
||
KeyValue,
|
||
NULL, // No length
|
||
&LastWriteTime
|
||
);
|
||
|
||
Status = RtlpNtQueryValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1],
|
||
&KeyValueType,
|
||
KeyValue,
|
||
&ZeroLength, // Zero length
|
||
&LastWriteTime
|
||
);
|
||
|
||
Status = RtlpNtQueryValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1],
|
||
&KeyValueType,
|
||
KeyValue,
|
||
&KeyValueLengthToQuery,
|
||
NULL // No time
|
||
);
|
||
//
|
||
// Test null pointer cases don't crash NtSetValueKey
|
||
//
|
||
|
||
Status = RtlpNtSetValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel+1],
|
||
RegistryKeys[KeyNumber].KeyValueType,
|
||
NULL, // No value, setting type only
|
||
RegistryKeys[KeyNumber].KeyValueLengthToSet
|
||
);
|
||
} else {
|
||
|
||
DbgPrint(
|
||
"Key number %d creation failed 0x%lx\n",
|
||
KeyNumber,
|
||
Status
|
||
);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Close all the keys in the table
|
||
//
|
||
|
||
for (KeyNumber = 0; KeyNumber < CT_REG_INITIAL_KEY_COUNT; KeyNumber++) {
|
||
|
||
Status = NtClose(
|
||
RegistryKeys[KeyNumber].KeyHandle
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
DbgPrint("Closing KeyNumber %d failed 0x%lx\n", Status);
|
||
}
|
||
}
|
||
|
||
DbgPrint("End of Create, Set, Query Registry Key Test\n");
|
||
}
|
||
|
||
|
||
VOID
|
||
CtRegExamineResult(
|
||
IN ULONG KeyNumber,
|
||
IN ULONG KeyValueType,
|
||
IN PUCHAR KeyValue,
|
||
IN ULONG KeyValueLengthReturned,
|
||
IN NTSTATUS ReturnedStatus
|
||
)
|
||
|
||
{
|
||
ULONG KeyValueLengthToCompare;
|
||
|
||
//
|
||
// Check the status. If bad, skip the other checks.
|
||
//
|
||
|
||
if (ReturnedStatus != RegistryKeys[KeyNumber].ExpectedStatus) {
|
||
|
||
DbgPrint(
|
||
"KeyNumber %d: RtlpNtQueryValueKey returned 0x%lx, expected 0x%lx\n",
|
||
KeyNumber,
|
||
ReturnedStatus,
|
||
RegistryKeys[KeyNumber].ExpectedStatus
|
||
);
|
||
|
||
} else {
|
||
|
||
//
|
||
// Check that the Key Type is as expected.
|
||
//
|
||
|
||
|
||
if (KeyValueType != RegistryKeys[KeyNumber].KeyValueType) {
|
||
|
||
DbgPrint(
|
||
"KeyNumber %d: RtlpNtQueryValueKey returned KeyValueType 0x%lx, \
|
||
expected 0x%lx\n",
|
||
KeyNumber,
|
||
KeyValueType,
|
||
RegistryKeys[KeyNumber].KeyValueType
|
||
);
|
||
|
||
}
|
||
|
||
//
|
||
// Check that the Key Length is as expected.
|
||
//
|
||
|
||
|
||
if (KeyValueLengthReturned !=
|
||
RegistryKeys[KeyNumber].KeyValueLengthToSet) {
|
||
|
||
DbgPrint(
|
||
"KeyNumber %d: RtlpNtQueryValueKey returned ValLength 0x%lx, \
|
||
expected 0x%lx\n",
|
||
KeyNumber,
|
||
KeyValueLengthReturned,
|
||
RegistryKeys[KeyNumber].KeyValueLengthToSet
|
||
);
|
||
|
||
}
|
||
|
||
//
|
||
// Check that the Key Value is as expected. Distinguish between
|
||
// Buffer truncated cases and regular cases.
|
||
//
|
||
|
||
if (RegistryKeys[KeyNumber].KeyValueLengthToSet != 0L) {
|
||
|
||
//
|
||
// Determine the length of returned key value to compare. This is
|
||
// the min of the set length and and the size of the return
|
||
// buffer.
|
||
//
|
||
|
||
KeyValueLengthToCompare =
|
||
RegistryKeys[KeyNumber].KeyValueLengthToSet;
|
||
|
||
if (KeyValueLengthToCompare >
|
||
RegistryKeys[KeyNumber].KeyValueLengthToQuery) {
|
||
|
||
KeyValueLengthToCompare =
|
||
RegistryKeys[KeyNumber].KeyValueLengthToQuery;
|
||
}
|
||
|
||
|
||
if (strncmp(
|
||
KeyValue,
|
||
RegistryKeys[KeyNumber].KeyValue,
|
||
KeyValueLengthToCompare
|
||
) != 0) {
|
||
|
||
//
|
||
// Output approriate error message. Message contains
|
||
// "truncated.." if key value should have been truncated
|
||
//
|
||
|
||
if (RegistryKeys[KeyNumber].KeyValueLengthToSet >
|
||
RegistryKeys[KeyNumber].KeyValueLengthToQuery) {
|
||
|
||
DbgPrint(
|
||
"KeyNumber %d: RtlpNtQueryValueKey returned KeyValue %s, \
|
||
expected %s truncated to %d characters\n",
|
||
KeyNumber,
|
||
KeyValue,
|
||
RegistryKeys[KeyNumber].KeyValue,
|
||
RegistryKeys[KeyNumber].KeyValueLengthToQuery
|
||
);
|
||
|
||
} else {
|
||
|
||
DbgPrint(
|
||
"KeyNumber %d: RtlpNtQueryValueKey returned KeyValue %s, \
|
||
expected %s\n",
|
||
KeyNumber,
|
||
KeyValue,
|
||
RegistryKeys[KeyNumber].KeyValue
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
CtOpenMakeTempCloseKey()
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function tests NtDeleteKey by deleting the CT configuration
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG KeyNumber;
|
||
ULONG KeyLevel;
|
||
STRING Name;
|
||
UNICODE_STRING UnicodeName;
|
||
NTSTATUS Status;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
|
||
//
|
||
// Open all of the initial test registry keys for write and delete
|
||
// access, set, query and delete each key.
|
||
//
|
||
|
||
DbgPrint("Start of Open Make Temp and Close Delete Registry Key Test\n");
|
||
|
||
//
|
||
// First, set all of the Parent handles to NULL
|
||
//
|
||
|
||
for (KeyNumber = 0; KeyNumber < CT_REG_INITIAL_KEY_COUNT; KeyNumber++) {
|
||
|
||
RegistryKeys[KeyNumber].ParentKeyHandle = NULL;
|
||
}
|
||
|
||
for (KeyLevel = 0; KeyLevel < CT_REG_INITIAL_LEVEL_COUNT; KeyLevel++) {
|
||
|
||
ParentKeyHandle[KeyLevel] = NULL;
|
||
}
|
||
|
||
for (KeyNumber = 0; KeyNumber < CT_REG_INITIAL_KEY_COUNT; KeyNumber++) {
|
||
|
||
RtlInitString(
|
||
&Name,
|
||
RegistryKeys[KeyNumber].KeyName
|
||
);
|
||
|
||
Status = RtlAnsiStringToUnicodeString(
|
||
&UnicodeName,
|
||
&Name,
|
||
TRUE );
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
DbgPrint("Security: Registry Init Ansi to Unicode failed 0x%lx\n",
|
||
Status);
|
||
return;
|
||
}
|
||
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&UnicodeName,
|
||
OBJ_CASE_INSENSITIVE,
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel],
|
||
NULL
|
||
);
|
||
|
||
//
|
||
// Open the key and store the returned key handle as the parent key
|
||
// handle for the next higher (child) level.
|
||
//
|
||
|
||
Status = RtlpNtOpenKey(
|
||
&RegistryKeys[KeyNumber].KeyHandle,
|
||
(KEY_READ | KEY_WRITE | DELETE),
|
||
&ObjectAttributes,
|
||
0L // No options
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
DbgPrint(
|
||
"NtOpenKey - KeyNumber %d failed 0x%lx\n",
|
||
KeyNumber,
|
||
Status
|
||
);
|
||
}
|
||
|
||
//
|
||
// Save the Key's handle as the next level's parent handle.
|
||
//
|
||
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1] =
|
||
RegistryKeys[KeyNumber].KeyHandle;
|
||
|
||
//
|
||
// Free the memory allocated for the Unicode name
|
||
//
|
||
|
||
RtlFreeUnicodeString( &UnicodeName );
|
||
|
||
if (NT_SUCCESS(Status) || Status == STATUS_OBJECT_NAME_COLLISION) {
|
||
|
||
//
|
||
// Set the key's value unless the length to set is zero.
|
||
//
|
||
|
||
if (RegistryKeys[KeyNumber].KeyValueLengthToSet != 0) {
|
||
|
||
Status=RtlpNtSetValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel+1],
|
||
RegistryKeys[KeyNumber].KeyValueType,
|
||
RegistryKeys[KeyNumber].KeyValue,
|
||
RegistryKeys[KeyNumber].KeyValueLengthToSet
|
||
);
|
||
}
|
||
|
||
//
|
||
// Read the key's value back
|
||
//
|
||
|
||
KeyValueLengthToQuery =
|
||
RegistryKeys[KeyNumber].KeyValueLengthToQuery;
|
||
|
||
Status = RtlpNtQueryValueKey(
|
||
ParentKeyHandle[RegistryKeys[KeyNumber].KeyLevel + 1],
|
||
&KeyValueType,
|
||
KeyValue,
|
||
&KeyValueLengthToQuery,
|
||
&LastWriteTime
|
||
);
|
||
|
||
//
|
||
// Verify that the expected KeyValue, KeyLength and Status
|
||
// were returned.
|
||
//
|
||
|
||
CtRegExamineResult(
|
||
KeyNumber,
|
||
KeyValueType,
|
||
KeyValue,
|
||
KeyValueLengthToQuery,
|
||
Status
|
||
);
|
||
|
||
} else {
|
||
|
||
DbgPrint(
|
||
"Key number %d open failed 0x%lx\n",
|
||
KeyNumber,
|
||
Status
|
||
);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Make Temporary and Close all the keys in the table
|
||
//
|
||
|
||
for (KeyNumber = CT_REG_INITIAL_KEY_COUNT-1; KeyNumber != 0L; KeyNumber--) {
|
||
|
||
Status = RtlpNtMakeTemporaryKey( RegistryKeys[KeyNumber].KeyHandle );
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
DbgPrint(
|
||
"Making Temporary KeyNumber %d failed 0x%lx\n",
|
||
KeyNumber,
|
||
Status
|
||
);
|
||
}
|
||
|
||
Status = NtClose(
|
||
RegistryKeys[KeyNumber].KeyHandle
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
DbgPrint(
|
||
"Closing KeyNumber %d failed 0x%lx\n",
|
||
KeyNumber,
|
||
Status
|
||
);
|
||
}
|
||
}
|
||
|
||
DbgPrint("End of Open Mk Temp and Close Registry Key Test\n");
|
||
}
|
||
|
||
|
||
VOID
|
||
InitTestKey(
|
||
IN ULONG KeyNumber,
|
||
IN ULONG KeyLevel,
|
||
IN PUCHAR KeyName,
|
||
IN ULONG KeyNameLength,
|
||
IN ULONG KeyValueType,
|
||
IN PUCHAR KeyValue,
|
||
IN ULONG KeyValueLengthToQuery,
|
||
IN ULONG KeyValueLengthToSet,
|
||
IN NTSTATUS ExpectedStatus
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function initializes an entry in the array of test keys
|
||
|
||
Arguments:
|
||
|
||
TBS.
|
||
|
||
Return Value:
|
||
|
||
--*/
|
||
|
||
{
|
||
RegistryKeys[KeyNumber].KeyLevel = KeyLevel;
|
||
RegistryKeys[KeyNumber].KeyName = KeyName;
|
||
RegistryKeys[KeyNumber].KeyValueType = KeyValueType;
|
||
RegistryKeys[KeyNumber].KeyValue = KeyValue;
|
||
RegistryKeys[KeyNumber].KeyValueLengthToSet = KeyValueLengthToSet;
|
||
RegistryKeys[KeyNumber].KeyValueLengthToQuery = KeyValueLengthToQuery;
|
||
RegistryKeys[KeyNumber].ExpectedStatus = ExpectedStatus;
|
||
RegistryKeys[KeyNumber].KeyHandle = NULL;
|
||
RegistryKeys[KeyNumber].ParentKeyHandle = NULL;
|
||
|
||
|
||
DBG_UNREFERENCED_PARAMETER (KeyNameLength);
|
||
}
|
||
|
||
|
||
|