Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

query.c File Reference

#include "iop.h"

Go to the source code of this file.

Classes

struct  _IO_QUERY_DESC

Defines

#define UNICODE_NUM_LENGTH   14
#define UNICODE_REGISTRY_PATH_LENGTH   1024

Typedefs

typedef _IO_QUERY_DESC IO_QUERY_DESC
typedef _IO_QUERY_DESCPIO_QUERY_DESC

Functions

NTSTATUS pIoQueryBusDescription (PIO_QUERY_DESC QueryDescription, UNICODE_STRING PathName, HANDLE RootHandle, PULONG BusNum, BOOLEAN HighKey)
NTSTATUS pIoQueryDeviceDescription (PIO_QUERY_DESC QueryDescription, UNICODE_STRING PathName, HANDLE RootHandle, ULONG BusNum, PKEY_VALUE_FULL_INFORMATION *BusValueInfo)
NTSTATUS IoQueryDeviceDescription (IN PINTERFACE_TYPE BusType OPTIONAL, IN PULONG BusNumber OPTIONAL, IN PCONFIGURATION_TYPE ControllerType OPTIONAL, IN PULONG ControllerNumber OPTIONAL, IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, IN PULONG PeripheralNumber OPTIONAL, IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, IN PVOID Context)


Define Documentation

#define UNICODE_NUM_LENGTH   14
 

Referenced by pIoQueryDeviceDescription().

#define UNICODE_REGISTRY_PATH_LENGTH   1024
 

Referenced by IoQueryDeviceDescription().


Typedef Documentation

typedef struct _IO_QUERY_DESC IO_QUERY_DESC
 

typedef struct _IO_QUERY_DESC * PIO_QUERY_DESC
 


Function Documentation

NTSTATUS IoQueryDeviceDescription IN PINTERFACE_TYPE BusType  OPTIONAL,
IN PULONG BusNumber  OPTIONAL,
IN PCONFIGURATION_TYPE ControllerType  OPTIONAL,
IN PULONG ControllerNumber  OPTIONAL,
IN PCONFIGURATION_TYPE PeripheralType  OPTIONAL,
IN PULONG PeripheralNumber  OPTIONAL,
IN PIO_QUERY_DEVICE_ROUTINE  CalloutRoutine,
IN PVOID  Context
 

Definition at line 70 of file io/query.c.

