- Partial rewrite of NdisReadConfiguration

- It now determines the parameter type based on the key instead of the ParameterType passed by the caller (documented on MSDN)
 - It also always sets (*ParameterValue)->ParameterType to NdisParameterInteger when reading an integer or hex integer value (documented on MSDN)
 - This will fix miniport drivers that supply a bogus ParameterType value because it is ignored by NDIS on NT

svn path=/trunk/; revision=41521
This commit is contained in:
Cameron Gutman 2009-06-22 00:49:06 +00:00
parent 586a1d0fff
commit 12b34a994b

View file

@ -323,22 +323,11 @@ NdisReadConfiguration(
ULONG KeyDataLength; ULONG KeyDataLength;
PMINIPORT_RESOURCE MiniportResource; PMINIPORT_RESOURCE MiniportResource;
PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle; PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle;
PVOID Buffer;
*ParameterValue = NULL; *ParameterValue = NULL;
*Status = NDIS_STATUS_FAILURE; *Status = NDIS_STATUS_FAILURE;
if(ParameterType != NdisParameterInteger &&
ParameterType != NdisParameterHexInteger &&
ParameterType != NdisParameterString &&
ParameterType != NdisParameterMultiString &&
ParameterType != NdisParameterBinary
)
{
NDIS_DbgPrint(MIN_TRACE,("unsupported parameter type\n"));
*Status = NDIS_STATUS_NOT_SUPPORTED;
return;
}
NDIS_DbgPrint(MAX_TRACE,("requested read of %wZ\n", Keyword)); NDIS_DbgPrint(MAX_TRACE,("requested read of %wZ\n", Keyword));
if (ConfigurationContext == NULL) if (ConfigurationContext == NULL)
@ -498,152 +487,105 @@ NdisReadConfiguration(
return; return;
} }
switch(ParameterType)
{
case NdisParameterInteger:
case NdisParameterHexInteger:
{
UNICODE_STRING str;
*ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER)); *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER));
if (!*ParameterValue) if (!*ParameterValue)
{ {
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
ExFreePool(MiniportResource);
ExFreePool(KeyInformation); ExFreePool(KeyInformation);
*Status = NDIS_STATUS_RESOURCES; *Status = NDIS_STATUS_RESOURCES;
return; return;
} }
RtlZeroMemory(*ParameterValue, sizeof(NDIS_CONFIGURATION_PARAMETER));
if (KeyInformation->Type == REG_BINARY)
{
NDIS_DbgPrint(MAX_TRACE, ("NdisParameterBinary\n"));
(*ParameterValue)->ParameterType = NdisParameterBinary;
Buffer = ExAllocatePool(NonPagedPool, KeyInformation->DataLength);
if (!Buffer)
{
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
ExFreePool(MiniportResource);
ExFreePool(KeyInformation);
*Status = NDIS_STATUS_RESOURCES;
return;
}
RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength);
(*ParameterValue)->ParameterData.BinaryData.Buffer = Buffer;
(*ParameterValue)->ParameterData.BinaryData.Length = KeyInformation->DataLength;
}
else if (KeyInformation->Type == REG_MULTI_SZ)
{
NDIS_DbgPrint(MAX_TRACE, ("NdisParameterMultiString\n"));
(*ParameterValue)->ParameterType = NdisParameterMultiString;
Buffer = ExAllocatePool(NonPagedPool, KeyInformation->DataLength);
if (!Buffer)
{
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
ExFreePool(MiniportResource);
ExFreePool(KeyInformation);
*Status = NDIS_STATUS_RESOURCES;
return;
}
RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength);
(*ParameterValue)->ParameterData.StringData.Buffer = Buffer;
(*ParameterValue)->ParameterData.StringData.Length = KeyInformation->DataLength;
}
else
{
UNICODE_STRING str;
str.Length = str.MaximumLength = (USHORT)KeyInformation->DataLength; str.Length = str.MaximumLength = (USHORT)KeyInformation->DataLength;
str.Buffer = (PWCHAR)KeyInformation->Data; str.Buffer = (PWCHAR)KeyInformation->Data;
(*ParameterValue)->ParameterType = ParameterType; if ((*Status = RtlUnicodeStringToInteger(&str, 0,
&(*ParameterValue)->ParameterData.IntegerData)) == STATUS_SUCCESS)
/*
If ParameterType is NdisParameterInteger then the base of str is decimal.
If ParameterType is NdisParameterHexInteger then the base of str is hexadecimal.
*/
if (ParameterType == NdisParameterInteger)
*Status = RtlUnicodeStringToInteger(&str, 10, &(*ParameterValue)->ParameterData.IntegerData);
else if (ParameterType == NdisParameterHexInteger)
*Status = RtlUnicodeStringToInteger(&str, 16, &(*ParameterValue)->ParameterData.IntegerData);
ExFreePool(KeyInformation);
if(*Status != STATUS_SUCCESS) {
ExFreePool(*ParameterValue);
*ParameterValue = NULL;
*Status = NDIS_STATUS_FAILURE;
return;
}
MiniportResource->ResourceType = 0;
MiniportResource->Resource = *ParameterValue;
NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource));
ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
*Status = NDIS_STATUS_SUCCESS;
return;
}
case NdisParameterString:
case NdisParameterMultiString:
{ {
PWCHAR RegData = 0; NDIS_DbgPrint(MAX_TRACE, ("NdisParameterInteger\n"));
if(KeyInformation->Type != REG_SZ && KeyInformation->Type != REG_MULTI_SZ) (*ParameterValue)->ParameterType = NdisParameterInteger;
{
NDIS_DbgPrint(MIN_TRACE,("requested type does not match actual value type\n"));
ExFreePool(KeyInformation);
*ParameterValue = NULL;
*Status = NDIS_STATUS_FAILURE;
return;
} }
else
{
NDIS_DbgPrint(MAX_TRACE, ("NdisParameterString\n"));
*ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER)); (*ParameterValue)->ParameterType = NdisParameterString;
if(!*ParameterValue)
Buffer = ExAllocatePool(NonPagedPool, KeyInformation->DataLength);
if (!Buffer)
{ {
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
ExFreePool(MiniportResource);
ExFreePool(KeyInformation); ExFreePool(KeyInformation);
*Status = NDIS_STATUS_RESOURCES; *Status = NDIS_STATUS_RESOURCES;
return; return;
} }
RegData = ExAllocatePool(PagedPool, KeyInformation->DataLength); RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength);
if(!RegData)
{ (*ParameterValue)->ParameterData.StringData.Buffer = Buffer;
NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); (*ParameterValue)->ParameterData.StringData.Length = KeyInformation->DataLength;
ExFreePool(KeyInformation); }
ExFreePool(*ParameterValue);
*ParameterValue = NULL;
*Status = NDIS_STATUS_FAILURE;
return;
} }
MiniportResource->ResourceType = 0; MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_MEMORY;
MiniportResource->Resource = *ParameterValue; MiniportResource->Resource = *ParameterValue;
NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource));
ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
memcpy(RegData, KeyInformation->Data, KeyInformation->DataLength);
(*ParameterValue)->ParameterType = ParameterType;
(*ParameterValue)->ParameterData.StringData.Length = (USHORT)KeyInformation->DataLength;
(*ParameterValue)->ParameterData.StringData.Buffer = RegData;
ExFreePool(KeyInformation);
*Status = NDIS_STATUS_SUCCESS;
return;
}
case NdisParameterBinary:
{
if(KeyInformation->Type != REG_BINARY)
{
NDIS_DbgPrint(MIN_TRACE,("requested type does not match actual value type\n"));
*Status = NDIS_STATUS_FAILURE;
ExFreePool(KeyInformation);
return;
}
*ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER) + KeyInformation->DataLength);
if(!*ParameterValue)
{
NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
ExFreePool(KeyInformation);
*Status = NDIS_STATUS_RESOURCES;
return;
}
(*ParameterValue)->ParameterData.BinaryData.Buffer = ExAllocatePool(PagedPool, KeyInformation->DataLength);
if (!(*ParameterValue)->ParameterData.BinaryData.Buffer)
{
NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
ExFreePool(KeyInformation);
*Status = NDIS_STATUS_RESOURCES;
return;
}
(*ParameterValue)->ParameterType = ParameterType;
(*ParameterValue)->ParameterData.BinaryData.Length = KeyInformation->DataLength;
memcpy((*ParameterValue)->ParameterData.BinaryData.Buffer, KeyInformation->Data, KeyInformation->DataLength);
MiniportResource->ResourceType = 0;
MiniportResource->Resource = *ParameterValue;
NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource));
ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock); ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
ExFreePool(KeyInformation); ExFreePool(KeyInformation);
*Status = NDIS_STATUS_SUCCESS; *Status = NDIS_STATUS_SUCCESS;
return;
}
}
} }