1097 lines
26 KiB
C
1097 lines
26 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
dlcreg.c
|
||
|
||
Abstract:
|
||
|
||
This module accesses the registry for DLC.SYS
|
||
|
||
Contents:
|
||
DlcRegistryInitialization
|
||
LoadDlcConfiguration
|
||
LoadAdapterConfiguration
|
||
GetAdapterParameters
|
||
OpenDlcRegistryHandle
|
||
OpenDlcAdapterRegistryHandle
|
||
GetRegistryParameter
|
||
SetRegistryParameter
|
||
DlcpGetParameter
|
||
DlcRegistryTermination
|
||
|
||
Author:
|
||
|
||
Richard L Firth (rfirth) 31-Mar-1993
|
||
|
||
Environment:
|
||
|
||
kernel mode only
|
||
|
||
Revision History:
|
||
|
||
30-Mar-1993 rfirth
|
||
created
|
||
|
||
04-May-1994 rfirth
|
||
Exposed GetAdapterParameters
|
||
|
||
--*/
|
||
|
||
#include <ntddk.h>
|
||
#include <windef.h>
|
||
#include <dlcapi.h>
|
||
#include <dlcio.h>
|
||
#include <ndis.h>
|
||
#include "llcapi.h"
|
||
#include "dlcdef.h"
|
||
#include "dlcreg.h"
|
||
#include "dlctyp.h"
|
||
#include "llcdef.h"
|
||
#include "llcmem.h"
|
||
#include "llctyp.h"
|
||
#include "llcext.h"
|
||
|
||
//
|
||
// manifests
|
||
//
|
||
|
||
#define MAX_ADAPTER_NAME_LENGTH 32 // ?
|
||
#define MAX_INFORMATION_BUFFER_LENGTH 256 // ?
|
||
#define PARAMETERS_STRING L"Parameters"
|
||
|
||
//
|
||
// indicies of parameters within parameter table
|
||
//
|
||
|
||
#define SWAP_INDEX 0
|
||
#define USEDIX_INDEX 1
|
||
#define T1_TICK_ONE_INDEX 2
|
||
#define T2_TICK_ONE_INDEX 3
|
||
#define Ti_TICK_ONE_INDEX 4
|
||
#define T1_TICK_TWO_INDEX 5
|
||
#define T2_TICK_TWO_INDEX 6
|
||
#define Ti_TICK_TWO_INDEX 7
|
||
#define FRAME_SIZE_INDEX 8
|
||
|
||
//
|
||
// typedefs
|
||
//
|
||
|
||
//
|
||
// macros
|
||
//
|
||
|
||
#define CloseDlcRegistryHandle(handle) ZwClose(handle)
|
||
#define CloseAdapterRegistryHandle(handle) ZwClose(handle)
|
||
|
||
//
|
||
// Global data
|
||
//
|
||
|
||
//
|
||
// private data
|
||
//
|
||
|
||
UNICODE_STRING DlcRegistryPath;
|
||
UNICODE_STRING ParametersPath;
|
||
|
||
//
|
||
// AdapterParameterTable - used for loading DLC parameters from registry in
|
||
// data-driven manner. Each adapter that DLC talks to can have a set of all
|
||
// or part of the following variables
|
||
//
|
||
|
||
DLC_REGISTRY_PARAMETER AdapterParameterTable[] = {
|
||
L"Swap",
|
||
(PVOID)DEFAULT_SWAP_ADDRESS_BITS,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_BOOLEAN,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
0,
|
||
0
|
||
},
|
||
|
||
L"UseDixOverEthernet",
|
||
(PVOID)DEFAULT_DIX_FORMAT,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_BOOLEAN,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
0,
|
||
0
|
||
},
|
||
|
||
L"T1TickOne",
|
||
(PVOID)DEFAULT_T1_TICK_ONE,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_UCHAR,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
MIN_TIMER_TICK_VALUE,
|
||
MAX_TIMER_TICK_VALUE
|
||
},
|
||
|
||
L"T2TickOne",
|
||
(PVOID)DEFAULT_T2_TICK_ONE,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_UCHAR,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
MIN_TIMER_TICK_VALUE,
|
||
MAX_TIMER_TICK_VALUE
|
||
},
|
||
|
||
L"TiTickOne",
|
||
(PVOID)DEFAULT_Ti_TICK_ONE,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_UCHAR,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
MIN_TIMER_TICK_VALUE,
|
||
MAX_TIMER_TICK_VALUE
|
||
},
|
||
|
||
L"T1TickTwo",
|
||
(PVOID)DEFAULT_T1_TICK_TWO,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_UCHAR,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
MIN_TIMER_TICK_VALUE,
|
||
MAX_TIMER_TICK_VALUE
|
||
},
|
||
|
||
L"T2TickTwo",
|
||
(PVOID)DEFAULT_T2_TICK_TWO,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_UCHAR,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
MIN_TIMER_TICK_VALUE,
|
||
MAX_TIMER_TICK_VALUE
|
||
},
|
||
|
||
L"TiTickTwo",
|
||
(PVOID)DEFAULT_Ti_TICK_TWO,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_UCHAR,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
MIN_TIMER_TICK_VALUE,
|
||
MAX_TIMER_TICK_VALUE
|
||
},
|
||
|
||
L"UseEthernetFrameSize",
|
||
(PVOID)DEFAULT_USE_ETHERNET_FRAME_SIZE,
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_IS_BOOLEAN,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
0,
|
||
0
|
||
}
|
||
};
|
||
|
||
#ifdef NDIS40
|
||
DLC_REGISTRY_PARAMETER AdapterInitTimeout =
|
||
{
|
||
L"WaitForAdapter",
|
||
(PVOID) 15, // Default is 15 seconds.
|
||
{
|
||
REG_DWORD,
|
||
PARAMETER_AS_SPECIFIED,
|
||
NULL,
|
||
sizeof(ULONG),
|
||
NULL,
|
||
0, // Min acceptable value
|
||
(ULONG) -1 // Allow to set anything.
|
||
}
|
||
};
|
||
#endif // NDIS40
|
||
|
||
#define NUMBER_OF_DLC_PARAMETERS (sizeof(AdapterParameterTable)/sizeof(AdapterParameterTable[0]))
|
||
|
||
//
|
||
// private function prototypes
|
||
//
|
||
|
||
NTSTATUS
|
||
OpenDlcRegistryHandle(
|
||
IN PUNICODE_STRING RegistryPath,
|
||
OUT PHANDLE DlcRegistryHandle
|
||
);
|
||
|
||
NTSTATUS
|
||
OpenDlcAdapterRegistryHandle(
|
||
IN HANDLE DlcRegistryHandle,
|
||
IN PUNICODE_STRING AdapterName,
|
||
OUT PHANDLE DlcAdapterRegistryHandle,
|
||
OUT PBOOLEAN Created
|
||
);
|
||
|
||
NTSTATUS
|
||
GetRegistryParameter(
|
||
IN HANDLE KeyHandle,
|
||
IN PDLC_REGISTRY_PARAMETER Parameter,
|
||
IN BOOLEAN SetOnFail
|
||
);
|
||
|
||
NTSTATUS
|
||
SetRegistryParameter(
|
||
IN HANDLE KeyHandle,
|
||
IN PDLC_REGISTRY_PARAMETER Parameter
|
||
);
|
||
|
||
NTSTATUS
|
||
DlcpGetParameter(
|
||
IN PWSTR ValueName,
|
||
IN ULONG ValueType,
|
||
IN PVOID ValueData,
|
||
IN ULONG ValueLength,
|
||
IN PVOID Context,
|
||
IN PVOID EntryContext
|
||
);
|
||
|
||
//
|
||
// debug display options
|
||
//
|
||
|
||
#if DBG
|
||
BOOLEAN DebugConfig = TRUE;
|
||
#endif
|
||
|
||
|
||
//
|
||
// functions
|
||
//
|
||
|
||
VOID
|
||
DlcRegistryInitialization(
|
||
IN PUNICODE_STRING RegistryPath
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initializes memory structures for functions in this module
|
||
|
||
Arguments:
|
||
|
||
RegistryPath - pointer to UNICODE_STRING giving base of DLC section in
|
||
registry
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
LlcInitUnicodeString(&DlcRegistryPath, RegistryPath);
|
||
RtlInitUnicodeString(&ParametersPath, PARAMETERS_STRING);
|
||
}
|
||
|
||
|
||
VOID
|
||
DlcRegistryTermination(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Undoes anything done in DlcRegistryInitialization
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
LlcFreeUnicodeString(&DlcRegistryPath);
|
||
}
|
||
|
||
|
||
VOID
|
||
LoadDlcConfiguration(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initializes the data structures used to access the registry and loads any
|
||
configuration parameters for the driver
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
//
|
||
// nothing else to do at present since we made all currently known
|
||
// configuration parameters per-adapter
|
||
//
|
||
}
|
||
|
||
|
||
VOID
|
||
LoadAdapterConfiguration(
|
||
IN PUNICODE_STRING AdapterName,
|
||
OUT PADAPTER_CONFIGURATION_INFO ConfigInfo
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Loads all of DLC initialization parameters for an adapter from registry:
|
||
|
||
Swap 0 or 1, default 1
|
||
UseDixOverEthernet 0 or 1, default 0
|
||
T1TickOne 1 - 255, default 5
|
||
T1TickTwo 1 - 255, default 25
|
||
T2TickOne 1 - 255, default 1
|
||
T2TickTwo 1 - 255, default 10
|
||
TiTickOne 1 - 255, default 25
|
||
TiTickTwo 1 - 255, default 125
|
||
UseEthernetFrameSize 0 or 1, default 1
|
||
|
||
If any of the parameters do not exist in the DLC\Parameters\<AdapterName>
|
||
section, then they are created
|
||
|
||
Arguments:
|
||
|
||
AdapterName - pointer to UNICODE_STRING structure giving the name of the
|
||
adapter we are opening. This is the value of a key in the
|
||
DLC\Parameters section.
|
||
The string is EXPECTED to be of the form \Device\<adapter>
|
||
ConfigInfo - pointer to the structure that receives the values on output
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
UINT i;
|
||
PDLC_REGISTRY_PARAMETER parameterTable;
|
||
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
//
|
||
// fill in the adapter configuration structure with default values. These
|
||
// will be used to update the registry if the value entry doesn't currently
|
||
// exist
|
||
//
|
||
|
||
ConfigInfo->SwapAddressBits = (BOOLEAN)DEFAULT_SWAP_ADDRESS_BITS;
|
||
ConfigInfo->UseDix = (BOOLEAN)DEFAULT_DIX_FORMAT;
|
||
ConfigInfo->TimerTicks.T1TickOne = (UCHAR)DEFAULT_T1_TICK_ONE;
|
||
ConfigInfo->TimerTicks.T2TickOne = (UCHAR)DEFAULT_T2_TICK_ONE;
|
||
ConfigInfo->TimerTicks.TiTickOne = (UCHAR)DEFAULT_Ti_TICK_ONE;
|
||
ConfigInfo->TimerTicks.T1TickTwo = (UCHAR)DEFAULT_T1_TICK_TWO;
|
||
ConfigInfo->TimerTicks.T2TickTwo = (UCHAR)DEFAULT_T2_TICK_TWO;
|
||
ConfigInfo->TimerTicks.TiTickTwo = (UCHAR)DEFAULT_Ti_TICK_TWO;
|
||
ConfigInfo->UseEthernetFrameSize = (BOOLEAN)DEFAULT_USE_ETHERNET_FRAME_SIZE;
|
||
|
||
//
|
||
// create and initialize a copy of the DLC adapter parameters template
|
||
//
|
||
|
||
parameterTable = (PDLC_REGISTRY_PARAMETER)ALLOCATE_MEMORY_DRIVER(
|
||
sizeof(*parameterTable) * NUMBER_OF_DLC_PARAMETERS);
|
||
if (parameterTable) {
|
||
RtlCopyMemory(parameterTable, AdapterParameterTable, sizeof(AdapterParameterTable));
|
||
for (i = 0; i < NUMBER_OF_DLC_PARAMETERS; ++i) {
|
||
parameterTable[i].Descriptor.Value = (PVOID)¶meterTable[i].DefaultValue;
|
||
switch (i) {
|
||
case SWAP_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->SwapAddressBits;
|
||
break;
|
||
|
||
case USEDIX_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->UseDix;
|
||
break;
|
||
|
||
case T1_TICK_ONE_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->TimerTicks.T1TickOne;
|
||
break;
|
||
|
||
case T2_TICK_ONE_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->TimerTicks.T2TickOne;
|
||
break;
|
||
|
||
case Ti_TICK_ONE_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->TimerTicks.TiTickOne;
|
||
break;
|
||
|
||
case T1_TICK_TWO_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->TimerTicks.T1TickTwo;
|
||
break;
|
||
|
||
case T2_TICK_TWO_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->TimerTicks.T2TickTwo;
|
||
break;
|
||
|
||
case Ti_TICK_TWO_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->TimerTicks.TiTickTwo;
|
||
break;
|
||
|
||
case FRAME_SIZE_INDEX:
|
||
parameterTable[i].Descriptor.Variable = &ConfigInfo->UseEthernetFrameSize;
|
||
break;
|
||
|
||
}
|
||
}
|
||
GetAdapterParameters(AdapterName, parameterTable, NUMBER_OF_DLC_PARAMETERS, FALSE);
|
||
FREE_MEMORY_DRIVER(parameterTable);
|
||
}
|
||
|
||
#if DBG
|
||
if (DebugConfig) {
|
||
DbgPrint("DLC.LoadAdapterConfigurationFromRegistry for adapter %ws:\n"
|
||
"\tSwap . . . . . . . . . : %d\n"
|
||
"\tUseDixOverEthernet . . : %d\n"
|
||
"\tT1TickOne. . . . . . . : %d\n"
|
||
"\tT2TickOne. . . . . . . : %d\n"
|
||
"\tTiTickOne. . . . . . . : %d\n"
|
||
"\tT1TickTwo. . . . . . . : %d\n"
|
||
"\tT2TickTwo. . . . . . . : %d\n"
|
||
"\tTiTickTwo. . . . . . . : %d\n"
|
||
"\tUseEthernetFrameSize . : %d\n",
|
||
AdapterName->Buffer,
|
||
ConfigInfo->SwapAddressBits,
|
||
ConfigInfo->UseDix,
|
||
ConfigInfo->TimerTicks.T1TickOne,
|
||
ConfigInfo->TimerTicks.T2TickOne,
|
||
ConfigInfo->TimerTicks.TiTickOne,
|
||
ConfigInfo->TimerTicks.T1TickTwo,
|
||
ConfigInfo->TimerTicks.T2TickTwo,
|
||
ConfigInfo->TimerTicks.TiTickTwo,
|
||
ConfigInfo->UseEthernetFrameSize
|
||
);
|
||
}
|
||
#endif
|
||
|
||
}
|
||
|
||
#ifdef NDIS40
|
||
|
||
NTSTATUS
|
||
GetAdapterWaitTimeout(
|
||
PULONG pulWait)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Some adapters are delayed during initialization and are not completed
|
||
even after the PnPBindsComplete event (such as ATM LANE adapter).
|
||
This timeout value 'WaitForAdapter' indicates how many seconds to wait for
|
||
an adapter if is not already present/bound in LlcOpenAdapter
|
||
|
||
Arguments:
|
||
|
||
pulWait -- Pointer to variable to store the wait timeout.
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS
|
||
STATUS_INSUFFICIENT_RESOURCES
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS NtStatus;
|
||
HANDLE hDlc;
|
||
HANDLE hDlcParms;
|
||
OBJECT_ATTRIBUTES ObjAttribs;
|
||
ULONG ulDisp;
|
||
|
||
NtStatus = OpenDlcRegistryHandle(&DlcRegistryPath, &hDlc);
|
||
|
||
if (NT_SUCCESS(NtStatus))
|
||
{
|
||
InitializeObjectAttributes(
|
||
&ObjAttribs,
|
||
&ParametersPath,
|
||
OBJ_CASE_INSENSITIVE,
|
||
hDlc,
|
||
NULL);
|
||
|
||
NtStatus = ZwCreateKey(
|
||
&hDlcParms,
|
||
KEY_READ,
|
||
&ObjAttribs,
|
||
0,
|
||
NULL,
|
||
0,
|
||
&ulDisp);
|
||
|
||
if (NT_SUCCESS(NtStatus))
|
||
{
|
||
PDLC_REGISTRY_PARAMETER pWaitTimeout;
|
||
|
||
pWaitTimeout = (PDLC_REGISTRY_PARAMETER) ALLOCATE_MEMORY_DRIVER(
|
||
sizeof(DLC_REGISTRY_PARAMETER));
|
||
|
||
if (pWaitTimeout)
|
||
{
|
||
RtlCopyMemory(
|
||
pWaitTimeout,
|
||
&AdapterInitTimeout,
|
||
sizeof(AdapterInitTimeout));
|
||
|
||
pWaitTimeout->Descriptor.Variable = pulWait;
|
||
pWaitTimeout->Descriptor.Value = (PVOID)&pWaitTimeout->DefaultValue;
|
||
|
||
NtStatus = GetRegistryParameter(
|
||
hDlcParms,
|
||
pWaitTimeout,
|
||
FALSE); // Don't set on fail.
|
||
|
||
FREE_MEMORY_DRIVER(pWaitTimeout);
|
||
}
|
||
else
|
||
{
|
||
NtStatus = STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
ZwClose(hDlcParms);
|
||
}
|
||
|
||
CloseDlcRegistryHandle(hDlc);
|
||
}
|
||
|
||
return (NtStatus);
|
||
}
|
||
#endif // NDIS40
|
||
|
||
|
||
NTSTATUS
|
||
GetAdapterParameters(
|
||
IN PUNICODE_STRING AdapterName,
|
||
IN PDLC_REGISTRY_PARAMETER Parameters,
|
||
IN ULONG NumberOfParameters,
|
||
IN BOOLEAN SetOnFail
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Retrieves a list of parameters from the DLC\Parameters\<AdapterName> section
|
||
in the registry
|
||
|
||
Arguments:
|
||
|
||
AdapterName - pointer to UNICODE_STRING identifying adapter section
|
||
in DLC section of registry to open
|
||
Parameters - pointer to array of DLC_REGISTRY_PARAMETER structures
|
||
describing variables and default values to retrieve
|
||
NumberOfParameters - number of structures in Parameters array
|
||
SetOnFail - TRUE if we should set the registry parameter if we
|
||
fail to get it
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
Success - STATUS_SUCCESS
|
||
Failure -
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS status;
|
||
HANDLE dlcHandle;
|
||
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
status = OpenDlcRegistryHandle(&DlcRegistryPath, &dlcHandle);
|
||
if (NT_SUCCESS(status)) {
|
||
|
||
HANDLE adapterHandle;
|
||
BOOLEAN created;
|
||
|
||
status = OpenDlcAdapterRegistryHandle(dlcHandle,
|
||
AdapterName,
|
||
&adapterHandle,
|
||
&created
|
||
);
|
||
if (NT_SUCCESS(status)) {
|
||
while (NumberOfParameters--) {
|
||
|
||
//
|
||
// if this adapter section was created then create the parameter
|
||
// value entries and set them to the defaults, else retrieve the
|
||
// current registry values
|
||
//
|
||
|
||
if (created) {
|
||
SetRegistryParameter(adapterHandle, Parameters);
|
||
} else {
|
||
GetRegistryParameter(adapterHandle, Parameters, SetOnFail);
|
||
}
|
||
++Parameters;
|
||
}
|
||
CloseAdapterRegistryHandle(adapterHandle);
|
||
}
|
||
CloseDlcRegistryHandle(dlcHandle);
|
||
}
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
OpenDlcRegistryHandle(
|
||
IN PUNICODE_STRING RegistryPath,
|
||
OUT PHANDLE DlcRegistryHandle
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Opens a handle to the DLC section in the registry
|
||
|
||
Arguments:
|
||
|
||
RegistryPath - pointer to UNICODE_STRING giving full registry path to
|
||
DLC section
|
||
DlcRegistryHandle - returned handle
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
Success - STATUS_SUCCESS
|
||
Failure -
|
||
|
||
--*/
|
||
|
||
{
|
||
OBJECT_ATTRIBUTES objectAttributes;
|
||
NTSTATUS status;
|
||
ULONG disposition;
|
||
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
InitializeObjectAttributes(&objectAttributes,
|
||
RegistryPath,
|
||
OBJ_CASE_INSENSITIVE,
|
||
NULL,
|
||
NULL
|
||
);
|
||
status = ZwCreateKey(DlcRegistryHandle,
|
||
KEY_WRITE, // might want to update something in registry
|
||
&objectAttributes,
|
||
0, // title index
|
||
NULL, // class
|
||
0, // create options
|
||
&disposition
|
||
);
|
||
|
||
#if DBG
|
||
if (DebugConfig) {
|
||
if (!NT_SUCCESS(status)) {
|
||
DbgPrint("DLC.OpenDlcRegistryHandle: Error: %08x\n", status);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
OpenDlcAdapterRegistryHandle(
|
||
IN HANDLE DlcRegistryHandle,
|
||
IN PUNICODE_STRING AdapterName,
|
||
OUT PHANDLE DlcAdapterRegistryHandle,
|
||
OUT PBOOLEAN Created
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Opens a handle to the DLC\Parameters\<AdapterName> section in the registry.
|
||
If this node does not exist, it is created
|
||
|
||
Arguments:
|
||
|
||
DlcRegistryHandle - open handle to DLC section in registry
|
||
AdapterName - name of adapter in Parameters section. This
|
||
MUST be of the form \Device\<adapter_name>
|
||
DlcAdapterRegistryHandle - returned open handle
|
||
Created - returned TRUE if the handle was created
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
Success - STATUS_SUCCESS
|
||
Failure -
|
||
|
||
--*/
|
||
|
||
{
|
||
UNICODE_STRING keyName;
|
||
UNICODE_STRING adapterName;
|
||
WCHAR keyBuffer[sizeof(PARAMETERS_STRING) + MAX_ADAPTER_NAME_LENGTH];
|
||
OBJECT_ATTRIBUTES objectAttributes;
|
||
NTSTATUS status;
|
||
ULONG disposition;
|
||
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
keyName.Buffer = keyBuffer;
|
||
keyName.Length = 0;
|
||
keyName.MaximumLength = sizeof(keyBuffer);
|
||
RtlCopyUnicodeString(&keyName, &ParametersPath);
|
||
|
||
RtlInitUnicodeString(&adapterName, AdapterName->Buffer);
|
||
adapterName.Buffer += sizeof(L"\\Device") / sizeof(L"") - 1;
|
||
adapterName.Length -= sizeof(L"\\Device") - sizeof(L"");
|
||
adapterName.MaximumLength -= sizeof(L"\\Device") - sizeof(L"");
|
||
RtlAppendUnicodeStringToString(&keyName, &adapterName);
|
||
|
||
InitializeObjectAttributes(&objectAttributes,
|
||
&keyName,
|
||
OBJ_CASE_INSENSITIVE,
|
||
DlcRegistryHandle,
|
||
NULL
|
||
);
|
||
|
||
//
|
||
// if the DLC\Parameters\<adapter_name> key does not exist, then we will
|
||
// create it
|
||
//
|
||
|
||
status = ZwCreateKey(DlcAdapterRegistryHandle,
|
||
KEY_WRITE,
|
||
&objectAttributes,
|
||
0,
|
||
NULL,
|
||
0,
|
||
&disposition
|
||
);
|
||
*Created = (disposition == REG_CREATED_NEW_KEY);
|
||
|
||
#if DBG
|
||
if (DebugConfig) {
|
||
if (!NT_SUCCESS(status)) {
|
||
DbgPrint("DLC.OpenDlcAdapterRegistryHandle: Error: %08x\n", status);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
GetRegistryParameter(
|
||
IN HANDLE KeyHandle,
|
||
IN PDLC_REGISTRY_PARAMETER Parameter,
|
||
IN BOOLEAN SetOnFail
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Retrieves a parameter from a section of the registry. If the section cannot
|
||
be accessed or returns invalid data, then we get the default value from the
|
||
Parameter structure
|
||
|
||
Arguments:
|
||
|
||
KeyHandle - open handle to the required section in the registry
|
||
Parameter - pointer to DLC_REGISTRY_PARAMETER structure giving address and
|
||
type of the parameter to be retrieved, etc.
|
||
SetOnFail - if we fail to get the value from the registry, we try to set
|
||
the default value in the registry
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
Success - STATUS_SUCCESS
|
||
Failure -
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS status;
|
||
UNICODE_STRING parameterName;
|
||
UCHAR informationBuffer[MAX_INFORMATION_BUFFER_LENGTH];
|
||
PKEY_VALUE_FULL_INFORMATION valueInformation = (PKEY_VALUE_FULL_INFORMATION)informationBuffer;
|
||
ULONG informationLength;
|
||
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
RtlInitUnicodeString(¶meterName, Parameter->ParameterName);
|
||
status = ZwQueryValueKey(KeyHandle,
|
||
¶meterName,
|
||
KeyValueFullInformation,
|
||
(PVOID)valueInformation,
|
||
sizeof(informationBuffer),
|
||
&informationLength
|
||
);
|
||
if (NT_SUCCESS(status) && valueInformation->DataLength) {
|
||
|
||
//
|
||
// use the value retrieved from the registry
|
||
//
|
||
|
||
status = DlcpGetParameter(Parameter->ParameterName,
|
||
valueInformation->Type,
|
||
(PVOID)&informationBuffer[valueInformation->DataOffset],
|
||
valueInformation->DataLength,
|
||
NULL,
|
||
(PVOID)&Parameter->Descriptor
|
||
);
|
||
} else {
|
||
|
||
#if DBG
|
||
|
||
if (DebugConfig) {
|
||
if (!NT_SUCCESS(status)) {
|
||
DbgPrint("DLC.GetRegistryParameter: Error: %08x\n", status);
|
||
} else {
|
||
DbgPrint("DLC.GetRegistryParameter: Error: valueInformation->DataLength is 0\n");
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
if (!NT_SUCCESS(status) && SetOnFail) {
|
||
SetRegistryParameter(KeyHandle, Parameter);
|
||
}
|
||
|
||
//
|
||
// set the default value
|
||
//
|
||
|
||
status = DlcpGetParameter(Parameter->ParameterName,
|
||
Parameter->Descriptor.Type,
|
||
Parameter->Descriptor.Value,
|
||
Parameter->Descriptor.Length,
|
||
NULL,
|
||
(PVOID)&Parameter->Descriptor
|
||
);
|
||
}
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SetRegistryParameter(
|
||
IN HANDLE KeyHandle,
|
||
IN PDLC_REGISTRY_PARAMETER Parameter
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Sets a parameter in the DLC\Parameters\<AdapterName> section
|
||
|
||
Arguments:
|
||
|
||
KeyHandle - open handle to required section in registry
|
||
Parameter - pointer to DLC_REGISTRY_PARAMETER containing all required
|
||
parameter information
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
Success - STATUS_SUCCESS
|
||
Failure -
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS status;
|
||
UNICODE_STRING name;
|
||
|
||
ASSUME_IRQL(PASSIVE_LEVEL);
|
||
|
||
RtlInitUnicodeString(&name, Parameter->ParameterName);
|
||
status = ZwSetValueKey(KeyHandle,
|
||
&name,
|
||
0, // TitleIndex
|
||
Parameter->Descriptor.Type,
|
||
Parameter->Descriptor.Value,
|
||
Parameter->Descriptor.Length
|
||
);
|
||
|
||
#if DBG
|
||
|
||
if (DebugConfig) {
|
||
if (!NT_SUCCESS(status)) {
|
||
DbgPrint("DLC.SetRegistryParameter: Error: %08x\n", status);
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
DlcpGetParameter(
|
||
IN PWSTR ValueName,
|
||
IN ULONG ValueType,
|
||
IN PVOID ValueData,
|
||
IN ULONG ValueLength,
|
||
IN PVOID Context,
|
||
IN PVOID EntryContext
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Call-back function which copies the data retrieved from the registry to
|
||
a variable
|
||
|
||
Arguments:
|
||
|
||
ValueName - pointer to name of parameter being set (ignored)
|
||
ValueType - type of parameter being set
|
||
ValueData - pointer to data retrieved from registry
|
||
ValueLength - length of data retrieved
|
||
Context - ignored
|
||
EntryContext - pointer to REGISTRY_PARAMETER_DESCRIPTOR structure
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
Success - STATUS_SUCCESS
|
||
Failure -
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
#define Descriptor ((PREGISTRY_PARAMETER_DESCRIPTOR)EntryContext)
|
||
|
||
//
|
||
// if we have a registry entry for the parameter, but it is a different
|
||
// type from that expected (say REG_SZ instead of REG_DWORD) then we use
|
||
// the default type, length and value
|
||
//
|
||
|
||
if (ValueType != Descriptor->Type) {
|
||
|
||
#if DBG
|
||
DbgPrint("DLC.DlcpGetParameter: Error: type for %ws is %d, expected %d, using default\n",
|
||
ValueName,
|
||
ValueType,
|
||
Descriptor->Type
|
||
);
|
||
#endif
|
||
|
||
ValueType = Descriptor->Type;
|
||
ValueData = Descriptor->Value;
|
||
ValueLength = Descriptor->Length;
|
||
}
|
||
|
||
switch (ValueType) {
|
||
case REG_DWORD: {
|
||
|
||
ULONG value;
|
||
|
||
if (Descriptor->RealType == PARAMETER_IS_BOOLEAN) {
|
||
value = (*(PULONG)ValueData != 0);
|
||
*(PBOOLEAN)(Descriptor->Variable) = (BOOLEAN)value;
|
||
|
||
//
|
||
// no limit check for BOOLEAN type
|
||
//
|
||
|
||
break;
|
||
} else {
|
||
value = *(PULONG)ValueData;
|
||
}
|
||
|
||
//
|
||
// check range. If outside range, use default. Comparison is ULONG
|
||
//
|
||
|
||
if (value < Descriptor->LowerLimit || value > Descriptor->UpperLimit) {
|
||
|
||
#if DBG
|
||
DbgPrint("DLC.DlcpGetParameter: Error: Parameter %ws = %d: Out of range (%d..%d). Using default = %d\n",
|
||
ValueName,
|
||
value,
|
||
Descriptor->LowerLimit,
|
||
Descriptor->UpperLimit,
|
||
*(PULONG)(Descriptor->Value)
|
||
);
|
||
#endif
|
||
|
||
value = *(PULONG)(Descriptor->Value);
|
||
}
|
||
if (Descriptor->RealType == PARAMETER_IS_UCHAR) {
|
||
*(PUCHAR)(Descriptor->Variable) = (UCHAR)value;
|
||
} else {
|
||
*(PULONG)(Descriptor->Variable) = value;
|
||
}
|
||
break;
|
||
}
|
||
|
||
#if DBG
|
||
default:
|
||
DbgPrint("DLC.DlcpGetParameter: Error: didn't expect ValueType %d\n", ValueType);
|
||
#endif
|
||
|
||
}
|
||
return STATUS_SUCCESS;
|
||
|
||
#undef pDescriptor
|
||
|
||
}
|