404 lines
11 KiB
C
404 lines
11 KiB
C
/*++
|
||
|
||
Copyright (c) 1991, 1992, 1993 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
registry.c
|
||
|
||
Abstract:
|
||
|
||
This module contains the code that is used to get values from the
|
||
registry and to manipulate entries in the registry.
|
||
|
||
Author:
|
||
|
||
Anthony V. Ercolano 26-Sep-1991
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History :
|
||
|
||
--*/
|
||
|
||
#include "precomp.h"
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(INIT,SerialGetConfigDefaults)
|
||
|
||
#pragma alloc_text(PAGESRP0,SerialGetRegistryKeyValue)
|
||
#pragma alloc_text(PAGESRP0,SerialPutRegistryKeyValue)
|
||
#endif // ALLOC_PRAGMA
|
||
|
||
|
||
NTSTATUS
|
||
SerialGetConfigDefaults(
|
||
IN PSERIAL_FIRMWARE_DATA DriverDefaultsPtr,
|
||
IN PUNICODE_STRING RegistryPath
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine reads the default configuration data from the
|
||
registry for the serial driver.
|
||
|
||
It also builds fields in the registry for several configuration
|
||
options if they don't exist.
|
||
|
||
Arguments:
|
||
|
||
DriverDefaultsPtr - Pointer to a structure that will contain
|
||
the default configuration values.
|
||
|
||
RegistryPath - points to the entry for this driver in the
|
||
current control set of the registry.
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS if we got the defaults, otherwise we failed.
|
||
The only way to fail this call is if the STATUS_INSUFFICIENT_RESOURCES.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
NTSTATUS Status = STATUS_SUCCESS; // return value
|
||
|
||
//
|
||
// We use this to query into the registry for defaults
|
||
//
|
||
|
||
RTL_QUERY_REGISTRY_TABLE paramTable[8];
|
||
|
||
PWCHAR path;
|
||
ULONG zero = 0;
|
||
ULONG DbgDefault = 0;//SER_DBG_DEFAULT;
|
||
ULONG notThereDefault = SERIAL_UNINITIALIZED_DEFAULT;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Since the registry path parameter is a "counted" UNICODE string, it
|
||
// might not be zero terminated. For a very short time allocate memory
|
||
// to hold the registry path zero terminated so that we can use it to
|
||
// delve into the registry.
|
||
//
|
||
// NOTE NOTE!!!! This is not an architected way of breaking into
|
||
// a driver. It happens to work for this driver because the author
|
||
// likes to do things this way.
|
||
//
|
||
|
||
path = ExAllocatePool (PagedPool, RegistryPath->Length+sizeof(WCHAR));
|
||
|
||
if (!path) {
|
||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||
return (Status);
|
||
}
|
||
|
||
RtlZeroMemory (DriverDefaultsPtr, sizeof(SERIAL_FIRMWARE_DATA));
|
||
RtlZeroMemory (¶mTable[0], sizeof(paramTable));
|
||
RtlZeroMemory (path, RegistryPath->Length+sizeof(WCHAR));
|
||
RtlMoveMemory (path, RegistryPath->Buffer, RegistryPath->Length);
|
||
|
||
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[0].Name = L"BreakOnEntry";
|
||
paramTable[0].EntryContext = &DriverDefaultsPtr->ShouldBreakOnEntry;
|
||
paramTable[0].DefaultType = REG_DWORD;
|
||
paramTable[0].DefaultData = &zero;
|
||
paramTable[0].DefaultLength = sizeof(ULONG);
|
||
|
||
paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[1].Name = L"DebugLevel";
|
||
paramTable[1].EntryContext = &DriverDefaultsPtr->DebugLevel;
|
||
paramTable[1].DefaultType = REG_DWORD;
|
||
paramTable[1].DefaultData = &DbgDefault;
|
||
paramTable[1].DefaultLength = sizeof(ULONG);
|
||
|
||
paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[2].Name = L"ForceFifoEnable";
|
||
paramTable[2].EntryContext = &DriverDefaultsPtr->ForceFifoEnableDefault;
|
||
paramTable[2].DefaultType = REG_DWORD;
|
||
paramTable[2].DefaultData = ¬ThereDefault;
|
||
paramTable[2].DefaultLength = sizeof(ULONG);
|
||
|
||
paramTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[3].Name = L"RxFIFO";
|
||
paramTable[3].EntryContext = &DriverDefaultsPtr->RxFIFODefault;
|
||
paramTable[3].DefaultType = REG_DWORD;
|
||
paramTable[3].DefaultData = ¬ThereDefault;
|
||
paramTable[3].DefaultLength = sizeof(ULONG);
|
||
|
||
paramTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[4].Name = L"TxFIFO";
|
||
paramTable[4].EntryContext = &DriverDefaultsPtr->TxFIFODefault;
|
||
paramTable[4].DefaultType = REG_DWORD;
|
||
paramTable[4].DefaultData = ¬ThereDefault;
|
||
paramTable[4].DefaultLength = sizeof(ULONG);
|
||
|
||
paramTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[5].Name = L"PermitShare";
|
||
paramTable[5].EntryContext = &DriverDefaultsPtr->PermitShareDefault;
|
||
paramTable[5].DefaultType = REG_DWORD;
|
||
paramTable[5].DefaultData = ¬ThereDefault;
|
||
paramTable[5].DefaultLength = sizeof(ULONG);
|
||
|
||
paramTable[6].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||
paramTable[6].Name = L"LogFifo";
|
||
paramTable[6].EntryContext = &DriverDefaultsPtr->LogFifoDefault;
|
||
paramTable[6].DefaultType = REG_DWORD;
|
||
paramTable[6].DefaultData = ¬ThereDefault;
|
||
paramTable[6].DefaultLength = sizeof(ULONG);
|
||
|
||
Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
|
||
path,
|
||
¶mTable[0],
|
||
NULL,
|
||
NULL);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
DriverDefaultsPtr->ShouldBreakOnEntry = 0;
|
||
DriverDefaultsPtr->DebugLevel = 0;
|
||
}
|
||
|
||
//
|
||
// Check to see if there was a forcefifo or an rxfifo size.
|
||
// If there isn't then write out values so that they could
|
||
// be adjusted later.
|
||
//
|
||
|
||
if (DriverDefaultsPtr->ForceFifoEnableDefault == notThereDefault) {
|
||
|
||
DriverDefaultsPtr->ForceFifoEnableDefault = SERIAL_FORCE_FIFO_DEFAULT;
|
||
RtlWriteRegistryValue(
|
||
RTL_REGISTRY_ABSOLUTE,
|
||
path,
|
||
L"ForceFifoEnable",
|
||
REG_DWORD,
|
||
&DriverDefaultsPtr->ForceFifoEnableDefault,
|
||
sizeof(ULONG)
|
||
);
|
||
|
||
}
|
||
|
||
if (DriverDefaultsPtr->RxFIFODefault == notThereDefault) {
|
||
DriverDefaultsPtr->RxFIFODefault = SERIAL_RX_FIFO_DEFAULT;
|
||
RtlWriteRegistryValue(
|
||
RTL_REGISTRY_ABSOLUTE,
|
||
path,
|
||
L"RxFIFO",
|
||
REG_DWORD,
|
||
&DriverDefaultsPtr->RxFIFODefault,
|
||
sizeof(ULONG)
|
||
);
|
||
}
|
||
|
||
if (DriverDefaultsPtr->TxFIFODefault == notThereDefault) {
|
||
|
||
DriverDefaultsPtr->TxFIFODefault = SERIAL_TX_FIFO_DEFAULT;
|
||
RtlWriteRegistryValue(
|
||
RTL_REGISTRY_ABSOLUTE,
|
||
path,
|
||
L"TxFIFO",
|
||
REG_DWORD,
|
||
&DriverDefaultsPtr->TxFIFODefault,
|
||
sizeof(ULONG)
|
||
);
|
||
}
|
||
|
||
|
||
if (DriverDefaultsPtr->PermitShareDefault == notThereDefault) {
|
||
|
||
DriverDefaultsPtr->PermitShareDefault = SERIAL_PERMIT_SHARE_DEFAULT;
|
||
//
|
||
// Only share if the user actual changes switch.
|
||
//
|
||
|
||
RtlWriteRegistryValue(
|
||
RTL_REGISTRY_ABSOLUTE,
|
||
path,
|
||
L"PermitShare",
|
||
REG_DWORD,
|
||
&DriverDefaultsPtr->PermitShareDefault,
|
||
sizeof(ULONG)
|
||
);
|
||
|
||
}
|
||
|
||
|
||
if (DriverDefaultsPtr->LogFifoDefault == notThereDefault) {
|
||
|
||
//
|
||
// Wasn't there. After this load don't log
|
||
// the message anymore. However this first
|
||
// time log the message.
|
||
//
|
||
|
||
DriverDefaultsPtr->LogFifoDefault = SERIAL_LOG_FIFO_DEFAULT;
|
||
|
||
RtlWriteRegistryValue(
|
||
RTL_REGISTRY_ABSOLUTE,
|
||
path,
|
||
L"LogFifo",
|
||
REG_DWORD,
|
||
&DriverDefaultsPtr->LogFifoDefault,
|
||
sizeof(ULONG)
|
||
);
|
||
|
||
DriverDefaultsPtr->LogFifoDefault = 1;
|
||
|
||
}
|
||
|
||
//
|
||
// We don't need that path anymore.
|
||
//
|
||
|
||
if (path) {
|
||
ExFreePool(path);
|
||
}
|
||
|
||
//
|
||
// Set the defaults for other values
|
||
//
|
||
DriverDefaultsPtr->PermitSystemWideShare = FALSE;
|
||
|
||
return (Status);
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SerialGetRegistryKeyValue (
|
||
IN HANDLE Handle,
|
||
IN PWCHAR KeyNameString,
|
||
IN ULONG KeyNameStringLength,
|
||
IN PVOID Data,
|
||
IN ULONG DataLength
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Reads a registry key value from an already opened registry key.
|
||
|
||
Arguments:
|
||
|
||
Handle Handle to the opened registry key
|
||
|
||
KeyNameString ANSI string to the desired key
|
||
|
||
KeyNameStringLength Length of the KeyNameString
|
||
|
||
Data Buffer to place the key value in
|
||
|
||
DataLength Length of the data buffer
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS if all works, otherwise status of system call that
|
||
went wrong.
|
||
|
||
--*/
|
||
{
|
||
UNICODE_STRING keyName;
|
||
ULONG length;
|
||
PKEY_VALUE_FULL_INFORMATION fullInfo;
|
||
|
||
NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
|
||
|
||
PAGED_CODE();
|
||
|
||
SerialDump(SERTRACECALLS, ("SERIAL: Enter SerialGetRegistryKeyValue\n"));
|
||
|
||
|
||
RtlInitUnicodeString (&keyName, KeyNameString);
|
||
|
||
length = sizeof(KEY_VALUE_FULL_INFORMATION) + KeyNameStringLength
|
||
+ DataLength;
|
||
fullInfo = ExAllocatePool(PagedPool, length);
|
||
|
||
if (fullInfo) {
|
||
ntStatus = ZwQueryValueKey (Handle,
|
||
&keyName,
|
||
KeyValueFullInformation,
|
||
fullInfo,
|
||
length,
|
||
&length);
|
||
|
||
if (NT_SUCCESS(ntStatus)) {
|
||
//
|
||
// If there is enough room in the data buffer, copy the output
|
||
//
|
||
|
||
if (DataLength >= fullInfo->DataLength) {
|
||
RtlCopyMemory (Data,
|
||
((PUCHAR) fullInfo) + fullInfo->DataOffset,
|
||
fullInfo->DataLength);
|
||
}
|
||
}
|
||
|
||
ExFreePool(fullInfo);
|
||
}
|
||
|
||
return ntStatus;
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
SerialPutRegistryKeyValue(IN HANDLE Handle, IN PWCHAR PKeyNameString,
|
||
IN ULONG KeyNameStringLength, IN ULONG Dtype,
|
||
IN PVOID PData, IN ULONG DataLength)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Writes a registry key value to an already opened registry key.
|
||
|
||
Arguments:
|
||
|
||
Handle Handle to the opened registry key
|
||
|
||
PKeyNameString ANSI string to the desired key
|
||
|
||
KeyNameStringLength Length of the KeyNameString
|
||
|
||
Dtype REG_XYZ value type
|
||
|
||
PData Buffer to place the key value in
|
||
|
||
DataLength Length of the data buffer
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS if all works, otherwise status of system call that
|
||
went wrong.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS status;
|
||
UNICODE_STRING keyname;
|
||
|
||
PAGED_CODE();
|
||
|
||
SerialDump(SERTRACECALLS,("SERIAL: Enter SerialPutRegistryKeyValue\n"));
|
||
|
||
RtlInitUnicodeString(&keyname, NULL);
|
||
keyname.MaximumLength = (USHORT)(KeyNameStringLength + sizeof(WCHAR));
|
||
keyname.Buffer = ExAllocatePool(PagedPool, keyname.MaximumLength);
|
||
|
||
if (keyname.Buffer == NULL) {
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
RtlAppendUnicodeToString(&keyname, PKeyNameString);
|
||
|
||
status = ZwSetValueKey(Handle, &keyname, 0, Dtype, PData, DataLength);
|
||
|
||
ExFreePool(keyname.Buffer);
|
||
|
||
return status;
|
||
}
|