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
;
71 /* reset parameter type to standard reg types */
74 case NdisParameterHexInteger
:
75 case NdisParameterInteger
:
79 Str
.Buffer
= (PWSTR
) &Buff
;
80 Str
.MaximumLength
= (USHORT
)sizeof(Buff
);
83 ParameterType
= REG_SZ
;
84 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
85 ParameterValue
->ParameterData
.IntegerData
,
86 (ParameterType
== NdisParameterInteger
) ? 10 : 16, &Str
)))
88 *Status
= NDIS_STATUS_FAILURE
;
92 DataSize
= Str
.Length
;
95 case NdisParameterString
:
96 case NdisParameterMultiString
:
97 ParameterType
= REG_SZ
;
98 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
99 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
102 /* New (undocumented) addition to 2k ddk */
103 case NdisParameterBinary
:
104 ParameterType
= REG_BINARY
;
105 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
106 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
110 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
114 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
115 Keyword
, 0, ParameterType
, Data
, DataSize
);
117 if(*Status
!= STATUS_SUCCESS
)
118 *Status
= NDIS_STATUS_FAILURE
;
120 *Status
= NDIS_STATUS_SUCCESS
;
129 NdisCloseConfiguration(
130 IN NDIS_HANDLE ConfigurationHandle
)
132 * FUNCTION: Closes handles and releases per-handle resources
134 * ConfigurationHandle - pointer to the context with the resources to free
137 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
138 PMINIPORT_RESOURCE Resource
;
140 while(!IsListEmpty(&ConfigurationContext
->ResourceListHead
))
142 Resource
= (PMINIPORT_RESOURCE
)RemoveTailList(&ConfigurationContext
->ResourceListHead
);
143 if(Resource
->ResourceType
== MINIPORT_RESOURCE_TYPE_MEMORY
)
145 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
146 ExFreePool(Resource
->Resource
);
149 ExFreePool(Resource
);
152 ZwClose(ConfigurationContext
->Handle
);
161 NdisOpenConfiguration(
162 OUT PNDIS_STATUS Status
,
163 OUT PNDIS_HANDLE ConfigurationHandle
,
164 IN NDIS_HANDLE WrapperConfigurationContext
)
166 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
168 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
169 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
170 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
172 * NDIS_STATUS_SUCCESS: the operation completed successfully
173 * NDIS_STATUS_FAILURE: the operation failed
175 * I think this is the parameters key; please verify.
179 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
180 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
181 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
183 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
185 *ConfigurationHandle
= NULL
;
187 *Status
= ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle
,
188 NtCurrentProcess(), &KeyHandle
, 0, 0,
189 DUPLICATE_SAME_ACCESS
);
190 if(!NT_SUCCESS(*Status
))
192 NDIS_DbgPrint(MID_TRACE
, ("Failed to open registry configuration for this miniport\n"));
193 *Status
= NDIS_STATUS_FAILURE
;
197 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
198 if(!ConfigurationContext
)
200 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
202 *Status
= NDIS_STATUS_RESOURCES
;
206 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
207 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
209 ConfigurationContext
->Handle
= KeyHandle
;
211 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
212 *Status
= NDIS_STATUS_SUCCESS
;
214 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
223 NdisOpenProtocolConfiguration(
224 OUT PNDIS_STATUS Status
,
225 OUT PNDIS_HANDLE ConfigurationHandle
,
226 IN PNDIS_STRING ProtocolSection
)
228 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
230 * Status: caller-allocated buffer where status is returned
231 * ConfigurationHandle: spot to return the opaque configuration context
232 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
234 * NDIS_STATUS_SUCCESS: the operation was a success
235 * NDIS_STATUS_FAILURE: the operation was not a success
237 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
240 OBJECT_ATTRIBUTES KeyAttributes
;
241 UNICODE_STRING KeyNameU
;
243 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
246 KeyNameU
.MaximumLength
= ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(UNICODE_NULL
);
247 KeyNameU
.Buffer
= ExAllocatePool(PagedPool
, KeyNameU
.MaximumLength
);
250 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
251 *ConfigurationHandle
= NULL
;
252 *Status
= NDIS_STATUS_FAILURE
;
256 RtlCopyUnicodeString(&KeyNameU
, ProtocolSection
);
257 RtlAppendUnicodeToString(&KeyNameU
, PARAMETERS_KEY
);
258 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
260 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
262 ExFreePool(KeyNameU
.Buffer
);
264 if(*Status
!= NDIS_STATUS_SUCCESS
)
266 *ConfigurationHandle
= NULL
;
267 *Status
= NDIS_STATUS_FAILURE
;
271 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
272 if(!ConfigurationContext
)
274 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
276 *ConfigurationHandle
= NULL
;
277 *Status
= NDIS_STATUS_FAILURE
;
281 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
282 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
284 ConfigurationContext
->Handle
= KeyHandle
;
286 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
287 *Status
= NDIS_STATUS_SUCCESS
;
296 NdisReadConfiguration(
297 OUT PNDIS_STATUS Status
,
298 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
299 IN NDIS_HANDLE ConfigurationHandle
,
300 IN PNDIS_STRING Keyword
,
301 IN NDIS_PARAMETER_TYPE ParameterType
)
303 * FUNCTION: Read a configuration value from the registry, tracking its resources
305 * Status: points to a place to write status into
306 * ParameterValue: Pointer to receive a newly-allocated parameter structure
307 * ConfigurationHandle: handle originally returned by an open function
308 * Keyword: Value name to read, or one of the following constants:
309 * Environment - returns NdisEnvironmentWindowsNt
310 * ProcessorType - returns NdisProcessorX86 until more architectures are added
311 * NdisVersion - returns NDIS_VERSION
312 * ParameterType: the type of the value to be queried
314 * - A status in Status
315 * - A parameter value in ParameterValue
318 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
320 PMINIPORT_RESOURCE MiniportResource
;
321 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
323 *ParameterValue
= NULL
;
324 *Status
= NDIS_STATUS_FAILURE
;
326 if(ParameterType
!= NdisParameterInteger
&&
327 ParameterType
!= NdisParameterHexInteger
&&
328 ParameterType
!= NdisParameterString
&&
329 ParameterType
!= NdisParameterMultiString
&&
330 ParameterType
!= NdisParameterBinary
333 NDIS_DbgPrint(MID_TRACE
,("unsupported parameter type\n"));
334 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
338 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
341 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
342 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
345 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
348 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
349 *Status
= NDIS_STATUS_RESOURCES
;
353 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
354 if(!MiniportResource
)
356 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
357 ExFreePool(*ParameterValue
);
358 *ParameterValue
= NULL
;
359 *Status
= NDIS_STATUS_RESOURCES
;
363 MiniportResource
->ResourceType
= 0;
364 MiniportResource
->Resource
= *ParameterValue
;
366 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
367 MiniportResource
->Resource
));
369 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
370 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
372 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
373 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
374 *Status
= NDIS_STATUS_SUCCESS
;
380 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
381 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
384 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
387 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
388 *Status
= NDIS_STATUS_RESOURCES
;
392 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
393 if(!MiniportResource
)
395 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
396 ExFreePool(*ParameterValue
);
397 *ParameterValue
= NULL
;
398 *Status
= NDIS_STATUS_RESOURCES
;
402 MiniportResource
->ResourceType
= 0;
403 MiniportResource
->Resource
= *ParameterValue
;
404 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
405 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
406 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
408 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
409 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
410 *Status
= NDIS_STATUS_SUCCESS
;
416 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
417 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
420 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
423 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
424 *Status
= NDIS_STATUS_RESOURCES
;
428 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
429 if(!MiniportResource
)
431 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
432 ExFreePool(*ParameterValue
);
433 *ParameterValue
= NULL
;
434 *Status
= NDIS_STATUS_RESOURCES
;
438 MiniportResource
->ResourceType
= 0;
439 MiniportResource
->Resource
= *ParameterValue
;
440 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
441 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
442 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
444 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
445 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
446 *Status
= NDIS_STATUS_SUCCESS
;
448 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
449 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
453 /* figure out how much buffer i should allocate */
454 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
455 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
457 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
458 *Status
= NDIS_STATUS_FAILURE
;
463 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
466 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
467 *Status
= NDIS_STATUS_RESOURCES
;
472 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
473 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
474 if(*Status
!= STATUS_SUCCESS
)
476 ExFreePool(KeyInformation
);
477 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
478 *Status
= NDIS_STATUS_FAILURE
;
482 switch(ParameterType
)
484 case NdisParameterInteger
:
485 case NdisParameterHexInteger
:
489 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
492 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
493 ExFreePool(KeyInformation
);
494 *Status
= NDIS_STATUS_RESOURCES
;
498 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
499 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
501 (*ParameterValue
)->ParameterType
= ParameterType
;
504 If ParameterType is NdisParameterInteger then the base of str is decimal.
505 If ParameterType is NdisParameterHexInteger then the base of str is hexadecimal.
507 if (ParameterType
== NdisParameterInteger
)
508 *Status
= RtlUnicodeStringToInteger(&str
, 10, &(*ParameterValue
)->ParameterData
.IntegerData
);
509 else if (ParameterType
== NdisParameterHexInteger
)
510 *Status
= RtlUnicodeStringToInteger(&str
, 16, &(*ParameterValue
)->ParameterData
.IntegerData
);
513 ExFreePool(KeyInformation
);
515 if(*Status
!= STATUS_SUCCESS
) {
516 ExFreePool(*ParameterValue
);
517 *ParameterValue
= NULL
;
518 *Status
= NDIS_STATUS_FAILURE
;
520 *Status
= NDIS_STATUS_SUCCESS
;
525 case NdisParameterString
:
526 case NdisParameterMultiString
:
530 if(KeyInformation
->Type
!= REG_SZ
&& KeyInformation
->Type
!= REG_MULTI_SZ
)
532 NDIS_DbgPrint(MID_TRACE
,("requested type does not match actual value type\n"));
533 ExFreePool(KeyInformation
);
534 *ParameterValue
= NULL
;
535 *Status
= NDIS_STATUS_FAILURE
;
539 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
542 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
543 ExFreePool(KeyInformation
);
544 *Status
= NDIS_STATUS_RESOURCES
;
548 RegData
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
551 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
552 ExFreePool(KeyInformation
);
553 ExFreePool(*ParameterValue
);
554 *ParameterValue
= NULL
;
555 *Status
= NDIS_STATUS_FAILURE
;
559 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
560 if(!MiniportResource
)
562 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
564 ExFreePool(KeyInformation
);
565 ExFreePool(*ParameterValue
);
566 *ParameterValue
= NULL
;
567 *Status
= NDIS_STATUS_RESOURCES
;
571 MiniportResource
->ResourceType
= 0;
572 MiniportResource
->Resource
= *ParameterValue
;
573 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
574 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
576 memcpy(RegData
, KeyInformation
->Data
, KeyInformation
->DataLength
);
578 (*ParameterValue
)->ParameterType
= ParameterType
;
579 (*ParameterValue
)->ParameterData
.StringData
.Length
= (USHORT
)KeyInformation
->DataLength
;
580 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= RegData
;
582 ExFreePool(KeyInformation
);
584 *Status
= NDIS_STATUS_SUCCESS
;
589 case NdisParameterBinary
:
591 if(KeyInformation
->Type
!= REG_BINARY
)
593 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
594 *Status
= NDIS_STATUS_FAILURE
;
595 ExFreePool(KeyInformation
);
599 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
) + KeyInformation
->DataLength
);
602 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
603 ExFreePool(KeyInformation
);
604 *Status
= NDIS_STATUS_RESOURCES
;
608 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
609 if(!MiniportResource
)
611 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
612 ExFreePool(KeyInformation
);
613 ExFreePool(*ParameterValue
);
614 *ParameterValue
= NULL
;
615 *Status
= NDIS_STATUS_RESOURCES
;
619 MiniportResource
->ResourceType
= 0;
620 MiniportResource
->Resource
= *ParameterValue
;
621 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
622 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
624 (*ParameterValue
)->ParameterType
= ParameterType
;
625 memcpy(&((*ParameterValue
)->ParameterData
.BinaryData
), KeyInformation
->Data
, KeyInformation
->DataLength
);
627 ExFreePool(KeyInformation
);
629 *Status
= NDIS_STATUS_SUCCESS
;
637 UCHAR
UnicodeToHexByte(WCHAR chr
)
639 * FUNCTION: Converts a unicode hex character to its numerical value
641 * chr: Unicode character to convert
643 * The numerical value of chr
686 NdisReadNetworkAddress(
687 OUT PNDIS_STATUS Status
,
688 OUT PVOID
* NetworkAddress
,
689 OUT PUINT NetworkAddressLength
,
690 IN NDIS_HANDLE ConfigurationHandle
)
692 * FUNCTION: Reads the network address from the registry
694 * Status - variable to receive status
695 * NetworkAddress - pointer to a buffered network address array
696 * NetworkAddressLength - length of the NetworkAddress array
697 * ConfigurationHandle: handle passed back from one of the open routines
699 * NDIS_STATUS_SUCCESS on success
700 * NDIS_STATUS_FAILURE on failure
701 * The network address is placed in the NetworkAddress buffer
704 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
705 PMINIPORT_RESOURCE MiniportResource
= NULL
;
706 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
711 /* FIXME - We don't quite support this yet due to buggy code below */
713 *Status
= NDIS_STATUS_FAILURE
;
717 *NetworkAddress
= NULL
;
718 *NetworkAddressLength
= 6;/* XXX magic constant */
720 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
721 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
722 if(*Status
!= NDIS_STATUS_SUCCESS
)
724 *Status
= NDIS_STATUS_FAILURE
;
728 /* 6 bytes for ethernet, tokenring, fddi, everything else? */
729 IntArray
= ExAllocatePool(PagedPool
, 6*sizeof(UINT
));
732 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
733 *Status
= NDIS_STATUS_RESOURCES
;
737 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
738 if(!MiniportResource
)
740 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
741 ExFreePool(IntArray
);
742 *Status
= NDIS_STATUS_RESOURCES
;
746 MiniportResource
->ResourceType
= 0;
747 MiniportResource
->Resource
= IntArray
;
748 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
749 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
751 /* convert from string to bytes */
754 IntArray
[i
] = (UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
]) << 4) +
755 UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
+1]);
758 *NetworkAddress
= IntArray
;
760 *Status
= NDIS_STATUS_SUCCESS
;
769 NdisOpenConfigurationKeyByIndex(
770 OUT PNDIS_STATUS Status
,
771 IN NDIS_HANDLE ConfigurationHandle
,
773 OUT PNDIS_STRING KeyName
,
774 OUT PNDIS_HANDLE KeyHandle
)
776 * FUNCTION: Opens a configuration subkey by index number
778 * Status: pointer to an NDIS_STATUS to receive status info
779 * ConfigurationHandle: the handle passed back from a previous open function
780 * Index: the zero-based index of the subkey to open
781 * KeyName: the name of the key that was opened
782 * KeyHandle: a handle to the key that was opened
784 * NDIS_STATUS_SUCCESS on success
785 * NDIS_STATUS_FAILURE on failure
786 * KeyName holds the name of the opened key
787 * KeyHandle holds a handle to the new key
790 KEY_BASIC_INFORMATION
*KeyInformation
;
791 ULONG KeyInformationLength
;
792 OBJECT_ATTRIBUTES KeyAttributes
;
793 NDIS_HANDLE RegKeyHandle
;
794 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
798 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
799 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
801 *Status
= NDIS_STATUS_FAILURE
;
805 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
808 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
809 *Status
= NDIS_STATUS_FAILURE
;
813 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
814 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
816 if(*Status
!= STATUS_SUCCESS
)
818 ExFreePool(KeyInformation
);
819 *Status
= NDIS_STATUS_FAILURE
;
823 /* should i fail instead if the passed-in string isn't long enough? */
824 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
825 KeyName
->Length
= (USHORT
)KeyInformation
->NameLength
;
827 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
829 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
831 ExFreePool(KeyInformation
);
833 if(*Status
!= STATUS_SUCCESS
)
835 *Status
= NDIS_STATUS_FAILURE
;
839 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
840 if(!ConfigurationContext
)
842 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
843 ZwClose(RegKeyHandle
);
844 *Status
= NDIS_STATUS_FAILURE
;
848 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
849 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
851 ConfigurationContext
->Handle
= RegKeyHandle
;
853 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
855 *Status
= NDIS_STATUS_SUCCESS
;
864 NdisOpenConfigurationKeyByName(
865 OUT PNDIS_STATUS Status
,
866 IN NDIS_HANDLE ConfigurationHandle
,
867 IN PNDIS_STRING KeyName
,
868 OUT PNDIS_HANDLE KeyHandle
)
870 * FUNCTION: Opens a configuration subkey by name
872 * Status: points to an NDIS_STATUS where status is returned
873 * ConfigurationHandle: handle returned by a previous open call
874 * KeyName: the name of the key to open
875 * KeyHandle: a handle to the opened key
877 * NDIS_STATUS_SUCCESS on success
878 * NDIS_STATUS_FAILURE on failure
879 * KeyHandle holds a handle to the newly-opened key
883 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
884 OBJECT_ATTRIBUTES KeyAttributes
;
885 NDIS_HANDLE RegKeyHandle
;
889 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
890 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
892 if(*Status
!= STATUS_SUCCESS
)
894 *Status
= NDIS_STATUS_FAILURE
;
898 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
899 if(!ConfigurationContext
)
901 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
902 ZwClose(RegKeyHandle
);
903 *Status
= NDIS_STATUS_FAILURE
;
907 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
908 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
910 ConfigurationContext
->Handle
= RegKeyHandle
;
912 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
914 *Status
= NDIS_STATUS_SUCCESS
;