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 Configuration 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
38 #define PARAMETERS_KEY L"Parameters" /* The parameters subkey under the device-specific key */
45 NdisWriteConfiguration(
46 OUT PNDIS_STATUS Status
,
47 IN NDIS_HANDLE ConfigurationHandle
,
48 IN PNDIS_STRING Keyword
,
49 IN PNDIS_CONFIGURATION_PARAMETER ParameterValue
)
51 * FUNCTION: Writes a configuration value to the registry
53 * Status: Pointer to a caller-supplied NDIS_STATUS where we return status
54 * ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
55 * Keyword: The registry value name to write
56 * ParameterValue: The value data to write
58 * NDIS_STATUS_SUCCESS - the operation completed successfully
59 * NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
60 * NDIS_STATUS_RESOURCES - out of memory, etc.
61 * NDIS_STATUS_FAILURE - any other failure
63 * There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
64 * I don't know why tho so i free everything before return. comments welcome.
72 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
74 NDIS_DbgPrint(MID_TRACE
, ("Parameter type: %d\n", ParameterValue
->ParameterType
));
76 /* reset parameter type to standard reg types */
77 switch(ParameterValue
->ParameterType
)
79 case NdisParameterHexInteger
:
80 case NdisParameterInteger
:
84 Str
.Buffer
= (PWSTR
) &Buff
;
85 Str
.MaximumLength
= (USHORT
)sizeof(Buff
);
88 ParameterType
= REG_SZ
;
89 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
90 ParameterValue
->ParameterData
.IntegerData
,
91 (ParameterValue
->ParameterType
== NdisParameterInteger
) ? 10 : 16, &Str
)))
93 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
94 *Status
= NDIS_STATUS_FAILURE
;
98 DataSize
= Str
.Length
;
101 case NdisParameterString
:
102 case NdisParameterMultiString
:
103 ParameterType
= (ParameterValue
->ParameterType
== NdisParameterString
) ? REG_SZ
: REG_MULTI_SZ
;
104 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
105 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
108 /* New (undocumented) addition to 2k ddk */
109 case NdisParameterBinary
:
110 ParameterType
= REG_BINARY
;
111 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
112 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
116 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
120 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
121 Keyword
, 0, ParameterType
, Data
, DataSize
);
123 if(*Status
!= STATUS_SUCCESS
) {
124 NDIS_DbgPrint(MIN_TRACE
, ("ZwSetValueKey failed (%x)\n", *Status
));
125 *Status
= NDIS_STATUS_FAILURE
;
127 *Status
= NDIS_STATUS_SUCCESS
;
136 NdisCloseConfiguration(
137 IN NDIS_HANDLE ConfigurationHandle
)
139 * FUNCTION: Closes handles and releases per-handle resources
141 * ConfigurationHandle - pointer to the context with the resources to free
144 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
145 PMINIPORT_RESOURCE Resource
;
146 PNDIS_CONFIGURATION_PARAMETER ParameterValue
;
147 PLIST_ENTRY CurrentEntry
;
149 while((CurrentEntry
= ExInterlockedRemoveHeadList(&ConfigurationContext
->ResourceListHead
,
150 &ConfigurationContext
->ResourceLock
)) != NULL
)
152 Resource
= CONTAINING_RECORD(CurrentEntry
, MINIPORT_RESOURCE
, ListEntry
);
153 switch(Resource
->ResourceType
)
155 case MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
:
156 ParameterValue
= Resource
->Resource
;
158 switch (ParameterValue
->ParameterType
)
160 case NdisParameterBinary
:
161 ExFreePool(ParameterValue
->ParameterData
.BinaryData
.Buffer
);
164 case NdisParameterString
:
165 case NdisParameterMultiString
:
166 ExFreePool(ParameterValue
->ParameterData
.StringData
.Buffer
);
173 /* Fall through to free NDIS_CONFIGURATION_PARAMETER struct */
175 case MINIPORT_RESOURCE_TYPE_MEMORY
:
176 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
177 ExFreePool(Resource
->Resource
);
181 NDIS_DbgPrint(MIN_TRACE
,("Unknown resource type: %d\n", Resource
->ResourceType
));
185 ExFreePool(Resource
);
188 ZwClose(ConfigurationContext
->Handle
);
197 NdisOpenConfiguration(
198 OUT PNDIS_STATUS Status
,
199 OUT PNDIS_HANDLE ConfigurationHandle
,
200 IN NDIS_HANDLE WrapperConfigurationContext
)
202 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
204 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
205 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
206 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
208 * NDIS_STATUS_SUCCESS: the operation completed successfully
209 * NDIS_STATUS_FAILURE: the operation failed
211 * I think this is the parameters key; please verify.
215 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
216 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
217 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
218 OBJECT_ATTRIBUTES ObjectAttributes
;
219 UNICODE_STRING NoName
= RTL_CONSTANT_STRING(L
"");
221 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
223 *ConfigurationHandle
= NULL
;
225 InitializeObjectAttributes(&ObjectAttributes
,
230 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &ObjectAttributes
);
231 if(!NT_SUCCESS(*Status
))
233 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open registry configuration for this miniport\n"));
234 *Status
= NDIS_STATUS_FAILURE
;
238 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
239 if(!ConfigurationContext
)
241 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
243 *Status
= NDIS_STATUS_RESOURCES
;
247 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
248 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
250 ConfigurationContext
->Handle
= KeyHandle
;
252 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
253 *Status
= NDIS_STATUS_SUCCESS
;
255 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
264 NdisOpenProtocolConfiguration(
265 OUT PNDIS_STATUS Status
,
266 OUT PNDIS_HANDLE ConfigurationHandle
,
267 IN PNDIS_STRING ProtocolSection
)
269 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
271 * Status: caller-allocated buffer where status is returned
272 * ConfigurationHandle: spot to return the opaque configuration context
273 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
275 * NDIS_STATUS_SUCCESS: the operation was a success
276 * NDIS_STATUS_FAILURE: the operation was not a success
278 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
281 OBJECT_ATTRIBUTES KeyAttributes
;
282 UNICODE_STRING KeyNameU
;
284 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
287 KeyNameU
.MaximumLength
= ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(UNICODE_NULL
);
288 KeyNameU
.Buffer
= ExAllocatePool(PagedPool
, KeyNameU
.MaximumLength
);
291 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
292 *ConfigurationHandle
= NULL
;
293 *Status
= NDIS_STATUS_FAILURE
;
297 RtlCopyUnicodeString(&KeyNameU
, ProtocolSection
);
298 RtlAppendUnicodeToString(&KeyNameU
, PARAMETERS_KEY
);
299 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
301 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
303 ExFreePool(KeyNameU
.Buffer
);
305 if(*Status
!= NDIS_STATUS_SUCCESS
)
307 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
308 *ConfigurationHandle
= NULL
;
309 *Status
= NDIS_STATUS_FAILURE
;
313 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
314 if(!ConfigurationContext
)
316 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
318 *ConfigurationHandle
= NULL
;
319 *Status
= NDIS_STATUS_FAILURE
;
323 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
324 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
326 ConfigurationContext
->Handle
= KeyHandle
;
328 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
329 *Status
= NDIS_STATUS_SUCCESS
;
332 UCHAR
UnicodeToHexByte(WCHAR chr
)
334 * FUNCTION: Converts a unicode hex character to its numerical value
336 * chr: Unicode character to convert
338 * The numerical value of chr
376 IsValidNumericString(PNDIS_STRING String
, ULONG Base
)
378 * FUNCTION: Determines if a string is a valid number
380 * String: Unicode string to evaluate
382 * TRUE if it is valid, FALSE if not
387 /* I don't think this will ever happen, but we warn it if it does */
388 if (String
->Length
== 0)
390 NDIS_DbgPrint(MIN_TRACE
, ("Got an empty string; not sure what to do here\n"));
394 for (i
= 0; i
< String
->Length
/ sizeof(WCHAR
); i
++)
396 /* Skip any NULL characters we find */
397 if (String
->Buffer
[i
] == UNICODE_NULL
)
400 /* Make sure the character is valid for a numeric string of this base */
401 if (UnicodeToHexByte(String
->Buffer
[i
]) >= Base
)
414 NdisReadConfiguration(
415 OUT PNDIS_STATUS Status
,
416 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
417 IN NDIS_HANDLE ConfigurationHandle
,
418 IN PNDIS_STRING Keyword
,
419 IN NDIS_PARAMETER_TYPE ParameterType
)
421 * FUNCTION: Read a configuration value from the registry, tracking its resources
423 * Status: points to a place to write status into
424 * ParameterValue: Pointer to receive a newly-allocated parameter structure
425 * ConfigurationHandle: handle originally returned by an open function
426 * Keyword: Value name to read, or one of the following constants:
427 * Environment - returns NdisEnvironmentWindowsNt
428 * ProcessorType - returns NdisProcessorX86 until more architectures are added
429 * NdisVersion - returns NDIS_VERSION
430 * ParameterType: the type of the value to be queried
432 * - A status in Status
433 * - A parameter value in ParameterValue
436 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
438 PMINIPORT_RESOURCE MiniportResource
;
439 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
442 //*ParameterValue = NULL;
443 *Status
= NDIS_STATUS_FAILURE
;
445 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
446 NDIS_DbgPrint(MID_TRACE
,("requested parameter type: %d\n", ParameterType
));
448 if (ConfigurationContext
== NULL
)
450 NDIS_DbgPrint(MIN_TRACE
,("invalid parameter ConfigurationContext (0x%x)\n",ConfigurationContext
));
454 if(!wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
455 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
))
457 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
460 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
461 *Status
= NDIS_STATUS_RESOURCES
;
465 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
466 if(!MiniportResource
)
468 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
469 ExFreePool(*ParameterValue
);
470 *ParameterValue
= NULL
;
471 *Status
= NDIS_STATUS_RESOURCES
;
475 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
476 MiniportResource
->Resource
= *ParameterValue
;
478 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
479 MiniportResource
->Resource
));
481 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
482 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
484 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
485 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
486 *Status
= NDIS_STATUS_SUCCESS
;
491 if(!wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
492 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
))
494 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
497 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
498 *Status
= NDIS_STATUS_RESOURCES
;
502 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
503 if(!MiniportResource
)
505 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
506 ExFreePool(*ParameterValue
);
507 *ParameterValue
= NULL
;
508 *Status
= NDIS_STATUS_RESOURCES
;
512 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
513 MiniportResource
->Resource
= *ParameterValue
;
514 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
515 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
516 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
518 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
519 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
520 *Status
= NDIS_STATUS_SUCCESS
;
525 if(!wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
526 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
))
528 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
531 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
532 *Status
= NDIS_STATUS_RESOURCES
;
536 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
537 if(!MiniportResource
)
539 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
540 ExFreePool(*ParameterValue
);
541 *ParameterValue
= NULL
;
542 *Status
= NDIS_STATUS_RESOURCES
;
546 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
547 MiniportResource
->Resource
= *ParameterValue
;
548 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
549 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
550 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
552 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
553 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
554 *Status
= NDIS_STATUS_SUCCESS
;
556 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
557 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
561 /* figure out how much buffer i should allocate */
562 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
563 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
565 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
566 *Status
= NDIS_STATUS_FAILURE
;
571 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
574 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
575 *Status
= NDIS_STATUS_RESOURCES
;
580 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
581 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
582 if(*Status
!= STATUS_SUCCESS
)
584 ExFreePool(KeyInformation
);
585 NDIS_DbgPrint(MIN_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
586 *Status
= NDIS_STATUS_FAILURE
;
590 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
591 if(!MiniportResource
)
593 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
594 ExFreePool(KeyInformation
);
595 *Status
= NDIS_STATUS_RESOURCES
;
599 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
600 if (!*ParameterValue
)
602 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
603 ExFreePool(MiniportResource
);
604 ExFreePool(KeyInformation
);
605 *Status
= NDIS_STATUS_RESOURCES
;
609 RtlZeroMemory(*ParameterValue
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
611 if (KeyInformation
->Type
== REG_BINARY
)
613 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterBinary\n"));
615 (*ParameterValue
)->ParameterType
= NdisParameterBinary
;
617 Buffer
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
620 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
621 ExFreePool(MiniportResource
);
622 ExFreePool(KeyInformation
);
623 *Status
= NDIS_STATUS_RESOURCES
;
627 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
629 (*ParameterValue
)->ParameterData
.BinaryData
.Buffer
= Buffer
;
630 (*ParameterValue
)->ParameterData
.BinaryData
.Length
= KeyInformation
->DataLength
;
632 else if (KeyInformation
->Type
== REG_MULTI_SZ
)
634 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterMultiString\n"));
636 (*ParameterValue
)->ParameterType
= NdisParameterMultiString
;
638 Buffer
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
641 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
642 ExFreePool(MiniportResource
);
643 ExFreePool(KeyInformation
);
644 *Status
= NDIS_STATUS_RESOURCES
;
648 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
650 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
651 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
653 else if (KeyInformation
->Type
== REG_DWORD
)
655 ASSERT(KeyInformation
->DataLength
== sizeof(ULONG
));
656 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterInteger\n"));
657 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
658 (*ParameterValue
)->ParameterData
.IntegerData
= * (ULONG
*) &KeyInformation
->Data
[0];
660 else if (KeyInformation
->Type
== REG_SZ
)
665 if (ParameterType
== NdisParameterInteger
)
667 else if (ParameterType
== NdisParameterHexInteger
)
672 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
673 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
675 if (Base
!= 0 && IsValidNumericString(&str
, Base
))
677 *Status
= RtlUnicodeStringToInteger(&str
, Base
, &(*ParameterValue
)->ParameterData
.IntegerData
);
678 ASSERT(*Status
== STATUS_SUCCESS
);
680 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameter(Hex)Integer\n"));
682 /* MSDN documents that this is returned for all integers, regardless of the ParameterType passed in */
683 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
687 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterString\n"));
689 (*ParameterValue
)->ParameterType
= NdisParameterString
;
691 Buffer
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
694 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
695 ExFreePool(MiniportResource
);
696 ExFreePool(KeyInformation
);
697 *Status
= NDIS_STATUS_RESOURCES
;
701 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
703 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
704 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
709 NDIS_DbgPrint(MIN_TRACE
, ("Invalid type for NdisReadConfiguration (%d)\n", KeyInformation
->Type
));
710 NDIS_DbgPrint(MIN_TRACE
, ("Requested type: %d\n", ParameterType
));
711 NDIS_DbgPrint(MIN_TRACE
, ("Registry entry: %wZ\n", Keyword
));
712 *Status
= NDIS_STATUS_FAILURE
;
713 ExFreePool(KeyInformation
);
717 if (((*ParameterValue
)->ParameterType
!= ParameterType
) &&
718 !((ParameterType
== NdisParameterHexInteger
) && ((*ParameterValue
)->ParameterType
== NdisParameterInteger
)))
720 NDIS_DbgPrint(MIN_TRACE
, ("Parameter type mismatch! (Requested: %d | Received: %d)\n",
721 ParameterType
, (*ParameterValue
)->ParameterType
));
722 NDIS_DbgPrint(MIN_TRACE
, ("Registry entry: %wZ\n", Keyword
));
725 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
726 MiniportResource
->Resource
= *ParameterValue
;
728 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
730 ExFreePool(KeyInformation
);
732 *Status
= NDIS_STATUS_SUCCESS
;
740 NdisReadNetworkAddress(
741 OUT PNDIS_STATUS Status
,
742 OUT PVOID
* NetworkAddress
,
743 OUT PUINT NetworkAddressLength
,
744 IN NDIS_HANDLE ConfigurationHandle
)
746 * FUNCTION: Reads the network address from the registry
748 * Status - variable to receive status
749 * NetworkAddress - pointer to a buffered network address array
750 * NetworkAddressLength - length of the NetworkAddress array
751 * ConfigurationHandle: handle passed back from one of the open routines
753 * NDIS_STATUS_SUCCESS on success
754 * NDIS_STATUS_FAILURE on failure
755 * The network address is placed in the NetworkAddress buffer
758 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
759 PMINIPORT_RESOURCE MiniportResource
= NULL
;
760 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
767 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
768 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
769 if(*Status
!= NDIS_STATUS_SUCCESS
)
771 NDIS_DbgPrint(MID_TRACE
, ("NdisReadConfiguration failed (%x)\n", *Status
));
772 *Status
= NDIS_STATUS_FAILURE
;
776 if (ParameterValue
->ParameterType
== NdisParameterInteger
)
778 NDIS_DbgPrint(MAX_TRACE
, ("Read integer data %lx\n",
779 ParameterValue
->ParameterData
.IntegerData
));
782 str
.MaximumLength
= (USHORT
)sizeof(Buff
);
785 *Status
= RtlIntegerToUnicodeString(ParameterValue
->ParameterData
.IntegerData
,
789 if (*Status
!= NDIS_STATUS_SUCCESS
)
791 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
792 *Status
= NDIS_STATUS_FAILURE
;
796 NDIS_DbgPrint(MAX_TRACE
, ("Converted integer data into %wZ\n", &str
));
800 ASSERT(ParameterValue
->ParameterType
== NdisParameterString
);
801 str
= ParameterValue
->ParameterData
.StringData
;
804 while (j
< str
.Length
&& str
.Buffer
[j
] != '\0') j
++;
806 *NetworkAddressLength
= (j
+1) >> 1;
808 if ((*NetworkAddressLength
) == 0)
810 NDIS_DbgPrint(MIN_TRACE
,("Empty NetworkAddress registry entry.\n"));
811 *Status
= NDIS_STATUS_FAILURE
;
815 IntArray
= ExAllocatePool(PagedPool
, (*NetworkAddressLength
)*sizeof(UINT
));
818 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
819 *Status
= NDIS_STATUS_RESOURCES
;
823 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
824 if(!MiniportResource
)
826 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
827 ExFreePool(IntArray
);
828 *Status
= NDIS_STATUS_RESOURCES
;
832 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_MEMORY
;
833 MiniportResource
->Resource
= IntArray
;
834 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
835 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
837 /* convert from string to bytes */
838 for(i
=0; i
<(*NetworkAddressLength
); i
++)
840 IntArray
[i
] = (UnicodeToHexByte((str
.Buffer
)[2*i
]) << 4) +
841 UnicodeToHexByte((str
.Buffer
)[2*i
+1]);
844 *NetworkAddress
= IntArray
;
846 *Status
= NDIS_STATUS_SUCCESS
;
855 NdisOpenConfigurationKeyByIndex(
856 OUT PNDIS_STATUS Status
,
857 IN NDIS_HANDLE ConfigurationHandle
,
859 OUT PNDIS_STRING KeyName
,
860 OUT PNDIS_HANDLE KeyHandle
)
862 * FUNCTION: Opens a configuration subkey by index number
864 * Status: pointer to an NDIS_STATUS to receive status info
865 * ConfigurationHandle: the handle passed back from a previous open function
866 * Index: the zero-based index of the subkey to open
867 * KeyName: the name of the key that was opened
868 * KeyHandle: a handle to the key that was opened
870 * NDIS_STATUS_SUCCESS on success
871 * NDIS_STATUS_FAILURE on failure
872 * KeyName holds the name of the opened key
873 * KeyHandle holds a handle to the new key
876 KEY_BASIC_INFORMATION
*KeyInformation
;
877 ULONG KeyInformationLength
;
878 OBJECT_ATTRIBUTES KeyAttributes
;
879 NDIS_HANDLE RegKeyHandle
;
880 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
884 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
885 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
887 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
888 *Status
= NDIS_STATUS_FAILURE
;
892 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
895 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
896 *Status
= NDIS_STATUS_FAILURE
;
900 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
901 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
903 if(*Status
!= STATUS_SUCCESS
)
905 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
906 ExFreePool(KeyInformation
);
907 *Status
= NDIS_STATUS_FAILURE
;
911 /* should i fail instead if the passed-in string isn't long enough? */
912 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
913 KeyName
->Length
= (USHORT
)min(KeyInformation
->NameLength
, KeyName
->MaximumLength
);
915 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, ConfigurationHandle
, NULL
);
917 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
919 ExFreePool(KeyInformation
);
921 if(*Status
!= STATUS_SUCCESS
)
923 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
924 *Status
= NDIS_STATUS_FAILURE
;
928 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
929 if(!ConfigurationContext
)
931 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
932 ZwClose(RegKeyHandle
);
933 *Status
= NDIS_STATUS_FAILURE
;
937 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
938 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
940 ConfigurationContext
->Handle
= RegKeyHandle
;
942 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
944 *Status
= NDIS_STATUS_SUCCESS
;
953 NdisOpenConfigurationKeyByName(
954 OUT PNDIS_STATUS Status
,
955 IN NDIS_HANDLE ConfigurationHandle
,
956 IN PNDIS_STRING KeyName
,
957 OUT PNDIS_HANDLE KeyHandle
)
959 * FUNCTION: Opens a configuration subkey by name
961 * Status: points to an NDIS_STATUS where status is returned
962 * ConfigurationHandle: handle returned by a previous open call
963 * KeyName: the name of the key to open
964 * KeyHandle: a handle to the opened key
966 * NDIS_STATUS_SUCCESS on success
967 * NDIS_STATUS_FAILURE on failure
968 * KeyHandle holds a handle to the newly-opened key
972 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
973 OBJECT_ATTRIBUTES KeyAttributes
;
974 NDIS_HANDLE RegKeyHandle
;
978 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, ConfigurationHandle
, 0);
979 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
981 if(*Status
!= STATUS_SUCCESS
)
983 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
984 *Status
= NDIS_STATUS_FAILURE
;
988 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
989 if(!ConfigurationContext
)
991 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
992 ZwClose(RegKeyHandle
);
993 *Status
= NDIS_STATUS_FAILURE
;
997 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
998 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
1000 ConfigurationContext
->Handle
= RegKeyHandle
;
1002 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
1004 *Status
= NDIS_STATUS_SUCCESS
;