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 NDIS_DbgPrint(MID_TRACE
, ("Parameter type: %d\n", ParameterValue
->ParameterType
));
74 /* reset parameter type to standard reg types */
75 switch(ParameterValue
->ParameterType
)
77 case NdisParameterHexInteger
:
78 case NdisParameterInteger
:
82 Str
.Buffer
= (PWSTR
) &Buff
;
83 Str
.MaximumLength
= (USHORT
)sizeof(Buff
);
86 ParameterType
= REG_SZ
;
87 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
88 ParameterValue
->ParameterData
.IntegerData
,
89 (ParameterValue
->ParameterType
== NdisParameterInteger
) ? 10 : 16, &Str
)))
91 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
92 *Status
= NDIS_STATUS_FAILURE
;
96 DataSize
= Str
.Length
;
99 case NdisParameterString
:
100 case NdisParameterMultiString
:
101 ParameterType
= (ParameterValue
->ParameterType
== NdisParameterString
) ? REG_SZ
: REG_MULTI_SZ
;
102 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
103 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
106 /* New (undocumented) addition to 2k ddk */
107 case NdisParameterBinary
:
108 ParameterType
= REG_BINARY
;
109 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
110 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
114 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
118 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
119 Keyword
, 0, ParameterType
, Data
, DataSize
);
121 if(*Status
!= STATUS_SUCCESS
) {
122 NDIS_DbgPrint(MIN_TRACE
, ("ZwSetValueKey failed (%x)\n", *Status
));
123 *Status
= NDIS_STATUS_FAILURE
;
125 *Status
= NDIS_STATUS_SUCCESS
;
134 NdisCloseConfiguration(
135 IN NDIS_HANDLE ConfigurationHandle
)
137 * FUNCTION: Closes handles and releases per-handle resources
139 * ConfigurationHandle - pointer to the context with the resources to free
142 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
143 PMINIPORT_RESOURCE Resource
;
144 PNDIS_CONFIGURATION_PARAMETER ParameterValue
;
145 PLIST_ENTRY CurrentEntry
;
147 while((CurrentEntry
= ExInterlockedRemoveHeadList(&ConfigurationContext
->ResourceListHead
,
148 &ConfigurationContext
->ResourceLock
)) != NULL
)
150 Resource
= CONTAINING_RECORD(CurrentEntry
, MINIPORT_RESOURCE
, ListEntry
);
151 switch(Resource
->ResourceType
)
153 case MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
:
154 ParameterValue
= Resource
->Resource
;
156 switch (ParameterValue
->ParameterType
)
158 case NdisParameterBinary
:
159 ExFreePool(ParameterValue
->ParameterData
.BinaryData
.Buffer
);
162 case NdisParameterString
:
163 case NdisParameterMultiString
:
164 ExFreePool(ParameterValue
->ParameterData
.StringData
.Buffer
);
171 /* Fall through to free NDIS_CONFIGURATION_PARAMETER struct */
173 case MINIPORT_RESOURCE_TYPE_MEMORY
:
174 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
175 ExFreePool(Resource
->Resource
);
179 NDIS_DbgPrint(MIN_TRACE
,("Unknown resource type: %d\n", Resource
->ResourceType
));
183 ExFreePool(Resource
);
186 ZwClose(ConfigurationContext
->Handle
);
195 NdisOpenConfiguration(
196 OUT PNDIS_STATUS Status
,
197 OUT PNDIS_HANDLE ConfigurationHandle
,
198 IN NDIS_HANDLE WrapperConfigurationContext
)
200 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
202 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
203 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
204 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
206 * NDIS_STATUS_SUCCESS: the operation completed successfully
207 * NDIS_STATUS_FAILURE: the operation failed
209 * I think this is the parameters key; please verify.
213 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
214 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
215 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
217 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
219 *ConfigurationHandle
= NULL
;
221 *Status
= ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle
,
222 NtCurrentProcess(), &KeyHandle
, 0, 0,
223 DUPLICATE_SAME_ACCESS
);
224 if(!NT_SUCCESS(*Status
))
226 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open registry configuration for this miniport\n"));
227 *Status
= NDIS_STATUS_FAILURE
;
231 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
232 if(!ConfigurationContext
)
234 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
236 *Status
= NDIS_STATUS_RESOURCES
;
240 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
241 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
243 ConfigurationContext
->Handle
= KeyHandle
;
245 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
246 *Status
= NDIS_STATUS_SUCCESS
;
248 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
257 NdisOpenProtocolConfiguration(
258 OUT PNDIS_STATUS Status
,
259 OUT PNDIS_HANDLE ConfigurationHandle
,
260 IN PNDIS_STRING ProtocolSection
)
262 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
264 * Status: caller-allocated buffer where status is returned
265 * ConfigurationHandle: spot to return the opaque configuration context
266 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
268 * NDIS_STATUS_SUCCESS: the operation was a success
269 * NDIS_STATUS_FAILURE: the operation was not a success
271 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
274 OBJECT_ATTRIBUTES KeyAttributes
;
275 UNICODE_STRING KeyNameU
;
277 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
280 KeyNameU
.MaximumLength
= ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(UNICODE_NULL
);
281 KeyNameU
.Buffer
= ExAllocatePool(PagedPool
, KeyNameU
.MaximumLength
);
284 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
285 *ConfigurationHandle
= NULL
;
286 *Status
= NDIS_STATUS_FAILURE
;
290 RtlCopyUnicodeString(&KeyNameU
, ProtocolSection
);
291 RtlAppendUnicodeToString(&KeyNameU
, PARAMETERS_KEY
);
292 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
294 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
296 ExFreePool(KeyNameU
.Buffer
);
298 if(*Status
!= NDIS_STATUS_SUCCESS
)
300 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
301 *ConfigurationHandle
= NULL
;
302 *Status
= NDIS_STATUS_FAILURE
;
306 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
307 if(!ConfigurationContext
)
309 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
311 *ConfigurationHandle
= NULL
;
312 *Status
= NDIS_STATUS_FAILURE
;
316 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
317 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
319 ConfigurationContext
->Handle
= KeyHandle
;
321 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
322 *Status
= NDIS_STATUS_SUCCESS
;
325 UCHAR
UnicodeToHexByte(WCHAR chr
)
327 * FUNCTION: Converts a unicode hex character to its numerical value
329 * chr: Unicode character to convert
331 * The numerical value of chr
369 IsValidNumericString(PNDIS_STRING String
, NDIS_PARAMETER_TYPE
*ParameterType
)
371 * FUNCTION: Determines if a string is a valid number
373 * String: Unicode string to evaluate
375 * TRUE if it is valid, FALSE if not
380 /* I don't think this will ever happen, but we warn it if it does */
381 if (String
->Length
== 0)
383 NDIS_DbgPrint(MIN_TRACE
, ("Got an empty string; not sure what to do here\n"));
387 /* Set the default parameter type */
388 *ParameterType
= NdisParameterInteger
;
391 for (i
= 0; i
< String
->Length
/ sizeof(WCHAR
); i
++)
393 /* Look at the second character for the base */
396 if (String
->Buffer
[i
] == L
'X' ||
397 String
->Buffer
[i
] == L
'x')
399 NDIS_DbgPrint(MID_TRACE
, ("Identified hex string\n"));
400 *ParameterType
= NdisParameterHexInteger
;
406 /* Skip any NULL characters we find */
407 if (String
->Buffer
[i
] == UNICODE_NULL
)
410 /* Make sure the character is valid for a numeric string of this base */
411 if (UnicodeToHexByte(String
->Buffer
[i
]) >= Base
)
424 NdisReadConfiguration(
425 OUT PNDIS_STATUS Status
,
426 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
427 IN NDIS_HANDLE ConfigurationHandle
,
428 IN PNDIS_STRING Keyword
,
429 IN NDIS_PARAMETER_TYPE ParameterType
)
431 * FUNCTION: Read a configuration value from the registry, tracking its resources
433 * Status: points to a place to write status into
434 * ParameterValue: Pointer to receive a newly-allocated parameter structure
435 * ConfigurationHandle: handle originally returned by an open function
436 * Keyword: Value name to read, or one of the following constants:
437 * Environment - returns NdisEnvironmentWindowsNt
438 * ProcessorType - returns NdisProcessorX86 until more architectures are added
439 * NdisVersion - returns NDIS_VERSION
440 * ParameterType: the type of the value to be queried
442 * - A status in Status
443 * - A parameter value in ParameterValue
446 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
448 PMINIPORT_RESOURCE MiniportResource
;
449 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
452 *ParameterValue
= NULL
;
453 *Status
= NDIS_STATUS_FAILURE
;
455 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
456 NDIS_DbgPrint(MID_TRACE
,("requested parameter type: %d\n", ParameterType
));
458 if (ConfigurationContext
== NULL
)
460 NDIS_DbgPrint(MIN_TRACE
,("invalid parameter ConfigurationContext (0x%x)\n",ConfigurationContext
));
465 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
466 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
469 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
472 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
473 *Status
= NDIS_STATUS_RESOURCES
;
477 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
478 if(!MiniportResource
)
480 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
481 ExFreePool(*ParameterValue
);
482 *ParameterValue
= NULL
;
483 *Status
= NDIS_STATUS_RESOURCES
;
487 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
488 MiniportResource
->Resource
= *ParameterValue
;
490 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
491 MiniportResource
->Resource
));
493 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
494 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
496 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
497 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
498 *Status
= NDIS_STATUS_SUCCESS
;
504 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
505 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
508 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
511 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
512 *Status
= NDIS_STATUS_RESOURCES
;
516 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
517 if(!MiniportResource
)
519 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
520 ExFreePool(*ParameterValue
);
521 *ParameterValue
= NULL
;
522 *Status
= NDIS_STATUS_RESOURCES
;
526 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
527 MiniportResource
->Resource
= *ParameterValue
;
528 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
529 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
530 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
532 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
533 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
534 *Status
= NDIS_STATUS_SUCCESS
;
540 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
541 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
544 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
547 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
548 *Status
= NDIS_STATUS_RESOURCES
;
552 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
553 if(!MiniportResource
)
555 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
556 ExFreePool(*ParameterValue
);
557 *ParameterValue
= NULL
;
558 *Status
= NDIS_STATUS_RESOURCES
;
562 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
563 MiniportResource
->Resource
= *ParameterValue
;
564 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
565 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
566 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
568 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
569 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
570 *Status
= NDIS_STATUS_SUCCESS
;
572 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
573 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
577 /* figure out how much buffer i should allocate */
578 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
579 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
581 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
582 *Status
= NDIS_STATUS_FAILURE
;
587 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
590 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
591 *Status
= NDIS_STATUS_RESOURCES
;
596 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
597 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
598 if(*Status
!= STATUS_SUCCESS
)
600 ExFreePool(KeyInformation
);
601 NDIS_DbgPrint(MIN_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
602 *Status
= NDIS_STATUS_FAILURE
;
606 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
607 if(!MiniportResource
)
609 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
610 ExFreePool(KeyInformation
);
611 *Status
= NDIS_STATUS_RESOURCES
;
615 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
616 if (!*ParameterValue
)
618 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
619 ExFreePool(MiniportResource
);
620 ExFreePool(KeyInformation
);
621 *Status
= NDIS_STATUS_RESOURCES
;
625 RtlZeroMemory(*ParameterValue
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
627 if (KeyInformation
->Type
== REG_BINARY
)
629 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterBinary\n"));
631 (*ParameterValue
)->ParameterType
= NdisParameterBinary
;
633 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
636 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
637 ExFreePool(MiniportResource
);
638 ExFreePool(KeyInformation
);
639 *Status
= NDIS_STATUS_RESOURCES
;
643 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
645 (*ParameterValue
)->ParameterData
.BinaryData
.Buffer
= Buffer
;
646 (*ParameterValue
)->ParameterData
.BinaryData
.Length
= KeyInformation
->DataLength
;
648 else if (KeyInformation
->Type
== REG_MULTI_SZ
)
650 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterMultiString\n"));
652 (*ParameterValue
)->ParameterType
= NdisParameterMultiString
;
654 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
657 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
658 ExFreePool(MiniportResource
);
659 ExFreePool(KeyInformation
);
660 *Status
= NDIS_STATUS_RESOURCES
;
664 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
666 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
667 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
669 else if (KeyInformation
->Type
== REG_SZ
)
673 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
674 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
676 if (IsValidNumericString(&str
, &(*ParameterValue
)->ParameterType
) &&
677 ((*Status
= RtlUnicodeStringToInteger(&str
, 0,
678 &(*ParameterValue
)->ParameterData
.IntegerData
)) == STATUS_SUCCESS
))
680 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameter(Hex)Integer\n"));
682 /* IsValidNumericString sets the parameter type when parsing the string */
686 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterString\n"));
688 (*ParameterValue
)->ParameterType
= NdisParameterString
;
690 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
693 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
694 ExFreePool(MiniportResource
);
695 ExFreePool(KeyInformation
);
696 *Status
= NDIS_STATUS_RESOURCES
;
700 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
702 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
703 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
708 NDIS_DbgPrint(MIN_TRACE
, ("Invalid type for NdisReadConfiguration (%d)\n", KeyInformation
->Type
));
709 NDIS_DbgPrint(MIN_TRACE
, ("Requested type: %d\n", ParameterType
));
710 NDIS_DbgPrint(MIN_TRACE
, ("Registry entry: %wZ\n", Keyword
));
711 *Status
= NDIS_STATUS_FAILURE
;
712 ExFreePool(KeyInformation
);
716 if ((*ParameterValue
)->ParameterType
!= ParameterType
)
718 NDIS_DbgPrint(MIN_TRACE
, ("Parameter type mismatch! (Requested: %d | Received: %d)\n",
719 ParameterType
, (*ParameterValue
)->ParameterType
));
720 NDIS_DbgPrint(MIN_TRACE
, ("Registry entry: %wZ\n", Keyword
));
723 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_REGISTRY_DATA
;
724 MiniportResource
->Resource
= *ParameterValue
;
726 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
728 ExFreePool(KeyInformation
);
730 *Status
= NDIS_STATUS_SUCCESS
;
738 NdisReadNetworkAddress(
739 OUT PNDIS_STATUS Status
,
740 OUT PVOID
* NetworkAddress
,
741 OUT PUINT NetworkAddressLength
,
742 IN NDIS_HANDLE ConfigurationHandle
)
744 * FUNCTION: Reads the network address from the registry
746 * Status - variable to receive status
747 * NetworkAddress - pointer to a buffered network address array
748 * NetworkAddressLength - length of the NetworkAddress array
749 * ConfigurationHandle: handle passed back from one of the open routines
751 * NDIS_STATUS_SUCCESS on success
752 * NDIS_STATUS_FAILURE on failure
753 * The network address is placed in the NetworkAddress buffer
756 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
757 PMINIPORT_RESOURCE MiniportResource
= NULL
;
758 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
764 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
765 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
766 if(*Status
!= NDIS_STATUS_SUCCESS
)
768 NDIS_DbgPrint(MID_TRACE
, ("NdisReadConfiguration failed (%x)\n", *Status
));
769 *Status
= NDIS_STATUS_FAILURE
;
773 if (ParameterValue
->ParameterType
== NdisParameterInteger
)
777 NDIS_DbgPrint(MAX_TRACE
, ("Read integer data %lx\n",
778 ParameterValue
->ParameterData
.IntegerData
));
781 str
.MaximumLength
= (USHORT
)sizeof(Buff
);
784 *Status
= RtlIntegerToUnicodeString(ParameterValue
->ParameterData
.IntegerData
,
788 if (*Status
!= NDIS_STATUS_SUCCESS
)
790 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
791 *Status
= NDIS_STATUS_FAILURE
;
795 NDIS_DbgPrint(MAX_TRACE
, ("Converted integer data into %wZ\n", &str
));
799 ASSERT(ParameterValue
->ParameterType
== NdisParameterString
);
800 str
= ParameterValue
->ParameterData
.StringData
;
803 while (j
< str
.Length
&& str
.Buffer
[j
] != '\0') j
++;
805 *NetworkAddressLength
= (j
+1) >> 1;
807 if ((*NetworkAddressLength
) == 0)
809 NDIS_DbgPrint(MIN_TRACE
,("Empty NetworkAddress registry entry.\n"));
810 *Status
= NDIS_STATUS_FAILURE
;
814 IntArray
= ExAllocatePool(PagedPool
, (*NetworkAddressLength
)*sizeof(UINT
));
817 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
818 *Status
= NDIS_STATUS_RESOURCES
;
822 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
823 if(!MiniportResource
)
825 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
826 ExFreePool(IntArray
);
827 *Status
= NDIS_STATUS_RESOURCES
;
831 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_MEMORY
;
832 MiniportResource
->Resource
= IntArray
;
833 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
834 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
836 /* convert from string to bytes */
837 for(i
=0; i
<(*NetworkAddressLength
); i
++)
839 IntArray
[i
] = (UnicodeToHexByte((str
.Buffer
)[2*i
]) << 4) +
840 UnicodeToHexByte((str
.Buffer
)[2*i
+1]);
843 *NetworkAddress
= IntArray
;
845 *Status
= NDIS_STATUS_SUCCESS
;
854 NdisOpenConfigurationKeyByIndex(
855 OUT PNDIS_STATUS Status
,
856 IN NDIS_HANDLE ConfigurationHandle
,
858 OUT PNDIS_STRING KeyName
,
859 OUT PNDIS_HANDLE KeyHandle
)
861 * FUNCTION: Opens a configuration subkey by index number
863 * Status: pointer to an NDIS_STATUS to receive status info
864 * ConfigurationHandle: the handle passed back from a previous open function
865 * Index: the zero-based index of the subkey to open
866 * KeyName: the name of the key that was opened
867 * KeyHandle: a handle to the key that was opened
869 * NDIS_STATUS_SUCCESS on success
870 * NDIS_STATUS_FAILURE on failure
871 * KeyName holds the name of the opened key
872 * KeyHandle holds a handle to the new key
875 KEY_BASIC_INFORMATION
*KeyInformation
;
876 ULONG KeyInformationLength
;
877 OBJECT_ATTRIBUTES KeyAttributes
;
878 NDIS_HANDLE RegKeyHandle
;
879 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
883 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
884 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
886 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
887 *Status
= NDIS_STATUS_FAILURE
;
891 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
894 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
895 *Status
= NDIS_STATUS_FAILURE
;
899 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
900 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
902 if(*Status
!= STATUS_SUCCESS
)
904 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
905 ExFreePool(KeyInformation
);
906 *Status
= NDIS_STATUS_FAILURE
;
910 /* should i fail instead if the passed-in string isn't long enough? */
911 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
912 KeyName
->Length
= (USHORT
)min(KeyInformation
->NameLength
, KeyName
->MaximumLength
);
914 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
916 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
918 ExFreePool(KeyInformation
);
920 if(*Status
!= STATUS_SUCCESS
)
922 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
923 *Status
= NDIS_STATUS_FAILURE
;
927 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
928 if(!ConfigurationContext
)
930 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
931 ZwClose(RegKeyHandle
);
932 *Status
= NDIS_STATUS_FAILURE
;
936 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
937 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
939 ConfigurationContext
->Handle
= RegKeyHandle
;
941 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
943 *Status
= NDIS_STATUS_SUCCESS
;
952 NdisOpenConfigurationKeyByName(
953 OUT PNDIS_STATUS Status
,
954 IN NDIS_HANDLE ConfigurationHandle
,
955 IN PNDIS_STRING KeyName
,
956 OUT PNDIS_HANDLE KeyHandle
)
958 * FUNCTION: Opens a configuration subkey by name
960 * Status: points to an NDIS_STATUS where status is returned
961 * ConfigurationHandle: handle returned by a previous open call
962 * KeyName: the name of the key to open
963 * KeyHandle: a handle to the opened key
965 * NDIS_STATUS_SUCCESS on success
966 * NDIS_STATUS_FAILURE on failure
967 * KeyHandle holds a handle to the newly-opened key
971 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
972 OBJECT_ATTRIBUTES KeyAttributes
;
973 NDIS_HANDLE RegKeyHandle
;
977 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
978 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
980 if(*Status
!= STATUS_SUCCESS
)
982 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
983 *Status
= NDIS_STATUS_FAILURE
;
987 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
988 if(!ConfigurationContext
)
990 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
991 ZwClose(RegKeyHandle
);
992 *Status
= NDIS_STATUS_FAILURE
;
996 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
997 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
999 ConfigurationContext
->Handle
= RegKeyHandle
;
1001 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
1003 *Status
= NDIS_STATUS_SUCCESS
;