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 0x00050000 /* 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 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
73 /* reset parameter type to standard reg types */
76 case NdisParameterHexInteger
:
77 case NdisParameterInteger
:
81 Str
.Buffer
= (PWSTR
) &Buff
;
82 Str
.MaximumLength
= (USHORT
)sizeof(Buff
);
85 ParameterType
= REG_SZ
;
86 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
87 ParameterValue
->ParameterData
.IntegerData
,
88 (ParameterType
== NdisParameterInteger
) ? 10 : 16, &Str
)))
90 *Status
= NDIS_STATUS_FAILURE
;
94 DataSize
= Str
.Length
;
97 case NdisParameterString
:
98 case NdisParameterMultiString
:
99 ParameterType
= REG_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
;
327 *ParameterValue
= NULL
;
328 *Status
= NDIS_STATUS_FAILURE
;
330 if(ParameterType
!= NdisParameterInteger
&&
331 ParameterType
!= NdisParameterHexInteger
&&
332 ParameterType
!= NdisParameterString
&&
333 ParameterType
!= NdisParameterMultiString
&&
334 ParameterType
!= NdisParameterBinary
337 NDIS_DbgPrint(MIN_TRACE
,("unsupported parameter type\n"));
338 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
342 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
344 if (ConfigurationContext
== NULL
)
346 NDIS_DbgPrint(MIN_TRACE
,("invalid parameter ConfigurationContext (0x%x)\n",ConfigurationContext
));
351 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
352 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
355 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
358 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
359 *Status
= NDIS_STATUS_RESOURCES
;
363 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
364 if(!MiniportResource
)
366 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
367 ExFreePool(*ParameterValue
);
368 *ParameterValue
= NULL
;
369 *Status
= NDIS_STATUS_RESOURCES
;
373 MiniportResource
->ResourceType
= 0;
374 MiniportResource
->Resource
= *ParameterValue
;
376 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
377 MiniportResource
->Resource
));
379 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
380 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
382 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
383 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
384 *Status
= NDIS_STATUS_SUCCESS
;
390 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
391 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
394 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
397 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
398 *Status
= NDIS_STATUS_RESOURCES
;
402 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
403 if(!MiniportResource
)
405 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
406 ExFreePool(*ParameterValue
);
407 *ParameterValue
= NULL
;
408 *Status
= NDIS_STATUS_RESOURCES
;
412 MiniportResource
->ResourceType
= 0;
413 MiniportResource
->Resource
= *ParameterValue
;
414 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
415 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
416 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
418 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
419 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
420 *Status
= NDIS_STATUS_SUCCESS
;
426 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
427 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
430 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
433 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
434 *Status
= NDIS_STATUS_RESOURCES
;
438 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
439 if(!MiniportResource
)
441 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
442 ExFreePool(*ParameterValue
);
443 *ParameterValue
= NULL
;
444 *Status
= NDIS_STATUS_RESOURCES
;
448 MiniportResource
->ResourceType
= 0;
449 MiniportResource
->Resource
= *ParameterValue
;
450 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
451 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
452 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
454 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
455 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
456 *Status
= NDIS_STATUS_SUCCESS
;
458 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
459 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
463 /* figure out how much buffer i should allocate */
464 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
465 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
467 NDIS_DbgPrint(MIN_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
468 *Status
= NDIS_STATUS_FAILURE
;
473 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
476 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
477 *Status
= NDIS_STATUS_RESOURCES
;
482 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
483 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
484 if(*Status
!= STATUS_SUCCESS
)
486 ExFreePool(KeyInformation
);
487 NDIS_DbgPrint(MIN_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
488 *Status
= NDIS_STATUS_FAILURE
;
492 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
493 if(!MiniportResource
)
495 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
496 ExFreePool(KeyInformation
);
497 *Status
= NDIS_STATUS_RESOURCES
;
501 switch(ParameterType
)
503 case NdisParameterInteger
:
504 case NdisParameterHexInteger
:
508 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
511 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
512 ExFreePool(KeyInformation
);
513 *Status
= NDIS_STATUS_RESOURCES
;
517 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
518 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
520 (*ParameterValue
)->ParameterType
= ParameterType
;
523 If ParameterType is NdisParameterInteger then the base of str is decimal.
524 If ParameterType is NdisParameterHexInteger then the base of str is hexadecimal.
526 if (ParameterType
== NdisParameterInteger
)
527 *Status
= RtlUnicodeStringToInteger(&str
, 10, &(*ParameterValue
)->ParameterData
.IntegerData
);
528 else if (ParameterType
== NdisParameterHexInteger
)
529 *Status
= RtlUnicodeStringToInteger(&str
, 16, &(*ParameterValue
)->ParameterData
.IntegerData
);
532 ExFreePool(KeyInformation
);
534 if(*Status
!= STATUS_SUCCESS
) {
535 ExFreePool(*ParameterValue
);
536 *ParameterValue
= NULL
;
537 *Status
= NDIS_STATUS_FAILURE
;
541 MiniportResource
->ResourceType
= 0;
542 MiniportResource
->Resource
= *ParameterValue
;
543 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
544 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
546 *Status
= NDIS_STATUS_SUCCESS
;
551 case NdisParameterString
:
552 case NdisParameterMultiString
:
556 if(KeyInformation
->Type
!= REG_SZ
&& KeyInformation
->Type
!= REG_MULTI_SZ
)
558 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
559 ExFreePool(KeyInformation
);
560 *ParameterValue
= NULL
;
561 *Status
= NDIS_STATUS_FAILURE
;
565 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
568 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
569 ExFreePool(KeyInformation
);
570 *Status
= NDIS_STATUS_RESOURCES
;
574 RegData
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
577 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
578 ExFreePool(KeyInformation
);
579 ExFreePool(*ParameterValue
);
580 *ParameterValue
= NULL
;
581 *Status
= NDIS_STATUS_FAILURE
;
585 MiniportResource
->ResourceType
= 0;
586 MiniportResource
->Resource
= *ParameterValue
;
587 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
588 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
590 memcpy(RegData
, KeyInformation
->Data
, KeyInformation
->DataLength
);
592 (*ParameterValue
)->ParameterType
= ParameterType
;
593 (*ParameterValue
)->ParameterData
.StringData
.Length
= (USHORT
)KeyInformation
->DataLength
;
594 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= RegData
;
596 ExFreePool(KeyInformation
);
598 *Status
= NDIS_STATUS_SUCCESS
;
603 case NdisParameterBinary
:
605 if(KeyInformation
->Type
!= REG_BINARY
)
607 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
608 *Status
= NDIS_STATUS_FAILURE
;
609 ExFreePool(KeyInformation
);
613 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
) + KeyInformation
->DataLength
);
616 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
617 ExFreePool(KeyInformation
);
618 *Status
= NDIS_STATUS_RESOURCES
;
622 (*ParameterValue
)->ParameterData
.BinaryData
.Buffer
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
623 if (!(*ParameterValue
)->ParameterData
.BinaryData
.Buffer
)
625 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
626 ExFreePool(KeyInformation
);
627 *Status
= NDIS_STATUS_RESOURCES
;
631 (*ParameterValue
)->ParameterType
= ParameterType
;
632 (*ParameterValue
)->ParameterData
.BinaryData
.Length
= KeyInformation
->DataLength
;
633 memcpy((*ParameterValue
)->ParameterData
.BinaryData
.Buffer
, KeyInformation
->Data
, KeyInformation
->DataLength
);
635 MiniportResource
->ResourceType
= 0;
636 MiniportResource
->Resource
= *ParameterValue
;
637 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
638 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
640 ExFreePool(KeyInformation
);
642 *Status
= NDIS_STATUS_SUCCESS
;
650 UCHAR
UnicodeToHexByte(WCHAR chr
)
652 * FUNCTION: Converts a unicode hex character to its numerical value
654 * chr: Unicode character to convert
656 * The numerical value of chr
699 NdisReadNetworkAddress(
700 OUT PNDIS_STATUS Status
,
701 OUT PVOID
* NetworkAddress
,
702 OUT PUINT NetworkAddressLength
,
703 IN NDIS_HANDLE ConfigurationHandle
)
705 * FUNCTION: Reads the network address from the registry
707 * Status - variable to receive status
708 * NetworkAddress - pointer to a buffered network address array
709 * NetworkAddressLength - length of the NetworkAddress array
710 * ConfigurationHandle: handle passed back from one of the open routines
712 * NDIS_STATUS_SUCCESS on success
713 * NDIS_STATUS_FAILURE on failure
714 * The network address is placed in the NetworkAddress buffer
717 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
718 PMINIPORT_RESOURCE MiniportResource
= NULL
;
719 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
724 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
725 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
726 if(*Status
!= NDIS_STATUS_SUCCESS
)
728 NDIS_DbgPrint(MIN_TRACE
, ("NdisReadConfiguration failed (%x)\n", *Status
));
729 *Status
= NDIS_STATUS_FAILURE
;
733 while (ParameterValue
->ParameterData
.StringData
.Buffer
[j
] != '\0') j
++;
735 *NetworkAddressLength
= (UINT
)((j
/2)+0.5);
739 NDIS_DbgPrint(MIN_TRACE
,("Empty NetworkAddress registry entry.\n"));
740 *Status
= NDIS_STATUS_FAILURE
;
744 IntArray
= ExAllocatePool(PagedPool
, (*NetworkAddressLength
)*sizeof(UINT
));
747 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
748 *Status
= NDIS_STATUS_RESOURCES
;
752 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
753 if(!MiniportResource
)
755 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
756 ExFreePool(IntArray
);
757 *Status
= NDIS_STATUS_RESOURCES
;
761 MiniportResource
->ResourceType
= 0;
762 MiniportResource
->Resource
= IntArray
;
763 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
764 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
766 /* convert from string to bytes */
767 for(i
=0; i
<(*NetworkAddressLength
); i
++)
769 IntArray
[i
] = (UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
]) << 4) +
770 UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
+1]);
773 *NetworkAddress
= IntArray
;
775 *Status
= NDIS_STATUS_SUCCESS
;
784 NdisOpenConfigurationKeyByIndex(
785 OUT PNDIS_STATUS Status
,
786 IN NDIS_HANDLE ConfigurationHandle
,
788 OUT PNDIS_STRING KeyName
,
789 OUT PNDIS_HANDLE KeyHandle
)
791 * FUNCTION: Opens a configuration subkey by index number
793 * Status: pointer to an NDIS_STATUS to receive status info
794 * ConfigurationHandle: the handle passed back from a previous open function
795 * Index: the zero-based index of the subkey to open
796 * KeyName: the name of the key that was opened
797 * KeyHandle: a handle to the key that was opened
799 * NDIS_STATUS_SUCCESS on success
800 * NDIS_STATUS_FAILURE on failure
801 * KeyName holds the name of the opened key
802 * KeyHandle holds a handle to the new key
805 KEY_BASIC_INFORMATION
*KeyInformation
;
806 ULONG KeyInformationLength
;
807 OBJECT_ATTRIBUTES KeyAttributes
;
808 NDIS_HANDLE RegKeyHandle
;
809 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
813 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
814 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
816 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
817 *Status
= NDIS_STATUS_FAILURE
;
821 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
824 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
825 *Status
= NDIS_STATUS_FAILURE
;
829 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
830 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
832 if(*Status
!= STATUS_SUCCESS
)
834 NDIS_DbgPrint(MIN_TRACE
, ("ZwEnumerateKey failed (%x)\n", *Status
));
835 ExFreePool(KeyInformation
);
836 *Status
= NDIS_STATUS_FAILURE
;
840 /* should i fail instead if the passed-in string isn't long enough? */
841 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
842 KeyName
->Length
= (USHORT
)KeyInformation
->NameLength
;
844 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
846 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
848 ExFreePool(KeyInformation
);
850 if(*Status
!= STATUS_SUCCESS
)
852 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
853 *Status
= NDIS_STATUS_FAILURE
;
857 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
858 if(!ConfigurationContext
)
860 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
861 ZwClose(RegKeyHandle
);
862 *Status
= NDIS_STATUS_FAILURE
;
866 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
867 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
869 ConfigurationContext
->Handle
= RegKeyHandle
;
871 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
873 *Status
= NDIS_STATUS_SUCCESS
;
882 NdisOpenConfigurationKeyByName(
883 OUT PNDIS_STATUS Status
,
884 IN NDIS_HANDLE ConfigurationHandle
,
885 IN PNDIS_STRING KeyName
,
886 OUT PNDIS_HANDLE KeyHandle
)
888 * FUNCTION: Opens a configuration subkey by name
890 * Status: points to an NDIS_STATUS where status is returned
891 * ConfigurationHandle: handle returned by a previous open call
892 * KeyName: the name of the key to open
893 * KeyHandle: a handle to the opened key
895 * NDIS_STATUS_SUCCESS on success
896 * NDIS_STATUS_FAILURE on failure
897 * KeyHandle holds a handle to the newly-opened key
901 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
902 OBJECT_ATTRIBUTES KeyAttributes
;
903 NDIS_HANDLE RegKeyHandle
;
907 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
908 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
910 if(*Status
!= STATUS_SUCCESS
)
912 NDIS_DbgPrint(MIN_TRACE
, ("ZwOpenKey failed (%x)\n", *Status
));
913 *Status
= NDIS_STATUS_FAILURE
;
917 ConfigurationContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
918 if(!ConfigurationContext
)
920 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
921 ZwClose(RegKeyHandle
);
922 *Status
= NDIS_STATUS_FAILURE
;
926 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
927 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
929 ConfigurationContext
->Handle
= RegKeyHandle
;
931 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
933 *Status
= NDIS_STATUS_SUCCESS
;