NT4/private/ntos/tdi/st/stcnfg.c
2020-09-30 17:12:29 +02:00

1278 lines
29 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1989-1993 Microsoft Corporation
Module Name:
stcnfg.c
Abstract:
This contains all routines necessary for the support of the dynamic
configuration of ST.
Revision History:
--*/
#include "st.h"
//
// Local functions used to access the registry.
//
NTSTATUS
StConfigureTransport (
IN PUNICODE_STRING RegistryPath,
IN PCONFIG_DATA * ConfigurationInfoPtr
);
VOID
StFreeConfigurationInfo (
IN PCONFIG_DATA ConfigurationInfo
);
NTSTATUS
StOpenParametersKey(
IN HANDLE StConfigHandle,
OUT PHANDLE ParametersHandle
);
VOID
StCloseParametersKey(
IN HANDLE ParametersHandle
);
NTSTATUS
StCountEntries(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
);
NTSTATUS
StAddBind(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
);
NTSTATUS
StAddExport(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
);
VOID
StReadLinkageInformation(
IN PWSTR RegistryPathBuffer,
IN PCONFIG_DATA * ConfigurationInfo
);
UINT
StReadSizeInformation(
IN HANDLE ParametersHandle
);
ULONG
StReadSingleParameter(
IN HANDLE ParametersHandle,
IN PWCHAR ValueName,
IN ULONG DefaultValue
);
VOID
StWriteSingleParameter(
IN HANDLE ParametersHandle,
IN PWCHAR ValueName,
IN ULONG ValueData
);
VOID
StSaveConfigInRegistry(
IN HANDLE ParametersHandle,
IN PCONFIG_DATA ConfigurationInfo
);
UINT
StWstrLength(
IN PWSTR Wstr
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,StWstrLength)
#pragma alloc_text(INIT,StConfigureTransport)
#pragma alloc_text(INIT,StFreeConfigurationInfo)
#pragma alloc_text(INIT,StOpenParametersKey)
#pragma alloc_text(INIT,StCloseParametersKey)
#pragma alloc_text(INIT,StCountEntries)
#pragma alloc_text(INIT,StAddBind)
#pragma alloc_text(INIT,StAddExport)
#pragma alloc_text(INIT,StReadLinkageInformation)
#pragma alloc_text(INIT,StReadSingleParameter)
#pragma alloc_text(INIT,StWriteSingleParameter)
#pragma alloc_text(INIT,StSaveConfigInRegistry)
#endif
UINT
StWstrLength(
IN PWSTR Wstr
)
{
UINT Length = 0;
while (*Wstr++) {
Length += sizeof(WCHAR);
}
return Length;
}
#define InsertAdapter(ConfigurationInfo, Subscript, Name) \
{ \
PWSTR _S; \
PWSTR _N = (Name); \
UINT _L = StWstrLength(_N)+sizeof(WCHAR); \
_S = (PWSTR)ExAllocatePool(NonPagedPool, _L); \
if (_S != NULL) { \
RtlCopyMemory(_S, _N, _L); \
RtlInitUnicodeString (&(ConfigurationInfo)->Names[Subscript], _S); \
} \
}
#define InsertDevice(ConfigurationInfo, Subscript, Name) \
{ \
PWSTR _S; \
PWSTR _N = (Name); \
UINT _L = StWstrLength(_N)+sizeof(WCHAR); \
_S = (PWSTR)ExAllocatePool(NonPagedPool, _L); \
if (_S != NULL) { \
RtlCopyMemory(_S, _N, _L); \
RtlInitUnicodeString (&(ConfigurationInfo)->Names[(ConfigurationInfo)->DevicesOffset+Subscript], _S); \
} \
}
#define RemoveAdapter(ConfigurationInfo, Subscript) \
ExFreePool ((ConfigurationInfo)->Names[Subscript].Buffer)
#define RemoveDevice(ConfigurationInfo, Subscript) \
ExFreePool ((ConfigurationInfo)->Names[(ConfigurationInfo)->DevicesOffset+Subscript].Buffer)
//
// These strings are used in various places by the registry.
//
#define DECLARE_STRING(_str_) STATIC WCHAR Str ## _str_[] = L#_str_
DECLARE_STRING(Large);
DECLARE_STRING(Medium);
DECLARE_STRING(Small);
DECLARE_STRING(InitRequests);
DECLARE_STRING(InitConnections);
DECLARE_STRING(InitAddressFiles);
DECLARE_STRING(InitAddresses);
DECLARE_STRING(MaxRequests);
DECLARE_STRING(MaxConnections);
DECLARE_STRING(MaxAddressFiles);
DECLARE_STRING(MaxAddresses);
DECLARE_STRING(InitPackets);
DECLARE_STRING(InitReceivePackets);
DECLARE_STRING(InitReceiveBuffers);
DECLARE_STRING(SendPacketPoolSize);
DECLARE_STRING(ReceivePacketPoolSize);
DECLARE_STRING(MaxMemoryUsage);
#define READ_HIDDEN_CONFIG(_Field) \
{ \
ConfigurationInfo->_Field = \
StReadSingleParameter( \
ParametersHandle, \
Str ## _Field, \
ConfigurationInfo->_Field); \
}
#define WRITE_HIDDEN_CONFIG(_Field) \
{ \
StWriteSingleParameter( \
ParametersHandle, \
Str ## _Field, \
ConfigurationInfo->_Field); \
}
NTSTATUS
StConfigureTransport (
IN PUNICODE_STRING RegistryPath,
IN PCONFIG_DATA * ConfigurationInfoPtr
)
/*++
Routine Description:
This routine is called by ST 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 nbfcnfg.h file.
Arguments:
RegistryPath - The name of ST's node in the registry.
ConfigurationInfoPtr - A pointer to the configuration information structure.
Return Value:
Status - STATUS_SUCCESS if everything OK, STATUS_INSUFFICIENT_RESOURCES
otherwise.
--*/
{
NTSTATUS OpenStatus;
HANDLE ParametersHandle;
UINT StSize;
HANDLE StConfigHandle;
NTSTATUS Status;
ULONG Disposition;
PWSTR RegistryPathBuffer;
OBJECT_ATTRIBUTES TmpObjectAttributes;
PCONFIG_DATA ConfigurationInfo;
//
// Open the registry.
//
InitializeObjectAttributes(
&TmpObjectAttributes,
RegistryPath, // name
OBJ_CASE_INSENSITIVE, // attributes
NULL, // root
NULL // security descriptor
);
Status = ZwCreateKey(
&StConfigHandle,
KEY_WRITE,
&TmpObjectAttributes,
0, // title index
NULL, // class
0, // create options
&Disposition); // disposition
if (!NT_SUCCESS(Status)) {
StPrint1("ST: Could not open/create ST key: %lx\n", Status);
return Status;
}
OpenStatus = StOpenParametersKey (StConfigHandle, &ParametersHandle);
if (OpenStatus != STATUS_SUCCESS) {
return OpenStatus;
}
//
// Read in the NDIS binding information (if none is present
// the array will be filled with all known drivers).
//
// StReadLinkageInformation expects a null-terminated path,
// so we have to create one from the UNICODE_STRING.
//
RegistryPathBuffer = (PWSTR)ExAllocatePool(
NonPagedPool,
RegistryPath->Length + sizeof(WCHAR));
if (RegistryPathBuffer == NULL) {
StCloseParametersKey (ParametersHandle);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory (RegistryPathBuffer, RegistryPath->Buffer, RegistryPath->Length);
*(PWCHAR)(((PUCHAR)RegistryPathBuffer)+RegistryPath->Length) = (WCHAR)'\0';
StReadLinkageInformation (RegistryPathBuffer, ConfigurationInfoPtr);
if (*ConfigurationInfoPtr == NULL) {
ExFreePool (RegistryPathBuffer);
StCloseParametersKey (ParametersHandle);
return STATUS_INSUFFICIENT_RESOURCES;
}
ConfigurationInfo = *ConfigurationInfoPtr;
//
// Read the size parameter; this returns 0 if none is
// present, or 1 (Small), 2 (Medium) and 3 (Large).
//
StSize = StReadSizeInformation (ParametersHandle);
switch (StSize) {
case 0:
case 1:
//
// Default is Small.
//
//
// These are the initial value used; the comment after
// each one shows the expected maximum (if every resource
// is at the expected maximum, ST should be very close
// to being out of memory).
//
// For now the "Max" values default to 0 (no limit).
//
ConfigurationInfo->InitRequests = 5; // 30
ConfigurationInfo->InitConnections = 1; // 10
ConfigurationInfo->InitAddressFiles = 0; // 10
ConfigurationInfo->InitAddresses = 0; // 10
//
// These are the initial values; remember that the
// resources above also allocate some of these each
// time they are allocated (shown in the comment).
//
ConfigurationInfo->InitPackets = 30; // + link + conn (40)
ConfigurationInfo->InitReceivePackets = 10; // + link + addr (30)
ConfigurationInfo->InitReceiveBuffers = 5; // + addr (15)
//
// Set the size of the packet pools and the total
// allocateable by ST.
//
ConfigurationInfo->SendPacketPoolSize = 100;
ConfigurationInfo->ReceivePacketPoolSize = 30;
ConfigurationInfo->MaxMemoryUsage = 100000;
break;
case 2:
//
// Medium ST.
//
//
// These are the initial value used; the comment after
// each one shows the expected maximum (if every resource
// is at the expected maximum, ST should be very close
// to being out of memory).
//
// For now the "Max" values default to 0 (no limit).
//
ConfigurationInfo->InitRequests = 10; // 100
ConfigurationInfo->InitConnections = 2; // 64
ConfigurationInfo->InitAddressFiles = 1; // 20
ConfigurationInfo->InitAddresses = 1; // 20
//
// These are the initial values; remember that the
// resources above also allocate some of these each
// time they are allocated (shown in the comment).
//
ConfigurationInfo->InitPackets = 50; // + link + conn (150)
ConfigurationInfo->InitReceivePackets = 15; // + link + addr (100)
ConfigurationInfo->InitReceiveBuffers = 10; // + addr (30)
//
// Set the size of the packet pools and the total
// allocateable by ST.
//
ConfigurationInfo->SendPacketPoolSize = 250;
ConfigurationInfo->ReceivePacketPoolSize = 100;
ConfigurationInfo->MaxMemoryUsage = 250000;
break;
case 3:
//
// Big ST.
//
//
// These are the initial value used.
//
// For now the "Max" values default to 0 (no limit).
//
ConfigurationInfo->InitRequests = 15;
ConfigurationInfo->InitConnections = 3;
ConfigurationInfo->InitAddressFiles = 2;
ConfigurationInfo->InitAddresses = 2;
//
// These are the initial values; remember that the
// resources above also allocate some of these each
// time they are allocated (shown in the comment).
//
ConfigurationInfo->InitPackets = 75; // + link + conn
ConfigurationInfo->InitReceivePackets = 25; // + link + addr
ConfigurationInfo->InitReceiveBuffers = 20; // + addr
//
// Set the size of the packet pools and the total
// allocateable by ST.
//
ConfigurationInfo->SendPacketPoolSize = 500;
ConfigurationInfo->ReceivePacketPoolSize = 200;
ConfigurationInfo->MaxMemoryUsage = 0; // no limit
break;
default:
ASSERT(FALSE);
break;
}
//
// Now read the optional "hidden" parameters; if these do
// not exist then the current values are used. Note that
// the current values will be 0 unless they have been
// explicitly initialized above.
//
// NOTE: These macros expect "ConfigurationInfo" and
// "ParametersHandle" to exist when they are expanded.
//
READ_HIDDEN_CONFIG (InitRequests);
READ_HIDDEN_CONFIG (InitConnections);
READ_HIDDEN_CONFIG (InitAddressFiles);
READ_HIDDEN_CONFIG (InitAddresses);
READ_HIDDEN_CONFIG (MaxRequests);
READ_HIDDEN_CONFIG (MaxConnections);
READ_HIDDEN_CONFIG (MaxAddressFiles);
READ_HIDDEN_CONFIG (MaxAddresses);
READ_HIDDEN_CONFIG (InitPackets);
READ_HIDDEN_CONFIG (InitReceivePackets);
READ_HIDDEN_CONFIG (InitReceiveBuffers);
READ_HIDDEN_CONFIG (SendPacketPoolSize);
READ_HIDDEN_CONFIG (ReceivePacketPoolSize);
READ_HIDDEN_CONFIG (MaxMemoryUsage);
//
// Now that we are completely configured, save the information
// in the registry.
//
StSaveConfigInRegistry (ParametersHandle, ConfigurationInfo);
ExFreePool (RegistryPathBuffer);
StCloseParametersKey (ParametersHandle);
ZwClose (StConfigHandle);
return STATUS_SUCCESS;
} /* StConfigureTransport */
VOID
StFreeConfigurationInfo (
IN PCONFIG_DATA ConfigurationInfo
)
/*++
Routine Description:
This routine is called by ST to get free any storage that was allocated
by StConfigureTransport in producing the specified CONFIG_DATA structure.
Arguments:
ConfigurationInfo - A pointer to the configuration information structure.
Return Value:
None.
--*/
{
UINT i;
for (i=0; i<ConfigurationInfo->NumAdapters; i++) {
RemoveAdapter (ConfigurationInfo, i);
RemoveDevice (ConfigurationInfo, i);
}
ExFreePool (ConfigurationInfo);
} /* StFreeConfigurationInfo */
NTSTATUS
StOpenParametersKey(
IN HANDLE StConfigHandle,
OUT PHANDLE ParametersHandle
)
/*++
Routine Description:
This routine is called by ST to open the ST "Parameters" key.
Arguments:
ParametersHandle - Returns the handle used to read parameters.
Return Value:
The status of the request.
--*/
{
NTSTATUS Status;
HANDLE ParamHandle;
PWSTR ParametersString = L"Parameters";
UNICODE_STRING ParametersKeyName;
OBJECT_ATTRIBUTES TmpObjectAttributes;
//
// Open the ST parameters key.
//
RtlInitUnicodeString (&ParametersKeyName, ParametersString);
InitializeObjectAttributes(
&TmpObjectAttributes,
&ParametersKeyName, // name
OBJ_CASE_INSENSITIVE, // attributes
StConfigHandle, // root
NULL // security descriptor
);
Status = ZwOpenKey(
&ParamHandle,
KEY_READ,
&TmpObjectAttributes);
if (!NT_SUCCESS(Status)) {
StPrint1("Could not open parameters key: %lx\n", Status);
return Status;
}
*ParametersHandle = ParamHandle;
//
// All keys successfully opened or created.
//
return STATUS_SUCCESS;
} /* StOpenParametersKey */
VOID
StCloseParametersKey(
IN HANDLE ParametersHandle
)
/*++
Routine Description:
This routine is called by ST to close the "Parameters" key.
It closes the handles passed in and does any other work needed.
Arguments:
ParametersHandle - The handle used to read other parameters.
Return Value:
None.
--*/
{
ZwClose (ParametersHandle);
} /* StCloseParametersKey */
NTSTATUS
StCountEntries(
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 with the "Bind" and "Export" multi-strings.
It counts the number of name entries required in the
CONFIGURATION_DATA structure and then allocates it.
Arguments:
ValueName - The name of the value ("Bind" or "Export" -- ignored).
ValueType - The type of the value (REG_MULTI_SZ -- ignored).
ValueData - The null-terminated data for the value.
ValueLength - The length of ValueData (ignored).
Context - A pointer to a pointer to the ConfigurationInfo structure.
When the "Export" callback is made this is filled in
with the allocate structure.
EntryContext - A pointer to a counter holding the total number
of name entries required.
Return Value:
STATUS_SUCCESS
--*/
{
ULONG StringCount;
PWCHAR ValuePointer = (PWCHAR)ValueData;
PCONFIG_DATA * ConfigurationInfo = (PCONFIG_DATA *)Context;
PULONG TotalCount = ((PULONG)EntryContext);
ULONG OldTotalCount = *TotalCount;
ASSERT (ValueType == REG_MULTI_SZ);
//
// Count the number of strings in the multi-string; first
// check that it is NULL-terminated to make the rest
// easier.
//
if ((ValueLength < 2) ||
(ValuePointer[(ValueLength/2)-1] != (WCHAR)'\0')) {
return STATUS_INVALID_PARAMETER;
}
StringCount = 0;
while (*ValuePointer != (WCHAR)'\0') {
while (*ValuePointer != (WCHAR)'\0') {
++ValuePointer;
}
++StringCount;
++ValuePointer;
if ((ULONG)((PUCHAR)ValuePointer - (PUCHAR)ValueData) >= ValueLength) {
break;
}
}
(*TotalCount) += StringCount;
if (*ValueName == (WCHAR)'E') {
//
// This is "Export", allocate the config data structure.
//
*ConfigurationInfo = ExAllocatePool(
NonPagedPool,
sizeof (CONFIG_DATA) +
((*TotalCount-1) * sizeof(NDIS_STRING)));
if (*ConfigurationInfo == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(
*ConfigurationInfo,
sizeof(CONFIG_DATA) + ((*TotalCount-1) * sizeof(NDIS_STRING)));
(*ConfigurationInfo)->DevicesOffset = OldTotalCount;
}
return STATUS_SUCCESS;
} /* StCountEntries */
NTSTATUS
StAddBind(
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 ConfigurationInfo 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 (ignored).
Context - A pointer to the ConfigurationInfo structure.
EntryContext - A pointer to a count of binds that is incremented.
Return Value:
STATUS_SUCCESS
--*/
{
PCONFIG_DATA ConfigurationInfo = *(PCONFIG_DATA *)Context;
PULONG CurBindNum = ((PULONG)EntryContext);
UNREFERENCED_PARAMETER(ValueName);
UNREFERENCED_PARAMETER(ValueType);
UNREFERENCED_PARAMETER(ValueLength);
InsertAdapter(
ConfigurationInfo,
*CurBindNum,
(PWSTR)(ValueData));
++(*CurBindNum);
return STATUS_SUCCESS;
} /* StAddBind */
NTSTATUS
StAddExport(
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 and
saves the information in a ConfigurationInfo 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 (ignored).
Context - A pointer to the ConfigurationInfo structure.
EntryContext - A pointer to a count of exports that is incremented.
Return Value:
STATUS_SUCCESS
--*/
{
PCONFIG_DATA ConfigurationInfo = *(PCONFIG_DATA *)Context;
PULONG CurExportNum = ((PULONG)EntryContext);
UNREFERENCED_PARAMETER(ValueName);
UNREFERENCED_PARAMETER(ValueType);
UNREFERENCED_PARAMETER(ValueLength);
InsertDevice(
ConfigurationInfo,
*CurExportNum,
(PWSTR)(ValueData));
++(*CurExportNum);
return STATUS_SUCCESS;
} /* StAddExport */
VOID
StReadLinkageInformation(
IN PWSTR RegistryPathBuffer,
IN PCONFIG_DATA * ConfigurationInfo
)
/*++
Routine Description:
This routine is called by ST to read its linkage information
from the registry. If there is none present, then ConfigData
is filled with a list of all the adapters that are known
to ST.
Arguments:
RegistryPathBuffer - The null-terminated root of the ST registry tree.
ConfigurationInfo - Returns ST's current configuration.
Return Value:
None.
--*/
{
UINT ConfigBindings;
UINT NameCount = 0;
NTSTATUS Status;
RTL_QUERY_REGISTRY_TABLE QueryTable[6];
PWSTR Subkey = L"Linkage";
PWSTR Bind = L"Bind";
PWSTR Export = L"Export";
ULONG BindCount, ExportCount;
UINT i;
//
// Set up QueryTable to do the following:
//
//
// 1) Switch to the Linkage key below ST
//
QueryTable[0].QueryRoutine = NULL;
QueryTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
QueryTable[0].Name = Subkey;
//
// 2) Call StCountEntries for the "Bind" multi-string
//
QueryTable[1].QueryRoutine = StCountEntries;
QueryTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
QueryTable[1].Name = Bind;
QueryTable[1].EntryContext = (PVOID)&NameCount;
QueryTable[1].DefaultType = REG_NONE;
//
// 3) Call StCountEntries for the "Export" multi-string
//
QueryTable[2].QueryRoutine = StCountEntries;
QueryTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
QueryTable[2].Name = Export;
QueryTable[2].EntryContext = (PVOID)&NameCount;
QueryTable[2].DefaultType = REG_NONE;
//
// 4) Call StAddBind for each string in "Bind"
//
QueryTable[3].QueryRoutine = StAddBind;
QueryTable[3].Flags = 0;
QueryTable[3].Name = Bind;
QueryTable[3].EntryContext = (PVOID)&BindCount;
QueryTable[3].DefaultType = REG_NONE;
//
// 5) Call StAddExport for each string in "Export"
//
QueryTable[4].QueryRoutine = StAddExport;
QueryTable[4].Flags = 0;
QueryTable[4].Name = Export;
QueryTable[4].EntryContext = (PVOID)&ExportCount;
QueryTable[4].DefaultType = REG_NONE;
//
// 6) Stop
//
QueryTable[5].QueryRoutine = NULL;
QueryTable[5].Flags = 0;
QueryTable[5].Name = NULL;
BindCount = 0;
ExportCount = 0;
Status = RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
RegistryPathBuffer,
QueryTable,
(PVOID)ConfigurationInfo,
NULL);
if (Status != STATUS_SUCCESS) {
return;
}
//
// Make sure that BindCount and ExportCount match, if not
// remove the extras.
//
if (BindCount < ExportCount) {
for (i=BindCount; i<ExportCount; i++) {
RemoveDevice (*ConfigurationInfo, i);
}
ConfigBindings = BindCount;
} else if (ExportCount < BindCount) {
for (i=ExportCount; i<BindCount; i++) {
RemoveAdapter (*ConfigurationInfo, i);
}
ConfigBindings = ExportCount;
} else {
ConfigBindings = BindCount; // which is equal to ExportCount
}
(*ConfigurationInfo)->NumAdapters = ConfigBindings;
} /* StReadLinkageInformation */
UINT
StReadSizeInformation(
IN HANDLE ParametersHandle
)
/*++
Routine Description:
This routine is called by ST to read the Size information
from the registry.
Arguments:
RegistryHandle - A pointer to the open registry.
Return Value:
0 - no Size specified
1 - Small
2 - Medium
3 - Big / Large
--*/
{
UINT SizeToReturn;
// STRING KeywordName;
// PCONFIG_KEYWORD Keyword;
ULONG InformationBuffer[16]; // declare ULONG to get it aligned
PKEY_VALUE_FULL_INFORMATION Information =
(PKEY_VALUE_FULL_INFORMATION)InformationBuffer;
ULONG InformationLength;
WCHAR SizeString[] = L"Size";
UNICODE_STRING SizeValueName;
NTSTATUS Status;
PUCHAR InformationData;
ULONG InformationLong;
//
// Read the size parameter out of the registry.
//
RtlInitUnicodeString (&SizeValueName, SizeString);
Status = ZwQueryValueKey(
ParametersHandle,
&SizeValueName,
KeyValueFullInformation,
(PVOID)Information,
sizeof (InformationBuffer),
&InformationLength);
//
// Compare to the expected values.
//
if (Status == STATUS_SUCCESS) {
InformationData = ((PUCHAR)Information) + Information->DataOffset;
InformationLong = *((PULONG)InformationData);
if ((Information->DataLength == sizeof(ULONG)) &&
(InformationLong >= 1 && InformationLong <= 3)) {
SizeToReturn = InformationLong;
} else {
if ((Information->DataLength >= 10) &&
(RtlEqualMemory (StrLarge, InformationData, 10))) {
SizeToReturn = 3;
} else if ((Information->DataLength >= 12) &&
(RtlEqualMemory (StrMedium, InformationData, 12))) {
SizeToReturn = 2;
} else if ((Information->DataLength >= 10) &&
(RtlEqualMemory (StrSmall, InformationData, 10))) {
SizeToReturn = 1;
} else {
SizeToReturn = 0;
}
}
} else {
SizeToReturn = 0;
}
return SizeToReturn;
} /* StReadSizeInformation */
ULONG
StReadSingleParameter(
IN HANDLE ParametersHandle,
IN PWCHAR ValueName,
IN ULONG DefaultValue
)
/*++
Routine Description:
This routine is called by ST to read a single parameter
from the registry. If the parameter is found it is stored
in Data.
Arguments:
ParametersHandle - A pointer to the open registry.
ValueName - The name of the value to search for.
DefaultValue - The default value.
Return Value:
The value to use; will be the default if the value is not
found or is not in the correct range.
--*/
{
ULONG InformationBuffer[16]; // declare ULONG to get it aligned
PKEY_VALUE_FULL_INFORMATION Information =
(PKEY_VALUE_FULL_INFORMATION)InformationBuffer;
UNICODE_STRING ValueKeyName;
ULONG InformationLength;
ULONG ReturnValue;
NTSTATUS Status;
RtlInitUnicodeString (&ValueKeyName, ValueName);
Status = ZwQueryValueKey(
ParametersHandle,
&ValueKeyName,
KeyValueFullInformation,
(PVOID)Information,
sizeof (InformationBuffer),
&InformationLength);
if ((Status == STATUS_SUCCESS) && (Information->DataLength == sizeof(ULONG))) {
RtlCopyMemory(
(PVOID)&ReturnValue,
((PUCHAR)Information) + Information->DataOffset,
sizeof(ULONG));
if (ReturnValue < 0) {
ReturnValue = DefaultValue;
}
} else {
ReturnValue = DefaultValue;
}
return ReturnValue;
} /* StReadSingleParameter */
VOID
StWriteSingleParameter(
IN HANDLE ParametersHandle,
IN PWCHAR ValueName,
IN ULONG ValueData
)
/*++
Routine Description:
This routine is called by ST to write a single parameter
from the registry.
Arguments:
ParametersHandle - A pointer to the open registry.
ValueName - The name of the value to store.
ValueData - The data to store at the value.
Return Value:
None.
--*/
{
UNICODE_STRING ValueKeyName;
NTSTATUS Status;
ULONG TmpValueData = ValueData;
RtlInitUnicodeString (&ValueKeyName, ValueName);
Status = ZwSetValueKey(
ParametersHandle,
&ValueKeyName,
0,
REG_DWORD,
(PVOID)&TmpValueData,
sizeof(ULONG));
if (!NT_SUCCESS(Status)) {
StPrint1("ST: Could not write dword key: %lx\n", Status);
}
} /* StWriteSingleParameter */
VOID
StSaveConfigInRegistry(
IN HANDLE ParametersHandle,
IN PCONFIG_DATA ConfigurationInfo
)
/*++
Routine Description:
This routine is called by ST to save its configuraition
information in the registry. It saves the information if
the registry structure did not exist before this boot.
Arguments:
ParametersHandle - The handle used to read other parameters.
ConfigurationInfo - Describes ST's current configuration.
Return Value:
None.
--*/
{
//
// Save the "hidden" parameters, these may not exist in
// the registry.
//
// NOTE: These macros expect "ConfigurationInfo" and
// "ParametersHandle" to exist when they are expanded.
//
//
// Don't write the parameters that are set
// based on Size, since otherwise these will overwrite
// those values since hidden parameters are set up
// after the Size-based configuration is done.
//
WRITE_HIDDEN_CONFIG (MaxRequests);
WRITE_HIDDEN_CONFIG (MaxConnections);
WRITE_HIDDEN_CONFIG (MaxAddressFiles);
WRITE_HIDDEN_CONFIG (MaxAddresses);
} /* StSaveConfigInRegistry */