674 lines
16 KiB
C
674 lines
16 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989-1993 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
config.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This contains all routines necessary for the support of the dynamic
|
|||
|
configuration of the ISN Netbios module.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Adam Barr (adamba) 16-November-1993
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "precomp.h"
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Local functions used to access the registry.
|
|||
|
//
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiGetConfigValue(
|
|||
|
IN PWSTR ValueName,
|
|||
|
IN ULONG ValueType,
|
|||
|
IN PVOID ValueData,
|
|||
|
IN ULONG ValueLength,
|
|||
|
IN PVOID Context,
|
|||
|
IN PVOID EntryContext
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiAddBind(
|
|||
|
IN PWSTR ValueName,
|
|||
|
IN ULONG ValueType,
|
|||
|
IN PVOID ValueData,
|
|||
|
IN ULONG ValueLength,
|
|||
|
IN PVOID Context,
|
|||
|
IN PVOID EntryContext
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiAddExport(
|
|||
|
IN PWSTR ValueName,
|
|||
|
IN ULONG ValueType,
|
|||
|
IN PVOID ValueData,
|
|||
|
IN ULONG ValueLength,
|
|||
|
IN PVOID Context,
|
|||
|
IN PVOID EntryContext
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiReadLinkageInformation(
|
|||
|
IN PCONFIG Config
|
|||
|
);
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(PAGE,NbiGetConfiguration)
|
|||
|
#pragma alloc_text(PAGE,NbiFreeConfiguration)
|
|||
|
#pragma alloc_text(PAGE,NbiGetConfigValue)
|
|||
|
#pragma alloc_text(PAGE,NbiAddBind)
|
|||
|
#pragma alloc_text(PAGE,NbiAddExport)
|
|||
|
#pragma alloc_text(PAGE,NbiReadLinkageInformation)
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiGetConfiguration (
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN PUNICODE_STRING RegistryPath,
|
|||
|
OUT PCONFIG * ConfigPtr
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called by Netbios to get information from the configuration
|
|||
|
management routines. We read the registry, starting at RegistryPath,
|
|||
|
to get the parameters. If they don't exist, we use the defaults
|
|||
|
set in ipxcnfg.h file. A list of adapters to bind to is chained
|
|||
|
on to the config information.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DriverObject - Used for logging errors.
|
|||
|
|
|||
|
RegistryPath - The name of Netbios' node in the registry.
|
|||
|
|
|||
|
ConfigPtr - Returns the configuration information.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Status - STATUS_SUCCESS if everything OK, STATUS_INSUFFICIENT_RESOURCES
|
|||
|
otherwise.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCONFIG Config;
|
|||
|
RTL_QUERY_REGISTRY_TABLE QueryTable[CONFIG_PARAMETERS+2];
|
|||
|
NTSTATUS Status;
|
|||
|
ULONG One = 1;
|
|||
|
ULONG Two = 2;
|
|||
|
ULONG Three = 3;
|
|||
|
ULONG Four = 4;
|
|||
|
ULONG Five = 5;
|
|||
|
ULONG Eight = 8;
|
|||
|
ULONG FortyEight = 48;
|
|||
|
ULONG Sixty = 60;
|
|||
|
ULONG TwoFifty = 250;
|
|||
|
ULONG FiveHundred = 500;
|
|||
|
ULONG SevenFifty = 750;
|
|||
|
ULONG MaxMTU = 0xffffffff;
|
|||
|
|
|||
|
PWSTR Parameters = L"Parameters";
|
|||
|
struct {
|
|||
|
PWSTR KeyName;
|
|||
|
PULONG DefaultValue;
|
|||
|
} ParameterValues[CONFIG_PARAMETERS] = {
|
|||
|
{ L"AckDelayTime", &TwoFifty } , // milliseconds
|
|||
|
{ L"AckWindow", &Two } ,
|
|||
|
{ L"AckWindowThreshold", &FiveHundred } , // milliseconds
|
|||
|
{ L"EnablePiggyBackAck", &One } ,
|
|||
|
{ L"Extensions", &One } ,
|
|||
|
{ L"RcvWindowMax", &Four } ,
|
|||
|
{ L"BroadcastCount", &Three } ,
|
|||
|
{ L"BroadcastTimeout", &SevenFifty} , // milliseconds
|
|||
|
{ L"ConnectionCount", &Five } ,
|
|||
|
{ L"ConnectionTimeout", &Two } , // half-seconds
|
|||
|
{ L"InitPackets", &Eight } ,
|
|||
|
{ L"MaxPackets", &FortyEight } ,
|
|||
|
{ L"InitialRetransmissionTime", &FiveHundred } , // milliseconds
|
|||
|
{ L"Internet", &One } ,
|
|||
|
{ L"KeepAliveCount", &Eight } ,
|
|||
|
{ L"KeepAliveTimeout", &Sixty } , // half-seconds
|
|||
|
{ L"RetransmitMax", &Eight } ,
|
|||
|
{ L"RouterMTU", &MaxMTU } };
|
|||
|
UINT i;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Allocate memory for the main config structure.
|
|||
|
//
|
|||
|
|
|||
|
Config = NbiAllocateMemory (sizeof(CONFIG), MEMORY_CONFIG, "Config");
|
|||
|
if (Config == NULL) {
|
|||
|
NbiWriteResourceErrorLog ((PVOID)DriverObject, sizeof(CONFIG), MEMORY_CONFIG);
|
|||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
}
|
|||
|
|
|||
|
Config->DeviceName.Buffer = NULL;
|
|||
|
Config->BindName.Buffer = NULL;
|
|||
|
Config->RegistryPath.Buffer = NULL;
|
|||
|
Config->DriverObject = DriverObject; // save this to log errors
|
|||
|
|
|||
|
//
|
|||
|
// Read in the NDIS binding information (if none is present
|
|||
|
// the array will be filled with all known drivers).
|
|||
|
//
|
|||
|
// NbiReadLinkageInformation expects a null-terminated path,
|
|||
|
// so we have to create one from the UNICODE_STRING.
|
|||
|
//
|
|||
|
|
|||
|
Config->RegistryPath.Length = RegistryPath->Length + sizeof(WCHAR);
|
|||
|
Config->RegistryPath.Buffer = (PWSTR)NbiAllocateMemory(Config->RegistryPath.Length,
|
|||
|
MEMORY_CONFIG, "RegistryPathBuffer");
|
|||
|
if (Config->RegistryPath.Buffer == NULL) {
|
|||
|
NbiWriteResourceErrorLog ((PVOID)DriverObject, RegistryPath->Length + sizeof(WCHAR), MEMORY_CONFIG);
|
|||
|
NbiFreeConfiguration(Config);
|
|||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
}
|
|||
|
RtlCopyMemory (Config->RegistryPath.Buffer, RegistryPath->Buffer, RegistryPath->Length);
|
|||
|
*(PWCHAR)(((PUCHAR)Config->RegistryPath.Buffer)+RegistryPath->Length) = (WCHAR)'\0';
|
|||
|
|
|||
|
//
|
|||
|
// Determine what name to export and who to bind to.
|
|||
|
//
|
|||
|
|
|||
|
Status = NbiReadLinkageInformation (Config);
|
|||
|
|
|||
|
if (Status != STATUS_SUCCESS) {
|
|||
|
|
|||
|
//
|
|||
|
// If it failed it logged an error.
|
|||
|
//
|
|||
|
|
|||
|
NbiFreeConfiguration(Config);
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read the per-transport (as opposed to per-binding)
|
|||
|
// parameters.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Set up QueryTable to do the following:
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// 1) Switch to the Parameters key below Netbios
|
|||
|
//
|
|||
|
|
|||
|
QueryTable[0].QueryRoutine = NULL;
|
|||
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
|
|||
|
QueryTable[0].Name = Parameters;
|
|||
|
|
|||
|
//
|
|||
|
// 2-18) Call NbiSetBindingValue for each of the keys we
|
|||
|
// care about.
|
|||
|
//
|
|||
|
|
|||
|
for (i = 0; i < CONFIG_PARAMETERS; i++) {
|
|||
|
|
|||
|
QueryTable[i+1].QueryRoutine = NbiGetConfigValue;
|
|||
|
QueryTable[i+1].Flags = 0;
|
|||
|
QueryTable[i+1].Name = ParameterValues[i].KeyName;
|
|||
|
QueryTable[i+1].EntryContext = UlongToPtr(i);
|
|||
|
QueryTable[i+1].DefaultType = REG_DWORD;
|
|||
|
QueryTable[i+1].DefaultData = (PVOID)(ParameterValues[i].DefaultValue);
|
|||
|
QueryTable[i+1].DefaultLength = sizeof(ULONG);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// 19) Stop
|
|||
|
//
|
|||
|
|
|||
|
QueryTable[CONFIG_PARAMETERS+1].QueryRoutine = NULL;
|
|||
|
QueryTable[CONFIG_PARAMETERS+1].Flags = 0;
|
|||
|
QueryTable[CONFIG_PARAMETERS+1].Name = NULL;
|
|||
|
|
|||
|
|
|||
|
Status = RtlQueryRegistryValues(
|
|||
|
RTL_REGISTRY_ABSOLUTE,
|
|||
|
Config->RegistryPath.Buffer,
|
|||
|
QueryTable,
|
|||
|
(PVOID)Config,
|
|||
|
NULL);
|
|||
|
|
|||
|
if (Status != STATUS_SUCCESS) {
|
|||
|
|
|||
|
NbiFreeConfiguration(Config);
|
|||
|
NbiWriteGeneralErrorLog(
|
|||
|
(PVOID)DriverObject,
|
|||
|
EVENT_IPX_ILLEGAL_CONFIG,
|
|||
|
701,
|
|||
|
Status,
|
|||
|
Parameters,
|
|||
|
0,
|
|||
|
NULL);
|
|||
|
return STATUS_DEVICE_CONFIGURATION_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
*ConfigPtr = Config;
|
|||
|
|
|||
|
// #if DBG
|
|||
|
//
|
|||
|
// Due to previous Registry entries not being cleanedup properly,
|
|||
|
// we can have stale entries for BroadcastTimeout -- if so, handle
|
|||
|
// it accordingly
|
|||
|
if (Config->Parameters[CONFIG_BROADCAST_TIMEOUT] < 10)
|
|||
|
{
|
|||
|
Config->Parameters[CONFIG_BROADCAST_TIMEOUT] = SevenFifty;
|
|||
|
}
|
|||
|
// #endif
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} /* NbiGetConfiguration */
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
NbiFreeConfiguration (
|
|||
|
IN PCONFIG Config
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called by Netbios to get free any storage that was allocated
|
|||
|
by NbiGetConfiguration in producing the specified CONFIG structure.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Config - A pointer to the configuration information structure.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (Config->BindName.Buffer) {
|
|||
|
NbiFreeMemory (Config->BindName.Buffer, Config->BindName.MaximumLength, MEMORY_CONFIG, "BindName");
|
|||
|
}
|
|||
|
|
|||
|
if (Config->DeviceName.Buffer) {
|
|||
|
NbiFreeMemory (Config->DeviceName.Buffer, Config->DeviceName.MaximumLength, MEMORY_CONFIG, "DeviceName");
|
|||
|
}
|
|||
|
|
|||
|
if (Config->RegistryPath.Buffer)
|
|||
|
{
|
|||
|
NbiFreeMemory (Config->RegistryPath.Buffer, Config->RegistryPath.Length,MEMORY_CONFIG,"RegistryPathBuffer");
|
|||
|
}
|
|||
|
|
|||
|
NbiFreeMemory (Config, sizeof(CONFIG), MEMORY_CONFIG, "Config");
|
|||
|
|
|||
|
} /* NbiFreeConfig */
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiGetConfigValue(
|
|||
|
IN PWSTR ValueName,
|
|||
|
IN ULONG ValueType,
|
|||
|
IN PVOID ValueData,
|
|||
|
IN ULONG ValueLength,
|
|||
|
IN PVOID Context,
|
|||
|
IN PVOID EntryContext
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is a callback routine for RtlQueryRegistryValues
|
|||
|
It is called for each entry in the Parameters
|
|||
|
node to set the config values. The table is set up
|
|||
|
so that this function will be called with correct default
|
|||
|
values for keys that are not present.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ValueName - The name of the value (ignored).
|
|||
|
|
|||
|
ValueType - The type of the value (REG_DWORD -- ignored).
|
|||
|
|
|||
|
ValueData - The data for the value.
|
|||
|
|
|||
|
ValueLength - The length of ValueData (ignored).
|
|||
|
|
|||
|
Context - A pointer to the CONFIG structure.
|
|||
|
|
|||
|
EntryContext - The index in Config->Parameters to save the value.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_SUCCESS
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PCONFIG Config = (PCONFIG)Context;
|
|||
|
ULONG Data = *(UNALIGNED ULONG *)ValueData;
|
|||
|
UNREFERENCED_PARAMETER(ValueName);
|
|||
|
UNREFERENCED_PARAMETER(ValueType);
|
|||
|
UNREFERENCED_PARAMETER(ValueLength);
|
|||
|
|
|||
|
if ((ValueType != REG_DWORD) || (ValueLength != sizeof(ULONG))) {
|
|||
|
return STATUS_INVALID_PARAMETER;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
switch ( (ULONG_PTR) EntryContext ) {
|
|||
|
case CONFIG_ROUTER_MTU:
|
|||
|
if ( ( Data - sizeof(NB_CONNECTION) - sizeof(IPX_HEADER) ) <= 0 ) {
|
|||
|
Config->Parameters[CONFIG_ROUTER_MTU] = 0xffffffff;
|
|||
|
NbiWriteGeneralErrorLog(
|
|||
|
(PVOID)Config->DriverObject,
|
|||
|
EVENT_IPX_ILLEGAL_CONFIG,
|
|||
|
704,
|
|||
|
STATUS_INVALID_PARAMETER,
|
|||
|
ValueName,
|
|||
|
0,
|
|||
|
NULL);
|
|||
|
return STATUS_SUCCESS;
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
NB_DEBUG2 (CONFIG, ("Config parameter %d, value %lx\n", (ULONG_PTR)EntryContext, Data));
|
|||
|
Config->Parameters[(ULONG_PTR)EntryContext] = Data;
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} /* NbiGetConfigValue */
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiAddBind(
|
|||
|
IN PWSTR ValueName,
|
|||
|
IN ULONG ValueType,
|
|||
|
IN PVOID ValueData,
|
|||
|
IN ULONG ValueLength,
|
|||
|
IN PVOID Context,
|
|||
|
IN PVOID EntryContext
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is a callback routine for RtlQueryRegistryValues
|
|||
|
It is called for each piece of the "Bind" multi-string and
|
|||
|
saves the information in a Config structure.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ValueName - The name of the value ("Bind" -- ignored).
|
|||
|
|
|||
|
ValueType - The type of the value (REG_SZ -- ignored).
|
|||
|
|
|||
|
ValueData - The null-terminated data for the value.
|
|||
|
|
|||
|
ValueLength - The length of ValueData.
|
|||
|
|
|||
|
Context - A pointer to the Config structure.
|
|||
|
|
|||
|
EntryContext - A pointer to a count of binds that is incremented.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_SUCCESS
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PCONFIG Config = (PCONFIG)Context;
|
|||
|
PULONG ValueReadOk = ((PULONG)EntryContext);
|
|||
|
PWCHAR NameBuffer;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER(ValueName);
|
|||
|
UNREFERENCED_PARAMETER(ValueType);
|
|||
|
|
|||
|
if (*ValueReadOk == 0) {
|
|||
|
|
|||
|
NB_DEBUG2 (CONFIG, ("Read bind value %ws\n", ValueData));
|
|||
|
|
|||
|
NameBuffer = (PWCHAR)NbiAllocateMemory (ValueLength, MEMORY_CONFIG, "BindName");
|
|||
|
if (NameBuffer == NULL) {
|
|||
|
NbiWriteResourceErrorLog ((PVOID)Config->DriverObject, ValueLength, MEMORY_CONFIG);
|
|||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
}
|
|||
|
|
|||
|
RtlCopyMemory (NameBuffer, ValueData, ValueLength);
|
|||
|
Config->BindName.Buffer = NameBuffer;
|
|||
|
Config->BindName.Length = (USHORT)(ValueLength - sizeof(WCHAR));
|
|||
|
Config->BindName.MaximumLength = (USHORT)ValueLength;
|
|||
|
|
|||
|
//
|
|||
|
// Set this to ignore any other callbacks and let the
|
|||
|
// caller know we read something.
|
|||
|
//
|
|||
|
|
|||
|
*ValueReadOk = 1;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} /* NbiAddBind */
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiAddExport(
|
|||
|
IN PWSTR ValueName,
|
|||
|
IN ULONG ValueType,
|
|||
|
IN PVOID ValueData,
|
|||
|
IN ULONG ValueLength,
|
|||
|
IN PVOID Context,
|
|||
|
IN PVOID EntryContext
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is a callback routine for RtlQueryRegistryValues
|
|||
|
It is called for each piece of the "Export" multi-string. It
|
|||
|
saves the first callback string in the Config structure.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ValueName - The name of the value ("Export" -- ignored).
|
|||
|
|
|||
|
ValueType - The type of the value (REG_SZ -- ignored).
|
|||
|
|
|||
|
ValueData - The null-terminated data for the value.
|
|||
|
|
|||
|
ValueLength - The length of ValueData.
|
|||
|
|
|||
|
Context - A pointer to the Config structure.
|
|||
|
|
|||
|
EntryContext - A pointer to a ULONG that goes to 1 after the
|
|||
|
first call to this routine (so we know to ignore other ones).
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_SUCCESS
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PCONFIG Config = (PCONFIG)Context;
|
|||
|
PULONG ValueReadOk = ((PULONG)EntryContext);
|
|||
|
PWCHAR NameBuffer;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER(ValueName);
|
|||
|
UNREFERENCED_PARAMETER(ValueType);
|
|||
|
|
|||
|
if (*ValueReadOk == 0) {
|
|||
|
|
|||
|
NB_DEBUG2 (CONFIG, ("Read export value %ws\n", ValueData));
|
|||
|
|
|||
|
NameBuffer = (PWCHAR)NbiAllocateMemory (ValueLength, MEMORY_CONFIG, "DeviceName");
|
|||
|
if (NameBuffer == NULL) {
|
|||
|
NbiWriteResourceErrorLog ((PVOID)Config->DriverObject, ValueLength, MEMORY_CONFIG);
|
|||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
}
|
|||
|
|
|||
|
RtlCopyMemory (NameBuffer, ValueData, ValueLength);
|
|||
|
Config->DeviceName.Buffer = NameBuffer;
|
|||
|
Config->DeviceName.Length = (USHORT)(ValueLength - sizeof(WCHAR));
|
|||
|
Config->DeviceName.MaximumLength = (USHORT)ValueLength;
|
|||
|
|
|||
|
//
|
|||
|
// Set this to ignore any other callbacks and let the
|
|||
|
// caller know we read something.
|
|||
|
//
|
|||
|
|
|||
|
*ValueReadOk = 1;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} /* NbiAddExport */
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NbiReadLinkageInformation(
|
|||
|
IN PCONFIG Config
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called by Netbios to read its linkage information
|
|||
|
from the registry.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Config - The config structure which will have per-binding information
|
|||
|
linked on to it.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The status of the operation.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
NTSTATUS Status;
|
|||
|
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
|
|||
|
PWSTR Subkey = L"Linkage";
|
|||
|
PWSTR Bind = L"Bind";
|
|||
|
PWSTR Export = L"Export";
|
|||
|
ULONG ValueReadOk; // set to TRUE when a value is read correctly
|
|||
|
|
|||
|
//
|
|||
|
// Set up QueryTable to do the following:
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// 1) Switch to the Linkage key below Netbios
|
|||
|
//
|
|||
|
|
|||
|
QueryTable[0].QueryRoutine = NULL;
|
|||
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
|
|||
|
QueryTable[0].Name = Subkey;
|
|||
|
|
|||
|
//
|
|||
|
// 1) Call NbiAddExport for each string in "Export"
|
|||
|
//
|
|||
|
|
|||
|
QueryTable[1].QueryRoutine = NbiAddExport;
|
|||
|
QueryTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED;
|
|||
|
QueryTable[1].Name = Export;
|
|||
|
QueryTable[1].EntryContext = (PVOID)&ValueReadOk;
|
|||
|
QueryTable[1].DefaultType = REG_NONE;
|
|||
|
|
|||
|
//
|
|||
|
// 2) Stop
|
|||
|
//
|
|||
|
|
|||
|
QueryTable[2].QueryRoutine = NULL;
|
|||
|
QueryTable[2].Flags = 0;
|
|||
|
QueryTable[2].Name = NULL;
|
|||
|
|
|||
|
|
|||
|
ValueReadOk = 0;
|
|||
|
|
|||
|
Status = RtlQueryRegistryValues(
|
|||
|
RTL_REGISTRY_ABSOLUTE,
|
|||
|
Config->RegistryPath.Buffer,
|
|||
|
QueryTable,
|
|||
|
(PVOID)Config,
|
|||
|
NULL);
|
|||
|
|
|||
|
if ((Status != STATUS_SUCCESS) || (ValueReadOk == 0)) {
|
|||
|
|
|||
|
NbiWriteGeneralErrorLog(
|
|||
|
(PVOID)Config->DriverObject,
|
|||
|
EVENT_IPX_ILLEGAL_CONFIG,
|
|||
|
702,
|
|||
|
Status,
|
|||
|
Export,
|
|||
|
0,
|
|||
|
NULL);
|
|||
|
return STATUS_DEVICE_CONFIGURATION_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// 1) Change to call NbiAddBind for each string in "Bind"
|
|||
|
//
|
|||
|
|
|||
|
QueryTable[1].QueryRoutine = NbiAddBind;
|
|||
|
QueryTable[1].Flags = 0; // not required
|
|||
|
QueryTable[1].Name = Bind;
|
|||
|
QueryTable[1].EntryContext = (PVOID)&ValueReadOk;
|
|||
|
QueryTable[1].DefaultType = REG_NONE;
|
|||
|
|
|||
|
ValueReadOk = 0;
|
|||
|
|
|||
|
Status = RtlQueryRegistryValues(
|
|||
|
RTL_REGISTRY_ABSOLUTE,
|
|||
|
Config->RegistryPath.Buffer,
|
|||
|
QueryTable,
|
|||
|
(PVOID)Config,
|
|||
|
NULL);
|
|||
|
|
|||
|
if ((Status != STATUS_SUCCESS) || (ValueReadOk == 0)) {
|
|||
|
|
|||
|
NbiWriteGeneralErrorLog(
|
|||
|
(PVOID)Config->DriverObject,
|
|||
|
EVENT_IPX_ILLEGAL_CONFIG,
|
|||
|
703,
|
|||
|
Status,
|
|||
|
Bind,
|
|||
|
0,
|
|||
|
NULL);
|
|||
|
return STATUS_DEVICE_CONFIGURATION_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} /* NbiReadLinkageInformation */
|
|||
|
|