2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
5 * PURPOSE: NDIS Configuration Services
6 * PROGRAMMERS: Vizzini (vizzini@plasmic.com)
8 * Vizzini 07-28-2003 Created
10 * - Resource tracking has to be implemented here because of the design of the NDIS API.
11 * Whenever a read operation is performed, the NDIS library allocates space and returns
12 * it. A linked list is kept associated with every handle of the memory allocated to
13 * it. When the handle is closed, the resources are systematically released.
14 * - The NDIS_HANDLE Configuraiton context is no longer a registry handle. An opaque struct
15 * had to be created to allow for resource tracking. This means that Miniports cannot just
16 * pass this NDIS_HANDLE to things like ZwQueryValueKey(). I don't thknk they do (they
17 * certainly should not), but it should be kept in mind.
18 * UPDATE: I just found this in the NTDDK:
19 * NdisOpenProtocolConfiguration returns a handle for the
20 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NICDriverInstance\Parameters\ProtocolName
21 * registry key. XXX This is a problem. Following that, the DDK instructs programmers
22 * to use NdisReadConfiguration and NdisWriteConfiguration. No telling what the world's idiots
23 * have done with this.
24 * - I have tried to stick to the DDK's definition of what return values are possible, which
25 * has resulted in stupid return values in some cases. I do use STATUS_RESOURCES in a few
26 * places that the DDK doesn't explicitly mention it, though.
27 * - There's a general reliance on the fact that UNICODE_STRING.Length doesn't include a trailing
28 * 0, which it shouldn't
29 * - I added support for NdisParameterBinary. It's at the end of the struct. I wonder if
31 * - All the routines in this file are PASSIVE_LEVEL only, and all memory is PagedPool
36 #define PARAMETERS_KEY L"Parameters" /* The parameters subkey under the device-specific key */
43 NdisWriteConfiguration(
44 OUT PNDIS_STATUS Status
,
45 IN NDIS_HANDLE ConfigurationHandle
,
46 IN PNDIS_STRING Keyword
,
47 IN PNDIS_CONFIGURATION_PARAMETER ParameterValue
)
49 * FUNCTION: Writes a configuration value to the registry
51 * Status: Pointer to a caller-supplied NDIS_STATUS where we return status
52 * ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
53 * Keyword: The registry value name to write
54 * ParameterValue: The value data to write
56 * NDIS_STATUS_SUCCESS - the operation completed successfully
57 * NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
58 * NDIS_STATUS_RESOURCES - out of memory, etc.
59 * NDIS_STATUS_FAILURE - any other failure
61 * There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
62 * I don't know why tho so i free everything before return. comments welcome.
70 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
72 /* reset parameter type to standard reg types */
73 switch(ParameterValue
->ParameterType
)
75 case NdisParameterHexInteger
:
76 case NdisParameterInteger
:
80 Str
.Buffer
= (PWSTR
) &Buff
;
81 Str
.MaximumLength
= (USHORT
)sizeof(Buff
);
84 ParameterType
= REG_SZ
;
85 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
86 ParameterValue
->ParameterData
.IntegerData
,
87 (ParameterValue
->ParameterType
== NdisParameterInteger
) ? 10 : 16, &Str
)))
89 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
90 *Status
= NDIS_STATUS_FAILURE
;
94 DataSize
= Str
.Length
;
97 case NdisParameterString
:
98 case NdisParameterMultiString
:
99 ParameterType
= (ParameterValue
->ParameterType
== NdisParameterString
) ? REG_SZ
: REG_MULTI_SZ
;
100 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
101 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
104 /* New (undocumented) addition to 2k ddk */
105 case NdisParameterBinary
:
106 ParameterType
= REG_BINARY
;
107 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
108 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
112 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
116 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
117 Keyword
, 0, ParameterType
, Data
, DataSize
);
119 if(*Status
!= STATUS_SUCCESS
) {
120 NDIS_DbgPrint(MIN_TRACE
, ("ZwSetValueKey failed (%x)\n", *Status
));
121 *Status
= NDIS_STATUS_FAILURE
;
123 *Status
= NDIS_STATUS_SUCCESS
;
132 NdisCloseConfiguration(
133 IN NDIS_HANDLE ConfigurationHandle
)
135 * FUNCTION: Closes handles and releases per-handle resources
137 * ConfigurationHandle - pointer to the context with the resources to free
140 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
141 PMINIPORT_RESOURCE Resource
;
142 PNDIS_CONFIGURATION_PARAMETER ParameterValue
;
143 PLIST_ENTRY CurrentEntry
;
145 while((CurrentEntry
= ExInterlockedRemoveHeadList(&ConfigurationContext
->ResourceListHead
,
146 &ConfigurationContext
->ResourceLock
)) != NULL
)
148 Resource
= CONTAINING_RECORD(CurrentEntry
, MINIPORT_RESOURCE
, ListEntry
);
149 switch(Resource
->ResourceType
)
151 case MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
:
152 ParameterValue
= Resource
->Resource
;
154 switch (ParameterValue
->ParameterType
)
156 case NdisParameterBinary
:
157 ExFreePool(ParameterValue
->ParameterData
.BinaryData
.Buffer
);
160 case NdisParameterString
:
161 case NdisParameterMultiString
:
162 ExFreePool(ParameterValue
->ParameterData
.StringData
.Buffer
);
169 /* Fall through to free NDIS_CONFIGURATION_PARAMETER struct */
171 case MINIPORT_RESOURCE_TYPE_MEMORY
:
172 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
173 ExFreePool(Resource
->Resource
);
177 NDIS_DbgPrint(MIN_TRACE
,("Unknown resource type: %d\n", Resource
->ResourceType
));
181 ExFreePool(Resource
);
184 ZwClose(ConfigurationContext
->Handle
);
193 NdisOpenConfiguration(
194 OUT PNDIS_STATUS Status
,
195 OUT PNDIS_HANDLE ConfigurationHandle
,
196 IN NDIS_HANDLE WrapperConfigurationContext
)
198 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
200 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
201 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
202 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
204 * NDIS_STATUS_SUCCESS: the operation completed successfully
205 * NDIS_STATUS_FAILURE: the operation failed
207 * I think this is the parameters key; please verify.
211 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
212 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
213 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
215 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
217 *ConfigurationHandle
= NULL
;
219 *Status
= ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle
,
220 NtCurrentProcess(), &KeyHandle
, 0, 0,
221 DUPLICATE_SAME_ACCESS
);
222 if(!NT_SUCCESS(*Status
))
224 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open registry configuration for this miniport\n"));
225 *Status
= NDIS_STATUS_FAILURE
;
229 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
230 if(!ConfigurationContext
)
232 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
234 *Status
= NDIS_STATUS_RESOURCES
;
238 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
239 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
241 ConfigurationContext
->Handle
= KeyHandle
;
243 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
244 *Status
= NDIS_STATUS_SUCCESS
;
246 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
255 NdisOpenProtocolConfiguration(
256 OUT PNDIS_STATUS Status
,
257 OUT PNDIS_HANDLE ConfigurationHandle
,
258 IN PNDIS_STRING ProtocolSection
)
260 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
262 * Status: caller-allocated buffer where status is returned
263 * ConfigurationHandle: spot to return the opaque configuration context
264 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
266 * NDIS_STATUS_SUCCESS: the operation was a success
267 * NDIS_STATUS_FAILURE: the operation was not a success
269 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
272 OBJECT_ATTRIBUTES KeyAttributes
;
273 UNICODE_STRING KeyNameU
;
275 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
278 KeyNameU
.MaximumLength
= ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(UNICODE_NULL
);
279 KeyNameU
.Buffer
= ExAllocatePool(PagedPool
, KeyNameU
.MaximumLength
);
282 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
283 *ConfigurationHandle
= NULL
;
284 *Status
= NDIS_STATUS_FAILURE
;
288 RtlCopyUnicodeString(&KeyNameU
, ProtocolSection
);
289 RtlAppendUnicodeToString(&KeyNameU
, PARAMETERS_KEY
);
290 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
292 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
294 ExFreePool(KeyNameU
.Buffer
);
296 if(*Status
!= NDIS_STATUS_SUCCESS
)
298 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
299 *ConfigurationHandle
= NULL
;
300 *Status
= NDIS_STATUS_FAILURE
;
304 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
305 if(!ConfigurationContext
)
307 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
309 *ConfigurationHandle
= NULL
;
310 *Status
= NDIS_STATUS_FAILURE
;
314 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
315 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
317 ConfigurationContext
->Handle
= KeyHandle
;
319 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
320 *Status
= NDIS_STATUS_SUCCESS
;
323 UCHAR
UnicodeToHexByte(WCHAR chr
)
325 * FUNCTION: Converts a unicode hex character to its numerical value
327 * chr: Unicode character to convert
329 * The numerical value of chr
367 IsValidNumericString(PNDIS_STRING String
, NDIS_PARAMETER_TYPE
*ParameterType
)
369 * FUNCTION: Determines if a string is a valid number
371 * String: Unicode string to evaluate
373 * TRUE if it is valid, FALSE if not
378 /* I don't think this will ever happen, but we warn it if it does */
379 if (String
->Length
== 0)
381 NDIS_DbgPrint(MIN_TRACE
, ("Got an empty string; not sure what to do here\n"));
385 /* Set the default parameter type */
386 *ParameterType
= NdisParameterInteger
;
388 for (i
= 0; i
< String
->Length
/ sizeof(WCHAR
); i
++)
390 /* Look at the second character for the base */
393 if (String
->Buffer
[i
] == L
'X' ||
394 String
->Buffer
[i
] == L
'x')
396 NDIS_DbgPrint(MID_TRACE
, ("Identified hex string\n"));
397 *ParameterType
= NdisParameterHexInteger
;
402 /* Skip any NULL characters we find */
403 if (String
->Buffer
[i
] == UNICODE_NULL
)
406 /* Make sure the character is valid for a numeric string */
407 if (UnicodeToHexByte(String
->Buffer
[i
]) == 0xFF)
420 NdisReadConfiguration(
421 OUT PNDIS_STATUS Status
,
422 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
423 IN NDIS_HANDLE ConfigurationHandle
,
424 IN PNDIS_STRING Keyword
,
425 IN NDIS_PARAMETER_TYPE ParameterType
)
427 * FUNCTION: Read a configuration value from the registry, tracking its resources
429 * Status: points to a place to write status into
430 * ParameterValue: Pointer to receive a newly-allocated parameter structure
431 * ConfigurationHandle: handle originally returned by an open function
432 * Keyword: Value name to read, or one of the following constants:
433 * Environment - returns NdisEnvironmentWindowsNt
434 * ProcessorType - returns NdisProcessorX86 until more architectures are added
435 * NdisVersion - returns NDIS_VERSION
436 * ParameterType: the type of the value to be queried
438 * - A status in Status
439 * - A parameter value in ParameterValue
442 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
444 PMINIPORT_RESOURCE MiniportResource
;
445 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
448 *ParameterValue
= NULL
;
449 *Status
= NDIS_STATUS_FAILURE
;
451 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
453 if (ConfigurationContext
== NULL
)
455 NDIS_DbgPrint(MIN_TRACE
,("invalid parameter ConfigurationContext (0x%x)\n",ConfigurationContext
));
460 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
461 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
464 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
467 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
468 *Status
= NDIS_STATUS_RESOURCES
;
472 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
473 if(!MiniportResource
)
475 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
476 ExFreePool(*ParameterValue
);
477 *ParameterValue
= NULL
;
478 *Status
= NDIS_STATUS_RESOURCES
;
482 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
483 MiniportResource
->Resource
= *ParameterValue
;
485 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
486 MiniportResource
->Resource
));
488 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
489 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
491 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
492 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
493 *Status
= NDIS_STATUS_SUCCESS
;
499 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
500 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
503 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
506 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
507 *Status
= NDIS_STATUS_RESOURCES
;
511 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
512 if(!MiniportResource
)
514 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
515 ExFreePool(*ParameterValue
);
516 *ParameterValue
= NULL
;
517 *Status
= NDIS_STATUS_RESOURCES
;
521 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
522 MiniportResource
->Resource
= *ParameterValue
;
523 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
524 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
525 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
527 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
528 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
529 *Status
= NDIS_STATUS_SUCCESS
;
535 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
536 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
539 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
542 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
543 *Status
= NDIS_STATUS_RESOURCES
;
547 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
548 if(!MiniportResource
)
550 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
551 ExFreePool(*ParameterValue
);
552 *ParameterValue
= NULL
;
553 *Status
= NDIS_STATUS_RESOURCES
;
557 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
558 MiniportResource
->Resource
= *ParameterValue
;
559 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
560 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
561 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
563 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
564 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
565 *Status
= NDIS_STATUS_SUCCESS
;
567 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
568 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
572 /* figure out how much buffer i should allocate */
573 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
574 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
576 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
577 *Status
= NDIS_STATUS_FAILURE
;
582 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
585 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
586 *Status
= NDIS_STATUS_RESOURCES
;
591 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
592 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
593 if(*Status
!= STATUS_SUCCESS
)
595 ExFreePool(KeyInformation
);
596 NDIS_DbgPrint(MIN_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
597 *Status
= NDIS_STATUS_FAILURE
;
601 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
602 if(!MiniportResource
)
604 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
605 ExFreePool(KeyInformation
);
606 *Status
= NDIS_STATUS_RESOURCES
;
610 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
611 if (!*ParameterValue
)
613 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
614 ExFreePool(MiniportResource
);
615 ExFreePool(KeyInformation
);
616 *Status
= NDIS_STATUS_RESOURCES
;
620 RtlZeroMemory(*ParameterValue
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
622 if (KeyInformation
->Type
== REG_BINARY
)
624 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterBinary\n"));
626 (*ParameterValue
)->ParameterType
= NdisParameterBinary
;
628 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
631 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
632 ExFreePool(MiniportResource
);
633 ExFreePool(KeyInformation
);
634 *Status
= NDIS_STATUS_RESOURCES
;
638 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
640 (*ParameterValue
)->ParameterData
.BinaryData
.Buffer
= Buffer
;
641 (*ParameterValue
)->ParameterData
.BinaryData
.Length
= KeyInformation
->DataLength
;
643 else if (KeyInformation
->Type
== REG_MULTI_SZ
)
645 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterMultiString\n"));
647 (*ParameterValue
)->ParameterType
= NdisParameterMultiString
;
649 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
652 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
653 ExFreePool(MiniportResource
);
654 ExFreePool(KeyInformation
);
655 *Status
= NDIS_STATUS_RESOURCES
;
659 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
661 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
662 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
668 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
669 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
671 if (IsValidNumericString(&str
, &(*ParameterValue
)->ParameterType
) &&
672 ((*Status
= RtlUnicodeStringToInteger(&str
, 0,
673 &(*ParameterValue
)->ParameterData
.IntegerData
)) == STATUS_SUCCESS
))
675 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameter(Hex)Integer\n"));
677 /* IsValidNumericString sets the parameter type when parsing the string */
681 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterString\n"));
683 (*ParameterValue
)->ParameterType
= NdisParameterString
;
685 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
688 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
689 ExFreePool(MiniportResource
);
690 ExFreePool(KeyInformation
);
691 *Status
= NDIS_STATUS_RESOURCES
;
695 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
697 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
698 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
702 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
703 MiniportResource
->Resource
= *ParameterValue
;
705 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
707 ExFreePool(KeyInformation
);
709 *Status
= NDIS_STATUS_SUCCESS
;
717 NdisReadNetworkAddress(
718 OUT PNDIS_STATUS Status
,
719 OUT PVOID
* NetworkAddress
,
720 OUT PUINT NetworkAddressLength
,
721 IN NDIS_HANDLE ConfigurationHandle
)
723 * FUNCTION: Reads the network address from the registry
725 * Status - variable to receive status
726 * NetworkAddress - pointer to a buffered network address array
727 * NetworkAddressLength - length of the NetworkAddress array
728 * ConfigurationHandle: handle passed back from one of the open routines
730 * NDIS_STATUS_SUCCESS on success
731 * NDIS_STATUS_FAILURE on failure
732 * The network address is placed in the NetworkAddress buffer
735 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
736 PMINIPORT_RESOURCE MiniportResource
= NULL
;
737 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
743 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
744 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
745 if(*Status
!= NDIS_STATUS_SUCCESS
)
747 NDIS_DbgPrint(MID_TRACE
, ("NdisReadConfiguration failed (%x)\n", *Status
));
748 *Status
= NDIS_STATUS_FAILURE
;
752 if (ParameterValue
->ParameterType
== NdisParameterInteger
)
756 NDIS_DbgPrint(MAX_TRACE
, ("Read integer data %lx\n",
757 ParameterValue
->ParameterData
.IntegerData
));
760 str
.MaximumLength
= (USHORT
)sizeof(Buff
);
763 *Status
= RtlIntegerToUnicodeString(ParameterValue
->ParameterData
.IntegerData
,
767 if (*Status
!= NDIS_STATUS_SUCCESS
)
769 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
770 *Status
= NDIS_STATUS_FAILURE
;
774 NDIS_DbgPrint(MAX_TRACE
, ("Converted integer data into %wZ\n", &str
));
778 ASSERT(ParameterValue
->ParameterType
== NdisParameterString
);
779 str
= ParameterValue
->ParameterData
.StringData
;
782 while (j
< str
.Length
&& str
.Buffer
[j
] != '\0') j
++;
784 *NetworkAddressLength
= (j
+1) >> 1;
786 if ((*NetworkAddressLength
) == 0)
788 NDIS_DbgPrint(MIN_TRACE
,("Empty NetworkAddress registry entry.\n"));
789 *Status
= NDIS_STATUS_FAILURE
;
793 IntArray
= ExAllocatePool(PagedPool
, (*NetworkAddressLength
)*sizeof(UINT
));
796 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
797 *Status
= NDIS_STATUS_RESOURCES
;
801 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
802 if(!MiniportResource
)
804 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
805 ExFreePool(IntArray
);
806 *Status
= NDIS_STATUS_RESOURCES
;
810 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_MEMORY
;
811 MiniportResource
->Resource
= IntArray
;
812 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
813 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
815 /* convert from string to bytes */
816 for(i
=0; i
<(*NetworkAddressLength
); i
++)
818 IntArray
[i
] = (UnicodeToHexByte((str
.Buffer
)[2*i
]) << 4) +
819 UnicodeToHexByte((str
.Buffer
)[2*i
+1]);
822 *NetworkAddress
= IntArray
;
824 *Status
= NDIS_STATUS_SUCCESS
;
833 NdisOpenConfigurationKeyByIndex(
834 OUT PNDIS_STATUS Status
,
835 IN NDIS_HANDLE ConfigurationHandle
,
837 OUT PNDIS_STRING KeyName
,
838 OUT PNDIS_HANDLE KeyHandle
)
840 * FUNCTION: Opens a configuration subkey by index number
842 * Status: pointer to an NDIS_STATUS to receive status info
843 * ConfigurationHandle: the handle passed back from a previous open function
844 * Index: the zero-based index of the subkey to open
845 * KeyName: the name of the key that was opened
846 * KeyHandle: a handle to the key that was opened
848 * NDIS_STATUS_SUCCESS on success
849 * NDIS_STATUS_FAILURE on failure
850 * KeyName holds the name of the opened key
851 * KeyHandle holds a handle to the new key
854 KEY_BASIC_INFORMATION
*KeyInformation
;
855 ULONG KeyInformationLength
;
856 OBJECT_ATTRIBUTES KeyAttributes
;
857 NDIS_HANDLE RegKeyHandle
;
858 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
862 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
863 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
865 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
866 *Status
= NDIS_STATUS_FAILURE
;
870 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
873 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
874 *Status
= NDIS_STATUS_FAILURE
;
878 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
879 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
881 if(*Status
!= STATUS_SUCCESS
)
883 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
884 ExFreePool(KeyInformation
);
885 *Status
= NDIS_STATUS_FAILURE
;
889 /* should i fail instead if the passed-in string isn't long enough? */
890 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
891 KeyName
->Length
= (USHORT
)min(KeyInformation
->NameLength
, KeyName
->MaximumLength
);
893 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
895 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
897 ExFreePool(KeyInformation
);
899 if(*Status
!= STATUS_SUCCESS
)
901 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
902 *Status
= NDIS_STATUS_FAILURE
;
906 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
907 if(!ConfigurationContext
)
909 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
910 ZwClose(RegKeyHandle
);
911 *Status
= NDIS_STATUS_FAILURE
;
915 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
916 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
918 ConfigurationContext
->Handle
= RegKeyHandle
;
920 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
922 *Status
= NDIS_STATUS_SUCCESS
;
931 NdisOpenConfigurationKeyByName(
932 OUT PNDIS_STATUS Status
,
933 IN NDIS_HANDLE ConfigurationHandle
,
934 IN PNDIS_STRING KeyName
,
935 OUT PNDIS_HANDLE KeyHandle
)
937 * FUNCTION: Opens a configuration subkey by name
939 * Status: points to an NDIS_STATUS where status is returned
940 * ConfigurationHandle: handle returned by a previous open call
941 * KeyName: the name of the key to open
942 * KeyHandle: a handle to the opened key
944 * NDIS_STATUS_SUCCESS on success
945 * NDIS_STATUS_FAILURE on failure
946 * KeyHandle holds a handle to the newly-opened key
950 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
951 OBJECT_ATTRIBUTES KeyAttributes
;
952 NDIS_HANDLE RegKeyHandle
;
956 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
957 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
959 if(*Status
!= STATUS_SUCCESS
)
961 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
962 *Status
= NDIS_STATUS_FAILURE
;
966 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
967 if(!ConfigurationContext
)
969 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
970 ZwClose(RegKeyHandle
);
971 *Status
= NDIS_STATUS_FAILURE
;
975 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
976 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
978 ConfigurationContext
->Handle
= RegKeyHandle
;
980 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
982 *Status
= NDIS_STATUS_SUCCESS
;