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 if(ParameterType
!= NdisParameterInteger
&&
72 ParameterType
!= NdisParameterHexInteger
&&
73 ParameterType
!= NdisParameterString
&&
74 ParameterType
!= NdisParameterMultiString
&&
75 ParameterType
!= NdisParameterBinary
78 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
82 /* reset parameter type to standard reg types */
85 case NdisParameterHexInteger
:
86 case NdisParameterInteger
:
90 Str
.Buffer
= (PWSTR
) &Buff
;
91 Str
.MaximumLength
= (USHORT
)sizeof(Buff
);
94 ParameterType
= REG_SZ
;
95 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
96 ParameterValue
->ParameterData
.IntegerData
,
97 (ParameterType
== NdisParameterInteger
) ? 10 : 16, &Str
)))
99 *Status
= NDIS_STATUS_FAILURE
;
103 DataSize
= Str
.Length
;
106 case NdisParameterString
:
107 case NdisParameterMultiString
:
108 ParameterType
= REG_SZ
;
109 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
110 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
113 /* New (undocumented) addition to 2k ddk */
114 case NdisParameterBinary
:
115 ParameterType
= REG_BINARY
;
116 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
117 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
121 *Status
= NDIS_STATUS_FAILURE
;
125 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
126 Keyword
, 0, ParameterType
, Data
, DataSize
);
128 if(*Status
!= STATUS_SUCCESS
)
129 *Status
= NDIS_STATUS_FAILURE
;
131 *Status
= NDIS_STATUS_SUCCESS
;
140 NdisCloseConfiguration(
141 IN NDIS_HANDLE ConfigurationHandle
)
143 * FUNCTION: Closes handles and releases per-handle resources
145 * ConfigurationHandle - pointer to the context with the resources to free
148 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
149 PMINIPORT_RESOURCE Resource
;
151 while(!IsListEmpty(&ConfigurationContext
->ResourceListHead
))
153 Resource
= (PMINIPORT_RESOURCE
)RemoveTailList(&ConfigurationContext
->ResourceListHead
);
154 if(Resource
->ResourceType
== MINIPORT_RESOURCE_TYPE_MEMORY
)
156 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
157 ExFreePool(Resource
->Resource
);
160 ExFreePool(Resource
);
163 ZwClose(ConfigurationContext
->Handle
);
172 NdisOpenConfiguration(
173 OUT PNDIS_STATUS Status
,
174 OUT PNDIS_HANDLE ConfigurationHandle
,
175 IN NDIS_HANDLE WrapperConfigurationContext
)
177 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
179 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
180 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
181 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
183 * NDIS_STATUS_SUCCESS: the operation completed successfully
184 * NDIS_STATUS_FAILURE: the operation failed
186 * I think this is the parameters key; please verify.
190 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
191 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
192 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
194 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
196 *ConfigurationHandle
= NULL
;
198 *Status
= ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle
,
199 NtCurrentProcess(), &KeyHandle
, 0, 0,
200 DUPLICATE_SAME_ACCESS
);
201 if(!NT_SUCCESS(*Status
))
203 NDIS_DbgPrint(MID_TRACE
, ("Failed to open registry configuration for this miniport\n"));
204 *Status
= NDIS_STATUS_FAILURE
;
208 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
209 if(!ConfigurationContext
)
211 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
213 *Status
= NDIS_STATUS_RESOURCES
;
217 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
218 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
220 ConfigurationContext
->Handle
= KeyHandle
;
222 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
223 *Status
= NDIS_STATUS_SUCCESS
;
225 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
234 NdisOpenProtocolConfiguration(
235 OUT PNDIS_STATUS Status
,
236 OUT PNDIS_HANDLE ConfigurationHandle
,
237 IN PNDIS_STRING ProtocolSection
)
239 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
241 * Status: caller-allocated buffer where status is returned
242 * ConfigurationHandle: spot to return the opaque configuration context
243 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
245 * NDIS_STATUS_SUCCESS: the operation was a success
246 * NDIS_STATUS_FAILURE: the operation was not a success
248 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
251 OBJECT_ATTRIBUTES KeyAttributes
;
252 UNICODE_STRING KeyNameU
;
254 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
257 KeyNameU
.MaximumLength
= ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(UNICODE_NULL
);
258 KeyNameU
.Buffer
= ExAllocatePool(PagedPool
, KeyNameU
.MaximumLength
);
261 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
262 *ConfigurationHandle
= NULL
;
263 *Status
= NDIS_STATUS_FAILURE
;
267 RtlCopyUnicodeString(&KeyNameU
, ProtocolSection
);
268 RtlAppendUnicodeToString(&KeyNameU
, PARAMETERS_KEY
);
269 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
271 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
273 ExFreePool(KeyNameU
.Buffer
);
275 if(*Status
!= NDIS_STATUS_SUCCESS
)
277 *ConfigurationHandle
= NULL
;
278 *Status
= NDIS_STATUS_FAILURE
;
282 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
283 if(!ConfigurationContext
)
285 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
286 *ConfigurationHandle
= NULL
;
287 *Status
= NDIS_STATUS_FAILURE
;
291 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
292 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
294 ConfigurationContext
->Handle
= KeyHandle
;
296 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
297 *Status
= NDIS_STATUS_SUCCESS
;
306 NdisReadConfiguration(
307 OUT PNDIS_STATUS Status
,
308 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
309 IN NDIS_HANDLE ConfigurationHandle
,
310 IN PNDIS_STRING Keyword
,
311 IN NDIS_PARAMETER_TYPE ParameterType
)
313 * FUNCTION: Read a configuration value from the registry, tracking its resources
315 * Status: points to a place to write status into
316 * ParameterValue: Pointer to receive a newly-allocated parameter structure
317 * ConfigurationHandle: handle originally returned by an open function
318 * Keyword: Value name to read, or one of the following constants:
319 * Environment - returns NdisEnvironmentWindowsNt
320 * ProcessorType - returns NdisProcessorX86 until more architectures are added
321 * NdisVersion - returns NDIS_VERSION
322 * ParameterType: the type of the value to be queried
324 * - A status in Status
325 * - A parameter value in ParameterValue
328 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
330 PMINIPORT_RESOURCE MiniportResource
;
331 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
333 *ParameterValue
= NULL
;
334 *Status
= NDIS_STATUS_FAILURE
;
336 if(ParameterType
!= NdisParameterInteger
&&
337 ParameterType
!= NdisParameterHexInteger
&&
338 ParameterType
!= NdisParameterString
&&
339 ParameterType
!= NdisParameterMultiString
&&
340 ParameterType
!= NdisParameterBinary
343 NDIS_DbgPrint(MID_TRACE
,("unsupported parameter type\n"));
347 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
350 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
351 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
354 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
357 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
358 *Status
= NDIS_STATUS_RESOURCES
;
362 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
363 if(!MiniportResource
)
365 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
366 ExFreePool(*ParameterValue
);
367 *ParameterValue
= NULL
;
368 *Status
= NDIS_STATUS_RESOURCES
;
372 MiniportResource
->ResourceType
= 0;
373 MiniportResource
->Resource
= *ParameterValue
;
375 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
376 MiniportResource
->Resource
));
378 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
379 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
381 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
382 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
383 *Status
= NDIS_STATUS_SUCCESS
;
389 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
390 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
393 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
396 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
397 *Status
= NDIS_STATUS_RESOURCES
;
401 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
402 if(!MiniportResource
)
404 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
405 ExFreePool(*ParameterValue
);
406 *ParameterValue
= NULL
;
407 *Status
= NDIS_STATUS_RESOURCES
;
411 MiniportResource
->ResourceType
= 0;
412 MiniportResource
->Resource
= *ParameterValue
;
413 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
414 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
415 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
417 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
418 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
419 *Status
= NDIS_STATUS_SUCCESS
;
425 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
426 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
429 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
432 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
433 *Status
= NDIS_STATUS_RESOURCES
;
437 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
438 if(!MiniportResource
)
440 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
441 ExFreePool(*ParameterValue
);
442 *ParameterValue
= NULL
;
443 *Status
= NDIS_STATUS_RESOURCES
;
447 MiniportResource
->ResourceType
= 0;
448 MiniportResource
->Resource
= *ParameterValue
;
449 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
450 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
451 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
453 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
454 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
455 *Status
= NDIS_STATUS_SUCCESS
;
457 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
458 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
462 /* figure out how much buffer i should allocate */
463 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
464 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
466 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
467 *Status
= NDIS_STATUS_FAILURE
;
472 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
475 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
476 *Status
= NDIS_STATUS_RESOURCES
;
481 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
482 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
483 if(*Status
!= STATUS_SUCCESS
)
485 ExFreePool(KeyInformation
);
486 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
487 *Status
= NDIS_STATUS_FAILURE
;
491 switch(ParameterType
)
493 case NdisParameterInteger
:
494 case NdisParameterHexInteger
:
498 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
501 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
502 ExFreePool(KeyInformation
);
503 *Status
= NDIS_STATUS_RESOURCES
;
507 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
508 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
510 (*ParameterValue
)->ParameterType
= ParameterType
;
513 If ParameterType is NdisParameterInteger then the base of str is decimal.
514 If ParameterType is NdisParameterHexInteger then the base of str is hexadecimal.
516 if (ParameterType
== NdisParameterInteger
)
517 *Status
= RtlUnicodeStringToInteger(&str
, 10, &(*ParameterValue
)->ParameterData
.IntegerData
);
518 else if (ParameterType
== NdisParameterHexInteger
)
519 *Status
= RtlUnicodeStringToInteger(&str
, 16, &(*ParameterValue
)->ParameterData
.IntegerData
);
522 ExFreePool(KeyInformation
);
524 if(*Status
!= STATUS_SUCCESS
)
525 *Status
= NDIS_STATUS_FAILURE
;
527 *Status
= NDIS_STATUS_SUCCESS
;
532 case NdisParameterString
:
533 case NdisParameterMultiString
:
537 if(KeyInformation
->Type
!= REG_SZ
&& KeyInformation
->Type
!= REG_MULTI_SZ
)
539 NDIS_DbgPrint(MID_TRACE
,("requested type does not match actual value type\n"));
540 ExFreePool(KeyInformation
);
541 *ParameterValue
= NULL
;
542 *Status
= NDIS_STATUS_FAILURE
;
546 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
549 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
550 ExFreePool(KeyInformation
);
551 *Status
= NDIS_STATUS_RESOURCES
;
555 RegData
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
558 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
559 ExFreePool(KeyInformation
);
560 ExFreePool(*ParameterValue
);
561 *ParameterValue
= NULL
;
562 *Status
= NDIS_STATUS_FAILURE
;
566 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
567 if(!MiniportResource
)
569 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
570 ExFreePool(KeyInformation
);
571 ExFreePool(*ParameterValue
);
572 *ParameterValue
= NULL
;
573 *Status
= NDIS_STATUS_RESOURCES
;
577 MiniportResource
->ResourceType
= 0;
578 MiniportResource
->Resource
= *ParameterValue
;
579 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
580 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
582 memcpy(RegData
, KeyInformation
->Data
, KeyInformation
->DataLength
);
584 (*ParameterValue
)->ParameterType
= ParameterType
;
585 (*ParameterValue
)->ParameterData
.StringData
.Length
= (USHORT
)KeyInformation
->DataLength
;
586 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= RegData
;
588 ExFreePool(KeyInformation
);
590 *Status
= NDIS_STATUS_SUCCESS
;
595 case NdisParameterBinary
:
597 if(KeyInformation
->Type
!= REG_BINARY
)
599 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
600 *Status
= NDIS_STATUS_FAILURE
;
601 ExFreePool(KeyInformation
);
605 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
) + KeyInformation
->DataLength
);
608 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
609 ExFreePool(KeyInformation
);
610 *Status
= NDIS_STATUS_RESOURCES
;
614 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
615 if(!MiniportResource
)
617 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
618 ExFreePool(KeyInformation
);
619 ExFreePool(*ParameterValue
);
620 *ParameterValue
= NULL
;
621 *Status
= NDIS_STATUS_RESOURCES
;
625 MiniportResource
->ResourceType
= 0;
626 MiniportResource
->Resource
= *ParameterValue
;
627 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
628 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
630 (*ParameterValue
)->ParameterType
= ParameterType
;
631 memcpy(&((*ParameterValue
)->ParameterData
.BinaryData
), KeyInformation
->Data
, KeyInformation
->DataLength
);
633 ExFreePool(KeyInformation
);
635 *Status
= NDIS_STATUS_SUCCESS
;
643 UCHAR
UnicodeToHexByte(WCHAR chr
)
645 * FUNCTION: Converts a unicode hex character to its numerical value
647 * chr: Unicode character to convert
649 * The numerical value of chr
692 NdisReadNetworkAddress(
693 OUT PNDIS_STATUS Status
,
694 OUT PVOID
* NetworkAddress
,
695 OUT PUINT NetworkAddressLength
,
696 IN NDIS_HANDLE ConfigurationHandle
)
698 * FUNCTION: Reads the network address from the registry
700 * Status - variable to receive status
701 * NetworkAddress - pointer to a buffered network address array
702 * NetworkAddressLength - length of the NetworkAddress array
703 * ConfigurationHandle: handle passed back from one of the open routines
705 * NDIS_STATUS_SUCCESS on success
706 * NDIS_STATUS_FAILURE on failure
707 * The network address is placed in the NetworkAddress buffer
710 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
711 PMINIPORT_RESOURCE MiniportResource
= NULL
;
712 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
717 /* FIXME - We don't quite support this yet due to buggy code below */
719 *Status
= NDIS_STATUS_FAILURE
;
723 *NetworkAddress
= NULL
;
724 *NetworkAddressLength
= 6;/* XXX magic constant */
726 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
727 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
728 if(*Status
!= NDIS_STATUS_SUCCESS
)
730 *Status
= NDIS_STATUS_FAILURE
;
734 /* 6 bytes for ethernet, tokenring, fddi, everything else? */
735 IntArray
= ExAllocatePool(PagedPool
, 6*sizeof(UINT
));
738 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
739 *Status
= NDIS_STATUS_RESOURCES
;
743 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
744 if(!MiniportResource
)
746 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
747 ExFreePool(IntArray
);
748 *Status
= NDIS_STATUS_RESOURCES
;
752 MiniportResource
->ResourceType
= 0;
753 MiniportResource
->Resource
= IntArray
;
754 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
755 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
757 /* convert from string to bytes */
760 IntArray
[i
] = (UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
]) << 4) +
761 UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
+1]);
764 *NetworkAddress
= IntArray
;
766 *Status
= NDIS_STATUS_SUCCESS
;
775 NdisOpenConfigurationKeyByIndex(
776 OUT PNDIS_STATUS Status
,
777 IN NDIS_HANDLE ConfigurationHandle
,
779 OUT PNDIS_STRING KeyName
,
780 OUT PNDIS_HANDLE KeyHandle
)
782 * FUNCTION: Opens a configuration subkey by index number
784 * Status: pointer to an NDIS_STATUS to receive status info
785 * ConfigurationHandle: the handle passed back from a previous open function
786 * Index: the zero-based index of the subkey to open
787 * KeyName: the name of the key that was opened
788 * KeyHandle: a handle to the key that was opened
790 * NDIS_STATUS_SUCCESS on success
791 * NDIS_STATUS_FAILURE on failure
792 * KeyName holds the name of the opened key
793 * KeyHandle holds a handle to the new key
796 KEY_BASIC_INFORMATION
*KeyInformation
;
797 ULONG KeyInformationLength
;
798 OBJECT_ATTRIBUTES KeyAttributes
;
799 NDIS_HANDLE RegKeyHandle
;
800 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
804 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
805 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
807 *Status
= NDIS_STATUS_FAILURE
;
811 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
814 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
815 *Status
= NDIS_STATUS_FAILURE
;
819 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
820 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
822 if(*Status
!= STATUS_SUCCESS
)
824 ExFreePool(KeyInformation
);
825 *Status
= NDIS_STATUS_FAILURE
;
829 /* should i fail instead if the passed-in string isn't long enough? */
830 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
831 KeyName
->Length
= (USHORT
)KeyInformation
->NameLength
;
833 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
835 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
837 ExFreePool(KeyInformation
);
839 if(*Status
!= STATUS_SUCCESS
)
841 *Status
= NDIS_STATUS_FAILURE
;
845 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
846 if(!ConfigurationContext
)
848 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
849 *Status
= NDIS_STATUS_FAILURE
;
853 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
854 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
856 ConfigurationContext
->Handle
= RegKeyHandle
;
858 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
860 *Status
= NDIS_STATUS_SUCCESS
;
869 NdisOpenConfigurationKeyByName(
870 OUT PNDIS_STATUS Status
,
871 IN NDIS_HANDLE ConfigurationHandle
,
872 IN PNDIS_STRING KeyName
,
873 OUT PNDIS_HANDLE KeyHandle
)
875 * FUNCTION: Opens a configuration subkey by name
877 * Status: points to an NDIS_STATUS where status is returned
878 * ConfigurationHandle: handle returned by a previous open call
879 * KeyName: the name of the key to open
880 * KeyHandle: a handle to the opened key
882 * NDIS_STATUS_SUCCESS on success
883 * NDIS_STATUS_FAILURE on failure
884 * KeyHandle holds a handle to the newly-opened key
888 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
889 OBJECT_ATTRIBUTES KeyAttributes
;
890 NDIS_HANDLE RegKeyHandle
;
894 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
895 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
897 if(*Status
!= STATUS_SUCCESS
)
899 *Status
= NDIS_STATUS_FAILURE
;
903 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
904 if(!ConfigurationContext
)
906 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
907 *Status
= NDIS_STATUS_FAILURE
;
911 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
912 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
914 ConfigurationContext
->Handle
= RegKeyHandle
;
916 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
918 *Status
= NDIS_STATUS_SUCCESS
;