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
37 #define NDIS_VERSION 0x00040000 /* the version of NDIS we claim to be to miniport drivers */
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.
67 ULONG ParameterType
= ParameterValue
->ParameterType
;
71 if(ParameterType
!= NdisParameterInteger
&&
72 ParameterType
!= NdisParameterHexInteger
&&
73 ParameterType
!= NdisParameterString
&&
74 ParameterType
!= NdisParameterMultiString
&&
75 ParameterType
!= NdisParameterBinary
78 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
82 /* reset parameter type to standard reg types */
85 /* TODO: figure out what do do with these; are they different? */
86 case NdisParameterHexInteger
:
87 case NdisParameterInteger
:
88 ParameterType
= REG_SZ
;
89 Data
= &ParameterValue
->ParameterData
.IntegerData
;
90 DataSize
= sizeof(ULONG
);
93 case NdisParameterString
:
94 case NdisParameterMultiString
:
95 ParameterType
= REG_SZ
;
96 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
97 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
100 /* New (undocumented) addition to 2k ddk */
101 case NdisParameterBinary
:
102 ParameterType
= REG_BINARY
;
103 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
104 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
108 *Status
= NDIS_STATUS_FAILURE
;
112 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
113 Keyword
, 0, ParameterType
, Data
, DataSize
);
115 if(*Status
!= STATUS_SUCCESS
)
116 *Status
= NDIS_STATUS_FAILURE
;
118 *Status
= NDIS_STATUS_SUCCESS
;
127 NdisCloseConfiguration(
128 IN NDIS_HANDLE ConfigurationHandle
)
130 * FUNCTION: Closes handles and releases per-handle resources
132 * ConfigurationHandle - pointer to the context with the resources to free
135 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
136 PMINIPORT_RESOURCE Resource
;
138 while(!IsListEmpty(&ConfigurationContext
->ResourceListHead
))
140 Resource
= (PMINIPORT_RESOURCE
)RemoveTailList(&ConfigurationContext
->ResourceListHead
);
141 if(Resource
->ResourceType
== MINIPORT_RESOURCE_TYPE_MEMORY
)
143 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
144 ExFreePool(Resource
->Resource
);
147 ExFreePool(Resource
);
150 ZwClose(ConfigurationContext
->Handle
);
159 NdisOpenConfiguration(
160 OUT PNDIS_STATUS Status
,
161 OUT PNDIS_HANDLE ConfigurationHandle
,
162 IN NDIS_HANDLE WrapperConfigurationContext
)
164 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
166 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
167 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
168 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
170 * NDIS_STATUS_SUCCESS: the operation completed successfully
171 * NDIS_STATUS_FAILURE: the operation failed
173 * I think this is the parameters key; please verify.
177 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
178 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
179 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
181 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
183 *Status
= ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle
,
184 NtCurrentProcess(), &KeyHandle
, 0, FALSE
,
185 DUPLICATE_SAME_ACCESS
);
186 if(!NT_SUCCESS(*Status
))
188 NDIS_DbgPrint(MID_TRACE
, ("Failed to open registry configuration for this miniport\n"));
189 *ConfigurationHandle
= NULL
;
190 *Status
= NDIS_STATUS_FAILURE
;
194 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
195 if(!ConfigurationContext
)
197 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
199 *Status
= NDIS_STATUS_RESOURCES
;
203 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
204 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
206 ConfigurationContext
->Handle
= KeyHandle
;
208 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
209 *Status
= NDIS_STATUS_SUCCESS
;
211 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
220 NdisOpenProtocolConfiguration(
221 OUT PNDIS_STATUS Status
,
222 OUT PNDIS_HANDLE ConfigurationHandle
,
223 IN PNDIS_STRING ProtocolSection
)
225 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
227 * Status: caller-allocated buffer where status is returned
228 * ConfigurationHandle: spot to return the opaque configuration context
229 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
231 * NDIS_STATUS_SUCCESS: the operation was a success
232 * NDIS_STATUS_FAILURE: the operation was not a success
234 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
237 OBJECT_ATTRIBUTES KeyAttributes
;
238 UNICODE_STRING KeyNameU
;
241 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
243 KeyName
= ExAllocatePool(PagedPool
, ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(WCHAR
));
246 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
247 *ConfigurationHandle
= NULL
;
248 *Status
= NDIS_STATUS_FAILURE
;
252 wcsncpy(KeyName
, ProtocolSection
->Buffer
, ProtocolSection
->Length
/sizeof(WCHAR
));
253 wcscpy(KeyName
+ ProtocolSection
->Length
, PARAMETERS_KEY
);
254 RtlInitUnicodeString(&KeyNameU
, KeyName
);
255 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
257 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
261 if(*Status
!= NDIS_STATUS_SUCCESS
)
263 *ConfigurationHandle
= NULL
;
264 *Status
= NDIS_STATUS_FAILURE
;
268 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
269 if(!ConfigurationContext
)
271 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
272 *ConfigurationHandle
= NULL
;
273 *Status
= NDIS_STATUS_FAILURE
;
277 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
278 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
280 ConfigurationContext
->Handle
= KeyHandle
;
282 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
283 *Status
= NDIS_STATUS_SUCCESS
;
292 NdisReadConfiguration(
293 OUT PNDIS_STATUS Status
,
294 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
295 IN NDIS_HANDLE ConfigurationHandle
,
296 IN PNDIS_STRING Keyword
,
297 IN NDIS_PARAMETER_TYPE ParameterType
)
299 * FUNCTION: Read a configuration value from the registry, tracking its resources
301 * Status: points to a place to write status into
302 * ParameterValue: Pointer to receive a newly-allocated parameter structure
303 * ConfigurationHandle: handle originally returned by an open function
304 * Keyword: Value name to read, or one of the following constants:
305 * Environment - returns NdisEnvironmentWindowsNt
306 * ProcessorType - returns NdisProcessorX86 until more architectures are added
307 * NdisVersion - returns NDIS_VERSION
308 * ParameterType: the type of the value to be queried
310 * - A status in Status
311 * - A parameter value in ParameterValue
314 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
316 PMINIPORT_RESOURCE MiniportResource
;
317 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
319 *ParameterValue
= NULL
;
320 *Status
= NDIS_STATUS_FAILURE
;
322 if(ParameterType
!= NdisParameterInteger
&&
323 ParameterType
!= NdisParameterHexInteger
&&
324 ParameterType
!= NdisParameterString
&&
325 ParameterType
!= NdisParameterMultiString
&&
326 ParameterType
!= NdisParameterBinary
329 NDIS_DbgPrint(MID_TRACE
,("unsupported parameter type\n"));
333 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
336 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
337 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
340 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
343 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
344 *Status
= NDIS_STATUS_RESOURCES
;
348 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
349 if(!MiniportResource
)
351 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
352 ExFreePool(*ParameterValue
);
353 *ParameterValue
= NULL
;
354 *Status
= NDIS_STATUS_RESOURCES
;
358 MiniportResource
->ResourceType
= 0;
359 MiniportResource
->Resource
= *ParameterValue
;
361 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
362 MiniportResource
->Resource
));
364 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
365 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
367 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
368 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
369 *Status
= NDIS_STATUS_SUCCESS
;
375 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
376 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
379 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
382 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
383 *Status
= NDIS_STATUS_RESOURCES
;
387 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
388 if(!MiniportResource
)
390 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
391 ExFreePool(*ParameterValue
);
392 *ParameterValue
= NULL
;
393 *Status
= NDIS_STATUS_RESOURCES
;
397 MiniportResource
->ResourceType
= 0;
398 MiniportResource
->Resource
= *ParameterValue
;
399 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
400 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
401 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
403 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
404 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
405 *Status
= NDIS_STATUS_SUCCESS
;
411 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
412 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
415 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
418 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
419 *Status
= NDIS_STATUS_RESOURCES
;
423 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
424 if(!MiniportResource
)
426 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
427 ExFreePool(*ParameterValue
);
428 *ParameterValue
= NULL
;
429 *Status
= NDIS_STATUS_RESOURCES
;
433 MiniportResource
->ResourceType
= 0;
434 MiniportResource
->Resource
= *ParameterValue
;
435 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
436 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
437 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
439 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
440 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
441 *Status
= NDIS_STATUS_SUCCESS
;
443 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
444 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
448 /* figure out how much buffer i should allocate */
449 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
450 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
452 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
453 *Status
= NDIS_STATUS_FAILURE
;
458 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
461 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
462 *Status
= NDIS_STATUS_RESOURCES
;
467 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
468 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
469 if(*Status
!= STATUS_SUCCESS
)
471 ExFreePool(KeyInformation
);
472 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
473 *Status
= NDIS_STATUS_FAILURE
;
477 switch(ParameterType
)
479 case NdisParameterInteger
:
480 case NdisParameterHexInteger
:
484 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
487 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
488 ExFreePool(KeyInformation
);
489 *Status
= NDIS_STATUS_RESOURCES
;
493 str
.Length
= str
.MaximumLength
= KeyInformation
->DataLength
;
494 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
496 (*ParameterValue
)->ParameterType
= ParameterType
;
497 *Status
= RtlUnicodeStringToInteger(&str
, 16, &(*ParameterValue
)->ParameterData
.IntegerData
);
499 ExFreePool(KeyInformation
);
501 if(*Status
!= STATUS_SUCCESS
)
502 *Status
= NDIS_STATUS_FAILURE
;
504 *Status
= NDIS_STATUS_SUCCESS
;
509 case NdisParameterString
:
510 case NdisParameterMultiString
:
512 PMINIPORT_RESOURCE MiniportResource
= 0;
515 if(KeyInformation
->Type
!= REG_SZ
&& KeyInformation
->Type
!= REG_MULTI_SZ
)
517 NDIS_DbgPrint(MID_TRACE
,("requested type does not match actual value type\n"));
518 ExFreePool(KeyInformation
);
519 *ParameterValue
= NULL
;
520 *Status
= NDIS_STATUS_FAILURE
;
524 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
527 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
528 ExFreePool(KeyInformation
);
529 *Status
= NDIS_STATUS_RESOURCES
;
533 RegData
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
536 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
537 ExFreePool(KeyInformation
);
538 ExFreePool(*ParameterValue
);
539 *ParameterValue
= NULL
;
540 *Status
= NDIS_STATUS_FAILURE
;
544 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
545 if(!MiniportResource
)
547 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
548 ExFreePool(KeyInformation
);
549 ExFreePool(*ParameterValue
);
550 *ParameterValue
= NULL
;
551 *Status
= NDIS_STATUS_RESOURCES
;
555 MiniportResource
->ResourceType
= 0;
556 MiniportResource
->Resource
= *ParameterValue
;
557 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
558 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
560 memcpy(RegData
, KeyInformation
->Data
, KeyInformation
->DataLength
);
562 (*ParameterValue
)->ParameterType
= ParameterType
;
563 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
564 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= RegData
;
566 ExFreePool(KeyInformation
);
568 *Status
= NDIS_STATUS_SUCCESS
;
573 case NdisParameterBinary
:
575 PMINIPORT_RESOURCE MiniportResource
;
577 if(KeyInformation
->Type
!= REG_BINARY
)
579 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
580 *Status
= NDIS_STATUS_FAILURE
;
581 ExFreePool(KeyInformation
);
585 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
) + KeyInformation
->DataLength
);
588 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
589 ExFreePool(KeyInformation
);
590 *Status
= NDIS_STATUS_RESOURCES
;
594 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
595 if(!MiniportResource
)
597 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
598 ExFreePool(KeyInformation
);
599 ExFreePool(*ParameterValue
);
600 *ParameterValue
= NULL
;
601 *Status
= NDIS_STATUS_RESOURCES
;
605 MiniportResource
->ResourceType
= 0;
606 MiniportResource
->Resource
= *ParameterValue
;
607 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
608 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
610 (*ParameterValue
)->ParameterType
= ParameterType
;
611 memcpy(&((*ParameterValue
)->ParameterData
.BinaryData
), KeyInformation
->Data
, KeyInformation
->DataLength
);
613 ExFreePool(KeyInformation
);
615 *Status
= NDIS_STATUS_SUCCESS
;
623 UCHAR
UnicodeToHexByte(WCHAR chr
)
625 * FUNCTION: Converts a unicode hex character to its numerical value
627 * chr: Unicode character to convert
629 * The numerical value of chr
672 NdisReadNetworkAddress(
673 OUT PNDIS_STATUS Status
,
674 OUT PVOID
* NetworkAddress
,
675 OUT PUINT NetworkAddressLength
,
676 IN NDIS_HANDLE ConfigurationHandle
)
678 * FUNCTION: Reads the network address from the registry
680 * Status - variable to receive status
681 * NetworkAddress - pointer to a buffered network address array
682 * NetworkAddressLength - length of the NetworkAddress array
683 * ConfigurationHandle: handle passed back from one of the open routines
685 * NDIS_STATUS_SUCCESS on success
686 * NDIS_STATUS_FAILURE on failure
687 * The network address is placed in the NetworkAddress buffer
690 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
691 PMINIPORT_RESOURCE MiniportResource
= NULL
;
692 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
697 /* FIXME - We don't quite support this yet due to buggy code below */
699 *Status
= NDIS_STATUS_FAILURE
;
703 *NetworkAddress
= NULL
;
704 *NetworkAddressLength
= 6;/* XXX magic constant */
706 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
707 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
708 if(*Status
!= NDIS_STATUS_SUCCESS
)
710 *Status
= NDIS_STATUS_FAILURE
;
714 /* 6 bytes for ethernet, tokenring, fddi, everything else? */
715 IntArray
= ExAllocatePool(PagedPool
, 6*sizeof(UINT
));
718 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
719 *Status
= NDIS_STATUS_RESOURCES
;
723 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
724 if(!MiniportResource
)
726 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
727 *Status
= NDIS_STATUS_FAILURE
;
731 MiniportResource
->ResourceType
= 0;
732 MiniportResource
->Resource
= IntArray
;
733 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
734 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
736 /* convert from string to bytes */
739 IntArray
[i
] = (UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
]) << 4) +
740 UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
+1]);
743 *NetworkAddress
= IntArray
;
745 *Status
= NDIS_STATUS_SUCCESS
;
754 NdisOpenConfigurationKeyByIndex(
755 OUT PNDIS_STATUS Status
,
756 IN NDIS_HANDLE ConfigurationHandle
,
758 OUT PNDIS_STRING KeyName
,
759 OUT PNDIS_HANDLE KeyHandle
)
761 * FUNCTION: Opens a configuration subkey by index number
763 * Status: pointer to an NDIS_STATUS to receive status info
764 * ConfigurationHandle: the handle passed back from a previous open function
765 * Index: the zero-based index of the subkey to open
766 * KeyName: the name of the key that was opened
767 * KeyHandle: a handle to the key that was opened
769 * NDIS_STATUS_SUCCESS on success
770 * NDIS_STATUS_FAILURE on failure
771 * KeyName holds the name of the opened key
772 * KeyHandle holds a handle to the new key
775 KEY_BASIC_INFORMATION
*KeyInformation
;
776 ULONG KeyInformationLength
;
777 OBJECT_ATTRIBUTES KeyAttributes
;
778 NDIS_HANDLE RegKeyHandle
;
779 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
781 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
782 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
784 *Status
= NDIS_STATUS_FAILURE
;
788 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
791 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
792 *Status
= NDIS_STATUS_FAILURE
;
796 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
797 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
799 if(*Status
!= STATUS_SUCCESS
)
801 ExFreePool(KeyInformation
);
802 *Status
= NDIS_STATUS_FAILURE
;
806 /* should i fail instead if the passed-in string isn't long enough? */
807 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
808 KeyName
->Length
= KeyInformation
->NameLength
;
810 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
812 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
814 ExFreePool(KeyInformation
);
816 if(*Status
!= STATUS_SUCCESS
)
818 *Status
= NDIS_STATUS_FAILURE
;
822 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
823 if(!ConfigurationContext
)
825 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
826 *Status
= NDIS_STATUS_FAILURE
;
830 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
831 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
833 ConfigurationContext
->Handle
= RegKeyHandle
;
835 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
837 *Status
= NDIS_STATUS_SUCCESS
;
846 NdisOpenConfigurationKeyByName(
847 OUT PNDIS_STATUS Status
,
848 IN NDIS_HANDLE ConfigurationHandle
,
849 IN PNDIS_STRING KeyName
,
850 OUT PNDIS_HANDLE KeyHandle
)
852 * FUNCTION: Opens a configuration subkey by name
854 * Status: points to an NDIS_STATUS where status is returned
855 * ConfigurationHandle: handle returned by a previous open call
856 * KeyName: the name of the key to open
857 * KeyHandle: a handle to the opened key
859 * NDIS_STATUS_SUCCESS on success
860 * NDIS_STATUS_FAILURE on failure
861 * KeyHandle holds a handle to the newly-opened key
865 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
866 OBJECT_ATTRIBUTES KeyAttributes
;
867 NDIS_HANDLE RegKeyHandle
;
869 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
870 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
872 if(*Status
!= STATUS_SUCCESS
)
874 *Status
= NDIS_STATUS_FAILURE
;
878 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
879 if(!ConfigurationContext
)
881 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
882 *Status
= NDIS_STATUS_FAILURE
;
886 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
887 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
889 ConfigurationContext
->Handle
= RegKeyHandle
;
891 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
893 *Status
= NDIS_STATUS_SUCCESS
;