2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
5 * PURPOSE: NDIS Configuration Services
6 * PROGRAMMERS: Vizzini (vizzini@plasmic.com)
8 * Vizzini 07-28-2003 Created
10 * - Resource tracking has to be implemented here because of the design of the NDIS API.
11 * Whenever a read operation is performed, the NDIS library allocates space and returns
12 * it. A linked list is kept associated with every handle of the memory allocated to
13 * it. When the handle is closed, the resources are systematically released.
14 * - The NDIS_HANDLE Configuraiton context is no longer a registry handle. An opaque struct
15 * had to be created to allow for resource tracking. This means that Miniports cannot just
16 * pass this NDIS_HANDLE to things like ZwQueryValueKey(). I don't thknk they do (they
17 * certainly should not), but it should be kept in mind.
18 * UPDATE: I just found this in the NTDDK:
19 * NdisOpenProtocolConfiguration returns a handle for the
20 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NICDriverInstance\Parameters\ProtocolName
21 * registry key. XXX This is a problem. Following that, the DDK instructs programmers
22 * to use NdisReadConfiguration and NdisWriteConfiguration. No telling what the world's idiots
23 * have done with this.
24 * - I have tried to stick to the DDK's definition of what return values are possible, which
25 * has resulted in stupid return values in some cases. I do use STATUS_RESOURCES in a few
26 * places that the DDK doesn't explicitly mention it, though.
27 * - There's a general reliance on the fact that UNICODE_STRING.Length doesn't include a trailing
28 * 0, which it shouldn't
29 * - I added support for NdisParameterBinary. It's at the end of the struct. I wonder if
31 * - All the routines in this file are PASSIVE_LEVEL only, and all memory is PagedPool
36 #define NDIS_VERSION 0x00040000 /* the version of NDIS we claim to be to miniport drivers */
37 #define PARAMETERS_KEY L"Parameters" /* The parameters subkey under the device-specific key */
44 NdisWriteConfiguration(
45 OUT PNDIS_STATUS Status
,
46 IN NDIS_HANDLE ConfigurationHandle
,
47 IN PNDIS_STRING Keyword
,
48 IN PNDIS_CONFIGURATION_PARAMETER ParameterValue
)
50 * FUNCTION: Writes a configuration value to the registry
52 * Status: Pointer to a caller-supplied NDIS_STATUS where we return status
53 * ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
54 * Keyword: The registry value name to write
55 * ParameterValue: The value data to write
57 * NDIS_STATUS_SUCCESS - the operation completed successfully
58 * NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
59 * NDIS_STATUS_RESOURCES - out of memory, etc.
60 * NDIS_STATUS_FAILURE - any other failure
62 * There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
63 * I don't know why tho so i free everything before return. comments welcome.
66 ULONG ParameterType
= ParameterValue
->ParameterType
;
70 if(ParameterType
!= NdisParameterInteger
&&
71 ParameterType
!= NdisParameterHexInteger
&&
72 ParameterType
!= NdisParameterString
&&
73 ParameterType
!= NdisParameterMultiString
&&
74 ParameterType
!= NdisParameterBinary
77 *Status
= NDIS_STATUS_NOT_SUPPORTED
;
81 /* reset parameter type to standard reg types */
84 /* TODO: figure out what do do with these; are they different? */
85 case NdisParameterHexInteger
:
86 case NdisParameterInteger
:
87 ParameterType
= REG_SZ
;
88 Data
= &ParameterValue
->ParameterData
.IntegerData
;
89 DataSize
= sizeof(ULONG
);
92 case NdisParameterString
:
93 case NdisParameterMultiString
:
94 ParameterType
= REG_SZ
;
95 Data
= ParameterValue
->ParameterData
.StringData
.Buffer
;
96 DataSize
= ParameterValue
->ParameterData
.StringData
.Length
;
99 /* New (undocumented) addition to 2k ddk */
100 case NdisParameterBinary
:
101 ParameterType
= REG_BINARY
;
102 Data
= ParameterValue
->ParameterData
.BinaryData
.Buffer
;
103 DataSize
= ParameterValue
->ParameterData
.BinaryData
.Length
;
107 *Status
= NDIS_STATUS_FAILURE
;
111 *Status
= ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
)->Handle
,
112 Keyword
, 0, ParameterType
, Data
, DataSize
);
114 if(*Status
!= STATUS_SUCCESS
)
115 *Status
= NDIS_STATUS_FAILURE
;
117 *Status
= NDIS_STATUS_SUCCESS
;
126 NdisCloseConfiguration(
127 IN NDIS_HANDLE ConfigurationHandle
)
129 * FUNCTION: Closes handles and releases per-handle resources
131 * ConfigurationHandle - pointer to the context with the resources to free
134 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
135 PMINIPORT_RESOURCE Resource
;
137 while(!IsListEmpty(&ConfigurationContext
->ResourceListHead
))
139 Resource
= (PMINIPORT_RESOURCE
)RemoveTailList(&ConfigurationContext
->ResourceListHead
);
140 if(Resource
->ResourceType
== MINIPORT_RESOURCE_TYPE_MEMORY
)
142 NDIS_DbgPrint(MAX_TRACE
,("freeing 0x%x\n", Resource
->Resource
));
143 ExFreePool(Resource
->Resource
);
146 ExFreePool(Resource
);
149 ZwClose(ConfigurationContext
->Handle
);
158 NdisOpenConfiguration(
159 OUT PNDIS_STATUS Status
,
160 OUT PNDIS_HANDLE ConfigurationHandle
,
161 IN NDIS_HANDLE WrapperConfigurationContext
)
163 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
165 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
166 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success
167 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
169 * NDIS_STATUS_SUCCESS: the operation completed successfully
170 * NDIS_STATUS_FAILURE: the operation failed
172 * I think this is the parameters key; please verify.
176 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
177 PNDIS_WRAPPER_CONTEXT WrapperContext
= (PNDIS_WRAPPER_CONTEXT
)WrapperConfigurationContext
;
178 HANDLE RootKeyHandle
= WrapperContext
->RegistryHandle
;
180 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
182 *Status
= ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle
,
183 NtCurrentProcess(), &KeyHandle
, 0, FALSE
,
184 DUPLICATE_SAME_ACCESS
);
185 if(!NT_SUCCESS(*Status
))
187 NDIS_DbgPrint(MID_TRACE
, ("Failed to open registry configuration for this miniport\n"));
188 *ConfigurationHandle
= NULL
;
189 *Status
= NDIS_STATUS_FAILURE
;
193 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
194 if(!ConfigurationContext
)
196 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
198 *Status
= NDIS_STATUS_RESOURCES
;
202 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
203 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
205 ConfigurationContext
->Handle
= KeyHandle
;
207 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
208 *Status
= NDIS_STATUS_SUCCESS
;
210 NDIS_DbgPrint(MAX_TRACE
,("returning success\n"));
219 NdisOpenProtocolConfiguration(
220 OUT PNDIS_STATUS Status
,
221 OUT PNDIS_HANDLE ConfigurationHandle
,
222 IN PNDIS_STRING ProtocolSection
)
224 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
226 * Status: caller-allocated buffer where status is returned
227 * ConfigurationHandle: spot to return the opaque configuration context
228 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
230 * NDIS_STATUS_SUCCESS: the operation was a success
231 * NDIS_STATUS_FAILURE: the operation was not a success
233 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
236 OBJECT_ATTRIBUTES KeyAttributes
;
237 UNICODE_STRING KeyNameU
;
239 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
242 KeyNameU
.MaximumLength
= ProtocolSection
->Length
+ sizeof(PARAMETERS_KEY
) + sizeof(UNICODE_NULL
);
243 KeyNameU
.Buffer
= ExAllocatePool(PagedPool
, KeyNameU
.MaximumLength
);
246 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
247 *ConfigurationHandle
= NULL
;
248 *Status
= NDIS_STATUS_FAILURE
;
252 RtlCopyUnicodeString(&KeyNameU
, ProtocolSection
);
253 RtlAppendUnicodeToString(&KeyNameU
, PARAMETERS_KEY
);
254 InitializeObjectAttributes(&KeyAttributes
, &KeyNameU
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
256 *Status
= ZwOpenKey(&KeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
258 ExFreePool(KeyNameU
.Buffer
);
260 if(*Status
!= NDIS_STATUS_SUCCESS
)
262 *ConfigurationHandle
= NULL
;
263 *Status
= NDIS_STATUS_FAILURE
;
267 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
268 if(!ConfigurationContext
)
270 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
271 *ConfigurationHandle
= NULL
;
272 *Status
= NDIS_STATUS_FAILURE
;
276 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
277 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
279 ConfigurationContext
->Handle
= KeyHandle
;
281 *ConfigurationHandle
= (NDIS_HANDLE
)ConfigurationContext
;
282 *Status
= NDIS_STATUS_SUCCESS
;
291 NdisReadConfiguration(
292 OUT PNDIS_STATUS Status
,
293 OUT PNDIS_CONFIGURATION_PARAMETER
* ParameterValue
,
294 IN NDIS_HANDLE ConfigurationHandle
,
295 IN PNDIS_STRING Keyword
,
296 IN NDIS_PARAMETER_TYPE ParameterType
)
298 * FUNCTION: Read a configuration value from the registry, tracking its resources
300 * Status: points to a place to write status into
301 * ParameterValue: Pointer to receive a newly-allocated parameter structure
302 * ConfigurationHandle: handle originally returned by an open function
303 * Keyword: Value name to read, or one of the following constants:
304 * Environment - returns NdisEnvironmentWindowsNt
305 * ProcessorType - returns NdisProcessorX86 until more architectures are added
306 * NdisVersion - returns NDIS_VERSION
307 * ParameterType: the type of the value to be queried
309 * - A status in Status
310 * - A parameter value in ParameterValue
313 KEY_VALUE_PARTIAL_INFORMATION
*KeyInformation
;
315 PMINIPORT_RESOURCE MiniportResource
;
316 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
318 *ParameterValue
= NULL
;
319 *Status
= NDIS_STATUS_FAILURE
;
321 if(ParameterType
!= NdisParameterInteger
&&
322 ParameterType
!= NdisParameterHexInteger
&&
323 ParameterType
!= NdisParameterString
&&
324 ParameterType
!= NdisParameterMultiString
&&
325 ParameterType
!= NdisParameterBinary
328 NDIS_DbgPrint(MID_TRACE
,("unsupported parameter type\n"));
332 NDIS_DbgPrint(MAX_TRACE
,("requested read of %wZ\n", Keyword
));
335 !wcsncmp(Keyword
->Buffer
, L
"Environment", Keyword
->Length
/sizeof(WCHAR
)) &&
336 wcslen(L
"Environment") == Keyword
->Length
/sizeof(WCHAR
)
339 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
342 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
343 *Status
= NDIS_STATUS_RESOURCES
;
347 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
348 if(!MiniportResource
)
350 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
351 ExFreePool(*ParameterValue
);
352 *ParameterValue
= NULL
;
353 *Status
= NDIS_STATUS_RESOURCES
;
357 MiniportResource
->ResourceType
= 0;
358 MiniportResource
->Resource
= *ParameterValue
;
360 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n",
361 MiniportResource
->Resource
));
363 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
364 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
366 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
367 (*ParameterValue
)->ParameterData
.IntegerData
= NdisEnvironmentWindowsNt
;
368 *Status
= NDIS_STATUS_SUCCESS
;
374 !wcsncmp(Keyword
->Buffer
, L
"ProcessorType", Keyword
->Length
/sizeof(WCHAR
)) &&
375 wcslen(L
"ProcessorType") == Keyword
->Length
/sizeof(WCHAR
)
378 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
381 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
382 *Status
= NDIS_STATUS_RESOURCES
;
386 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
387 if(!MiniportResource
)
389 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
390 ExFreePool(*ParameterValue
);
391 *ParameterValue
= NULL
;
392 *Status
= NDIS_STATUS_RESOURCES
;
396 MiniportResource
->ResourceType
= 0;
397 MiniportResource
->Resource
= *ParameterValue
;
398 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
399 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
400 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
402 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
403 (*ParameterValue
)->ParameterData
.IntegerData
= NdisProcessorX86
; /* XXX non-portable */
404 *Status
= NDIS_STATUS_SUCCESS
;
410 !wcsncmp(Keyword
->Buffer
, L
"NdisVersion", Keyword
->Length
/sizeof(WCHAR
)) &&
411 wcslen(L
"NdisVersion") == Keyword
->Length
/sizeof(WCHAR
)
414 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
417 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
418 *Status
= NDIS_STATUS_RESOURCES
;
422 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
423 if(!MiniportResource
)
425 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
426 ExFreePool(*ParameterValue
);
427 *ParameterValue
= NULL
;
428 *Status
= NDIS_STATUS_RESOURCES
;
432 MiniportResource
->ResourceType
= 0;
433 MiniportResource
->Resource
= *ParameterValue
;
434 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
435 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
,
436 &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
438 (*ParameterValue
)->ParameterType
= NdisParameterInteger
;
439 (*ParameterValue
)->ParameterData
.IntegerData
= NDIS_VERSION
;
440 *Status
= NDIS_STATUS_SUCCESS
;
442 NDIS_DbgPrint(MAX_TRACE
,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
443 (*ParameterValue
)->ParameterType
, (*ParameterValue
)->ParameterData
.IntegerData
));
447 /* figure out how much buffer i should allocate */
448 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
, NULL
, 0, &KeyDataLength
);
449 if(*Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_SUCCESS
)
451 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
452 *Status
= NDIS_STATUS_FAILURE
;
457 KeyInformation
= ExAllocatePool(PagedPool
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
));
460 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
461 *Status
= NDIS_STATUS_RESOURCES
;
466 *Status
= ZwQueryValueKey(ConfigurationContext
->Handle
, Keyword
, KeyValuePartialInformation
,
467 KeyInformation
, KeyDataLength
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION
), &KeyDataLength
);
468 if(*Status
!= STATUS_SUCCESS
)
470 ExFreePool(KeyInformation
);
471 NDIS_DbgPrint(MID_TRACE
,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword
, *Status
));
472 *Status
= NDIS_STATUS_FAILURE
;
476 switch(ParameterType
)
478 case NdisParameterInteger
:
479 case NdisParameterHexInteger
:
483 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
486 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
487 ExFreePool(KeyInformation
);
488 *Status
= NDIS_STATUS_RESOURCES
;
492 str
.Length
= str
.MaximumLength
= (USHORT
)KeyInformation
->DataLength
;
493 str
.Buffer
= (PWCHAR
)KeyInformation
->Data
;
495 (*ParameterValue
)->ParameterType
= ParameterType
;
496 *Status
= RtlUnicodeStringToInteger(&str
, 16, &(*ParameterValue
)->ParameterData
.IntegerData
);
498 ExFreePool(KeyInformation
);
500 if(*Status
!= STATUS_SUCCESS
)
501 *Status
= NDIS_STATUS_FAILURE
;
503 *Status
= NDIS_STATUS_SUCCESS
;
508 case NdisParameterString
:
509 case NdisParameterMultiString
:
513 if(KeyInformation
->Type
!= REG_SZ
&& KeyInformation
->Type
!= REG_MULTI_SZ
)
515 NDIS_DbgPrint(MID_TRACE
,("requested type does not match actual value type\n"));
516 ExFreePool(KeyInformation
);
517 *ParameterValue
= NULL
;
518 *Status
= NDIS_STATUS_FAILURE
;
522 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
));
525 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
526 ExFreePool(KeyInformation
);
527 *Status
= NDIS_STATUS_RESOURCES
;
531 RegData
= ExAllocatePool(PagedPool
, KeyInformation
->DataLength
);
534 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
535 ExFreePool(KeyInformation
);
536 ExFreePool(*ParameterValue
);
537 *ParameterValue
= NULL
;
538 *Status
= NDIS_STATUS_FAILURE
;
542 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
543 if(!MiniportResource
)
545 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
546 ExFreePool(KeyInformation
);
547 ExFreePool(*ParameterValue
);
548 *ParameterValue
= NULL
;
549 *Status
= NDIS_STATUS_RESOURCES
;
553 MiniportResource
->ResourceType
= 0;
554 MiniportResource
->Resource
= *ParameterValue
;
555 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
556 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
558 memcpy(RegData
, KeyInformation
->Data
, KeyInformation
->DataLength
);
560 (*ParameterValue
)->ParameterType
= ParameterType
;
561 (*ParameterValue
)->ParameterData
.StringData
.Length
= (USHORT
)KeyInformation
->DataLength
;
562 (*ParameterValue
)->ParameterData
.StringData
.Buffer
= RegData
;
564 ExFreePool(KeyInformation
);
566 *Status
= NDIS_STATUS_SUCCESS
;
571 case NdisParameterBinary
:
573 if(KeyInformation
->Type
!= REG_BINARY
)
575 NDIS_DbgPrint(MIN_TRACE
,("requested type does not match actual value type\n"));
576 *Status
= NDIS_STATUS_FAILURE
;
577 ExFreePool(KeyInformation
);
581 *ParameterValue
= ExAllocatePool(PagedPool
, sizeof(NDIS_CONFIGURATION_PARAMETER
) + KeyInformation
->DataLength
);
584 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
585 ExFreePool(KeyInformation
);
586 *Status
= NDIS_STATUS_RESOURCES
;
590 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
591 if(!MiniportResource
)
593 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
594 ExFreePool(KeyInformation
);
595 ExFreePool(*ParameterValue
);
596 *ParameterValue
= NULL
;
597 *Status
= NDIS_STATUS_RESOURCES
;
601 MiniportResource
->ResourceType
= 0;
602 MiniportResource
->Resource
= *ParameterValue
;
603 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
604 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
606 (*ParameterValue
)->ParameterType
= ParameterType
;
607 memcpy(&((*ParameterValue
)->ParameterData
.BinaryData
), KeyInformation
->Data
, KeyInformation
->DataLength
);
609 ExFreePool(KeyInformation
);
611 *Status
= NDIS_STATUS_SUCCESS
;
619 UCHAR
UnicodeToHexByte(WCHAR chr
)
621 * FUNCTION: Converts a unicode hex character to its numerical value
623 * chr: Unicode character to convert
625 * The numerical value of chr
668 NdisReadNetworkAddress(
669 OUT PNDIS_STATUS Status
,
670 OUT PVOID
* NetworkAddress
,
671 OUT PUINT NetworkAddressLength
,
672 IN NDIS_HANDLE ConfigurationHandle
)
674 * FUNCTION: Reads the network address from the registry
676 * Status - variable to receive status
677 * NetworkAddress - pointer to a buffered network address array
678 * NetworkAddressLength - length of the NetworkAddress array
679 * ConfigurationHandle: handle passed back from one of the open routines
681 * NDIS_STATUS_SUCCESS on success
682 * NDIS_STATUS_FAILURE on failure
683 * The network address is placed in the NetworkAddress buffer
686 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
= (PMINIPORT_CONFIGURATION_CONTEXT
)ConfigurationHandle
;
687 PMINIPORT_RESOURCE MiniportResource
= NULL
;
688 PNDIS_CONFIGURATION_PARAMETER ParameterValue
= NULL
;
693 /* FIXME - We don't quite support this yet due to buggy code below */
695 *Status
= NDIS_STATUS_FAILURE
;
699 *NetworkAddress
= NULL
;
700 *NetworkAddressLength
= 6;/* XXX magic constant */
702 NdisInitUnicodeString(&Keyword
, L
"NetworkAddress");
703 NdisReadConfiguration(Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
704 if(*Status
!= NDIS_STATUS_SUCCESS
)
706 *Status
= NDIS_STATUS_FAILURE
;
710 /* 6 bytes for ethernet, tokenring, fddi, everything else? */
711 IntArray
= ExAllocatePool(PagedPool
, 6*sizeof(UINT
));
714 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
715 *Status
= NDIS_STATUS_RESOURCES
;
719 MiniportResource
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_RESOURCE
));
720 if(!MiniportResource
)
722 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
723 *Status
= NDIS_STATUS_FAILURE
;
727 MiniportResource
->ResourceType
= 0;
728 MiniportResource
->Resource
= IntArray
;
729 NDIS_DbgPrint(MID_TRACE
,("inserting 0x%x into the resource list\n", MiniportResource
->Resource
));
730 ExInterlockedInsertTailList(&ConfigurationContext
->ResourceListHead
, &MiniportResource
->ListEntry
, &ConfigurationContext
->ResourceLock
);
732 /* convert from string to bytes */
735 IntArray
[i
] = (UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
]) << 4) +
736 UnicodeToHexByte((ParameterValue
->ParameterData
.StringData
.Buffer
)[2*i
+1]);
739 *NetworkAddress
= IntArray
;
741 *Status
= NDIS_STATUS_SUCCESS
;
750 NdisOpenConfigurationKeyByIndex(
751 OUT PNDIS_STATUS Status
,
752 IN NDIS_HANDLE ConfigurationHandle
,
754 OUT PNDIS_STRING KeyName
,
755 OUT PNDIS_HANDLE KeyHandle
)
757 * FUNCTION: Opens a configuration subkey by index number
759 * Status: pointer to an NDIS_STATUS to receive status info
760 * ConfigurationHandle: the handle passed back from a previous open function
761 * Index: the zero-based index of the subkey to open
762 * KeyName: the name of the key that was opened
763 * KeyHandle: a handle to the key that was opened
765 * NDIS_STATUS_SUCCESS on success
766 * NDIS_STATUS_FAILURE on failure
767 * KeyName holds the name of the opened key
768 * KeyHandle holds a handle to the new key
771 KEY_BASIC_INFORMATION
*KeyInformation
;
772 ULONG KeyInformationLength
;
773 OBJECT_ATTRIBUTES KeyAttributes
;
774 NDIS_HANDLE RegKeyHandle
;
775 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
777 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, NULL
, 0, &KeyInformationLength
);
778 if(*Status
!= STATUS_BUFFER_TOO_SMALL
&& *Status
!= STATUS_BUFFER_OVERFLOW
&& *Status
!= STATUS_SUCCESS
)
780 *Status
= NDIS_STATUS_FAILURE
;
784 KeyInformation
= ExAllocatePool(PagedPool
, KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
));
787 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
788 *Status
= NDIS_STATUS_FAILURE
;
792 *Status
= ZwEnumerateKey(ConfigurationHandle
, Index
, KeyBasicInformation
, KeyInformation
,
793 KeyInformationLength
+ sizeof(KEY_BASIC_INFORMATION
), &KeyInformationLength
);
795 if(*Status
!= STATUS_SUCCESS
)
797 ExFreePool(KeyInformation
);
798 *Status
= NDIS_STATUS_FAILURE
;
802 /* should i fail instead if the passed-in string isn't long enough? */
803 wcsncpy(KeyName
->Buffer
, KeyInformation
->Name
, KeyName
->MaximumLength
/sizeof(WCHAR
));
804 KeyName
->Length
= (USHORT
)KeyInformation
->NameLength
;
806 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, NULL
);
808 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
810 ExFreePool(KeyInformation
);
812 if(*Status
!= STATUS_SUCCESS
)
814 *Status
= NDIS_STATUS_FAILURE
;
818 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
819 if(!ConfigurationContext
)
821 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
822 *Status
= NDIS_STATUS_FAILURE
;
826 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
827 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
829 ConfigurationContext
->Handle
= RegKeyHandle
;
831 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
833 *Status
= NDIS_STATUS_SUCCESS
;
842 NdisOpenConfigurationKeyByName(
843 OUT PNDIS_STATUS Status
,
844 IN NDIS_HANDLE ConfigurationHandle
,
845 IN PNDIS_STRING KeyName
,
846 OUT PNDIS_HANDLE KeyHandle
)
848 * FUNCTION: Opens a configuration subkey by name
850 * Status: points to an NDIS_STATUS where status is returned
851 * ConfigurationHandle: handle returned by a previous open call
852 * KeyName: the name of the key to open
853 * KeyHandle: a handle to the opened key
855 * NDIS_STATUS_SUCCESS on success
856 * NDIS_STATUS_FAILURE on failure
857 * KeyHandle holds a handle to the newly-opened key
861 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext
;
862 OBJECT_ATTRIBUTES KeyAttributes
;
863 NDIS_HANDLE RegKeyHandle
;
865 InitializeObjectAttributes(&KeyAttributes
, KeyName
, OBJ_CASE_INSENSITIVE
, ConfigurationHandle
, 0);
866 *Status
= ZwOpenKey(&RegKeyHandle
, KEY_ALL_ACCESS
, &KeyAttributes
);
868 if(*Status
!= STATUS_SUCCESS
)
870 *Status
= NDIS_STATUS_FAILURE
;
874 ConfigurationContext
= ExAllocatePool(PagedPool
, sizeof(MINIPORT_CONFIGURATION_CONTEXT
));
875 if(!ConfigurationContext
)
877 NDIS_DbgPrint(MIN_TRACE
,("Insufficient resources.\n"));
878 *Status
= NDIS_STATUS_FAILURE
;
882 KeInitializeSpinLock(&ConfigurationContext
->ResourceLock
);
883 InitializeListHead(&ConfigurationContext
->ResourceListHead
);
885 ConfigurationContext
->Handle
= RegKeyHandle
;
887 *KeyHandle
= (NDIS_HANDLE
)ConfigurationContext
;
889 *Status
= NDIS_STATUS_SUCCESS
;