📄 config.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS NDIS library
* FILE: ndis/config.c
* PURPOSE: NDIS Configuration Services
* PROGRAMMERS: Vizzini (vizzini@plasmic.com)
* REVISIONS:
* Vizzini 07-28-2003 Created
* NOTES:
* - Resource tracking has to be implemented here because of the design of the NDIS API.
* Whenever a read operation is performed, the NDIS library allocates space and returns
* it. A linked list is kept associated with every handle of the memory allocated to
* it. When the handle is closed, the resources are systematically released.
* - The NDIS_HANDLE Configuraiton context is no longer a registry handle. An opaque struct
* had to be created to allow for resource tracking. This means that Miniports cannot just
* pass this NDIS_HANDLE to things like ZwQueryValueKey(). I don't thknk they do (they
* certainly should not), but it should be kept in mind.
* UPDATE: I just found this in the NTDDK:
* NdisOpenProtocolConfiguration returns a handle for the
* HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NICDriverInstance\Parameters\ProtocolName
* registry key. XXX This is a problem. Following that, the DDK instructs programmers
* to use NdisReadConfiguration and NdisWriteConfiguration. No telling what the world's idiots
* have done with this.
* - I have tried to stick to the DDK's definition of what return values are possible, which
* has resulted in stupid return values in some cases. I do use STATUS_RESOURCES in a few
* places that the DDK doesn't explicitly mention it, though.
* - There's a general reliance on the fact that UNICODE_STRING.Length doesn't include a trailing
* 0, which it shouldn't
* - I added support for NdisParameterBinary. It's at the end of the struct. I wonder if
* it'll break things.
* - All the routines in this file are PASSIVE_LEVEL only, and all memory is PagedPool
*/
#include "ndissys.h"
#define NDIS_VERSION 0x00040000 /* the version of NDIS we claim to be to miniport drivers */
#define PARAMETERS_KEY L"Parameters" /* The parameters subkey under the device-specific key */
/*
* @implemented
*/
VOID
EXPORT
NdisWriteConfiguration(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE ConfigurationHandle,
IN PNDIS_STRING Keyword,
IN PNDIS_CONFIGURATION_PARAMETER ParameterValue)
/*
* FUNCTION: Writes a configuration value to the registry
* ARGUMENTS:
* Status: Pointer to a caller-supplied NDIS_STATUS where we return status
* ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
* Keyword: The registry value name to write
* ParameterValue: The value data to write
* RETURNS:
* NDIS_STATUS_SUCCESS - the operation completed successfully
* NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
* NDIS_STATUS_RESOURCES - out of memory, etc.
* NDIS_STATUS_FAILURE - any other failure
* NOTES:
* There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
* I don't know why tho so i free everything before return. comments welcome.
*/
{
ULONG ParameterType = ParameterValue->ParameterType;
ULONG DataSize;
PVOID Data;
WCHAR Buff[25];
if(ParameterType != NdisParameterInteger &&
ParameterType != NdisParameterHexInteger &&
ParameterType != NdisParameterString &&
ParameterType != NdisParameterMultiString &&
ParameterType != NdisParameterBinary
)
{
*Status = NDIS_STATUS_NOT_SUPPORTED;
return;
}
/* reset parameter type to standard reg types */
switch(ParameterType)
{
case NdisParameterHexInteger:
case NdisParameterInteger:
{
UNICODE_STRING Str;
Str.Buffer = (PWSTR) &Buff;
Str.MaximumLength = (USHORT)sizeof(Buff);
Str.Length = 0;
ParameterType = REG_SZ;
if (!NT_SUCCESS(RtlIntegerToUnicodeString(
ParameterValue->ParameterData.IntegerData,
(ParameterType == NdisParameterInteger) ? 10 : 16, &Str)))
{
*Status = NDIS_STATUS_FAILURE;
return;
}
Data = Str.Buffer;
DataSize = Str.Length;
}
break;
case NdisParameterString:
case NdisParameterMultiString:
ParameterType = REG_SZ;
Data = ParameterValue->ParameterData.StringData.Buffer;
DataSize = ParameterValue->ParameterData.StringData.Length;
break;
/* New (undocumented) addition to 2k ddk */
case NdisParameterBinary:
ParameterType = REG_BINARY;
Data = ParameterValue->ParameterData.BinaryData.Buffer;
DataSize = ParameterValue->ParameterData.BinaryData.Length;
break;
default:
*Status = NDIS_STATUS_FAILURE;
return;
}
*Status = ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle)->Handle,
Keyword, 0, ParameterType, Data, DataSize);
if(*Status != STATUS_SUCCESS)
*Status = NDIS_STATUS_FAILURE;
else
*Status = NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
EXPORT
NdisCloseConfiguration(
IN NDIS_HANDLE ConfigurationHandle)
/*
* FUNCTION: Closes handles and releases per-handle resources
* ARGUMENTS:
* ConfigurationHandle - pointer to the context with the resources to free
*/
{
PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle;
PMINIPORT_RESOURCE Resource;
while(!IsListEmpty(&ConfigurationContext->ResourceListHead))
{
Resource = (PMINIPORT_RESOURCE)RemoveTailList(&ConfigurationContext->ResourceListHead);
if(Resource->ResourceType == MINIPORT_RESOURCE_TYPE_MEMORY)
{
NDIS_DbgPrint(MAX_TRACE,("freeing 0x%x\n", Resource->Resource));
ExFreePool(Resource->Resource);
}
ExFreePool(Resource);
}
ZwClose(ConfigurationContext->Handle);
}
/*
* @implemented
*/
VOID
EXPORT
NdisOpenConfiguration(
OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE ConfigurationHandle,
IN NDIS_HANDLE WrapperConfigurationContext)
/*
* FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
* ARGUMENTS:
* Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
* ConfigurationHandle: Pointer to an opaque configuration handle returned on success
* WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
* RETURNS:
* NDIS_STATUS_SUCCESS: the operation completed successfully
* NDIS_STATUS_FAILURE: the operation failed
* NOTES:
* I think this is the parameters key; please verify.
*/
{
HANDLE KeyHandle;
PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;
PNDIS_WRAPPER_CONTEXT WrapperContext = (PNDIS_WRAPPER_CONTEXT)WrapperConfigurationContext;
HANDLE RootKeyHandle = WrapperContext->RegistryHandle;
NDIS_DbgPrint(MAX_TRACE, ("Called\n"));
*Status = ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle,
NtCurrentProcess(), &KeyHandle, 0, 0,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(*Status))
{
NDIS_DbgPrint(MID_TRACE, ("Failed to open registry configuration for this miniport\n"));
*ConfigurationHandle = NULL;
*Status = NDIS_STATUS_FAILURE;
return;
}
ConfigurationContext = ExAllocatePool(PagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
if(!ConfigurationContext)
{
NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
ZwClose(KeyHandle);
*Status = NDIS_STATUS_RESOURCES;
return;
}
KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
InitializeListHead(&ConfigurationContext->ResourceListHead);
ConfigurationContext->Handle = KeyHandle;
*ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext;
*Status = NDIS_STATUS_SUCCESS;
NDIS_DbgPrint(MAX_TRACE,("returning success\n"));
}
/*
* @implemented
*/
VOID
EXPORT
NdisOpenProtocolConfiguration(
OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE ConfigurationHandle,
IN PNDIS_STRING ProtocolSection)
/*
* FUNCTION: Open the configuration key and set up resource tracking for the protocol
* ARGUMENTS:
* Status: caller-allocated buffer where status is returned
* ConfigurationHandle: spot to return the opaque configuration context
* ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
* RETURNS:
* NDIS_STATUS_SUCCESS: the operation was a success
* NDIS_STATUS_FAILURE: the operation was not a success
* NOTES:
* I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
*/
{
OBJECT_ATTRIBUTES KeyAttributes;
UNICODE_STRING KeyNameU;
HANDLE KeyHandle;
PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;
KeyNameU.Length = 0;
KeyNameU.MaximumLength = ProtocolSection->Length + sizeof(PARAMETERS_KEY) + sizeof(UNICODE_NULL);
KeyNameU.Buffer = ExAllocatePool(PagedPool, KeyNameU.MaximumLength);
if(!KeyNameU.Buffer)
{
NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
*ConfigurationHandle = NULL;
*Status = NDIS_STATUS_FAILURE;
return;
}
RtlCopyUnicodeString(&KeyNameU, ProtocolSection);
RtlAppendUnicodeToString(&KeyNameU, PARAMETERS_KEY);
InitializeObjectAttributes(&KeyAttributes, &KeyNameU, OBJ_CASE_INSENSITIVE, NULL, NULL);
*Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
ExFreePool(KeyNameU.Buffer);
if(*Status != NDIS_STATUS_SUCCESS)
{
*ConfigurationHandle = NULL;
*Status = NDIS_STATUS_FAILURE;
return;
}
ConfigurationContext = ExAllocatePool(PagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
if(!ConfigurationContext)
{
NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
*ConfigurationHandle = NULL;
*Status = NDIS_STATUS_FAILURE;
return;
}
KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
InitializeListHead(&ConfigurationContext->ResourceListHead);
ConfigurationContext->Handle = KeyHandle;
*ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext;
*Status = NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
EXPORT
NdisReadConfiguration(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -