Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenconfig.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS NDIS library 00004 * FILE: ndis/config.c 00005 * PURPOSE: NDIS Configuration Services 00006 * PROGRAMMERS: Vizzini (vizzini@plasmic.com) 00007 * REVISIONS: 00008 * Vizzini 07-28-2003 Created 00009 * NOTES: 00010 * - Resource tracking has to be implemented here because of the design of the NDIS API. 00011 * Whenever a read operation is performed, the NDIS library allocates space and returns 00012 * it. A linked list is kept associated with every handle of the memory allocated to 00013 * it. When the handle is closed, the resources are systematically released. 00014 * - The NDIS_HANDLE Configuraiton context is no longer a registry handle. An opaque struct 00015 * had to be created to allow for resource tracking. This means that Miniports cannot just 00016 * pass this NDIS_HANDLE to things like ZwQueryValueKey(). I don't thknk they do (they 00017 * certainly should not), but it should be kept in mind. 00018 * UPDATE: I just found this in the NTDDK: 00019 * NdisOpenProtocolConfiguration returns a handle for the 00020 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NICDriverInstance\Parameters\ProtocolName 00021 * registry key. XXX This is a problem. Following that, the DDK instructs programmers 00022 * to use NdisReadConfiguration and NdisWriteConfiguration. No telling what the world's idiots 00023 * have done with this. 00024 * - I have tried to stick to the DDK's definition of what return values are possible, which 00025 * has resulted in stupid return values in some cases. I do use STATUS_RESOURCES in a few 00026 * places that the DDK doesn't explicitly mention it, though. 00027 * - There's a general reliance on the fact that UNICODE_STRING.Length doesn't include a trailing 00028 * 0, which it shouldn't 00029 * - I added support for NdisParameterBinary. It's at the end of the struct. I wonder if 00030 * it'll break things. 00031 * - All the routines in this file are PASSIVE_LEVEL only, and all memory is PagedPool 00032 */ 00033 00034 #include "ndissys.h" 00035 00036 #define PARAMETERS_KEY L"Parameters" /* The parameters subkey under the device-specific key */ 00037 00038 /* 00039 * @implemented 00040 */ 00041 VOID 00042 EXPORT 00043 NdisWriteConfiguration( 00044 OUT PNDIS_STATUS Status, 00045 IN NDIS_HANDLE ConfigurationHandle, 00046 IN PNDIS_STRING Keyword, 00047 IN PNDIS_CONFIGURATION_PARAMETER ParameterValue) 00048 /* 00049 * FUNCTION: Writes a configuration value to the registry 00050 * ARGUMENTS: 00051 * Status: Pointer to a caller-supplied NDIS_STATUS where we return status 00052 * ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions 00053 * Keyword: The registry value name to write 00054 * ParameterValue: The value data to write 00055 * RETURNS: 00056 * NDIS_STATUS_SUCCESS - the operation completed successfully 00057 * NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported 00058 * NDIS_STATUS_RESOURCES - out of memory, etc. 00059 * NDIS_STATUS_FAILURE - any other failure 00060 * NOTES: 00061 * There's a cryptic comment in the ddk implying that this function allocates and keeps memory. 00062 * I don't know why tho so i free everything before return. comments welcome. 00063 */ 00064 { 00065 ULONG ParameterType; 00066 ULONG DataSize; 00067 PVOID Data; 00068 WCHAR Buff[11]; 00069 00070 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00071 00072 NDIS_DbgPrint(MID_TRACE, ("Parameter type: %d\n", ParameterValue->ParameterType)); 00073 00074 /* reset parameter type to standard reg types */ 00075 switch(ParameterValue->ParameterType) 00076 { 00077 case NdisParameterHexInteger: 00078 case NdisParameterInteger: 00079 { 00080 UNICODE_STRING Str; 00081 00082 Str.Buffer = (PWSTR) &Buff; 00083 Str.MaximumLength = (USHORT)sizeof(Buff); 00084 Str.Length = 0; 00085 00086 ParameterType = REG_SZ; 00087 if (!NT_SUCCESS(RtlIntegerToUnicodeString( 00088 ParameterValue->ParameterData.IntegerData, 00089 (ParameterValue->ParameterType == NdisParameterInteger) ? 10 : 16, &Str))) 00090 { 00091 NDIS_DbgPrint(MIN_TRACE, ("RtlIntegerToUnicodeString failed (%x)\n", *Status)); 00092 *Status = NDIS_STATUS_FAILURE; 00093 return; 00094 } 00095 Data = Str.Buffer; 00096 DataSize = Str.Length; 00097 } 00098 break; 00099 case NdisParameterString: 00100 case NdisParameterMultiString: 00101 ParameterType = (ParameterValue->ParameterType == NdisParameterString) ? REG_SZ : REG_MULTI_SZ; 00102 Data = ParameterValue->ParameterData.StringData.Buffer; 00103 DataSize = ParameterValue->ParameterData.StringData.Length; 00104 break; 00105 00106 /* New (undocumented) addition to 2k ddk */ 00107 case NdisParameterBinary: 00108 ParameterType = REG_BINARY; 00109 Data = ParameterValue->ParameterData.BinaryData.Buffer; 00110 DataSize = ParameterValue->ParameterData.BinaryData.Length; 00111 break; 00112 00113 default: 00114 *Status = NDIS_STATUS_NOT_SUPPORTED; 00115 return; 00116 } 00117 00118 *Status = ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle)->Handle, 00119 Keyword, 0, ParameterType, Data, DataSize); 00120 00121 if(*Status != STATUS_SUCCESS) { 00122 NDIS_DbgPrint(MIN_TRACE, ("ZwSetValueKey failed (%x)\n", *Status)); 00123 *Status = NDIS_STATUS_FAILURE; 00124 } else 00125 *Status = NDIS_STATUS_SUCCESS; 00126 } 00127 00128 00129 /* 00130 * @implemented 00131 */ 00132 VOID 00133 EXPORT 00134 NdisCloseConfiguration( 00135 IN NDIS_HANDLE ConfigurationHandle) 00136 /* 00137 * FUNCTION: Closes handles and releases per-handle resources 00138 * ARGUMENTS: 00139 * ConfigurationHandle - pointer to the context with the resources to free 00140 */ 00141 { 00142 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle; 00143 PMINIPORT_RESOURCE Resource; 00144 PNDIS_CONFIGURATION_PARAMETER ParameterValue; 00145 PLIST_ENTRY CurrentEntry; 00146 00147 while((CurrentEntry = ExInterlockedRemoveHeadList(&ConfigurationContext->ResourceListHead, 00148 &ConfigurationContext->ResourceLock)) != NULL) 00149 { 00150 Resource = CONTAINING_RECORD(CurrentEntry, MINIPORT_RESOURCE, ListEntry); 00151 switch(Resource->ResourceType) 00152 { 00153 case MINIPORT_RESOURCE_TYPE_REGISTRY_DATA: 00154 ParameterValue = Resource->Resource; 00155 00156 switch (ParameterValue->ParameterType) 00157 { 00158 case NdisParameterBinary: 00159 ExFreePool(ParameterValue->ParameterData.BinaryData.Buffer); 00160 break; 00161 00162 case NdisParameterString: 00163 case NdisParameterMultiString: 00164 ExFreePool(ParameterValue->ParameterData.StringData.Buffer); 00165 break; 00166 00167 default: 00168 break; 00169 } 00170 00171 /* Fall through to free NDIS_CONFIGURATION_PARAMETER struct */ 00172 00173 case MINIPORT_RESOURCE_TYPE_MEMORY: 00174 NDIS_DbgPrint(MAX_TRACE,("freeing 0x%x\n", Resource->Resource)); 00175 ExFreePool(Resource->Resource); 00176 break; 00177 00178 default: 00179 NDIS_DbgPrint(MIN_TRACE,("Unknown resource type: %d\n", Resource->ResourceType)); 00180 break; 00181 } 00182 00183 ExFreePool(Resource); 00184 } 00185 00186 ZwClose(ConfigurationContext->Handle); 00187 } 00188 00189 00190 /* 00191 * @implemented 00192 */ 00193 VOID 00194 EXPORT 00195 NdisOpenConfiguration( 00196 OUT PNDIS_STATUS Status, 00197 OUT PNDIS_HANDLE ConfigurationHandle, 00198 IN NDIS_HANDLE WrapperConfigurationContext) 00199 /* 00200 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle 00201 * ARGUMENTS: 00202 * Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value 00203 * ConfigurationHandle: Pointer to an opaque configuration handle returned on success 00204 * WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper 00205 * RETURNS: 00206 * NDIS_STATUS_SUCCESS: the operation completed successfully 00207 * NDIS_STATUS_FAILURE: the operation failed 00208 * NOTES: 00209 * I think this is the parameters key; please verify. 00210 */ 00211 { 00212 HANDLE KeyHandle; 00213 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext; 00214 PNDIS_WRAPPER_CONTEXT WrapperContext = (PNDIS_WRAPPER_CONTEXT)WrapperConfigurationContext; 00215 HANDLE RootKeyHandle = WrapperContext->RegistryHandle; 00216 00217 NDIS_DbgPrint(MAX_TRACE, ("Called\n")); 00218 00219 *ConfigurationHandle = NULL; 00220 00221 *Status = ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle, 00222 NtCurrentProcess(), &KeyHandle, 0, 0, 00223 DUPLICATE_SAME_ACCESS); 00224 if(!NT_SUCCESS(*Status)) 00225 { 00226 NDIS_DbgPrint(MIN_TRACE, ("Failed to open registry configuration for this miniport\n")); 00227 *Status = NDIS_STATUS_FAILURE; 00228 return; 00229 } 00230 00231 ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT)); 00232 if(!ConfigurationContext) 00233 { 00234 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00235 ZwClose(KeyHandle); 00236 *Status = NDIS_STATUS_RESOURCES; 00237 return; 00238 } 00239 00240 KeInitializeSpinLock(&ConfigurationContext->ResourceLock); 00241 InitializeListHead(&ConfigurationContext->ResourceListHead); 00242 00243 ConfigurationContext->Handle = KeyHandle; 00244 00245 *ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext; 00246 *Status = NDIS_STATUS_SUCCESS; 00247 00248 NDIS_DbgPrint(MAX_TRACE,("returning success\n")); 00249 } 00250 00251 00252 /* 00253 * @implemented 00254 */ 00255 VOID 00256 EXPORT 00257 NdisOpenProtocolConfiguration( 00258 OUT PNDIS_STATUS Status, 00259 OUT PNDIS_HANDLE ConfigurationHandle, 00260 IN PNDIS_STRING ProtocolSection) 00261 /* 00262 * FUNCTION: Open the configuration key and set up resource tracking for the protocol 00263 * ARGUMENTS: 00264 * Status: caller-allocated buffer where status is returned 00265 * ConfigurationHandle: spot to return the opaque configuration context 00266 * ProtocolSection: configuration string originally passed in to ProtocolBindAdapter 00267 * RETURNS: 00268 * NDIS_STATUS_SUCCESS: the operation was a success 00269 * NDIS_STATUS_FAILURE: the operation was not a success 00270 * NOTES: 00271 * I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify. 00272 */ 00273 { 00274 OBJECT_ATTRIBUTES KeyAttributes; 00275 UNICODE_STRING KeyNameU; 00276 HANDLE KeyHandle; 00277 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext; 00278 00279 KeyNameU.Length = 0; 00280 KeyNameU.MaximumLength = ProtocolSection->Length + sizeof(PARAMETERS_KEY) + sizeof(UNICODE_NULL); 00281 KeyNameU.Buffer = ExAllocatePool(PagedPool, KeyNameU.MaximumLength); 00282 if(!KeyNameU.Buffer) 00283 { 00284 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00285 *ConfigurationHandle = NULL; 00286 *Status = NDIS_STATUS_FAILURE; 00287 return; 00288 } 00289 00290 RtlCopyUnicodeString(&KeyNameU, ProtocolSection); 00291 RtlAppendUnicodeToString(&KeyNameU, PARAMETERS_KEY); 00292 InitializeObjectAttributes(&KeyAttributes, &KeyNameU, OBJ_CASE_INSENSITIVE, NULL, NULL); 00293 00294 *Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes); 00295 00296 ExFreePool(KeyNameU.Buffer); 00297 00298 if(*Status != NDIS_STATUS_SUCCESS) 00299 { 00300 NDIS_DbgPrint(MIN_TRACE, ("ZwOpenKey failed (%x)\n", *Status)); 00301 *ConfigurationHandle = NULL; 00302 *Status = NDIS_STATUS_FAILURE; 00303 return; 00304 } 00305 00306 ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT)); 00307 if(!ConfigurationContext) 00308 { 00309 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00310 ZwClose(KeyHandle); 00311 *ConfigurationHandle = NULL; 00312 *Status = NDIS_STATUS_FAILURE; 00313 return; 00314 } 00315 00316 KeInitializeSpinLock(&ConfigurationContext->ResourceLock); 00317 InitializeListHead(&ConfigurationContext->ResourceListHead); 00318 00319 ConfigurationContext->Handle = KeyHandle; 00320 00321 *ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext; 00322 *Status = NDIS_STATUS_SUCCESS; 00323 } 00324 00325 UCHAR UnicodeToHexByte(WCHAR chr) 00326 /* 00327 * FUNCTION: Converts a unicode hex character to its numerical value 00328 * ARGUMENTS: 00329 * chr: Unicode character to convert 00330 * RETURNS: 00331 * The numerical value of chr 00332 */ 00333 { 00334 switch(chr) 00335 { 00336 case L'0': return 0; 00337 case L'1': return 1; 00338 case L'2': return 2; 00339 case L'3': return 3; 00340 case L'4': return 4; 00341 case L'5': return 5; 00342 case L'6': return 6; 00343 case L'7': return 7; 00344 case L'8': return 8; 00345 case L'9': return 9; 00346 case L'A': 00347 case L'a': 00348 return 10; 00349 case L'B': 00350 case L'b': 00351 return 11; 00352 case L'C': 00353 case L'c': 00354 return 12; 00355 case L'D': 00356 case L'd': 00357 return 13; 00358 case L'E': 00359 case L'e': 00360 return 14; 00361 case L'F': 00362 case L'f': 00363 return 15; 00364 } 00365 return 0xFF; 00366 } 00367 00368 BOOLEAN 00369 IsValidNumericString(PNDIS_STRING String, ULONG Base) 00370 /* 00371 * FUNCTION: Determines if a string is a valid number 00372 * ARGUMENTS: 00373 * String: Unicode string to evaluate 00374 * RETURNS: 00375 * TRUE if it is valid, FALSE if not 00376 */ 00377 { 00378 ULONG i; 00379 00380 /* I don't think this will ever happen, but we warn it if it does */ 00381 if (String->Length == 0) 00382 { 00383 NDIS_DbgPrint(MIN_TRACE, ("Got an empty string; not sure what to do here\n")); 00384 return FALSE; 00385 } 00386 00387 for (i = 0; i < String->Length / sizeof(WCHAR); i++) 00388 { 00389 /* Skip any NULL characters we find */ 00390 if (String->Buffer[i] == UNICODE_NULL) 00391 continue; 00392 00393 /* Make sure the character is valid for a numeric string of this base */ 00394 if (UnicodeToHexByte(String->Buffer[i]) >= Base) 00395 return FALSE; 00396 } 00397 00398 /* It's valid */ 00399 return TRUE; 00400 } 00401 00402 /* 00403 * @implemented 00404 */ 00405 VOID 00406 EXPORT 00407 NdisReadConfiguration( 00408 OUT PNDIS_STATUS Status, 00409 OUT PNDIS_CONFIGURATION_PARAMETER * ParameterValue, 00410 IN NDIS_HANDLE ConfigurationHandle, 00411 IN PNDIS_STRING Keyword, 00412 IN NDIS_PARAMETER_TYPE ParameterType) 00413 /* 00414 * FUNCTION: Read a configuration value from the registry, tracking its resources 00415 * ARGUMENTS: 00416 * Status: points to a place to write status into 00417 * ParameterValue: Pointer to receive a newly-allocated parameter structure 00418 * ConfigurationHandle: handle originally returned by an open function 00419 * Keyword: Value name to read, or one of the following constants: 00420 * Environment - returns NdisEnvironmentWindowsNt 00421 * ProcessorType - returns NdisProcessorX86 until more architectures are added 00422 * NdisVersion - returns NDIS_VERSION 00423 * ParameterType: the type of the value to be queried 00424 * RETURNS: 00425 * - A status in Status 00426 * - A parameter value in ParameterValue 00427 */ 00428 { 00429 KEY_VALUE_PARTIAL_INFORMATION *KeyInformation; 00430 ULONG KeyDataLength; 00431 PMINIPORT_RESOURCE MiniportResource; 00432 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle; 00433 PVOID Buffer; 00434 00435 *ParameterValue = NULL; 00436 *Status = NDIS_STATUS_FAILURE; 00437 00438 NDIS_DbgPrint(MAX_TRACE,("requested read of %wZ\n", Keyword)); 00439 NDIS_DbgPrint(MID_TRACE,("requested parameter type: %d\n", ParameterType)); 00440 00441 if (ConfigurationContext == NULL) 00442 { 00443 NDIS_DbgPrint(MIN_TRACE,("invalid parameter ConfigurationContext (0x%x)\n",ConfigurationContext)); 00444 return; 00445 } 00446 00447 if(!wcsncmp(Keyword->Buffer, L"Environment", Keyword->Length/sizeof(WCHAR)) && 00448 wcslen(L"Environment") == Keyword->Length/sizeof(WCHAR)) 00449 { 00450 *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER)); 00451 if(!*ParameterValue) 00452 { 00453 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00454 *Status = NDIS_STATUS_RESOURCES; 00455 return; 00456 } 00457 00458 MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE)); 00459 if(!MiniportResource) 00460 { 00461 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00462 ExFreePool(*ParameterValue); 00463 *ParameterValue = NULL; 00464 *Status = NDIS_STATUS_RESOURCES; 00465 return; 00466 } 00467 00468 MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA; 00469 MiniportResource->Resource = *ParameterValue; 00470 00471 NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", 00472 MiniportResource->Resource)); 00473 00474 ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, 00475 &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock); 00476 00477 (*ParameterValue)->ParameterType = NdisParameterInteger; 00478 (*ParameterValue)->ParameterData.IntegerData = NdisEnvironmentWindowsNt; 00479 *Status = NDIS_STATUS_SUCCESS; 00480 00481 return; 00482 } 00483 00484 if(!wcsncmp(Keyword->Buffer, L"ProcessorType", Keyword->Length/sizeof(WCHAR)) && 00485 wcslen(L"ProcessorType") == Keyword->Length/sizeof(WCHAR)) 00486 { 00487 *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER)); 00488 if(!*ParameterValue) 00489 { 00490 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00491 *Status = NDIS_STATUS_RESOURCES; 00492 return; 00493 } 00494 00495 MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE)); 00496 if(!MiniportResource) 00497 { 00498 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00499 ExFreePool(*ParameterValue); 00500 *ParameterValue = NULL; 00501 *Status = NDIS_STATUS_RESOURCES; 00502 return; 00503 } 00504 00505 MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA; 00506 MiniportResource->Resource = *ParameterValue; 00507 NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource)); 00508 ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, 00509 &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock); 00510 00511 (*ParameterValue)->ParameterType = NdisParameterInteger; 00512 (*ParameterValue)->ParameterData.IntegerData = NdisProcessorX86; /* XXX non-portable */ 00513 *Status = NDIS_STATUS_SUCCESS; 00514 00515 return; 00516 } 00517 00518 if(!wcsncmp(Keyword->Buffer, L"NdisVersion", Keyword->Length/sizeof(WCHAR)) && 00519 wcslen(L"NdisVersion") == Keyword->Length/sizeof(WCHAR)) 00520 { 00521 *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER)); 00522 if(!*ParameterValue) 00523 { 00524 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00525 *Status = NDIS_STATUS_RESOURCES; 00526 return; 00527 } 00528 00529 MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE)); 00530 if(!MiniportResource) 00531 { 00532 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00533 ExFreePool(*ParameterValue); 00534 *ParameterValue = NULL; 00535 *Status = NDIS_STATUS_RESOURCES; 00536 return; 00537 } 00538 00539 MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA; 00540 MiniportResource->Resource = *ParameterValue; 00541 NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource)); 00542 ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, 00543 &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock); 00544 00545 (*ParameterValue)->ParameterType = NdisParameterInteger; 00546 (*ParameterValue)->ParameterData.IntegerData = NDIS_VERSION; 00547 *Status = NDIS_STATUS_SUCCESS; 00548 00549 NDIS_DbgPrint(MAX_TRACE,("ParameterType = %0x%x, ParameterValue = 0x%x\n", 00550 (*ParameterValue)->ParameterType, (*ParameterValue)->ParameterData.IntegerData)); 00551 return; 00552 } 00553 00554 /* figure out how much buffer i should allocate */ 00555 *Status = ZwQueryValueKey(ConfigurationContext->Handle, Keyword, KeyValuePartialInformation, NULL, 0, &KeyDataLength); 00556 if(*Status != STATUS_BUFFER_OVERFLOW && *Status != STATUS_BUFFER_TOO_SMALL && *Status != STATUS_SUCCESS) 00557 { 00558 NDIS_DbgPrint(MID_TRACE,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword, *Status)); 00559 *Status = NDIS_STATUS_FAILURE; 00560 return; 00561 } 00562 00563 /* allocate it */ 00564 KeyInformation = ExAllocatePool(PagedPool, KeyDataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION)); 00565 if(!KeyInformation) 00566 { 00567 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00568 *Status = NDIS_STATUS_RESOURCES; 00569 return; 00570 } 00571 00572 /* grab the value */ 00573 *Status = ZwQueryValueKey(ConfigurationContext->Handle, Keyword, KeyValuePartialInformation, 00574 KeyInformation, KeyDataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION), &KeyDataLength); 00575 if(*Status != STATUS_SUCCESS) 00576 { 00577 ExFreePool(KeyInformation); 00578 NDIS_DbgPrint(MIN_TRACE,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword, *Status)); 00579 *Status = NDIS_STATUS_FAILURE; 00580 return; 00581 } 00582 00583 MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE)); 00584 if(!MiniportResource) 00585 { 00586 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00587 ExFreePool(KeyInformation); 00588 *Status = NDIS_STATUS_RESOURCES; 00589 return; 00590 } 00591 00592 *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER)); 00593 if (!*ParameterValue) 00594 { 00595 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00596 ExFreePool(MiniportResource); 00597 ExFreePool(KeyInformation); 00598 *Status = NDIS_STATUS_RESOURCES; 00599 return; 00600 } 00601 00602 RtlZeroMemory(*ParameterValue, sizeof(NDIS_CONFIGURATION_PARAMETER)); 00603 00604 if (KeyInformation->Type == REG_BINARY) 00605 { 00606 NDIS_DbgPrint(MAX_TRACE, ("NdisParameterBinary\n")); 00607 00608 (*ParameterValue)->ParameterType = NdisParameterBinary; 00609 00610 Buffer = ExAllocatePool(PagedPool, KeyInformation->DataLength); 00611 if (!Buffer) 00612 { 00613 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00614 ExFreePool(MiniportResource); 00615 ExFreePool(KeyInformation); 00616 *Status = NDIS_STATUS_RESOURCES; 00617 return; 00618 } 00619 00620 RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength); 00621 00622 (*ParameterValue)->ParameterData.BinaryData.Buffer = Buffer; 00623 (*ParameterValue)->ParameterData.BinaryData.Length = KeyInformation->DataLength; 00624 } 00625 else if (KeyInformation->Type == REG_MULTI_SZ) 00626 { 00627 NDIS_DbgPrint(MAX_TRACE, ("NdisParameterMultiString\n")); 00628 00629 (*ParameterValue)->ParameterType = NdisParameterMultiString; 00630 00631 Buffer = ExAllocatePool(PagedPool, KeyInformation->DataLength); 00632 if (!Buffer) 00633 { 00634 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00635 ExFreePool(MiniportResource); 00636 ExFreePool(KeyInformation); 00637 *Status = NDIS_STATUS_RESOURCES; 00638 return; 00639 } 00640 00641 RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength); 00642 00643 (*ParameterValue)->ParameterData.StringData.Buffer = Buffer; 00644 (*ParameterValue)->ParameterData.StringData.Length = KeyInformation->DataLength; 00645 } 00646 else if (KeyInformation->Type == REG_SZ) 00647 { 00648 UNICODE_STRING str; 00649 ULONG Base; 00650 00651 if (ParameterType == NdisParameterInteger) 00652 Base = 10; 00653 else if (ParameterType == NdisParameterHexInteger) 00654 Base = 16; 00655 else 00656 Base = 0; 00657 00658 str.Length = str.MaximumLength = (USHORT)KeyInformation->DataLength; 00659 str.Buffer = (PWCHAR)KeyInformation->Data; 00660 00661 if (Base != 0 && IsValidNumericString(&str, Base) && 00662 ((*Status = RtlUnicodeStringToInteger(&str, Base, 00663 &(*ParameterValue)->ParameterData.IntegerData)) == STATUS_SUCCESS)) 00664 { 00665 NDIS_DbgPrint(MAX_TRACE, ("NdisParameter(Hex)Integer\n")); 00666 00667 (*ParameterValue)->ParameterType = ParameterType; 00668 } 00669 else 00670 { 00671 NDIS_DbgPrint(MAX_TRACE, ("NdisParameterString\n")); 00672 00673 (*ParameterValue)->ParameterType = NdisParameterString; 00674 00675 Buffer = ExAllocatePool(PagedPool, KeyInformation->DataLength); 00676 if (!Buffer) 00677 { 00678 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00679 ExFreePool(MiniportResource); 00680 ExFreePool(KeyInformation); 00681 *Status = NDIS_STATUS_RESOURCES; 00682 return; 00683 } 00684 00685 RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength); 00686 00687 (*ParameterValue)->ParameterData.StringData.Buffer = Buffer; 00688 (*ParameterValue)->ParameterData.StringData.Length = KeyInformation->DataLength; 00689 } 00690 } 00691 else 00692 { 00693 NDIS_DbgPrint(MIN_TRACE, ("Invalid type for NdisReadConfiguration (%d)\n", KeyInformation->Type)); 00694 NDIS_DbgPrint(MIN_TRACE, ("Requested type: %d\n", ParameterType)); 00695 NDIS_DbgPrint(MIN_TRACE, ("Registry entry: %wZ\n", Keyword)); 00696 *Status = NDIS_STATUS_FAILURE; 00697 ExFreePool(KeyInformation); 00698 return; 00699 } 00700 00701 if ((*ParameterValue)->ParameterType != ParameterType) 00702 { 00703 NDIS_DbgPrint(MIN_TRACE, ("Parameter type mismatch! (Requested: %d | Received: %d)\n", 00704 ParameterType, (*ParameterValue)->ParameterType)); 00705 NDIS_DbgPrint(MIN_TRACE, ("Registry entry: %wZ\n", Keyword)); 00706 } 00707 00708 MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA; 00709 MiniportResource->Resource = *ParameterValue; 00710 00711 ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock); 00712 00713 ExFreePool(KeyInformation); 00714 00715 *Status = NDIS_STATUS_SUCCESS; 00716 } 00717 00718 /* 00719 * @implemented 00720 */ 00721 VOID 00722 EXPORT 00723 NdisReadNetworkAddress( 00724 OUT PNDIS_STATUS Status, 00725 OUT PVOID * NetworkAddress, 00726 OUT PUINT NetworkAddressLength, 00727 IN NDIS_HANDLE ConfigurationHandle) 00728 /* 00729 * FUNCTION: Reads the network address from the registry 00730 * ARGUMENTS: 00731 * Status - variable to receive status 00732 * NetworkAddress - pointer to a buffered network address array 00733 * NetworkAddressLength - length of the NetworkAddress array 00734 * ConfigurationHandle: handle passed back from one of the open routines 00735 * RETURNS: 00736 * NDIS_STATUS_SUCCESS on success 00737 * NDIS_STATUS_FAILURE on failure 00738 * The network address is placed in the NetworkAddress buffer 00739 */ 00740 { 00741 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle; 00742 PMINIPORT_RESOURCE MiniportResource = NULL; 00743 PNDIS_CONFIGURATION_PARAMETER ParameterValue = NULL; 00744 NDIS_STRING Keyword; 00745 UINT *IntArray = 0; 00746 UINT i,j = 0; 00747 NDIS_STRING str; 00748 00749 NdisInitUnicodeString(&Keyword, L"NetworkAddress"); 00750 NdisReadConfiguration(Status, &ParameterValue, ConfigurationHandle, &Keyword, NdisParameterString); 00751 if(*Status != NDIS_STATUS_SUCCESS) 00752 { 00753 NDIS_DbgPrint(MID_TRACE, ("NdisReadConfiguration failed (%x)\n", *Status)); 00754 *Status = NDIS_STATUS_FAILURE; 00755 return; 00756 } 00757 00758 if (ParameterValue->ParameterType == NdisParameterInteger) 00759 { 00760 WCHAR Buff[11]; 00761 00762 NDIS_DbgPrint(MAX_TRACE, ("Read integer data %lx\n", 00763 ParameterValue->ParameterData.IntegerData)); 00764 00765 str.Buffer = Buff; 00766 str.MaximumLength = (USHORT)sizeof(Buff); 00767 str.Length = 0; 00768 00769 *Status = RtlIntegerToUnicodeString(ParameterValue->ParameterData.IntegerData, 00770 10, 00771 &str); 00772 00773 if (*Status != NDIS_STATUS_SUCCESS) 00774 { 00775 NDIS_DbgPrint(MIN_TRACE, ("RtlIntegerToUnicodeString failed (%x)\n", *Status)); 00776 *Status = NDIS_STATUS_FAILURE; 00777 return; 00778 } 00779 00780 NDIS_DbgPrint(MAX_TRACE, ("Converted integer data into %wZ\n", &str)); 00781 } 00782 else 00783 { 00784 ASSERT(ParameterValue->ParameterType == NdisParameterString); 00785 str = ParameterValue->ParameterData.StringData; 00786 } 00787 00788 while (j < str.Length && str.Buffer[j] != '\0') j++; 00789 00790 *NetworkAddressLength = (j+1) >> 1; 00791 00792 if ((*NetworkAddressLength) == 0) 00793 { 00794 NDIS_DbgPrint(MIN_TRACE,("Empty NetworkAddress registry entry.\n")); 00795 *Status = NDIS_STATUS_FAILURE; 00796 return; 00797 } 00798 00799 IntArray = ExAllocatePool(PagedPool, (*NetworkAddressLength)*sizeof(UINT)); 00800 if(!IntArray) 00801 { 00802 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00803 *Status = NDIS_STATUS_RESOURCES; 00804 return; 00805 } 00806 00807 MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE)); 00808 if(!MiniportResource) 00809 { 00810 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00811 ExFreePool(IntArray); 00812 *Status = NDIS_STATUS_RESOURCES; 00813 return; 00814 } 00815 00816 MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_MEMORY; 00817 MiniportResource->Resource = IntArray; 00818 NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource)); 00819 ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock); 00820 00821 /* convert from string to bytes */ 00822 for(i=0; i<(*NetworkAddressLength); i++) 00823 { 00824 IntArray[i] = (UnicodeToHexByte((str.Buffer)[2*i]) << 4) + 00825 UnicodeToHexByte((str.Buffer)[2*i+1]); 00826 } 00827 00828 *NetworkAddress = IntArray; 00829 00830 *Status = NDIS_STATUS_SUCCESS; 00831 } 00832 00833 00834 /* 00835 * @implemented 00836 */ 00837 VOID 00838 EXPORT 00839 NdisOpenConfigurationKeyByIndex( 00840 OUT PNDIS_STATUS Status, 00841 IN NDIS_HANDLE ConfigurationHandle, 00842 IN ULONG Index, 00843 OUT PNDIS_STRING KeyName, 00844 OUT PNDIS_HANDLE KeyHandle) 00845 /* 00846 * FUNCTION: Opens a configuration subkey by index number 00847 * ARGUMENTS: 00848 * Status: pointer to an NDIS_STATUS to receive status info 00849 * ConfigurationHandle: the handle passed back from a previous open function 00850 * Index: the zero-based index of the subkey to open 00851 * KeyName: the name of the key that was opened 00852 * KeyHandle: a handle to the key that was opened 00853 * RETURNS: 00854 * NDIS_STATUS_SUCCESS on success 00855 * NDIS_STATUS_FAILURE on failure 00856 * KeyName holds the name of the opened key 00857 * KeyHandle holds a handle to the new key 00858 */ 00859 { 00860 KEY_BASIC_INFORMATION *KeyInformation; 00861 ULONG KeyInformationLength; 00862 OBJECT_ATTRIBUTES KeyAttributes; 00863 NDIS_HANDLE RegKeyHandle; 00864 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext; 00865 00866 *KeyHandle = NULL; 00867 00868 *Status = ZwEnumerateKey(ConfigurationHandle, Index, KeyBasicInformation, NULL, 0, &KeyInformationLength); 00869 if(*Status != STATUS_BUFFER_TOO_SMALL && *Status != STATUS_BUFFER_OVERFLOW && *Status != STATUS_SUCCESS) 00870 { 00871 NDIS_DbgPrint(MIN_TRACE, ("ZwEnumerateKey failed (%x)\n", *Status)); 00872 *Status = NDIS_STATUS_FAILURE; 00873 return; 00874 } 00875 00876 KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength + sizeof(KEY_BASIC_INFORMATION)); 00877 if(!KeyInformation) 00878 { 00879 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00880 *Status = NDIS_STATUS_FAILURE; 00881 return; 00882 } 00883 00884 *Status = ZwEnumerateKey(ConfigurationHandle, Index, KeyBasicInformation, KeyInformation, 00885 KeyInformationLength + sizeof(KEY_BASIC_INFORMATION), &KeyInformationLength); 00886 00887 if(*Status != STATUS_SUCCESS) 00888 { 00889 NDIS_DbgPrint(MIN_TRACE, ("ZwEnumerateKey failed (%x)\n", *Status)); 00890 ExFreePool(KeyInformation); 00891 *Status = NDIS_STATUS_FAILURE; 00892 return; 00893 } 00894 00895 /* should i fail instead if the passed-in string isn't long enough? */ 00896 wcsncpy(KeyName->Buffer, KeyInformation->Name, KeyName->MaximumLength/sizeof(WCHAR)); 00897 KeyName->Length = (USHORT)min(KeyInformation->NameLength, KeyName->MaximumLength); 00898 00899 InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE, ConfigurationHandle, NULL); 00900 00901 *Status = ZwOpenKey(&RegKeyHandle, KEY_ALL_ACCESS, &KeyAttributes); 00902 00903 ExFreePool(KeyInformation); 00904 00905 if(*Status != STATUS_SUCCESS) 00906 { 00907 NDIS_DbgPrint(MIN_TRACE, ("ZwOpenKey failed (%x)\n", *Status)); 00908 *Status = NDIS_STATUS_FAILURE; 00909 return; 00910 } 00911 00912 ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT)); 00913 if(!ConfigurationContext) 00914 { 00915 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00916 ZwClose(RegKeyHandle); 00917 *Status = NDIS_STATUS_FAILURE; 00918 return; 00919 } 00920 00921 KeInitializeSpinLock(&ConfigurationContext->ResourceLock); 00922 InitializeListHead(&ConfigurationContext->ResourceListHead); 00923 00924 ConfigurationContext->Handle = RegKeyHandle; 00925 00926 *KeyHandle = (NDIS_HANDLE)ConfigurationContext; 00927 00928 *Status = NDIS_STATUS_SUCCESS; 00929 } 00930 00931 00932 /* 00933 * @implemented 00934 */ 00935 VOID 00936 EXPORT 00937 NdisOpenConfigurationKeyByName( 00938 OUT PNDIS_STATUS Status, 00939 IN NDIS_HANDLE ConfigurationHandle, 00940 IN PNDIS_STRING KeyName, 00941 OUT PNDIS_HANDLE KeyHandle) 00942 /* 00943 * FUNCTION: Opens a configuration subkey by name 00944 * ARGUMENTS: 00945 * Status: points to an NDIS_STATUS where status is returned 00946 * ConfigurationHandle: handle returned by a previous open call 00947 * KeyName: the name of the key to open 00948 * KeyHandle: a handle to the opened key 00949 * RETURNS: 00950 * NDIS_STATUS_SUCCESS on success 00951 * NDIS_STATUS_FAILURE on failure 00952 * KeyHandle holds a handle to the newly-opened key 00953 * NOTES: 00954 */ 00955 { 00956 PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext; 00957 OBJECT_ATTRIBUTES KeyAttributes; 00958 NDIS_HANDLE RegKeyHandle; 00959 00960 *KeyHandle = NULL; 00961 00962 InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE, ConfigurationHandle, 0); 00963 *Status = ZwOpenKey(&RegKeyHandle, KEY_ALL_ACCESS, &KeyAttributes); 00964 00965 if(*Status != STATUS_SUCCESS) 00966 { 00967 NDIS_DbgPrint(MIN_TRACE, ("ZwOpenKey failed (%x)\n", *Status)); 00968 *Status = NDIS_STATUS_FAILURE; 00969 return; 00970 } 00971 00972 ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT)); 00973 if(!ConfigurationContext) 00974 { 00975 NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n")); 00976 ZwClose(RegKeyHandle); 00977 *Status = NDIS_STATUS_FAILURE; 00978 return; 00979 } 00980 00981 KeInitializeSpinLock(&ConfigurationContext->ResourceLock); 00982 InitializeListHead(&ConfigurationContext->ResourceListHead); 00983 00984 ConfigurationContext->Handle = RegKeyHandle; 00985 00986 *KeyHandle = (NDIS_HANDLE)ConfigurationContext; 00987 00988 *Status = NDIS_STATUS_SUCCESS; 00989 } Generated on Fri May 25 2012 04:16:57 for ReactOS by
1.7.6.1
|