2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
5 * PURPOSE: NDIS Configuration Services
6 * PROGRAMMERS: Vizzini (vizzini@plasmic.com)
8 * Vizzini 07-28-2003 Created
10 * - Resource tracking has to be implemented here because of the design of the NDIS API.
11 * Whenever a read operation is performed, the NDIS library allocates space and returns
12 * it. A linked list is kept associated with every handle of the memory allocated to
13 * it. When the handle is closed, the resources are systematically released.
14 * - The NDIS_HANDLE Configuraiton context is no longer a registry handle. An opaque struct
15 * had to be created to allow for resource tracking. This means that Miniports cannot just
16 * pass this NDIS_HANDLE to things like ZwQueryValueKey(). I don't thknk they do (they
17 * certainly should not), but it should be kept in mind.
18 * UPDATE: I just found this in the NTDDK:
19 * NdisOpenProtocolConfiguration returns a handle for the
20 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NICDriverInstance\Parameters\ProtocolName
21 * registry key. XXX This is a problem. Following that, the DDK instructs programmers
22 * to use NdisReadConfiguration and NdisWriteConfiguration. No telling what the world's idiots
23 * have done with this.
24 * - I have tried to stick to the DDK's definition of what return values are possible, which
25 * has resulted in stupid return values in some cases. I do use STATUS_RESOURCES in a few
26 * places that the DDK doesn't explicitly mention it, though.
27 * - There's a general reliance on the fact that UNICODE_STRING.Length doesn't include a trailing
28 * 0, which it shouldn't
29 * - I added support for NdisParameterBinary. It's at the end of the struct. I wonder if
31 * - All the routines in this file are PASSIVE_LEVEL only, and all memory is PagedPool
36 #define PARAMETERS_KEY L"Parameters" /* The parameters subkey under the device-specific key */
43 NdisWriteConfiguration(
44 OUT PNDIS_STATUS Status
,
45 IN NDIS_HANDLE ConfigurationHandle
,
46 IN PNDIS_STRING Keyword
,
47 IN PNDIS_CONFIGURATION_PARAMETER ParameterValue
)
49 * FUNCTION: Writes a configuration value to the registry
51 * Status: Pointer to a caller-supplied NDIS_STATUS where we return status
52 * ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
53 * Keyword: The registry value name to write
54 * ParameterValue: The value data to write
56 * NDIS_STATUS_SUCCESS - the operation completed successfully
57 * NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
58 * NDIS_STATUS_RESOURCES - out of memory, etc.
59 * NDIS_STATUS_FAILURE - any other failure
61 * There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
62 * I don't know why tho so i free everything before return. comments welcome.
70 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
72 /* reset parameter type to standard reg types */
73 switch(ParameterValue
->ParameterType
)
75 case NdisParameterHexInteger
:
76 case NdisParameterInteger
:
80 Str
.Buffer
= (PWSTR
) &Buff
;
81 Str
.MaximumLength
= (USHORT
)sizeof(Buff
);
84 ParameterType
= REG_SZ
;
85 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
86 ParameterValue
->ParameterData
.IntegerData
,
87 (ParameterValue
->ParameterType
== NdisParameterInteger
) ? 10 : 16, &Str
)))
89 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
90 *Status
= NDIS_STATUS_FAILURE
;
94 DataSize
= Str
.Length
;
97 case NdisParameterString
:
98 case NdisParameterMultiString
:
99 ParameterType
= (ParameterValue
->ParameterType
== NdisParameterString
) ? REG_SZ
: REG_MULTI_SZ
;
100 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
101 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
104 /* New (undocumented) addition to 2k ddk */
105 case NdisParameterBinary
:
106 ParameterType
= REG_BINARY
;
107 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
108 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
112 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
116 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
117 Keyword
, 0, ParameterType
, Data
, DataSize
);
119 if(*Status
!= STATUS_SUCCESS
) {
120 NDIS_DbgPrint(MIN_TRACE
, ("ZwSetValueKey failed (%x)\n", *Status
));
121 *Status
= NDIS_STATUS_FAILURE
;
123 *Status
= NDIS_STATUS_SUCCESS
;
132 NdisCloseConfiguration(
133 IN NDIS_HANDLE ConfigurationHandle
)
135 * FUNCTION: Closes handles and releases per-handle resources
137 * ConfigurationHandle - pointer to the context with the resources to free
140 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
141 PMINIPORT_RESOURCE Resource
;
143 while(!IsListEmpty(&ConfigurationContext
->ResourceListHead
))
145 Resource
= (PMINIPORT_RESOURCE
)ExInterlockedRemoveHeadList(&ConfigurationContext
->ResourceListHead
, &ConfigurationContext
->ResourceLock
);
146 if(Resource
->ResourceType
== MINIPORT_RESOURCE_TYPE_MEMORY
)
148 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
149 ExFreePool(Resource
->Resource
);
152 ExFreePool(Resource
);
155 ZwClose(ConfigurationContext
->Handle
);
164 NdisOpenConfiguration(
165 OUT PNDIS_STATUS Status
,
166 OUT PNDIS_HANDLE ConfigurationHandle
,
167 IN NDIS_HANDLE WrapperConfigurationContext
)
169 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
171 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
172 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
173 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
175 * NDIS_STATUS_SUCCESS: the operation completed successfully
176 * NDIS_STATUS_FAILURE: the operation failed
178 * I think this is the parameters key; please verify.
182 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
183 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
184 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
186 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
188 *ConfigurationHandle
= NULL
;
190 *Status
= ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle
,
191 NtCurrentProcess(), &KeyHandle
, 0, 0,
192 DUPLICATE_SAME_ACCESS
);
193 if(!NT_SUCCESS(*Status
))
195 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open registry configuration for this miniport\n"));
196 *Status
= NDIS_STATUS_FAILURE
;
200 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
201 if(!ConfigurationContext
)
203 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
205 *Status
= NDIS_STATUS_RESOURCES
;
209 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
210 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
212 ConfigurationContext
->Handle
= KeyHandle
;
214 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
215 *Status
= NDIS_STATUS_SUCCESS
;
217 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
226 NdisOpenProtocolConfiguration(
227 OUT PNDIS_STATUS Status
,
228 OUT PNDIS_HANDLE ConfigurationHandle
,
229 IN PNDIS_STRING ProtocolSection
)
231 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
233 * Status: caller-allocated buffer where status is returned
234 * ConfigurationHandle: spot to return the opaque configuration context
235 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
237 * NDIS_STATUS_SUCCESS: the operation was a success
238 * NDIS_STATUS_FAILURE: the operation was not a success
240 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
243 OBJECT_ATTRIBUTES KeyAttributes
;
244 UNICODE_STRING KeyNameU
;
246 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
249 KeyNameU
.MaximumLength
= ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(UNICODE_NULL
);
250 KeyNameU
.Buffer
= ExAllocatePool(PagedPool
, KeyNameU
.MaximumLength
);
253 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
254 *ConfigurationHandle
= NULL
;
255 *Status
= NDIS_STATUS_FAILURE
;
259 RtlCopyUnicodeString(&KeyNameU
, ProtocolSection
);
260 RtlAppendUnicodeToString(&KeyNameU
, PARAMETERS_KEY
);
261 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
263 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
265 ExFreePool(KeyNameU
.Buffer
);
267 if(*Status
!= NDIS_STATUS_SUCCESS
)
269 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
270 *ConfigurationHandle
= NULL
;
271 *Status
= NDIS_STATUS_FAILURE
;
275 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
276 if(!ConfigurationContext
)
278 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
280 *ConfigurationHandle
= NULL
;
281 *Status
= NDIS_STATUS_FAILURE
;
285 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
286 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
288 ConfigurationContext
->Handle
= KeyHandle
;
290 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
291 *Status
= NDIS_STATUS_SUCCESS
;
300 NdisReadConfiguration(
301 OUT PNDIS_STATUS Status
,
302 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
303 IN NDIS_HANDLE ConfigurationHandle
,
304 IN PNDIS_STRING Keyword
,
305 IN NDIS_PARAMETER_TYPE ParameterType
)
307 * FUNCTION: Read a configuration value from the registry, tracking its resources
309 * Status: points to a place to write status into
310 * ParameterValue: Pointer to receive a newly-allocated parameter structure
311 * ConfigurationHandle: handle originally returned by an open function
312 * Keyword: Value name to read, or one of the following constants:
313 * Environment - returns NdisEnvironmentWindowsNt
314 * ProcessorType - returns NdisProcessorX86 until more architectures are added
315 * NdisVersion - returns NDIS_VERSION
316 * ParameterType: the type of the value to be queried
318 * - A status in Status
319 * - A parameter value in ParameterValue
322 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
324 PMINIPORT_RESOURCE MiniportResource
;
325 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
328 *ParameterValue
= NULL
;
329 *Status
= NDIS_STATUS_FAILURE
;
331 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
333 if (ConfigurationContext
== NULL
)
335 NDIS_DbgPrint(MIN_TRACE
,("invalid parameter ConfigurationContext (0x%x)\n",ConfigurationContext
));
340 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
341 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
344 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
347 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
348 *Status
= NDIS_STATUS_RESOURCES
;
352 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
353 if(!MiniportResource
)
355 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
356 ExFreePool(*ParameterValue
);
357 *ParameterValue
= NULL
;
358 *Status
= NDIS_STATUS_RESOURCES
;
362 MiniportResource
->ResourceType
= 0;
363 MiniportResource
->Resource
= *ParameterValue
;
365 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
366 MiniportResource
->Resource
));
368 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
369 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
371 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
372 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
373 *Status
= NDIS_STATUS_SUCCESS
;
379 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
380 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
383 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
386 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
387 *Status
= NDIS_STATUS_RESOURCES
;
391 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
392 if(!MiniportResource
)
394 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
395 ExFreePool(*ParameterValue
);
396 *ParameterValue
= NULL
;
397 *Status
= NDIS_STATUS_RESOURCES
;
401 MiniportResource
->ResourceType
= 0;
402 MiniportResource
->Resource
= *ParameterValue
;
403 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
404 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
405 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
407 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
408 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
409 *Status
= NDIS_STATUS_SUCCESS
;
415 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
416 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
419 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
422 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
423 *Status
= NDIS_STATUS_RESOURCES
;
427 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
428 if(!MiniportResource
)
430 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
431 ExFreePool(*ParameterValue
);
432 *ParameterValue
= NULL
;
433 *Status
= NDIS_STATUS_RESOURCES
;
437 MiniportResource
->ResourceType
= 0;
438 MiniportResource
->Resource
= *ParameterValue
;
439 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
440 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
441 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
443 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
444 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
445 *Status
= NDIS_STATUS_SUCCESS
;
447 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
448 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
452 /* figure out how much buffer i should allocate */
453 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
454 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
456 NDIS_DbgPrint(MIN_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
457 *Status
= NDIS_STATUS_FAILURE
;
462 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
465 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
466 *Status
= NDIS_STATUS_RESOURCES
;
471 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
472 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
473 if(*Status
!= STATUS_SUCCESS
)
475 ExFreePool(KeyInformation
);
476 NDIS_DbgPrint(MIN_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
477 *Status
= NDIS_STATUS_FAILURE
;
481 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
482 if(!MiniportResource
)
484 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
485 ExFreePool(KeyInformation
);
486 *Status
= NDIS_STATUS_RESOURCES
;
490 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
491 if (!*ParameterValue
)
493 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
494 ExFreePool(MiniportResource
);
495 ExFreePool(KeyInformation
);
496 *Status
= NDIS_STATUS_RESOURCES
;
500 RtlZeroMemory(*ParameterValue
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
502 if (KeyInformation
->Type
== REG_BINARY
)
504 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterBinary\n"));
506 (*ParameterValue
)->ParameterType
= NdisParameterBinary
;
508 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
511 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
512 ExFreePool(MiniportResource
);
513 ExFreePool(KeyInformation
);
514 *Status
= NDIS_STATUS_RESOURCES
;
518 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
520 (*ParameterValue
)->ParameterData
.BinaryData
.Buffer
= Buffer
;
521 (*ParameterValue
)->ParameterData
.BinaryData
.Length
= KeyInformation
->DataLength
;
523 else if (KeyInformation
->Type
== REG_MULTI_SZ
)
525 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterMultiString\n"));
527 (*ParameterValue
)->ParameterType
= NdisParameterMultiString
;
529 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
532 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
533 ExFreePool(MiniportResource
);
534 ExFreePool(KeyInformation
);
535 *Status
= NDIS_STATUS_RESOURCES
;
539 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
541 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
542 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
548 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
549 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
551 if ((*Status
= RtlUnicodeStringToInteger(&str
, 0,
552 &(*ParameterValue
)->ParameterData
.IntegerData
)) == STATUS_SUCCESS
)
554 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterInteger\n"));
556 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
560 NDIS_DbgPrint(MAX_TRACE
, ("NdisParameterString\n"));
562 (*ParameterValue
)->ParameterType
= NdisParameterString
;
564 Buffer
= ExAllocatePool(NonPagedPool
, KeyInformation
->DataLength
);
567 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
568 ExFreePool(MiniportResource
);
569 ExFreePool(KeyInformation
);
570 *Status
= NDIS_STATUS_RESOURCES
;
574 RtlCopyMemory(Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
576 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= Buffer
;
577 (*ParameterValue
)->ParameterData
.StringData
.Length
= KeyInformation
->DataLength
;
581 MiniportResource
->ResourceType
= MINIPORT_RESOURCE_TYPE_MEMORY
;
582 MiniportResource
->Resource
= *ParameterValue
;
584 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
586 ExFreePool(KeyInformation
);
588 *Status
= NDIS_STATUS_SUCCESS
;
592 UCHAR
UnicodeToHexByte(WCHAR chr
)
594 * FUNCTION: Converts a unicode hex character to its numerical value
596 * chr: Unicode character to convert
598 * The numerical value of chr
641 NdisReadNetworkAddress(
642 OUT PNDIS_STATUS Status
,
643 OUT PVOID
* NetworkAddress
,
644 OUT PUINT NetworkAddressLength
,
645 IN NDIS_HANDLE ConfigurationHandle
)
647 * FUNCTION: Reads the network address from the registry
649 * Status - variable to receive status
650 * NetworkAddress - pointer to a buffered network address array
651 * NetworkAddressLength - length of the NetworkAddress array
652 * ConfigurationHandle: handle passed back from one of the open routines
654 * NDIS_STATUS_SUCCESS on success
655 * NDIS_STATUS_FAILURE on failure
656 * The network address is placed in the NetworkAddress buffer
659 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
660 PMINIPORT_RESOURCE MiniportResource
= NULL
;
661 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
667 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
668 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
669 if(*Status
!= NDIS_STATUS_SUCCESS
)
671 NDIS_DbgPrint(MIN_TRACE
, ("NdisReadConfiguration failed (%x)\n", *Status
));
672 *Status
= NDIS_STATUS_FAILURE
;
676 if (ParameterValue
->ParameterType
== NdisParameterInteger
)
680 NDIS_DbgPrint(MAX_TRACE
, ("Read integer data %lx\n",
681 ParameterValue
->ParameterData
.IntegerData
));
684 str
.MaximumLength
= (USHORT
)sizeof(Buff
);
687 *Status
= RtlIntegerToUnicodeString(ParameterValue
->ParameterData
.IntegerData
,
691 if (*Status
!= NDIS_STATUS_SUCCESS
)
693 NDIS_DbgPrint(MIN_TRACE
, ("RtlIntegerToUnicodeString failed (%x)\n", *Status
));
694 *Status
= NDIS_STATUS_FAILURE
;
698 NDIS_DbgPrint(MAX_TRACE
, ("Converted integer data into %wZ\n", &str
));
702 ASSERT(ParameterValue
->ParameterType
== NdisParameterString
);
703 str
= ParameterValue
->ParameterData
.StringData
;
706 while (j
< str
.Length
&& str
.Buffer
[j
] != '\0') j
++;
708 *NetworkAddressLength
= (j
+1) >> 1;
710 if ((*NetworkAddressLength
) == 0)
712 NDIS_DbgPrint(MIN_TRACE
,("Empty NetworkAddress registry entry.\n"));
713 *Status
= NDIS_STATUS_FAILURE
;
717 IntArray
= ExAllocatePool(PagedPool
, (*NetworkAddressLength
)*sizeof(UINT
));
720 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
721 *Status
= NDIS_STATUS_RESOURCES
;
725 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
726 if(!MiniportResource
)
728 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
729 ExFreePool(IntArray
);
730 *Status
= NDIS_STATUS_RESOURCES
;
734 MiniportResource
->ResourceType
= 0;
735 MiniportResource
->Resource
= IntArray
;
736 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
737 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
739 /* convert from string to bytes */
740 for(i
=0; i
<(*NetworkAddressLength
); i
++)
742 IntArray
[i
] = (UnicodeToHexByte((str
.Buffer
)[2*i
]) << 4) +
743 UnicodeToHexByte((str
.Buffer
)[2*i
+1]);
746 *NetworkAddress
= IntArray
;
748 *Status
= NDIS_STATUS_SUCCESS
;
757 NdisOpenConfigurationKeyByIndex(
758 OUT PNDIS_STATUS Status
,
759 IN NDIS_HANDLE ConfigurationHandle
,
761 OUT PNDIS_STRING KeyName
,
762 OUT PNDIS_HANDLE KeyHandle
)
764 * FUNCTION: Opens a configuration subkey by index number
766 * Status: pointer to an NDIS_STATUS to receive status info
767 * ConfigurationHandle: the handle passed back from a previous open function
768 * Index: the zero-based index of the subkey to open
769 * KeyName: the name of the key that was opened
770 * KeyHandle: a handle to the key that was opened
772 * NDIS_STATUS_SUCCESS on success
773 * NDIS_STATUS_FAILURE on failure
774 * KeyName holds the name of the opened key
775 * KeyHandle holds a handle to the new key
778 KEY_BASIC_INFORMATION
*KeyInformation
;
779 ULONG KeyInformationLength
;
780 OBJECT_ATTRIBUTES KeyAttributes
;
781 NDIS_HANDLE RegKeyHandle
;
782 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
786 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
787 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
789 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
790 *Status
= NDIS_STATUS_FAILURE
;
794 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
797 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
798 *Status
= NDIS_STATUS_FAILURE
;
802 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
803 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
805 if(*Status
!= STATUS_SUCCESS
)
807 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
808 ExFreePool(KeyInformation
);
809 *Status
= NDIS_STATUS_FAILURE
;
813 /* should i fail instead if the passed-in string isn't long enough? */
814 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
815 KeyName
->Length
= (USHORT
)KeyInformation
->NameLength
;
817 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
819 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
821 ExFreePool(KeyInformation
);
823 if(*Status
!= STATUS_SUCCESS
)
825 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
826 *Status
= NDIS_STATUS_FAILURE
;
830 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
831 if(!ConfigurationContext
)
833 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
834 ZwClose(RegKeyHandle
);
835 *Status
= NDIS_STATUS_FAILURE
;
839 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
840 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
842 ConfigurationContext
->Handle
= RegKeyHandle
;
844 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
846 *Status
= NDIS_STATUS_SUCCESS
;
855 NdisOpenConfigurationKeyByName(
856 OUT PNDIS_STATUS Status
,
857 IN NDIS_HANDLE ConfigurationHandle
,
858 IN PNDIS_STRING KeyName
,
859 OUT PNDIS_HANDLE KeyHandle
)
861 * FUNCTION: Opens a configuration subkey by name
863 * Status: points to an NDIS_STATUS where status is returned
864 * ConfigurationHandle: handle returned by a previous open call
865 * KeyName: the name of the key to open
866 * KeyHandle: a handle to the opened key
868 * NDIS_STATUS_SUCCESS on success
869 * NDIS_STATUS_FAILURE on failure
870 * KeyHandle holds a handle to the newly-opened key
874 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
875 OBJECT_ATTRIBUTES KeyAttributes
;
876 NDIS_HANDLE RegKeyHandle
;
880 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
881 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
883 if(*Status
!= STATUS_SUCCESS
)
885 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
886 *Status
= NDIS_STATUS_FAILURE
;
890 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
891 if(!ConfigurationContext
)
893 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
894 ZwClose(RegKeyHandle
);
895 *Status
= NDIS_STATUS_FAILURE
;
899 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
900 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
902 ConfigurationContext
->Handle
= RegKeyHandle
;
904 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
906 *Status
= NDIS_STATUS_SUCCESS
;