00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00056
00057
00058
00059
#pragma alloc_text(PAGE, IopDumpCmResourceDescriptor)
00060
#pragma alloc_text(PAGE, IopDumpCmResourceList)
00061
00062
#endif
00063
00064
00065
VOID
00066 IopInitializeResourceMap (
00067
PLOADER_PARAMETER_BLOCK LoaderBlock
00068 )
00069
00070
00071
00072
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
00097
00098
00099
RtlInitUnicodeString( &unicodeString,
IopWstrPhysicalMemory);
00100 MemoryBlock =
MmPhysicalMemoryBlock;
00101
break;
00102
00103
case 1:
00104
00105
00106
00107
00108
00109
RtlInitUnicodeString( &unicodeString,
IopWstrSpecialMemory);
00110
00111
00112
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
00133
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
00160
00161 CmDescriptor->u.Memory.Length =
00162 (ULONG)(MemoryBlock->
Run[i].
PageCount <<
PAGE_SHIFT);
00163
00164 CmDescriptor++;
00165 }
00166
00167
00168
00169
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
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
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
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
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
00262
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
00281
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
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 {
00351
00352
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
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
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
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
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
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
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
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
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
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
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
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
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
00833
00834
00835
00836
00837
00838
00839
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 0
L,
00852 REG_RESOURCE_LIST,
00853 ResourceList,
00854 ResourceListSize );
00855
00856 }
00857
00858 ZwClose( driverKeyHandle );
00859
00860 }
00861 }
00862
00863
return status;
00864 }
00865
00866
00867
VOID
00868 IopDumpCmResourceDescriptor (
00869 IN PUCHAR Indent,
00870 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Desc
00871 )
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
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
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
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