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 NDIS_DbgPrint(MID_TRACE
, ("Failed to open registry configuration for this miniport\n"));
186 *ConfigurationHandle
= NULL
;
187 *Status
= NDIS_STATUS_FAILURE
;
191 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
192 if(!ConfigurationContext
)
194 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
196 *Status
= NDIS_STATUS_RESOURCES
;
200 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
201 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
203 ConfigurationContext
->Handle
= KeyHandle
;
205 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
206 *Status
= NDIS_STATUS_SUCCESS
;
208 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
217 NdisOpenProtocolConfiguration(
218 OUT PNDIS_STATUS Status
,
219 OUT PNDIS_HANDLE ConfigurationHandle
,
220 IN PNDIS_STRING ProtocolSection
)
222 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
224 * Status: caller-allocated buffer where status is returned
225 * ConfigurationHandle: spot to return the opaque configuration context
226 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
228 * NDIS_STATUS_SUCCESS: the operation was a success
229 * NDIS_STATUS_FAILURE: the operation was not a success
231 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
234 OBJECT_ATTRIBUTES KeyAttributes
;
235 UNICODE_STRING KeyNameU
;
238 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
240 KeyName
= ExAllocatePool(PagedPool
, ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(WCHAR
));
243 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
244 *ConfigurationHandle
= NULL
;
245 *Status
= NDIS_STATUS_FAILURE
;
249 wcsncpy(KeyName
, ProtocolSection
->Buffer
, ProtocolSection
->Length
/sizeof(WCHAR
));
250 wcscpy(KeyName
+ ProtocolSection
->Length
, PARAMETERS_KEY
);
251 RtlInitUnicodeString(&KeyNameU
, KeyName
);
252 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
254 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
258 if(*Status
!= NDIS_STATUS_SUCCESS
)
260 *ConfigurationHandle
= NULL
;
261 *Status
= NDIS_STATUS_FAILURE
;
265 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
266 if(!ConfigurationContext
)
268 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
269 *ConfigurationHandle
= NULL
;
270 *Status
= NDIS_STATUS_FAILURE
;
274 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
275 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
277 ConfigurationContext
->Handle
= KeyHandle
;
279 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
280 *Status
= NDIS_STATUS_SUCCESS
;
289 NdisReadConfiguration(
290 OUT PNDIS_STATUS Status
,
291 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
292 IN NDIS_HANDLE ConfigurationHandle
,
293 IN PNDIS_STRING Keyword
,
294 IN NDIS_PARAMETER_TYPE ParameterType
)
296 * FUNCTION: Read a configuration value from the registry, tracking its resources
298 * Status: points to a place to write status into
299 * ParameterValue: Pointer to receive a newly-allocated parameter structure
300 * ConfigurationHandle: handle originally returned by an open function
301 * Keyword: Value name to read, or one of the following constants:
302 * Environment - returns NdisEnvironmentWindowsNt
303 * ProcessorType - returns NdisProcessorX86 until more architectures are added
304 * NdisVersion - returns NDIS_VERSION
305 * ParameterType: the type of the value to be queried
307 * - A status in Status
308 * - A parameter value in ParameterValue
311 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
313 PMINIPORT_RESOURCE MiniportResource
;
314 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
316 *ParameterValue
= NULL
;
317 *Status
= NDIS_STATUS_FAILURE
;
319 if(ParameterType
!= NdisParameterInteger
&&
320 ParameterType
!= NdisParameterHexInteger
&&
321 ParameterType
!= NdisParameterString
&&
322 ParameterType
!= NdisParameterMultiString
&&
323 ParameterType
!= NdisParameterBinary
326 NDIS_DbgPrint(MID_TRACE
,("unsupported parameter type\n"));
330 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
333 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
334 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
337 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
340 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
341 *Status
= NDIS_STATUS_RESOURCES
;
345 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
346 if(!MiniportResource
)
348 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
349 ExFreePool(*ParameterValue
);
350 *ParameterValue
= NULL
;
351 *Status
= NDIS_STATUS_RESOURCES
;
355 MiniportResource
->ResourceType
= 0;
356 MiniportResource
->Resource
= *ParameterValue
;
358 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
359 MiniportResource
->Resource
));
361 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
362 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
364 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
365 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
366 *Status
= NDIS_STATUS_SUCCESS
;
372 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
373 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
376 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
379 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
380 *Status
= NDIS_STATUS_RESOURCES
;
384 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
385 if(!MiniportResource
)
387 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
388 ExFreePool(*ParameterValue
);
389 *ParameterValue
= NULL
;
390 *Status
= NDIS_STATUS_RESOURCES
;
394 MiniportResource
->ResourceType
= 0;
395 MiniportResource
->Resource
= *ParameterValue
;
396 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
397 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
398 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
400 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
401 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
402 *Status
= NDIS_STATUS_SUCCESS
;
408 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
409 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
412 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
415 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
416 *Status
= NDIS_STATUS_RESOURCES
;
420 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
421 if(!MiniportResource
)
423 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
424 ExFreePool(*ParameterValue
);
425 *ParameterValue
= NULL
;
426 *Status
= NDIS_STATUS_RESOURCES
;
430 MiniportResource
->ResourceType
= 0;
431 MiniportResource
->Resource
= *ParameterValue
;
432 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
433 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
434 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
436 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
437 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
438 *Status
= NDIS_STATUS_SUCCESS
;
440 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
441 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
445 /* figure out how much buffer i should allocate */
446 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
447 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
449 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
450 *Status
= NDIS_STATUS_FAILURE
;
455 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
458 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
459 *Status
= NDIS_STATUS_RESOURCES
;
464 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
465 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
466 if(*Status
!= STATUS_SUCCESS
)
468 ExFreePool(KeyInformation
);
469 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
470 *Status
= NDIS_STATUS_FAILURE
;
474 switch(ParameterType
)
476 case NdisParameterInteger
:
477 case NdisParameterHexInteger
:
481 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
484 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
485 ExFreePool(KeyInformation
);
486 *Status
= NDIS_STATUS_RESOURCES
;
490 str
.Length
= str
.MaximumLength
= KeyInformation
->DataLength
;
491 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
493 (*ParameterValue
)->ParameterType
= ParameterType
;
494 *Status
= RtlUnicodeStringToInteger(&str
, 16, &(*ParameterValue
)->ParameterData
.IntegerData
);
496 ExFreePool(KeyInformation
);
498 if(*Status
!= STATUS_SUCCESS
)
499 *Status
= NDIS_STATUS_FAILURE
;
501 *Status
= NDIS_STATUS_SUCCESS
;
506 case NdisParameterString
:
507 case NdisParameterMultiString
:
509 PMINIPORT_RESOURCE MiniportResource
= 0;
512 if(KeyInformation
->Type
!= REG_SZ
&& KeyInformation
->Type
!= REG_MULTI_SZ
)
514 NDIS_DbgPrint(MID_TRACE
,("requested type does not match actual value type\n"));
515 ExFreePool(KeyInformation
);
516 *ParameterValue
= NULL
;
517 *Status
= NDIS_STATUS_FAILURE
;
521 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
524 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
525 ExFreePool(KeyInformation
);
526 *Status
= NDIS_STATUS_RESOURCES
;
530 RegData
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
533 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
534 ExFreePool(KeyInformation
);
535 ExFreePool(*ParameterValue
);
536 *ParameterValue
= NULL
;
537 *Status
= NDIS_STATUS_FAILURE
;
541 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
542 if(!MiniportResource
)
544 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
545 ExFreePool(KeyInformation
);
546 ExFreePool(*ParameterValue
);
547 *ParameterValue
= NULL
;
548 *Status
= NDIS_STATUS_RESOURCES
;
552 MiniportResource
->ResourceType
= 0;
553 MiniportResource
->Resource
= *ParameterValue
;
554 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
555 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
557 memcpy(RegData
, KeyInformation
->Data
, KeyInformation
->DataLength
);
559 (*ParameterValue
)->ParameterType
= ParameterType
;
560 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
561 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= RegData
;
563 ExFreePool(KeyInformation
);
565 *Status
= NDIS_STATUS_SUCCESS
;
570 case NdisParameterBinary
:
572 PMINIPORT_RESOURCE MiniportResource
;
574 if(KeyInformation
->Type
!= REG_BINARY
)
576 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
577 *Status
= NDIS_STATUS_FAILURE
;
578 ExFreePool(KeyInformation
);
582 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
) + KeyInformation
->DataLength
);
585 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
586 ExFreePool(KeyInformation
);
587 *Status
= NDIS_STATUS_RESOURCES
;
591 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
592 if(!MiniportResource
)
594 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
595 ExFreePool(KeyInformation
);
596 ExFreePool(*ParameterValue
);
597 *ParameterValue
= NULL
;
598 *Status
= NDIS_STATUS_RESOURCES
;
602 MiniportResource
->ResourceType
= 0;
603 MiniportResource
->Resource
= *ParameterValue
;
604 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
605 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
607 (*ParameterValue
)->ParameterType
= ParameterType
;
608 memcpy(&((*ParameterValue
)->ParameterData
.BinaryData
), KeyInformation
->Data
, KeyInformation
->DataLength
);
610 ExFreePool(KeyInformation
);
612 *Status
= NDIS_STATUS_SUCCESS
;
620 UCHAR
UnicodeToHexByte(WCHAR chr
)
622 * FUNCTION: Converts a unicode hex character to its numerical value
624 * chr: Unicode character to convert
626 * The numerical value of chr
669 NdisReadNetworkAddress(
670 OUT PNDIS_STATUS Status
,
671 OUT PVOID
* NetworkAddress
,
672 OUT PUINT NetworkAddressLength
,
673 IN NDIS_HANDLE ConfigurationHandle
)
675 * FUNCTION: Reads the network address from the registry
677 * Status - variable to receive status
678 * NetworkAddress - pointer to a buffered network address array
679 * NetworkAddressLength - length of the NetworkAddress array
680 * ConfigurationHandle: handle passed back from one of the open routines
682 * NDIS_STATUS_SUCCESS on success
683 * NDIS_STATUS_FAILURE on failure
684 * The network address is placed in the NetworkAddress buffer
687 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
688 PMINIPORT_RESOURCE MiniportResource
= NULL
;
689 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
694 /* FIXME - We don't quite support this yet due to buggy code below */
696 *Status
= NDIS_STATUS_FAILURE
;
700 *NetworkAddress
= NULL
;
701 *NetworkAddressLength
= 6;/* XXX magic constant */
703 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
704 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
705 if(*Status
!= NDIS_STATUS_SUCCESS
)
707 *Status
= NDIS_STATUS_FAILURE
;
711 /* 6 bytes for ethernet, tokenring, fddi, everything else? */
712 IntArray
= ExAllocatePool(PagedPool
, 6*sizeof(UINT
));
715 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
716 *Status
= NDIS_STATUS_RESOURCES
;
720 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
721 if(!MiniportResource
)
723 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
724 *Status
= NDIS_STATUS_FAILURE
;
728 MiniportResource
->ResourceType
= 0;
729 MiniportResource
->Resource
= IntArray
;
730 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
731 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
733 /* convert from string to bytes */
736 IntArray
[i
] = (UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
]) << 4) +
737 UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
+1]);
740 *NetworkAddress
= IntArray
;
742 *Status
= NDIS_STATUS_SUCCESS
;
751 NdisOpenConfigurationKeyByIndex(
752 OUT PNDIS_STATUS Status
,
753 IN NDIS_HANDLE ConfigurationHandle
,
755 OUT PNDIS_STRING KeyName
,
756 OUT PNDIS_HANDLE KeyHandle
)
758 * FUNCTION: Opens a configuration subkey by index number
760 * Status: pointer to an NDIS_STATUS to receive status info
761 * ConfigurationHandle: the handle passed back from a previous open function
762 * Index: the zero-based index of the subkey to open
763 * KeyName: the name of the key that was opened
764 * KeyHandle: a handle to the key that was opened
766 * NDIS_STATUS_SUCCESS on success
767 * NDIS_STATUS_FAILURE on failure
768 * KeyName holds the name of the opened key
769 * KeyHandle holds a handle to the new key
772 KEY_BASIC_INFORMATION
*KeyInformation
;
773 ULONG KeyInformationLength
;
774 OBJECT_ATTRIBUTES KeyAttributes
;
775 NDIS_HANDLE RegKeyHandle
;
776 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
778 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
779 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
781 *Status
= NDIS_STATUS_FAILURE
;
785 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
788 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
789 *Status
= NDIS_STATUS_FAILURE
;
793 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
794 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
796 if(*Status
!= STATUS_SUCCESS
)
798 ExFreePool(KeyInformation
);
799 *Status
= NDIS_STATUS_FAILURE
;
803 /* should i fail instead if the passed-in string isn't long enough? */
804 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
805 KeyName
->Length
= KeyInformation
->NameLength
;
807 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
809 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
811 ExFreePool(KeyInformation
);
813 if(*Status
!= STATUS_SUCCESS
)
815 *Status
= NDIS_STATUS_FAILURE
;
819 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
820 if(!ConfigurationContext
)
822 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
823 *Status
= NDIS_STATUS_FAILURE
;
827 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
828 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
830 ConfigurationContext
->Handle
= RegKeyHandle
;
832 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
834 *Status
= NDIS_STATUS_SUCCESS
;
843 NdisOpenConfigurationKeyByName(
844 OUT PNDIS_STATUS Status
,
845 IN NDIS_HANDLE ConfigurationHandle
,
846 IN PNDIS_STRING KeyName
,
847 OUT PNDIS_HANDLE KeyHandle
)
849 * FUNCTION: Opens a configuration subkey by name
851 * Status: points to an NDIS_STATUS where status is returned
852 * ConfigurationHandle: handle returned by a previous open call
853 * KeyName: the name of the key to open
854 * KeyHandle: a handle to the opened key
856 * NDIS_STATUS_SUCCESS on success
857 * NDIS_STATUS_FAILURE on failure
858 * KeyHandle holds a handle to the newly-opened key
862 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
863 OBJECT_ATTRIBUTES KeyAttributes
;
864 NDIS_HANDLE RegKeyHandle
;
866 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
867 *Status
= ZwOpenKey(RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
869 if(*Status
!= STATUS_SUCCESS
)
871 *Status
= NDIS_STATUS_FAILURE
;
875 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
876 if(!ConfigurationContext
)
878 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
879 *Status
= NDIS_STATUS_FAILURE
;
883 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
884 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
886 ConfigurationContext
->Handle
= RegKeyHandle
;
888 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
890 *Status
= NDIS_STATUS_SUCCESS
;