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

report.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 report.c 00008 00009 Abstract: 00010 00011 This module contains the subroutines used to report resources used by 00012 the drivers and the HAL into the registry resource map. 00013 00014 Author: 00015 00016 Andre Vachon (andreva) 15-Dec-1992 00017 00018 Environment: 00019 00020 Kernel mode, local to I/O system 00021 00022 Revision History: 00023 00024 00025 --*/ 00026 00027 #include "iop.h" 00028 00029 #define DBG_AR 0 00030 00031 extern WCHAR IopWstrRaw[]; 00032 extern WCHAR IopWstrTranslated[]; 00033 extern WCHAR IopWstrBusTranslated[]; 00034 extern WCHAR IopWstrOtherDrivers[]; 00035 00036 extern WCHAR IopWstrHal[]; 00037 extern WCHAR IopWstrSystem[]; 00038 extern WCHAR IopWstrPhysicalMemory[]; 00039 extern WCHAR IopWstrSpecialMemory[]; 00040 00041 BOOLEAN 00042 IopChangeInterfaceType( 00043 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST IoResources, 00044 IN OUT PCM_RESOURCE_LIST *AllocatedResource 00045 ); 00046 00047 #ifdef ALLOC_PRAGMA 00048 #pragma alloc_text(PAGE, IoReportResourceUsageInternal) 00049 #pragma alloc_text(PAGE, IoReportResourceUsage) 00050 #pragma alloc_text(PAGE, IoReportResourceForDetection) 00051 #pragma alloc_text(PAGE, IopChangeInterfaceType) 00052 #pragma alloc_text(PAGE, IopWriteResourceList) 00053 #pragma alloc_text(INIT, IopInitializeResourceMap) 00054 #pragma alloc_text(INIT, IoReportHalResourceUsage) 00055 // BUGBUG - For now we want the following two dbg routines for free build. 00056 // So, we can track resource allocation on free build by enabling 00057 // a debug flag. 00058 //#if DBG 00059 #pragma alloc_text(PAGE, IopDumpCmResourceDescriptor) 00060 #pragma alloc_text(PAGE, IopDumpCmResourceList) 00061 //#endif 00062 #endif 00063 00064 00065 VOID 00066 IopInitializeResourceMap ( 00067 PLOADER_PARAMETER_BLOCK LoaderBlock 00068 ) 00069 /*++ 00070 00071 Initializes the resource map by adding in the physical memory 00072 which is in use by the system. 00073 00074 --*/ 00075 { 00076 ULONG i, j, pass, length; 00077 LARGE_INTEGER li; 00078 HANDLE keyHandle; 00079 UNICODE_STRING unicodeString, systemString, listString; 00080 NTSTATUS status; 00081 PCM_RESOURCE_LIST ResourceList; 00082 PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor; 00083 BOOLEAN IncludeType[LoaderMaximum]; 00084 ULONG MemoryAlloc[(sizeof(PHYSICAL_MEMORY_DESCRIPTOR) + 00085 sizeof(PHYSICAL_MEMORY_RUN)*MAX_PHYSICAL_MEMORY_FRAGMENTS) / 00086 sizeof(ULONG)]; 00087 PPHYSICAL_MEMORY_DESCRIPTOR MemoryBlock; 00088 00089 RtlInitUnicodeString( &systemString, IopWstrSystem); 00090 RtlInitUnicodeString( &listString, IopWstrTranslated ); 00091 00092 for (pass=0; pass < 2; pass++) { 00093 switch (pass) { 00094 case 0: 00095 // 00096 // Add MmPhysicalMemoryBlock to regitry 00097 // 00098 00099 RtlInitUnicodeString( &unicodeString, IopWstrPhysicalMemory); 00100 MemoryBlock = MmPhysicalMemoryBlock; 00101 break; 00102 00103 case 1: 00104 00105 // 00106 // Add LoadSpecialMemory to registry 00107 // 00108 00109 RtlInitUnicodeString( &unicodeString, IopWstrSpecialMemory); 00110 00111 // 00112 // Computer memory limits of LoaderSpecialMemory 00113 // 00114 00115 MemoryBlock = (PPHYSICAL_MEMORY_DESCRIPTOR)&MemoryAlloc; 00116 MemoryBlock->NumberOfRuns = MAX_PHYSICAL_MEMORY_FRAGMENTS; 00117 00118 for (j=0; j < LoaderMaximum; j++) { 00119 IncludeType[j] = FALSE; 00120 } 00121 IncludeType[LoaderSpecialMemory] = TRUE; 00122 MmInitializeMemoryLimits( 00123 LoaderBlock, 00124 IncludeType, 00125 MemoryBlock 00126 ); 00127 00128 break; 00129 } 00130 00131 // 00132 // Allocate and build a CM_RESOURCE_LIST to describe all 00133 // of physical memory 00134 // 00135 00136 j = MemoryBlock->NumberOfRuns; 00137 if (j == 0) { 00138 continue; 00139 } 00140 00141 length = sizeof(CM_RESOURCE_LIST) + (j-1) * sizeof (CM_PARTIAL_RESOURCE_DESCRIPTOR); 00142 ResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (PagedPool, length); 00143 if (!ResourceList) { 00144 return; 00145 } 00146 RtlZeroMemory ((PVOID) ResourceList, length); 00147 00148 ResourceList->Count = 1; 00149 ResourceList->List[0].PartialResourceList.Count = j; 00150 CmDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; 00151 00152 for (i=0; i < j; i++) { 00153 CmDescriptor->Type = CmResourceTypeMemory; 00154 CmDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00155 li.QuadPart = (LONGLONG)(MemoryBlock->Run[i].BasePage); 00156 li.QuadPart <<= PAGE_SHIFT; 00157 CmDescriptor->u.Memory.Start = li; 00158 00159 // fixfix - handle page frame numbers greater than 32 bits. 00160 00161 CmDescriptor->u.Memory.Length = 00162 (ULONG)(MemoryBlock->Run[i].PageCount << PAGE_SHIFT); 00163 00164 CmDescriptor++; 00165 } 00166 00167 00168 // 00169 // Add the resoruce list to the resorucemap 00170 // 00171 00172 status = IopOpenRegistryKey( &keyHandle, 00173 (HANDLE) NULL, 00174 &CmRegistryMachineHardwareResourceMapName, 00175 KEY_READ | KEY_WRITE, 00176 TRUE ); 00177 if (NT_SUCCESS( status )) { 00178 IopWriteResourceList ( keyHandle, 00179 &systemString, 00180 &unicodeString, 00181 &listString, 00182 ResourceList, 00183 length 00184 ); 00185 ZwClose( keyHandle ); 00186 } 00187 ExFreePool (ResourceList); 00188 } 00189 } 00190 00191 00192 NTSTATUS 00193 IoReportHalResourceUsage( 00194 IN PUNICODE_STRING HalName, 00195 IN PCM_RESOURCE_LIST RawResourceList, 00196 IN PCM_RESOURCE_LIST TranslatedResourceList, 00197 IN ULONG ResourceListSize 00198 ) 00199 00200 /*++ 00201 00202 Routine Description: 00203 00204 This routine is called by the HAL to report its resources. 00205 The Hal is the first component to report its resources, so we don't need 00206 to acquire the resourcemap semaphore, and we do not need to check for 00207 conflicts. 00208 00209 Arguments: 00210 00211 HalName - Name of the HAL reporting the resources. 00212 00213 RawResourceList - Pointer to the HAL's raw resource list. 00214 00215 TranslatedResourceList - Pointer to the HAL's translated resource list. 00216 00217 DriverListSize - Value determining the size of the HAL's resource list. 00218 00219 Return Value: 00220 00221 The status returned is the final completion status of the operation. 00222 00223 --*/ 00224 00225 { 00226 HANDLE keyHandle; 00227 UNICODE_STRING halString; 00228 UNICODE_STRING listString; 00229 NTSTATUS status; 00230 00231 PAGED_CODE(); 00232 00233 // 00234 // First open a handle to the RESOURCEMAP key. 00235 // 00236 00237 RtlInitUnicodeString( &halString, IopWstrHal ); 00238 00239 status = IopOpenRegistryKey( &keyHandle, 00240 (HANDLE) NULL, 00241 &CmRegistryMachineHardwareResourceMapName, 00242 KEY_READ | KEY_WRITE, 00243 TRUE ); 00244 00245 // 00246 // Write out the raw resource list 00247 // 00248 00249 if (NT_SUCCESS( status )) { 00250 00251 RtlInitUnicodeString( &listString, IopWstrRaw); 00252 00253 status = IopWriteResourceList( keyHandle, 00254 &halString, 00255 HalName, 00256 &listString, 00257 RawResourceList, 00258 ResourceListSize ); 00259 00260 // 00261 // If we successfully wrote out the raw resource list, write out 00262 // the translated resource list. 00263 // 00264 00265 if (NT_SUCCESS( status )) { 00266 00267 RtlInitUnicodeString( &listString, IopWstrTranslated); 00268 status = IopWriteResourceList( keyHandle, 00269 &halString, 00270 HalName, 00271 &listString, 00272 TranslatedResourceList, 00273 ResourceListSize ); 00274 00275 } 00276 ZwClose( keyHandle ); 00277 } 00278 00279 // 00280 // If every looks fine, we will make a copy of the Hal resources so will 00281 // can call Arbiters to reserve the resources after they initialized. 00282 // 00283 00284 if (NT_SUCCESS(status)) { 00285 IopInitHalResources = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool, ResourceListSize); 00286 if (IopInitHalResources) { 00287 RtlMoveMemory(IopInitHalResources, RawResourceList, ResourceListSize); 00288 } else { 00289 status = STATUS_INSUFFICIENT_RESOURCES; 00290 } 00291 } 00292 00293 return status; 00294 } 00295 00296 NTSTATUS 00297 IoReportResourceForDetection( 00298 IN PDRIVER_OBJECT DriverObject, 00299 IN PCM_RESOURCE_LIST DriverList OPTIONAL, 00300 IN ULONG DriverListSize OPTIONAL, 00301 IN PDEVICE_OBJECT DeviceObject OPTIONAL, 00302 IN PCM_RESOURCE_LIST DeviceList OPTIONAL, 00303 IN ULONG DeviceListSize OPTIONAL, 00304 OUT PBOOLEAN ConflictDetected 00305 ) 00306 00307 /*++ 00308 00309 Routine Description: 00310 00311 This routine will automatically search through the configuration 00312 registry for resource conflicts between resources requested by a device 00313 and the resources already claimed by previously installed drivers. The 00314 contents of the DriverList and the DeviceList will be matched against 00315 all the other resource list stored in the registry to determine 00316 conflicts. 00317 00318 The function may be called more than once for a given device or driver. 00319 If a new resource list is given, the previous resource list stored in 00320 the registry will be replaced by the new list. 00321 00322 Note, this function is for the drivers acquiring resources for detection. 00323 00324 Arguments: 00325 00326 DriverObject - Pointer to the driver's driver object. 00327 00328 DriverList - Optional pointer to the driver's resource list. 00329 00330 DriverListSize - Optional value determining the size of the driver's 00331 resource list. 00332 00333 DeviceObject - Optional pointer to driver's device object. 00334 00335 DeviceList - Optional pointer to the device's resource list. 00336 00337 DriverListSize - Optional value determining the size of the device's 00338 resource list. 00339 00340 ConflictDetected - Supplies a pointer to a boolean that is set to TRUE 00341 if the resource list conflicts with an already existing resource 00342 list in the configuration registry. 00343 00344 Return Value: 00345 00346 The status returned is the final completion status of the operation. 00347 00348 --*/ 00349 00350 { 00351 // 00352 // Sanity check that the caller did not pass in a PnP PDO. 00353 // 00354 00355 if (DeviceObject) { 00356 00357 if ( DeviceObject->DeviceObjectExtension->DeviceNode && 00358 !(((PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode)->Flags & DNF_LEGACY_RESOURCE_DEVICENODE)) { 00359 00360 KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, PNP_ERR_INVALID_PDO, (ULONG_PTR)DeviceObject, 0, 0); 00361 00362 } 00363 00364 } 00365 00366 return IoReportResourceUsageInternal( ArbiterRequestPnpDetected, 00367 NULL, 00368 DriverObject, 00369 DriverList, 00370 DriverListSize, 00371 DeviceObject, 00372 DeviceList, 00373 DeviceListSize, 00374 FALSE, 00375 ConflictDetected); 00376 } 00377 00378 NTSTATUS 00379 IoReportResourceUsage( 00380 IN PUNICODE_STRING DriverClassName OPTIONAL, 00381 IN PDRIVER_OBJECT DriverObject, 00382 IN PCM_RESOURCE_LIST DriverList OPTIONAL, 00383 IN ULONG DriverListSize OPTIONAL, 00384 IN PDEVICE_OBJECT DeviceObject OPTIONAL, 00385 IN PCM_RESOURCE_LIST DeviceList OPTIONAL, 00386 IN ULONG DeviceListSize OPTIONAL, 00387 IN BOOLEAN OverrideConflict, 00388 OUT PBOOLEAN ConflictDetected 00389 ) 00390 00391 /*++ 00392 00393 Routine Description: 00394 00395 This routine will automatically search through the configuration 00396 registry for resource conflicts between resources requested by a device 00397 and the resources already claimed by previously installed drivers. The 00398 contents of the DriverList and the DeviceList will be matched against 00399 all the other resource list stored in the registry to determine 00400 conflicts. 00401 00402 If not conflict was detected, or if the OverrideConflict flag is set, 00403 this routine will create appropriate entries in the system resource map 00404 (in the registry) that will contain the specified resource lists. 00405 00406 The function may be called more than once for a given device or driver. 00407 If a new resource list is given, the previous resource list stored in 00408 the registry will be replaced by the new list. 00409 00410 Arguments: 00411 00412 DriverClassName - Optional pointer to a UNICODE_STRING which describes 00413 the class of driver under which the driver information should be 00414 stored. A default type is used if none is given. 00415 00416 DriverObject - Pointer to the driver's driver object. 00417 00418 DriverList - Optional pointer to the driver's resource list. 00419 00420 DriverListSize - Optional value determining the size of the driver's 00421 resource list. 00422 00423 DeviceObject - Optional pointer to driver's device object. 00424 00425 DeviceList - Optional pointer to the device's resource list. 00426 00427 DriverListSize - Optional value determining the size of the driver's 00428 resource list. 00429 00430 OverrideConflict - Determines if the information should be reported 00431 in the configuration registry eventhough a conflict was found with 00432 another driver or device. 00433 00434 ConflictDetected - Supplies a pointer to a boolean that is set to TRUE 00435 if the resource list conflicts with an already existing resource 00436 list in the configuration registry. 00437 00438 Return Value: 00439 00440 The status returned is the final completion status of the operation. 00441 00442 --*/ 00443 00444 { 00445 if (DeviceObject) { 00446 00447 if ( DeviceObject->DeviceObjectExtension->DeviceNode && 00448 !(((PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode)->Flags & DNF_LEGACY_RESOURCE_DEVICENODE)) { 00449 00450 KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, PNP_ERR_INVALID_PDO, (ULONG_PTR)DeviceObject, 0, 0); 00451 00452 } 00453 00454 } 00455 00456 return IoReportResourceUsageInternal( ArbiterRequestLegacyReported, 00457 DriverClassName, 00458 DriverObject, 00459 DriverList, 00460 DriverListSize, 00461 DeviceObject, 00462 DeviceList, 00463 DeviceListSize, 00464 OverrideConflict, 00465 ConflictDetected); 00466 } 00467 00468 NTSTATUS 00469 IoReportResourceUsageInternal( 00470 IN ARBITER_REQUEST_SOURCE AllocationType, 00471 IN PUNICODE_STRING DriverClassName OPTIONAL, 00472 IN PDRIVER_OBJECT DriverObject, 00473 IN PCM_RESOURCE_LIST DriverList OPTIONAL, 00474 IN ULONG DriverListSize OPTIONAL, 00475 IN PDEVICE_OBJECT DeviceObject OPTIONAL, 00476 IN PCM_RESOURCE_LIST DeviceList OPTIONAL, 00477 IN ULONG DeviceListSize OPTIONAL, 00478 IN BOOLEAN OverrideConflict, 00479 OUT PBOOLEAN ConflictDetected 00480 ) 00481 00482 /*++ 00483 00484 Routine Description: 00485 00486 This internal routine will do all the work for IoReportResourceUsage. 00487 00488 Arguments: 00489 00490 AllocationType - Specifies the request type. 00491 00492 DriverClassName - Optional pointer to a UNICODE_STRING which describes 00493 the class of driver under which the driver information should be 00494 stored. A default type is used if none is given. 00495 00496 DriverObject - Pointer to the driver's driver object. 00497 00498 DriverList - Optional pointer to the driver's resource list. 00499 00500 DriverListSize - Optional value determining the size of the driver's 00501 resource list. 00502 00503 DeviceObject - Optional pointer to driver's device object. 00504 00505 DeviceList - Optional pointer to the device's resource list. 00506 00507 DriverListSize - Optional value determining the size of the driver's 00508 resource list. 00509 00510 OverrideConflict - Determines if the information should be reported 00511 in the configuration registry eventhough a conflict was found with 00512 another driver or device. 00513 00514 ConflictDetected - Supplies a pointer to a boolean that is set to TRUE 00515 if the resource list conflicts with an already existing resource 00516 list in the configuration registry. 00517 00518 Return Value: 00519 00520 The status returned is the final completion status of the operation. 00521 00522 --*/ 00523 00524 { 00525 NTSTATUS status = STATUS_UNSUCCESSFUL; 00526 PCM_RESOURCE_LIST resourceList; 00527 PCM_RESOURCE_LIST allocatedResources; 00528 PIO_RESOURCE_REQUIREMENTS_LIST resourceRequirements; 00529 ULONG attempt; 00530 BOOLEAN freeAllocatedResources; 00531 00532 ASSERT(DriverObject && ConflictDetected); 00533 00534 if (DeviceList) { 00535 00536 resourceList = DeviceList; 00537 00538 } else if (DriverList) { 00539 00540 resourceList = DriverList; 00541 00542 } else { 00543 00544 resourceList = NULL; 00545 00546 } 00547 00548 resourceRequirements = NULL; 00549 00550 if (resourceList) { 00551 00552 if (resourceList->Count && resourceList->List[0].PartialResourceList.Count) { 00553 00554 resourceRequirements = IopCmResourcesToIoResources (0, resourceList, LCPRI_NORMAL); 00555 00556 if (resourceRequirements == NULL) { 00557 00558 return status; 00559 00560 } 00561 00562 } else { 00563 00564 resourceList = NULL; 00565 00566 } 00567 00568 } 00569 00570 *ConflictDetected = TRUE; 00571 attempt = 0; 00572 allocatedResources = resourceList; 00573 freeAllocatedResources = FALSE; 00574 do { 00575 00576 // 00577 // Do the legacy resource allocation. 00578 // 00579 00580 status = IopLegacyResourceAllocation ( AllocationType, 00581 DriverObject, 00582 DeviceObject, 00583 resourceRequirements, 00584 &allocatedResources); 00585 00586 if (NT_SUCCESS(status)) { 00587 00588 *ConflictDetected = FALSE; 00589 break; 00590 } 00591 00592 // 00593 // Change the interface type and try again. 00594 // 00595 00596 if (!IopChangeInterfaceType(resourceRequirements, &allocatedResources)) { 00597 00598 break; 00599 } 00600 freeAllocatedResources = TRUE; 00601 00602 } while (++attempt < 2); 00603 00604 if (resourceRequirements) { 00605 00606 ExFreePool(resourceRequirements); 00607 00608 } 00609 00610 if (freeAllocatedResources) { 00611 00612 ExFreePool(allocatedResources); 00613 } 00614 00615 if (NT_SUCCESS(status)) { 00616 00617 status = STATUS_SUCCESS; 00618 00619 } else { 00620 00621 status = STATUS_INSUFFICIENT_RESOURCES; 00622 00623 } 00624 00625 return status; 00626 } 00627 00628 BOOLEAN 00629 IopChangeInterfaceType( 00630 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST IoResources, 00631 IN OUT PCM_RESOURCE_LIST *AllocatedResources 00632 ) 00633 00634 /*++ 00635 00636 Routine Description: 00637 00638 This routine takes an Io resourcelist and changes its interfacetype 00639 from internal to default type (isa or eisa or mca). 00640 00641 Arguments: 00642 00643 IoResources - Pointer to requirement list. 00644 00645 AllocatedResources - Pointer to a variable that receives the pointer to the resource list. 00646 00647 Return Value: 00648 00649 BOOLEAN value to indicates if change made or not. 00650 00651 --*/ 00652 00653 { 00654 PIO_RESOURCE_LIST IoResourceList; 00655 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor; 00656 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptorEnd; 00657 LONG IoResourceListCount; 00658 BOOLEAN changed; 00659 00660 ASSERT(AllocatedResources); 00661 00662 changed = FALSE; 00663 00664 if (!IoResources) { 00665 00666 return changed; 00667 00668 } 00669 00670 if (IoResources->InterfaceType == Internal) { 00671 00672 IoResources->InterfaceType = PnpDefaultInterfaceType; 00673 changed = TRUE; 00674 00675 } 00676 00677 IoResourceList = IoResources->List; 00678 IoResourceListCount = IoResources->AlternativeLists; 00679 while (--IoResourceListCount >= 0) { 00680 00681 IoResourceDescriptor = IoResourceList->Descriptors; 00682 IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count; 00683 00684 for (;IoResourceDescriptor < IoResourceDescriptorEnd; IoResourceDescriptor++) { 00685 00686 if (IoResourceDescriptor->Type == CmResourceTypeReserved && 00687 IoResourceDescriptor->u.DevicePrivate.Data[0] == Internal) { 00688 00689 IoResourceDescriptor->u.DevicePrivate.Data[0] = PnpDefaultInterfaceType; 00690 changed = TRUE; 00691 00692 } 00693 } 00694 IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd; 00695 } 00696 00697 if (changed) { 00698 00699 PCM_RESOURCE_LIST oldResources = *AllocatedResources; 00700 PCM_RESOURCE_LIST newResources; 00701 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc; 00702 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc; 00703 ULONG size; 00704 00705 if (oldResources) { 00706 00707 size = IopDetermineResourceListSize(oldResources); 00708 newResources = ExAllocatePool(PagedPool, size); 00709 if (newResources == NULL) { 00710 00711 changed = FALSE; 00712 00713 } else { 00714 00715 ULONG i; 00716 ULONG j; 00717 00718 00719 RtlCopyMemory(newResources, oldResources, size); 00720 00721 // 00722 // Fix up the interface type 00723 // 00724 00725 cmFullDesc = &newResources->List[0]; 00726 for (i = 0; i < oldResources->Count; i++) { 00727 00728 if (cmFullDesc->InterfaceType == Internal) { 00729 00730 cmFullDesc->InterfaceType = PnpDefaultInterfaceType; 00731 00732 } 00733 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0]; 00734 for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) { 00735 00736 size = 0; 00737 switch (cmPartDesc->Type) { 00738 00739 case CmResourceTypeDeviceSpecific: 00740 size = cmPartDesc->u.DeviceSpecificData.DataSize; 00741 break; 00742 00743 } 00744 cmPartDesc++; 00745 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size); 00746 } 00747 00748 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc; 00749 } 00750 00751 *AllocatedResources = newResources; 00752 } 00753 } 00754 } 00755 00756 return changed; 00757 } 00758 00759 NTSTATUS 00760 IopWriteResourceList( 00761 HANDLE ResourceMapKey, 00762 PUNICODE_STRING ClassName, 00763 PUNICODE_STRING DriverName, 00764 PUNICODE_STRING DeviceName, 00765 PCM_RESOURCE_LIST ResourceList, 00766 ULONG ResourceListSize 00767 ) 00768 00769 /*++ 00770 00771 Routine Description: 00772 00773 This routine takes a resourcelist and stores it in the registry resource 00774 map, using the ClassName, DriverName and DeviceName as the path of the 00775 key to store it in. 00776 00777 Arguments: 00778 00779 ResourceMapKey - Handle to the root of the resource map. 00780 00781 ClassName - Pointer to a Unicode String that contains the name of the Class 00782 for this resource list. 00783 00784 DriverName - Pointer to a Unicode String that contains the name of the 00785 Driver for this resource list. 00786 00787 DeviceName - Pointer to a Unicode String that contains the name of the 00788 Device for this resource list. 00789 00790 ResourceList - P to the resource list. 00791 00792 ResourceListSize - Value determining the size of the resource list. 00793 00794 Return Value: 00795 00796 The status returned is the final completion status of the operation. 00797 00798 --*/ 00799 00800 00801 { 00802 NTSTATUS status; 00803 HANDLE classKeyHandle; 00804 HANDLE driverKeyHandle; 00805 00806 PAGED_CODE(); 00807 00808 status = IopOpenRegistryKey( &classKeyHandle, 00809 ResourceMapKey, 00810 ClassName, 00811 KEY_READ | KEY_WRITE, 00812 TRUE ); 00813 00814 if (NT_SUCCESS( status )) { 00815 00816 // 00817 // Take the resulting name to create the key. 00818 // 00819 00820 status = IopOpenRegistryKey( &driverKeyHandle, 00821 classKeyHandle, 00822 DriverName, 00823 KEY_READ | KEY_WRITE, 00824 TRUE ); 00825 00826 ZwClose( classKeyHandle ); 00827 00828 00829 if (NT_SUCCESS( status )) { 00830 00831 // 00832 // With this key handle, we can now store the required information 00833 // in the value entries of the key. 00834 // 00835 00836 // 00837 // Store the device name as a value name and the device information 00838 // as the rest of the data. 00839 // Only store the information if the CM_RESOURCE_LIST was present. 00840 // 00841 00842 if (ResourceList->Count == 0) { 00843 00844 status = ZwDeleteValueKey( driverKeyHandle, 00845 DeviceName ); 00846 00847 } else { 00848 00849 status = ZwSetValueKey( driverKeyHandle, 00850 DeviceName, 00851 0L, 00852 REG_RESOURCE_LIST, 00853 ResourceList, 00854 ResourceListSize ); 00855 00856 } 00857 00858 ZwClose( driverKeyHandle ); 00859 00860 } 00861 } 00862 00863 return status; 00864 } 00865 //#if DBG 00866 00867 VOID 00868 IopDumpCmResourceDescriptor ( 00869 IN PUCHAR Indent, 00870 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Desc 00871 ) 00872 /*++ 00873 00874 Routine Description: 00875 00876 This routine processes a IO_RESOURCE_DESCRIPTOR and displays it. 00877 00878 Arguments: 00879 00880 Indent - # char of indentation. 00881 00882 Desc - supplies a pointer to the IO_RESOURCE_DESCRIPTOR to be displayed. 00883 00884 Return Value: 00885 00886 None. 00887 00888 --*/ 00889 { 00890 PAGED_CODE(); 00891 00892 switch (Desc->Type) { 00893 case CmResourceTypePort: 00894 DbgPrint ("%sIO Start: %x:%08x, Length: %x\n", 00895 Indent, 00896 Desc->u.Port.Start.HighPart, Desc->u.Port.Start.LowPart, 00897 Desc->u.Port.Length 00898 ); 00899 break; 00900 00901 case CmResourceTypeMemory: 00902 DbgPrint ("%sMEM Start: %x:%08x, Length: %x\n", 00903 Indent, 00904 Desc->u.Memory.Start.HighPart, Desc->u.Memory.Start.LowPart, 00905 Desc->u.Memory.Length 00906 ); 00907 break; 00908 00909 case CmResourceTypeInterrupt: 00910 DbgPrint ("%sINT Level: %x, Vector: %x, Affinity: %x\n", 00911 Indent, 00912 Desc->u.Interrupt.Level, 00913 Desc->u.Interrupt.Vector, 00914 Desc->u.Interrupt.Affinity 00915 ); 00916 break; 00917 00918 case CmResourceTypeDma: 00919 DbgPrint ("%sDMA Channel: %x, Port: %x\n", 00920 Indent, 00921 Desc->u.Dma.Channel, 00922 Desc->u.Dma.Port 00923 ); 00924 break; 00925 } 00926 } 00927 00928 VOID 00929 IopDumpCmResourceList ( 00930 IN PCM_RESOURCE_LIST CmList 00931 ) 00932 /*++ 00933 00934 Routine Description: 00935 00936 This routine displays CM resource list. 00937 00938 Arguments: 00939 00940 CmList - supplies a pointer to CM resource list 00941 00942 Return Value: 00943 00944 None. 00945 00946 --*/ 00947 { 00948 PCM_FULL_RESOURCE_DESCRIPTOR fullDesc; 00949 PCM_PARTIAL_RESOURCE_LIST partialDesc; 00950 PCM_PARTIAL_RESOURCE_DESCRIPTOR desc; 00951 ULONG count, i; 00952 00953 PAGED_CODE(); 00954 00955 if (CmList->Count > 0) { 00956 if (CmList) { 00957 fullDesc = &CmList->List[0]; 00958 DbgPrint("Cm Resource List -\n"); 00959 DbgPrint(" List Count = %x, Bus Number = %x\n", CmList->Count, fullDesc->BusNumber); 00960 partialDesc = &fullDesc->PartialResourceList; 00961 DbgPrint(" Version = %x, Revision = %x, Desc count = %x\n", partialDesc->Version, 00962 partialDesc->Revision, partialDesc->Count); 00963 count = partialDesc->Count; 00964 desc = &partialDesc->PartialDescriptors[0]; 00965 for (i = 0; i < count; i++) { 00966 IopDumpCmResourceDescriptor(" ", desc); 00967 desc++; 00968 } 00969 } 00970 } 00971 } 00972 //#endif

Generated on Sat May 15 19:41:38 2004 for test by doxygen 1.3.7