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 NDIS_VERSION 0x00040000 /* the version of NDIS we claim to be to miniport drivers */
37 #define PARAMETERS_KEY L"Parameters" /* The parameters subkey under the device-specific key */
44 NdisWriteConfiguration(
45 OUT PNDIS_STATUS Status
,
46 IN NDIS_HANDLE ConfigurationHandle
,
47 IN PNDIS_STRING Keyword
,
48 IN PNDIS_CONFIGURATION_PARAMETER ParameterValue
)
50 * FUNCTION: Writes a configuration value to the registry
52 * Status: Pointer to a caller-supplied NDIS_STATUS where we return status
53 * ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
54 * Keyword: The registry value name to write
55 * ParameterValue: The value data to write
57 * NDIS_STATUS_SUCCESS - the operation completed successfully
58 * NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
59 * NDIS_STATUS_RESOURCES - out of memory, etc.
60 * NDIS_STATUS_FAILURE - any other failure
62 * There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
63 * I don't know why tho so i free everything before return. comments welcome.
66 ULONG ParameterType
= ParameterValue
->ParameterType
;
70 if(ParameterType
!= NdisParameterInteger
&&
71 ParameterType
!= NdisParameterHexInteger
&&
72 ParameterType
!= NdisParameterString
&&
73 ParameterType
!= NdisParameterMultiString
&&
74 ParameterType
!= NdisParameterBinary
77 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
81 /* reset parameter type to standard reg types */
84 /* TODO: figure out what do do with these; are they different? */
85 case NdisParameterHexInteger
:
86 case NdisParameterInteger
:
87 ParameterType
= REG_SZ
;
88 Data
= &ParameterValue
->ParameterData
.IntegerData
;
89 DataSize
= sizeof(ULONG
);
92 case NdisParameterString
:
93 case NdisParameterMultiString
:
94 ParameterType
= REG_SZ
;
95 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
96 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
99 /* New (undocumented) addition to 2k ddk */
100 case NdisParameterBinary
:
101 ParameterType
= REG_BINARY
;
102 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
103 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
107 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
108 Keyword
, 0, ParameterType
, Data
, DataSize
);
110 if(*Status
!= STATUS_SUCCESS
)
111 *Status
= NDIS_STATUS_FAILURE
;
113 *Status
= NDIS_STATUS_SUCCESS
;
122 NdisCloseConfiguration(
123 IN NDIS_HANDLE ConfigurationHandle
)
125 * FUNCTION: Closes handles and releases per-handle resources
127 * ConfigurationHandle - pointer to the context with the resources to free
130 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
131 PMINIPORT_RESOURCE Resource
;
133 while(!IsListEmpty(&ConfigurationContext
->ResourceListHead
))
135 Resource
= (PMINIPORT_RESOURCE
)RemoveTailList(&ConfigurationContext
->ResourceListHead
);
136 if(Resource
->ResourceType
== MINIPORT_RESOURCE_TYPE_MEMORY
)
138 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
139 ExFreePool(Resource
->Resource
);
142 ExFreePool(Resource
);
145 ZwClose(ConfigurationContext
->Handle
);
154 NdisOpenConfiguration(
155 OUT PNDIS_STATUS Status
,
156 OUT PNDIS_HANDLE ConfigurationHandle
,
157 IN NDIS_HANDLE WrapperConfigurationContext
)
159 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
161 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
162 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
163 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
165 * NDIS_STATUS_SUCCESS: the operation completed successfully
166 * NDIS_STATUS_FAILURE: the operation failed
168 * I think this is the parameters key; please verify.
171 OBJECT_ATTRIBUTES KeyAttributes
;
172 UNICODE_STRING KeyNameU
;
174 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
175 HANDLE RootKeyHandle
= (HANDLE
)WrapperConfigurationContext
;
177 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
179 RtlInitUnicodeString(&KeyNameU
, PARAMETERS_KEY
);
180 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, RootKeyHandle
, NULL
);
182 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
183 if(*Status
!= STATUS_SUCCESS
)
185 *ConfigurationHandle
= NULL
;
186 *Status
= NDIS_STATUS_FAILURE
;
190 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
191 if(!ConfigurationContext
)
193 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
195 *Status
= NDIS_STATUS_RESOURCES
;
199 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
200 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
202 ConfigurationContext
->Handle
= KeyHandle
;
204 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
205 *Status
= NDIS_STATUS_SUCCESS
;
207 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
216 NdisOpenProtocolConfiguration(
217 OUT PNDIS_STATUS Status
,
218 OUT PNDIS_HANDLE ConfigurationHandle
,
219 IN PNDIS_STRING ProtocolSection
)
221 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
223 * Status: caller-allocated buffer where status is returned
224 * ConfigurationHandle: spot to return the opaque configuration context
225 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
227 * NDIS_STATUS_SUCCESS: the operation was a success
228 * NDIS_STATUS_FAILURE: the operation was not a success
230 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
233 OBJECT_ATTRIBUTES KeyAttributes
;
234 UNICODE_STRING KeyNameU
;
237 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
239 KeyName
= ExAllocatePool(PagedPool
, ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(WCHAR
));
242 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
243 *ConfigurationHandle
= NULL
;
244 *Status
= NDIS_STATUS_FAILURE
;
248 wcsncpy(KeyName
, ProtocolSection
->Buffer
, ProtocolSection
->Length
/sizeof(WCHAR
));
249 wcscpy(KeyName
+ ProtocolSection
->Length
, PARAMETERS_KEY
);
250 RtlInitUnicodeString(&KeyNameU
, KeyName
);
251 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
253 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
257 if(*Status
!= NDIS_STATUS_SUCCESS
)
259 *ConfigurationHandle
= NULL
;
260 *Status
= NDIS_STATUS_FAILURE
;
264 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
265 if(!ConfigurationContext
)
267 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
268 *ConfigurationHandle
= NULL
;
269 *Status
= NDIS_STATUS_FAILURE
;
273 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
274 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
276 ConfigurationContext
->Handle
= KeyHandle
;
278 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
279 *Status
= NDIS_STATUS_SUCCESS
;
288 NdisReadConfiguration(
289 OUT PNDIS_STATUS Status
,
290 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
291 IN NDIS_HANDLE ConfigurationHandle
,
292 IN PNDIS_STRING Keyword
,
293 IN NDIS_PARAMETER_TYPE ParameterType
)
295 * FUNCTION: Read a configuration value from the registry, tracking its resources
297 * Status: points to a place to write status into
298 * ParameterValue: Pointer to receive a newly-allocated parameter structure
299 * ConfigurationHandle: handle originally returned by an open function
300 * Keyword: Value name to read, or one of the following constants:
301 * Environment - returns NdisEnvironmentWindowsNt
302 * ProcessorType - returns NdisProcessorX86 until more architectures are added
303 * NdisVersion - returns NDIS_VERSION
304 * ParameterType: the type of the value to be queried
306 * - A status in Status
307 * - A parameter value in ParameterValue
310 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
312 PMINIPORT_RESOURCE MiniportResource
;
313 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
315 *ParameterValue
= NULL
;
316 *Status
= NDIS_STATUS_FAILURE
;
318 if(ParameterType
!= NdisParameterInteger
&&
319 ParameterType
!= NdisParameterHexInteger
&&
320 ParameterType
!= NdisParameterString
&&
321 ParameterType
!= NdisParameterMultiString
&&
322 ParameterType
!= NdisParameterBinary
325 NDIS_DbgPrint(MID_TRACE
,("unsupported parameter type\n"));
329 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
332 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
333 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
336 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(ULONG
));
339 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
340 *Status
= NDIS_STATUS_RESOURCES
;
344 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
345 if(!MiniportResource
)
347 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
348 *ParameterValue
= NULL
;
349 *Status
= NDIS_STATUS_RESOURCES
;
353 MiniportResource
->ResourceType
= 0;
354 MiniportResource
->Resource
= *ParameterValue
;
356 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
357 MiniportResource
->Resource
));
359 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
360 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
362 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
363 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
364 *Status
= NDIS_STATUS_SUCCESS
;
370 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
371 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
374 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(ULONG
));
377 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
378 *Status
= NDIS_STATUS_RESOURCES
;
382 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
383 if(!MiniportResource
)
385 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
386 *ParameterValue
= NULL
;
387 *Status
= NDIS_STATUS_RESOURCES
;
391 MiniportResource
->ResourceType
= 0;
392 MiniportResource
->Resource
= *ParameterValue
;
393 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
394 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
395 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
397 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
398 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
399 *Status
= NDIS_STATUS_SUCCESS
;
405 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
406 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
409 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(ULONG
));
412 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
413 *Status
= NDIS_STATUS_RESOURCES
;
417 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
418 if(!MiniportResource
)
420 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
421 *ParameterValue
= NULL
;
422 *Status
= NDIS_STATUS_RESOURCES
;
426 MiniportResource
->ResourceType
= 0;
427 MiniportResource
->Resource
= *ParameterValue
;
428 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
429 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
430 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
432 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
433 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
434 *Status
= NDIS_STATUS_SUCCESS
;
439 /* figure out how much buffer i should allocate */
440 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
441 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
443 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
444 *Status
= NDIS_STATUS_FAILURE
;
449 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
452 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
453 *Status
= NDIS_STATUS_RESOURCES
;
458 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
459 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
460 if(*Status
!= STATUS_SUCCESS
)
462 ExFreePool(KeyInformation
);
463 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
464 *Status
= NDIS_STATUS_FAILURE
;
468 switch(ParameterType
)
470 case NdisParameterInteger
:
471 case NdisParameterHexInteger
:
475 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
478 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
479 ExFreePool(KeyInformation
);
480 *Status
= NDIS_STATUS_RESOURCES
;
484 str
.Length
= str
.MaximumLength
= KeyInformation
->DataLength
;
485 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
487 (*ParameterValue
)->ParameterType
= ParameterType
;
488 *Status
= RtlUnicodeStringToInteger(&str
, 16, &(*ParameterValue
)->ParameterData
.IntegerData
);
490 ExFreePool(KeyInformation
);
492 if(*Status
!= STATUS_SUCCESS
)
493 *Status
= NDIS_STATUS_FAILURE
;
495 *Status
= NDIS_STATUS_SUCCESS
;
500 case NdisParameterString
:
501 case NdisParameterMultiString
:
503 PMINIPORT_RESOURCE MiniportResource
= 0;
506 if(KeyInformation
->Type
!= REG_SZ
&& KeyInformation
->Type
!= REG_MULTI_SZ
)
508 NDIS_DbgPrint(MID_TRACE
,("requested type does not match actual value type\n"));
509 ExFreePool(KeyInformation
);
510 *ParameterValue
= NULL
;
511 *Status
= NDIS_STATUS_FAILURE
;
515 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
518 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
519 ExFreePool(KeyInformation
);
520 *Status
= NDIS_STATUS_RESOURCES
;
524 RegData
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
527 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
528 ExFreePool(KeyInformation
);
529 ExFreePool(*ParameterValue
);
530 *ParameterValue
= NULL
;
531 *Status
= NDIS_STATUS_FAILURE
;
535 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
536 if(!MiniportResource
)
538 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
539 ExFreePool(KeyInformation
);
540 ExFreePool(*ParameterValue
);
541 *ParameterValue
= NULL
;
542 *Status
= NDIS_STATUS_RESOURCES
;
546 MiniportResource
->ResourceType
= 0;
547 MiniportResource
->Resource
= *ParameterValue
;
548 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
549 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
551 memcpy(RegData
, KeyInformation
->Data
, KeyInformation
->DataLength
);
553 (*ParameterValue
)->ParameterType
= ParameterType
;
554 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
555 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= RegData
;
557 ExFreePool(KeyInformation
);
559 *Status
= NDIS_STATUS_SUCCESS
;
564 case NdisParameterBinary
:
566 PMINIPORT_RESOURCE MiniportResource
;
568 if(KeyInformation
->Type
!= REG_BINARY
)
570 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
571 *Status
= NDIS_STATUS_FAILURE
;
572 ExFreePool(KeyInformation
);
576 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
) + KeyInformation
->DataLength
);
579 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
580 ExFreePool(KeyInformation
);
581 *Status
= NDIS_STATUS_RESOURCES
;
585 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
586 if(!MiniportResource
)
588 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
589 ExFreePool(KeyInformation
);
590 ExFreePool(*ParameterValue
);
591 *ParameterValue
= NULL
;
592 *Status
= NDIS_STATUS_RESOURCES
;
596 MiniportResource
->ResourceType
= 0;
597 MiniportResource
->Resource
= *ParameterValue
;
598 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
599 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
601 (*ParameterValue
)->ParameterType
= ParameterType
;
602 memcpy(&((*ParameterValue
)->ParameterData
.BinaryData
), KeyInformation
->Data
, KeyInformation
->DataLength
);
604 ExFreePool(KeyInformation
);
606 *Status
= NDIS_STATUS_SUCCESS
;
614 UCHAR
UnicodeToHexByte(WCHAR chr
)
616 * FUNCTION: Converts a unicode hex character to its numerical value
618 * chr: Unicode character to convert
620 * The numerical value of chr
663 NdisReadNetworkAddress(
664 OUT PNDIS_STATUS Status
,
665 OUT PVOID
* NetworkAddress
,
666 OUT PUINT NetworkAddressLength
,
667 IN NDIS_HANDLE ConfigurationHandle
)
669 * FUNCTION: Reads the network address from the registry
671 * Status - variable to receive status
672 * NetworkAddress - pointer to a buffered network address array
673 * NetworkAddressLength - length of the NetworkAddress array
674 * ConfigurationHandle: handle passed back from one of the open routines
676 * NDIS_STATUS_SUCCESS on success
677 * NDIS_STATUS_FAILURE on failure
678 * The network address is placed in the NetworkAddress buffer
681 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
682 PMINIPORT_RESOURCE MiniportResource
= NULL
;
683 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
688 /* FIXME - We don't quite support this yet due to buggy code below */
690 *Status
= NDIS_STATUS_FAILURE
;
694 *NetworkAddress
= NULL
;
695 *NetworkAddressLength
= 6;/* XXX magic constant */
697 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
698 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
699 if(*Status
!= NDIS_STATUS_SUCCESS
)
701 *Status
= NDIS_STATUS_FAILURE
;
705 /* 6 bytes for ethernet, tokenring, fddi, everything else? */
706 IntArray
= ExAllocatePool(PagedPool
, 6*sizeof(UINT
));
709 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
710 *Status
= NDIS_STATUS_RESOURCES
;
714 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
715 if(!MiniportResource
)
717 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
718 *Status
= NDIS_STATUS_FAILURE
;
722 MiniportResource
->ResourceType
= 0;
723 MiniportResource
->Resource
= IntArray
;
724 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
725 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
727 /* convert from string to bytes */
730 IntArray
[i
] = (UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
]) << 4) +
731 UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
+1]);
734 *NetworkAddress
= IntArray
;
736 *Status
= NDIS_STATUS_SUCCESS
;
745 NdisOpenConfigurationKeyByIndex(
746 OUT PNDIS_STATUS Status
,
747 IN NDIS_HANDLE ConfigurationHandle
,
749 OUT PNDIS_STRING KeyName
,
750 OUT PNDIS_HANDLE KeyHandle
)
752 * FUNCTION: Opens a configuration subkey by index number
754 * Status: pointer to an NDIS_STATUS to receive status info
755 * ConfigurationHandle: the handle passed back from a previous open function
756 * Index: the zero-based index of the subkey to open
757 * KeyName: the name of the key that was opened
758 * KeyHandle: a handle to the key that was opened
760 * NDIS_STATUS_SUCCESS on success
761 * NDIS_STATUS_FAILURE on failure
762 * KeyName holds the name of the opened key
763 * KeyHandle holds a handle to the new key
766 KEY_BASIC_INFORMATION
*KeyInformation
;
767 ULONG KeyInformationLength
;
768 OBJECT_ATTRIBUTES KeyAttributes
;
769 NDIS_HANDLE RegKeyHandle
;
770 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
772 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
773 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
775 *Status
= NDIS_STATUS_FAILURE
;
779 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
782 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
783 *Status
= NDIS_STATUS_FAILURE
;
787 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
788 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
790 if(*Status
!= STATUS_SUCCESS
)
792 ExFreePool(KeyInformation
);
793 *Status
= NDIS_STATUS_FAILURE
;
797 /* should i fail instead if the passed-in string isn't long enough? */
798 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
799 KeyName
->Length
= KeyInformation
->NameLength
;
801 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
803 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
805 ExFreePool(KeyInformation
);
807 if(*Status
!= STATUS_SUCCESS
)
809 *Status
= NDIS_STATUS_FAILURE
;
813 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
814 if(!ConfigurationContext
)
816 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
817 *Status
= NDIS_STATUS_FAILURE
;
821 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
822 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
824 ConfigurationContext
->Handle
= RegKeyHandle
;
826 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
828 *Status
= NDIS_STATUS_SUCCESS
;
837 NdisOpenConfigurationKeyByName(
838 OUT PNDIS_STATUS Status
,
839 IN NDIS_HANDLE ConfigurationHandle
,
840 IN PNDIS_STRING KeyName
,
841 OUT PNDIS_HANDLE KeyHandle
)
843 * FUNCTION: Opens a configuration subkey by name
845 * Status: points to an NDIS_STATUS where status is returned
846 * ConfigurationHandle: handle returned by a previous open call
847 * KeyName: the name of the key to open
848 * KeyHandle: a handle to the opened key
850 * NDIS_STATUS_SUCCESS on success
851 * NDIS_STATUS_FAILURE on failure
852 * KeyHandle holds a handle to the newly-opened key
856 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
857 OBJECT_ATTRIBUTES KeyAttributes
;
858 NDIS_HANDLE RegKeyHandle
;
860 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
861 *Status
= ZwOpenKey(RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
863 if(*Status
!= STATUS_SUCCESS
)
865 *Status
= NDIS_STATUS_FAILURE
;
869 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
870 if(!ConfigurationContext
)
872 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
873 *Status
= NDIS_STATUS_FAILURE
;
877 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
878 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
880 ConfigurationContext
->Handle
= RegKeyHandle
;
882 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
884 *Status
= NDIS_STATUS_SUCCESS
;