Any Win9X wizards on this list? Is there a better list on which I could ask
this question?
I’m doing a Win98 miniport, which needs to get a value out of the registry
in the DriverEntry routine, and I’m not having any success.
I can open a key, and read the name of the value I’m looking for, but I
can’t read the value itself. Since I already know the name of the value,
being able to retrieve it really doesn’t help much. But it does appear to
validate that the ZwOpenKey call is returning a valid handle. Doesn’t it?
Below is the code demonstrating the problem. I’ve tried ZwCreateKey with
the same options as ZwOpenKey, and it didn’t work any better. Any
suggestions for different options, incantations, or other secret sauce that
might make this work?
UNICODE_STRING uPath, uName, uResult;
ANSI_STRING aResult;
HANDLE hFolder = NULL;
OBJECT_ATTRIBUTES objAttribs;
NTSTATUS lastError = STATUS_SUCCESS;
ULONG dataLength = 0x80;
ULONG structLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + \
dataLength + sizeof(UNICODE_NULL);
PKEY_VALUE_BASIC_INFORMATION pBasicValue = NULL;
PKEY_VALUE_PARTIAL_INFORMATION pPartialValue = NULL;
PKEY_VALUE_FULL_INFORMATION pFullValue = NULL;
pBasicValue = (PKEY_VALUE_BASIC_INFORMATION) \
ExAllocatePool(PagedPool, structLength);
pPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION) \
ExAllocatePool(PagedPool, structLength);
pFullValue = (PKEY_VALUE_FULL_INFORMATION) \
ExAllocatePool(PagedPool, structLength);
RtlInitUnicodeString(&uPath, L"\Registry\Machine\System\“\
L"CurrentControlSet\Services\Class\Dummy”);
RtlInitUnicodeString(&uName, L"Target");
InitializeObjectAttributes(&objAttribs, &uPath, \
OBJ_CASE_INSENSITIVE, NULL, NULL);
lastError = ZwOpenKey(&hFolder, KEY_ALL_ACCESS, &objAttribs);
if(lastError != ERROR_SUCCESS)
{
DbgPrint(“Couldn’t open key: %s. Ending function.\n”, pKeyPath);
return lastError;
}
//Try to verify that the name is what I think it is.
memset(pBasicValue, 0, structLength);
lastError = ZwQueryValueKey(&hFolder, &uName, KeyValueBasicInformation, \
pBasicValue, structLength,
&dataLength);
switch(lastError)
{
case STATUS_INVALID_HANDLE:
//We’re dead in the water here. Should never get here!
DbgPrint(“ZwQueryValueKey(Basic) says the handle is bogus.\n”);
break;
case STATUS_BUFFER_OVERFLOW:
//Since it failed because of insufficient storage, allocate enough.
ExFreePool(pBasicValue);
structLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + dataLength + \
sizeof(UNICODE_NULL);
pBasicValue = (PKEY_VALUE_BASIC_INFORMATION) \
ExAllocatePool(PagedPool, structLength);
lastError = ZwQueryValueKey(&hFolder, &uName, \
KeyValueBasicInformation, pBasicValue, \
structLength, &dataLength);
if(lastError != ERROR_SUCCESS)
{
//Just give it up. Shouldn’t get here, either.
DbgPrint("ZwQueryValueKey(Basic): Still didn’t get it. "\
“Status: %X\n”, lastError);
break;
}
//Fall Through
case ERROR_SUCCESS:
RtlInitUnicodeString(&uResult, pBasicValue->Name);
break;
}
ExFreePool(pBasicValue);
//Try to read the value, using the PKEY_VALUE_PARTIAL_INFORMATION.
memset(pPartialValue, 0, structLength);
lastError = ZwQueryValueKey(&hFolder, &uName, \
KeyValuePartialInformation, pPartialValue, \
structLength, &dataLength);
switch(lastError)
{
case STATUS_INVALID_HANDLE: //Always end up here.
DbgPrint(“ZwQueryValueKey(Partial) says the handle is bogus.\n”);
break;
case STATUS_BUFFER_OVERFLOW:
//Since it failed because of insufficient storage, allocate enough.
ExFreePool(pPartialValue);
structLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + \
dataLength + sizeof(UNICODE_NULL);
pPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)\
ExAllocatePool(PagedPool, structLength);
lastError = ZwQueryValueKey(&hFolder, &uName, \
KeyValuePartialInformation, pPartialValue, \
structLength, &dataLength);
if(lastError != ERROR_SUCCESS)
{
//Just give it up. Shouldn’t get here, either.
DbgPrint(“ZwQueryValueKey(Partial): Still didn’t get it.”\
" Status: %X\n", lastError);
break;
}
//Fall Through
case ERROR_SUCCESS:
RtlInitAnsiString(&aResult, pPartialValue->Data);
break;
}
ExFreePool(pPartialValue);
//Try to read the whole thing, using the PKEY_VALUE_FULL_INFORMATION.
memset(pFullValue, 0, structLength);
lastError = ZwQueryValueKey(&hFolder, &uName, \
KeyValueFullInformation, pFullValue, structLength, \
&dataLength);
switch(lastError)
{
case STATUS_INVALID_HANDLE: //Always end up here.
DbgPrint(“ZwQueryValueKey(Full) says the handle is bogus.\n”);
break;
case STATUS_BUFFER_OVERFLOW:
//Since it failed because of insufficient storage, allocate enough.
ExFreePool(pFullValue);
structLength = sizeof(KEY_VALUE_FULL_INFORMATION) + \
dataLength + sizeof(UNICODE_NULL);
pFullValue = (PKEY_VALUE_FULL_INFORMATION)\
ExAllocatePool(PagedPool, structLength);
lastError = ZwQueryValueKey(&hFolder, &uName, \
KeyValueFullInformation, pFullValue, \
structLength, &dataLength);
if(lastError != ERROR_SUCCESS)
{
//Just give it up. Shouldn’t get here, either.
DbgPrint(“ZwQueryValueKey(Full): Still didn’t get it.”\
" Status: %X\n", lastError);
break;
}
//Fall Through
case ERROR_SUCCESS:
RtlInitUnicodeString(&uResult, pFullValue->Name);
RtlInitUnicodeString(&uResult, (PWCHAR)(pFullValue +
pFullValue->DataOffset));
break;
}
ExFreePool(pFullValue);
return ERROR_SUCCESS;
Thanks,
Phil
* Philip D. Barila | (503) 264-8386
* Intel Corp. | M/S JF2-53 Office JF2-2-G6
* Storage Architecture and Performance
* Internet Systems Lab