References ASSERT, BusNumber, _IO_QUERY_DESC::BusNumber, _IO_QUERY_DESC::BusType, _IO_QUERY_DESC::CalloutRoutine, CmRegistryMachineHardwareDescriptionSystemName, _IO_QUERY_DESC::Context, _IO_QUERY_DESC::ControllerNumber, ControllerType, _IO_QUERY_DESC::ControllerType, ExAllocatePoolWithTag, ExFreePool(), FALSE, IopOpenRegistryKey(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _IO_QUERY_DESC::PeripheralNumber, PeripheralType, _IO_QUERY_DESC::PeripheralType, pIoQueryBusDescription(), RtlAppendUnicodeStringToString(), TRUE, and UNICODE_REGISTRY_PATH_LENGTH.

Referenced by FsVgaConfiguration(), MapperCallback(), and MapperProcessFirmwareTree().

00083 : 00084 00085 00086 Arguments: 00087 00088 BusType - Supplies an optional bus type being searched for in the 00089 description tree. Valid types are Mca, Isa, Eisa ... If no bus type 00090 is specified, the system information (i.e. machine BIOS) is returned. 00091 00092 BusNumber - Supplies an optional value determining which bus should be 00093 queried. 00094 00095 ControllerType - Supplies an optional controller type being searched for. 00096 If no Controller type is specified, only the Bus information is 00097 returned. 00098 00099 ControllerNumber - Supplies an optional value determining which 00100 controller should be queried. 00101 00102 PeripheralType - Supplies an optional peripheral type being searched for. 00103 If no Controller type is specified, only the Bus information and the 00104 controller information are returned. 00105 00106 PeripheralNumber - Supplies an optional value determining which 00107 peripheral should be queried. 00108 00109 CalloutRoutine - Supplies a pointer to a routine that gets called 00110 for each successful match of PeripheralType. 00111 00112 Context - Supplies a context value that is passed back to the callback 00113 routine. 00114 00115 Return Value: 00116 00117 The status returned is the final completion status of the operation. 00118 00119 Notes: 00120 00121 --*/ 00122 00123 { 00124 00125 #define UNICODE_NUM_LENGTH 14 00126 #define UNICODE_REGISTRY_PATH_LENGTH 1024 00127 00128 IO_QUERY_DESC queryDesc; 00129 00130 NTSTATUS status; 00131 UNICODE_STRING registryPathName; 00132 HANDLE rootHandle; 00133 ULONG busNumber = (ULONG) -1; 00134 00135 00136 PAGED_CODE(); 00137 00138 ASSERT( CalloutRoutine != NULL ); 00139 00140 // 00141 // Check if we need to return the machine information 00142 // 00143 00144 if (!ARGUMENT_PRESENT( BusType )) { 00145 return STATUS_NOT_IMPLEMENTED; 00146 } 00147 00148 queryDesc.BusType = BusType; 00149 queryDesc.BusNumber = BusNumber; 00150 queryDesc.ControllerType = ControllerType; 00151 queryDesc.ControllerNumber = ControllerNumber; 00152 queryDesc.PeripheralType = PeripheralType; 00153 queryDesc.PeripheralNumber = PeripheralNumber; 00154 queryDesc.CalloutRoutine = CalloutRoutine; 00155 queryDesc.Context = Context; 00156 00157 00158 // 00159 // Set up a string with the pathname to the hardware description 00160 // portion of the registry. 00161 // 00162 00163 registryPathName.Length = 0; 00164 registryPathName.MaximumLength = UNICODE_REGISTRY_PATH_LENGTH * 00165 sizeof(WCHAR); 00166 00167 registryPathName.Buffer = ExAllocatePoolWithTag( PagedPool, 00168 UNICODE_REGISTRY_PATH_LENGTH, 00169 'mNoI' ); 00170 00171 if (!registryPathName.Buffer) { 00172 00173 return STATUS_INSUFFICIENT_RESOURCES; 00174 00175 } 00176 00177 RtlAppendUnicodeStringToString( &registryPathName, 00178 &CmRegistryMachineHardwareDescriptionSystemName ); 00179 00180 00181 // 00182 // Open a handle to the root path we have. 00183 // 00184 00185 status = IopOpenRegistryKey( &rootHandle, 00186 (HANDLE) NULL, 00187 &registryPathName, 00188 KEY_READ, 00189 FALSE ); 00190 00191 if (NT_SUCCESS( status )) { 00192 00193 status = pIoQueryBusDescription(&queryDesc, 00194 registryPathName, 00195 rootHandle, 00196 &busNumber, 00197 TRUE ); 00198 00199 ZwClose( rootHandle ); 00200 00201 } 00202 00203 ExFreePool( registryPathName.Buffer ); 00204 00205 // 00206 // For compatibility with old version of the function. 00207 // 00208 00209 if (status == STATUS_NO_MORE_ENTRIES) { 00210 00211 return STATUS_OBJECT_NAME_NOT_FOUND; 00212 00213 00214 } else { 00215 00216 return status; 00217 00218 } 00219 }

NTSTATUS pIoQueryBusDescription PIO_QUERY_DESC  QueryDescription,
UNICODE_STRING  PathName,
HANDLE  RootHandle,
PULONG  BusNum,
BOOLEAN  HighKey
 

Definition at line 223 of file io/query.c.

References _IO_QUERY_DESC::BusNumber, _IO_QUERY_DESC::BusType, _IO_QUERY_DESC::CalloutRoutine, CmTypeString, _IO_QUERY_DESC::Context, _IO_QUERY_DESC::ControllerType, EisaAdapter, ExAllocatePoolWithTag, ExFreePool(), FALSE, IopGetRegistryKeyInformation(), IopGetRegistryValues(), IopOpenRegistryKey(), IoQueryDeviceConfigurationData, IoQueryDeviceMaxData, L, MultiFunctionAdapter, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, pIoQueryDeviceDescription(), RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), TcAdapter, and USHORT.

Referenced by IoQueryDeviceDescription().

00233 : 00234 00235 00236 Arguments: 00237 00238 QueryDescription - Buffer containing all the query information requested 00239 by the driver. 00240 00241 PathName - Registry path name of the key we are dealing with. This is 00242 a unicode strig so that we don't have to bother with resetting NULLs 00243 at the end of the string - the length determines how much of the 00244 string is valid. 00245 00246 RootHandle - Handle equivalent to the registry path. 00247 00248 BusNum - Pointer to a variable that keeps track of the bus number we are 00249 searching for (buses have to be accumulated. 00250 00251 HighKey - Determines is this is a high key (a root key with a list of 00252 bus types) or a low level key (under which the number of the various 00253 buses will be little). 00254 00255 Return Value: 00256 00257 The status returned is the final completion status of the operation. 00258 00259 Notes: 00260 00261 --*/ 00262 00263 { 00264 NTSTATUS status; 00265 ULONG i; 00266 UNICODE_STRING unicodeString; 00267 00268 UNICODE_STRING registryPathName; 00269 00270 ULONG keyBasicInformationSize; 00271 PKEY_BASIC_INFORMATION keyBasicInformation = NULL; 00272 HANDLE handle; 00273 00274 PKEY_FULL_INFORMATION keyInformation; 00275 ULONG size; 00276 00277 PKEY_VALUE_FULL_INFORMATION busValueInfo[IoQueryDeviceMaxData]; 00278 00279 00280 PAGED_CODE(); 00281 00282 status = IopGetRegistryKeyInformation( RootHandle, 00283 &keyInformation ); 00284 00285 if (NT_SUCCESS( status )) { 00286 00287 // 00288 // With the keyInformation, allocate a buffer that will be large 00289 // enough for all the subkeys 00290 // 00291 00292 keyBasicInformationSize = keyInformation->MaxNameLen + 00293 sizeof(KEY_NODE_INFORMATION); 00294 00295 keyBasicInformation = ExAllocatePoolWithTag( PagedPool, 00296 keyBasicInformationSize, 00297 'mNoI' ); 00298 00299 ExFreePool(keyInformation); 00300 00301 if (keyBasicInformation == NULL) { 00302 00303 return STATUS_INSUFFICIENT_RESOURCES; 00304 00305 } 00306 } 00307 00308 // 00309 // Now we need to enumerate the keys and see if one of them is a bus 00310 // 00311 00312 for (i = 0; NT_SUCCESS( status ); i++) { 00313 00314 00315 // 00316 // If we have found the Bus we are looking for, break 00317 // 00318 00319 if ((ARGUMENT_PRESENT( QueryDescription->BusNumber )) && 00320 (*(QueryDescription->BusNumber) == *BusNum)) { 00321 00322 break; 00323 00324 } 00325 00326 status = ZwEnumerateKey( RootHandle, 00327 i, 00328 KeyBasicInformation, 00329 keyBasicInformation, 00330 keyBasicInformationSize, 00331 &size ); 00332 00333 // 00334 // If the sub function enumerated all the buses till the end, then 00335 // treat that as success. 00336 // 00337 00338 if (!NT_SUCCESS( status )) { 00339 00340 break; 00341 00342 } 00343 00344 // 00345 // Only if this is a high key (otherwise we are in the callback 00346 // pass which we will process later on). 00347 // 00348 // If the string is any valid bus string, then we have to go down 00349 // the tree recursively. 00350 // Otherwise, go on to the next key. 00351 // 00352 00353 if (HighKey) { 00354 00355 if (wcsncmp( keyBasicInformation->Name, 00356 CmTypeString[MultiFunctionAdapter], 00357 keyBasicInformation->NameLength / sizeof(WCHAR) ) && 00358 wcsncmp( keyBasicInformation->Name, 00359 CmTypeString[EisaAdapter], 00360 keyBasicInformation->NameLength / sizeof(WCHAR) ) && 00361 wcsncmp( keyBasicInformation->Name, 00362 CmTypeString[TcAdapter], 00363 keyBasicInformation->NameLength / sizeof(WCHAR) )) { 00364 00365 // 00366 // All the comparisons returned 1 (which means they all were 00367 // unsuccessful) so we do not have a bus. 00368 // 00369 // Go on to the next key. 00370 // 00371 00372 continue; 00373 } 00374 } 00375 00376 // 00377 // We have a bus. Open that key and enumerate it's clidren 00378 // (which should be numbers) 00379 // 00380 00381 unicodeString.Buffer = keyBasicInformation->Name; 00382 unicodeString.Length = (USHORT) keyBasicInformation->NameLength; 00383 unicodeString.MaximumLength = (USHORT) keyBasicInformation->NameLength; 00384 00385 if (!NT_SUCCESS( IopOpenRegistryKey( &handle, 00386 RootHandle, 00387 &unicodeString, 00388 KEY_READ, 00389 FALSE ) )) { 00390 00391 // 00392 // The key could not be opened. Go to the next key 00393 // 00394 00395 continue; 00396 00397 } 00398 00399 // 00400 // We have the key. now build the name for this path. 00401 // 00402 // Reset the string to its original value 00403 // 00404 00405 registryPathName = PathName; 00406 00407 RtlAppendUnicodeToString( &registryPathName, 00408 L"\\" ); 00409 00410 RtlAppendUnicodeStringToString( &registryPathName, 00411 &unicodeString ); 00412 00413 00414 if (!HighKey) { 00415 00416 // 00417 // We have a Key. Get the information for that key 00418 // 00419 00420 status = IopGetRegistryValues( handle, 00421 &busValueInfo[0] ); 00422 00423 if (NT_SUCCESS( status )) { 00424 00425 // 00426 // Verify that the identifier value for this bus 00427 // sub-key matches the user-specified bus type. 00428 // If not, do not increment the number of *found* 00429 // buses. 00430 // 00431 00432 if (( busValueInfo[IoQueryDeviceConfigurationData] != NULL ) && 00433 ( busValueInfo[IoQueryDeviceConfigurationData]->DataLength != 0 ) && 00434 ( ((PCM_FULL_RESOURCE_DESCRIPTOR) 00435 ((PCCHAR) busValueInfo[IoQueryDeviceConfigurationData] + 00436 busValueInfo[IoQueryDeviceConfigurationData]->DataOffset)) 00437 ->InterfaceType == *(QueryDescription->BusType) )) { 00438 00439 // 00440 // Increment the number of buses of desired type we 00441 // have found. 00442 // 00443 00444 (*BusNum)++; 00445 00446 // 00447 // If we are looking for a specific bus number, 00448 // check to see if we are at the right number. 00449 // If we are not goto the next bus. Otherwise 00450 // (i.e we have the right bus number, or we 00451 // specified all buses), then go on so the 00452 // information can be reported. 00453 // 00454 00455 if ( (QueryDescription->BusNumber == NULL) || 00456 (*(QueryDescription->BusNumber) == *BusNum) ) { 00457 00458 00459 // 00460 // If we want controller information, call 00461 // the controller function. 00462 // Otherwise just return the bus information. 00463 // 00464 00465 if (QueryDescription->ControllerType != NULL) { 00466 00467 status = pIoQueryDeviceDescription( 00468 QueryDescription, 00469 registryPathName, 00470 handle, 00471 *BusNum, 00472 (PKEY_VALUE_FULL_INFORMATION *) busValueInfo ); 00473 00474 } else { 00475 00476 status = QueryDescription->CalloutRoutine( 00477 QueryDescription->Context, 00478 &registryPathName, 00479 *(QueryDescription->BusType), 00480 *BusNum, 00481 (PKEY_VALUE_FULL_INFORMATION *) busValueInfo, 00482 0, 00483 0, 00484 NULL, 00485 0, 00486 0, 00487 NULL ); 00488 00489 } 00490 } 00491 } 00492 00493 // 00494 // Free the pool allocated for the controller value data. 00495 // 00496 00497 if (busValueInfo[0]) { 00498 ExFreePool( busValueInfo[0] ); 00499 busValueInfo[0] = NULL; 00500 } 00501 if (busValueInfo[1]) { 00502 ExFreePool( busValueInfo[1] ); 00503 busValueInfo[1] = NULL; 00504 } 00505 if (busValueInfo[2]) { 00506 ExFreePool( busValueInfo[2] ); 00507 busValueInfo[2] = NULL; 00508 } 00509 00510 } 00511 00512 00513 // 00514 // Shortcurt exit to avoid the recursive call. 00515 // 00516 00517 if ((QueryDescription->BusNumber !=NULL ) && 00518 (*(QueryDescription->BusNumber) == *BusNum)) { 00519 ZwClose( handle ); 00520 handle = NULL; 00521 continue; 00522 00523 } 00524 } 00525 00526 // 00527 // If we have the key handle, do recursive enumeration. 00528 // enumaration (for both high and low keys) 00529 // 00530 00531 status = pIoQueryBusDescription( 00532 QueryDescription, 00533 registryPathName, 00534 handle, 00535 BusNum, 00536 (BOOLEAN)!HighKey ); 00537 00538 // 00539 // If the sub function enumerated all the buses till the end, then 00540 // treat that as success. 00541 // 00542 00543 if (status == STATUS_NO_MORE_ENTRIES) { 00544 00545 status = STATUS_SUCCESS; 00546 00547 } 00548 00549 ZwClose( handle ); 00550 handle = NULL; 00551 00552 } 00553 00554 if (keyBasicInformation) { 00555 ExFreePool( keyBasicInformation ); 00556 } 00557 00558 return status; 00559 }

NTSTATUS pIoQueryDeviceDescription PIO_QUERY_DESC  QueryDescription,
UNICODE_STRING  PathName,
HANDLE  RootHandle,
ULONG  BusNum,
PKEY_VALUE_FULL_INFORMATION *  BusValueInfo
 

Definition at line 565 of file io/query.c.

References _IO_QUERY_DESC::BusType, _IO_QUERY_DESC::CalloutRoutine, CmTypeString, _IO_QUERY_DESC::Context, _IO_QUERY_DESC::ControllerNumber, _IO_QUERY_DESC::ControllerType, ExFreePool(), FALSE, IopGetRegistryKeyInformation(), IopGetRegistryValues(), IopOpenRegistryKey(), IoQueryDeviceMaxData, L, NT_SUCCESS, NTSTATUS(), NULL, _IO_QUERY_DESC::PeripheralNumber, _IO_QUERY_DESC::PeripheralType, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlIntegerToUnicodeString(), and UNICODE_NUM_LENGTH.

Referenced by pIoQueryBusDescription().

00573 { 00574 00575 NTSTATUS status; 00576 UNICODE_STRING registryPathName = PathName; 00577 UNICODE_STRING controllerBackupRegistryPathName; 00578 UNICODE_STRING peripheralBackupRegistryPathName; 00579 HANDLE controllerHandle = NULL; 00580 HANDLE peripheralHandle = NULL; 00581 PKEY_FULL_INFORMATION controllerTypeInfo = NULL; 00582 PKEY_FULL_INFORMATION peripheralTypeInfo = NULL; 00583 ULONG maxControllerNum; 00584 ULONG maxPeripheralNum; 00585 ULONG controllerNum; 00586 ULONG peripheralNum; 00587 WCHAR numBuffer[UNICODE_NUM_LENGTH]; 00588 UNICODE_STRING bufferUnicodeString; 00589 PKEY_VALUE_FULL_INFORMATION controllerValueInfo[IoQueryDeviceMaxData]; 00590 PKEY_VALUE_FULL_INFORMATION peripheralValueInfo[IoQueryDeviceMaxData]; 00591 00592 00593 // 00594 // Set up a string for the number translation. 00595 // 00596 00597 bufferUnicodeString.MaximumLength = UNICODE_NUM_LENGTH * sizeof(WCHAR); 00598 bufferUnicodeString.Buffer = &numBuffer[0]; 00599 00600 00601 // For each controller of the specified type (subkeys 0..M) 00602 // if we are looking for controller information 00603 // call the specified callout routine 00604 // else 00605 // For each peripheral of the specified type (subkeys 0..N) 00606 // call the specified callout routine 00607 00608 // 00609 // Add the controller name to the registry path name. 00610 // 00611 00612 status = RtlAppendUnicodeToString( &registryPathName, 00613 L"\\" ); 00614 00615 if (NT_SUCCESS( status )) { 00616 00617 status = RtlAppendUnicodeToString( &registryPathName, 00618 CmTypeString[*(QueryDescription->ControllerType)] ); 00619 00620 } 00621 00622 if (!NT_SUCCESS( status )) { 00623 return status; 00624 } 00625 00626 // 00627 // If a Contoller number was specified by the caller, use that 00628 // controller number. Otherwise, find out how many buses are present 00629 // by querying the key. 00630 // 00631 00632 if (ARGUMENT_PRESENT( QueryDescription->ControllerNumber )) { 00633 00634 controllerNum = *(QueryDescription->ControllerNumber); 00635 maxControllerNum = controllerNum + 1; 00636 00637 } else { 00638 00639 // 00640 // Open the registry key for the controller and 00641 // Get the full key information for the controller key to 00642 // determine the number of sub-keys (controller numbers). 00643 // And we fail, then go on to the next bus. 00644 // Note the memory allocated by the query must be freed. 00645 // 00646 00647 status = IopOpenRegistryKey( &controllerHandle, 00648 (HANDLE) NULL, 00649 &registryPathName, 00650 KEY_READ, 00651 FALSE ); 00652 00653 if (NT_SUCCESS( status )) { 00654 00655 status = IopGetRegistryKeyInformation( controllerHandle, 00656 &controllerTypeInfo ); 00657 00658 ZwClose( controllerHandle ); 00659 controllerHandle = NULL; 00660 } 00661 00662 // 00663 // If no controller of this type was found on the bus, go on to 00664 // the next bus; goto the end of the loop with a successful status 00665 // so that the memory gets freed, but we continue looping. 00666 // 00667 00668 if (!NT_SUCCESS( status )) { 00669 00670 return status; 00671 00672 } 00673 00674 // 00675 // Get the number of controller sub-keys for this controller 00676 // type and free the pool. 00677 // 00678 00679 maxControllerNum = controllerTypeInfo->SubKeys; 00680 controllerNum = 0; 00681 00682 ExFreePool( controllerTypeInfo ); 00683 controllerTypeInfo = NULL; 00684 } 00685 00686 // 00687 // Make a backup of the string since we want to start where we were 00688 // on the next loop iteration. 00689 // 00690 00691 controllerBackupRegistryPathName = registryPathName; 00692 00693 // 00694 // For each controller of the specified type (subkeys 0..M). 00695 // We use BusNumber as the initial value since it is zero if we want 00696 // all buses, and we only want the bus specified if the value is not 00697 // zero. 00698 // 00699 00700 for ( ; controllerNum < maxControllerNum; controllerNum++) { 00701 00702 // 00703 // Reset the string to its original value 00704 // 00705 00706 registryPathName = controllerBackupRegistryPathName; 00707 00708 // 00709 // Convert the controller number to a unicode string and append 00710 // it to the registry path name. 00711 // 00712 00713 bufferUnicodeString.Length = (UNICODE_NUM_LENGTH-1) * sizeof(WCHAR); 00714 status = RtlIntegerToUnicodeString( controllerNum, 00715 10, 00716 &bufferUnicodeString ); 00717 00718 if (NT_SUCCESS( status )) { 00719 00720 status = RtlAppendUnicodeToString( &registryPathName, 00721 L"\\" ); 00722 00723 if (NT_SUCCESS( status )) { 00724 00725 status = RtlAppendUnicodeStringToString( 00726 &registryPathName, 00727 &bufferUnicodeString ); 00728 00729 } 00730 } 00731 00732 if (!NT_SUCCESS( status )) { 00733 break; 00734 } 00735 00736 // 00737 // Open the registry key for the controller number and 00738 // Get the value data for this controller and save it for later. 00739 // 00740 00741 00742 status = IopOpenRegistryKey( &controllerHandle, 00743 (HANDLE) NULL, 00744 &registryPathName, 00745 KEY_READ, 00746 FALSE ); 00747 00748 if (NT_SUCCESS( status )) { 00749 00750 status = IopGetRegistryValues( controllerHandle, 00751 &controllerValueInfo[0] ); 00752 00753 ZwClose( controllerHandle ); 00754 controllerHandle = NULL; 00755 } 00756 00757 // 00758 // If we could not open the key and get the info, just continue 00759 // since there is no memory to free and we are using the for 00760 // loop to determine when we get to the last controller. 00761 // 00762 00763 if (!NT_SUCCESS( status )) { 00764 continue; 00765 } 00766 00767 // 00768 // Check if we want the controller and bus information only. If 00769 // it is the case, invoque the callout routine and go on to the 00770 // next loop (unless an error occurs in the callout). 00771 // 00772 00773 if (!ARGUMENT_PRESENT( (QueryDescription->PeripheralType) )) { 00774 00775 status = QueryDescription->CalloutRoutine( 00776 QueryDescription->Context, 00777 &registryPathName, 00778 *(QueryDescription->BusType), 00779 BusNum, 00780 BusValueInfo, 00781 *(QueryDescription->ControllerType), 00782 controllerNum, 00783 (PKEY_VALUE_FULL_INFORMATION *) controllerValueInfo, 00784 0, 00785 0, 00786 NULL ); 00787 00788 goto IoQueryDeviceControllerLoop; 00789 } 00790 00791 // 00792 // Add the peripheral name to the registry path name. 00793 // 00794 00795 status = RtlAppendUnicodeToString( &registryPathName, 00796 L"\\" ); 00797 00798 if (NT_SUCCESS( status )) { 00799 00800 status = RtlAppendUnicodeToString( 00801 &registryPathName, 00802 CmTypeString[*(QueryDescription->PeripheralType)] ); 00803 00804 } 00805 00806 if (!NT_SUCCESS( status )) { 00807 goto IoQueryDeviceControllerLoop; 00808 } 00809 00810 // 00811 // If a Peripheralnumber was specified by the caller, use that 00812 // peripheral number. Otherwise, find out how many buses are 00813 // present by querying the key. 00814 // 00815 00816 if (ARGUMENT_PRESENT( (QueryDescription->PeripheralNumber) )) { 00817 00818 peripheralNum = *(QueryDescription->PeripheralNumber); 00819 maxPeripheralNum = peripheralNum + 1; 00820 00821 } else { 00822 00823 // 00824 // Open the registry key for the peripheral and 00825 // Get the full key information for the peripheral key to 00826 // determine the number of sub-keys (peripheral numbers). 00827 // And we fail, then go on to the next controller. 00828 // Note the memory allocated by the query must be freed. 00829 // 00830 00831 status = IopOpenRegistryKey( &peripheralHandle, 00832 (HANDLE) NULL, 00833 &registryPathName, 00834 KEY_READ, 00835 FALSE ); 00836 00837 if (NT_SUCCESS( status )) { 00838 00839 status = IopGetRegistryKeyInformation( peripheralHandle, 00840 &peripheralTypeInfo ); 00841 00842 ZwClose( peripheralHandle ); 00843 peripheralHandle = NULL; 00844 } 00845 00846 // 00847 // If no controller of this type was found on the bus, go on to 00848 // the next bus; goto the end of the loop with a successful 00849 // status so that the memory gets freed, but we continue looping. 00850 // 00851 00852 if (!NT_SUCCESS( status )) { 00853 status = STATUS_SUCCESS; 00854 goto IoQueryDeviceControllerLoop; 00855 } 00856 00857 // 00858 // Get the number of peripheral sub-keys for this peripheral 00859 // type and free the pool. 00860 // 00861 00862 maxPeripheralNum = peripheralTypeInfo->SubKeys; 00863 peripheralNum = 0; 00864 00865 ExFreePool( peripheralTypeInfo ); 00866 peripheralTypeInfo = NULL; 00867 } 00868 00869 // 00870 // Make a backup of the string since we want to start where we 00871 // were on the next loop iteration. 00872 // 00873 00874 peripheralBackupRegistryPathName = registryPathName; 00875 00876 // 00877 // For each peripheral of the specified type (subkeys 0..N). 00878 // We use BusNumber as the initial value since it is zero if we 00879 // want all buses, and we only want the bus specified if the 00880 // value is not zero. 00881 // 00882 00883 for ( ; peripheralNum < maxPeripheralNum; peripheralNum++) { 00884 00885 // 00886 // Reset the string to its original value. 00887 // 00888 00889 registryPathName = peripheralBackupRegistryPathName; 00890 00891 // 00892 // Convert the peripheral number to a unicode string and append 00893 // it to the registry path name. 00894 // 00895 00896 bufferUnicodeString.Length = 00897 (UNICODE_NUM_LENGTH-1) * sizeof(WCHAR); 00898 status = RtlIntegerToUnicodeString( peripheralNum, 00899 10, 00900 &bufferUnicodeString ); 00901 00902 if (NT_SUCCESS( status )) { 00903 00904 status = RtlAppendUnicodeToString( &registryPathName, 00905 L"\\" ); 00906 00907 if (NT_SUCCESS( status )) { 00908 00909 status = RtlAppendUnicodeStringToString( 00910 &registryPathName, 00911 &bufferUnicodeString ); 00912 00913 } 00914 } 00915 00916 if (!NT_SUCCESS( status )) { 00917 break; 00918 } 00919 00920 // 00921 // Open the registry key for the peripheral number and 00922 // Get the value data for this peripheral and save it for 00923 // later. 00924 // 00925 00926 status = IopOpenRegistryKey( &peripheralHandle, 00927 (HANDLE) NULL, 00928 &registryPathName, 00929 KEY_READ, 00930 FALSE ); 00931 00932 if (NT_SUCCESS( status )) { 00933 00934 status = IopGetRegistryValues( peripheralHandle, 00935 &peripheralValueInfo[0] ); 00936 00937 ZwClose( peripheralHandle ); 00938 peripheralHandle = NULL; 00939 } 00940 00941 // 00942 // If getting the peripheral information worked properly, 00943 // call the user-specified callout routine. 00944 // 00945 00946 if (NT_SUCCESS( status )) { 00947 00948 status = QueryDescription->CalloutRoutine( 00949 QueryDescription->Context, 00950 &registryPathName, 00951 *(QueryDescription->BusType), 00952 BusNum, 00953 BusValueInfo, 00954 *(QueryDescription->ControllerType), 00955 controllerNum, 00956 (PKEY_VALUE_FULL_INFORMATION *) controllerValueInfo, 00957 *(QueryDescription->PeripheralType), 00958 peripheralNum, 00959 (PKEY_VALUE_FULL_INFORMATION *) peripheralValueInfo ); 00960 00961 // 00962 // Free the pool allocated for the peripheral value data. 00963 // 00964 00965 if (peripheralValueInfo[0]) { 00966 ExFreePool( peripheralValueInfo[0] ); 00967 peripheralValueInfo[0] = NULL; 00968 } 00969 if (peripheralValueInfo[1]) { 00970 ExFreePool( peripheralValueInfo[1] ); 00971 peripheralValueInfo[1] = NULL; 00972 } 00973 if (peripheralValueInfo[2]) { 00974 ExFreePool( peripheralValueInfo[2] ); 00975 peripheralValueInfo[2] = NULL; 00976 } 00977 00978 // 00979 // If the user-specified callout routine returned with 00980 // an unsuccessful status, quit. 00981 // 00982 00983 if (!NT_SUCCESS( status )) { 00984 break; 00985 } 00986 } 00987 00988 } // for ( ; peripheralNum < maxPeripheralNum ... 00989 00990 IoQueryDeviceControllerLoop: 00991 00992 // 00993 // Free the pool allocated for the controller value data. 00994 // 00995 00996 if (controllerValueInfo[0]) { 00997 ExFreePool( controllerValueInfo[0] ); 00998 controllerValueInfo[0] = NULL; 00999 } 01000 if (controllerValueInfo[1]) { 01001 ExFreePool( controllerValueInfo[1] ); 01002 controllerValueInfo[1] = NULL; 01003 } 01004 if (controllerValueInfo[2]) { 01005 ExFreePool( controllerValueInfo[2] ); 01006 controllerValueInfo[2] = NULL; 01007 } 01008 01009 if (!NT_SUCCESS( status )) { 01010 break; 01011 } 01012 01013 } // for ( ; controllerNum < maxControllerNum... 01014 01015 01016 return( status ); 01017 }


Generated on Sat May 15 19:45:25 2004 for test by doxygen 1.3.7