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
00028
00029
00030
00031
00032
00033
00034
00035
#include "iop.h"
00036
#pragma hdrstop
00037
00038 #define MYDBG 0
00039
00040
#ifdef POOL_TAGGING
00041
#undef ExAllocatePool
00042
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'erpP')
00043
#endif // POOL_TAGGING
00044
00045
#if MYDBG
00046
#define ExAllocatePoolAT(a,b) ExAllocatePoolWithTag(a,b,'0rpP')
00047
#define ExAllocatePoolRD(a,b) ExAllocatePoolWithTag(a,b,'1rpP')
00048
#define ExAllocatePoolCMRL(a,b) ExAllocatePoolWithTag(a,b,'2rpP')
00049
#define ExAllocatePoolCMRR(a,b) ExAllocatePoolWithTag(a,b,'3rpP')
00050
#define ExAllocatePoolAE(a,b) ExAllocatePoolWithTag(a,b,'4rpP')
00051
#define ExAllocatePoolTE(a,b) ExAllocatePoolWithTag(a,b,'5rpP')
00052
#define ExAllocatePoolPRD(a,b) ExAllocatePoolWithTag(a,b,'6rpP')
00053
#define ExAllocatePoolIORD(a,b) ExAllocatePoolWithTag(a,b,'7rpP')
00054
#define ExAllocatePool1RD(a,b) ExAllocatePoolWithTag(a,b,'8rpP')
00055
#define ExAllocatePoolPDO(a,b) ExAllocatePoolWithTag(a,b,'9rpP')
00056
#define ExAllocatePoolIORR(a,b) ExAllocatePoolWithTag(a,b,'ArpP')
00057
#define ExAllocatePoolIORL(a,b) ExAllocatePoolWithTag(a,b,'BrpP')
00058
#define ExAllocatePoolIORRR(a,b) ExAllocatePoolWithTag(a,b,'CrpP')
00059
#else // MYDBG
00060 #define ExAllocatePoolAT(a,b) ExAllocatePool(a,b)
00061 #define ExAllocatePoolRD(a,b) ExAllocatePool(a,b)
00062 #define ExAllocatePoolCMRL(a,b) ExAllocatePool(a,b)
00063 #define ExAllocatePoolCMRR(a,b) ExAllocatePool(a,b)
00064 #define ExAllocatePoolAE(a,b) ExAllocatePool(a,b)
00065 #define ExAllocatePoolTE(a,b) ExAllocatePool(a,b)
00066 #define ExAllocatePoolPRD(a,b) ExAllocatePool(a,b)
00067 #define ExAllocatePoolIORD(a,b) ExAllocatePool(a,b)
00068 #define ExAllocatePool1RD(a,b) ExAllocatePool(a,b)
00069 #define ExAllocatePoolPDO(a,b) ExAllocatePool(a,b)
00070 #define ExAllocatePoolIORR(a,b) ExAllocatePool(a,b)
00071 #define ExAllocatePoolIORL(a,b) ExAllocatePool(a,b)
00072 #define ExAllocatePoolIORRR(a,b) ExAllocatePool(a,b)
00073
#endif // MYDBG
00074
00075
00076
00077
00078
00079 typedef struct _REQ_DESC
00080 REQ_DESC, *
PREQ_DESC;
00081 typedef struct _REQ_ALTERNATIVE
00082 REQ_ALTERNATIVE, *
PREQ_ALTERNATIVE;
00083 typedef struct _REQ_LIST
00084 REQ_LIST, *
PREQ_LIST;
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 struct _REQ_DESC {
00095 BOOLEAN
ArbitrationRequired;
00096 UCHAR
Reserved[3];
00097 INTERFACE_TYPE
InterfaceType;
00098 ULONG
BusNumber;
00099 PREQ_ALTERNATIVE ReqAlternative;
00100 ULONG
ReqDescIndex;
00101 ULONG
DevicePrivateCount;
00102 PIO_RESOURCE_DESCRIPTOR
DevicePrivate;
00103 PREQ_DESC TranslatedReqDesc;
00104
union {
00105 PPI_RESOURCE_ARBITER_ENTRY Arbiter;
00106 PPI_RESOURCE_TRANSLATOR_ENTRY Translator;
00107 } u;
00108 ARBITER_LIST_ENTRY AlternativeTable;
00109 CM_PARTIAL_RESOURCE_DESCRIPTOR
Allocation;
00110
00111
00112
00113
00114
00115 ARBITER_LIST_ENTRY BestAlternativeTable;
00116 CM_PARTIAL_RESOURCE_DESCRIPTOR
BestAllocation;
00117 };
00118
00119 struct _REQ_ALTERNATIVE {
00120 PREQ_LIST ReqList;
00121 ULONG
ReqAlternativeIndex;
00122 ULONG
Priority;
00123 ULONG
ReqDescCount;
00124 PREQ_DESC *
ReqDescTableEnd;
00125 PREQ_DESC ReqDescTable[1];
00126 };
00127
00128 struct _REQ_LIST {
00129 PIOP_RESOURCE_REQUEST AssignEntry;
00130 PDEVICE_OBJECT PhysicalDevice;
00131 INTERFACE_TYPE
InterfaceType;
00132 ULONG
BusNumber;
00133 PREQ_ALTERNATIVE *
SelectedAlternative;
00134 ULONG
ReqAlternativeCount;
00135 PREQ_ALTERNATIVE *
ReqBestAlternative;
00136
00137 PREQ_ALTERNATIVE ReqAlternativeTable[1];
00138 };
00139
00140
00141
00142
00143
00144 typedef struct _Counter {
00145 ULONG
Count;
00146 ULONG
ResetValue;
00147 ULONG
MaximumValue;
00148 }
COUNTER, *
PCOUNTER;
00149
00150
00151 #define IS_TRANSLATED_REQ_DESC(r) ((r)->ReqAlternative ? FALSE : TRUE)
00152
00153
00154
00155
00156
00157 #define IopReleaseBootResources(DeviceNode) \
00158
ASSERT(((DeviceNode)->Flags & DNF_MADEUP) == 0); \
00159
IopReleaseResourcesInternal(DeviceNode); \
00160
(DeviceNode)->Flags &= ~DNF_HAS_BOOT_CONFIG; \
00161
(DeviceNode)->Flags &= ~DNF_BOOT_CONFIG_RESERVED; \
00162
if ((DeviceNode)->BootResources) { \
00163
ExFreePool((DeviceNode)->BootResources); \
00164
(DeviceNode)->BootResources = NULL; \
00165
}
00166
00167
00168
00169
00170
00171 typedef struct _DUPLICATE_DETECTION_CONTEXT {
00172 PCM_RESOURCE_LIST
TranslatedResources;
00173 PDEVICE_NODE Duplicate;
00174 }
DUPLICATE_DETECTION_CONTEXT, *
PDUPLICATE_DETECTION_CONTEXT;
00175
00176
00177
00178
00179
00180 #define NextDeviceNode Sibling
00181 #define PreviousDeviceNode Child
00182
00183
00184
00185
00186
00187 #define STRUCTURE_ALIGNMENT 1 // disable the structure alignment.
00188
00189
00190
00191
00192
00193 typedef struct _IOP_POOL {
00194 PUCHAR
PoolStart;
00195 PUCHAR
PoolEnd;
00196 ULONG
PoolSize;
00197 }
IOP_POOL, *
PIOP_POOL;
00198
00199
#define IopInitPool( \
00200
Pool, \
00201 Start, \
00202 Size \
00203 ) \
00204 { \
00205 (Pool)->PoolStart = (Start); \
00206 (Pool)->PoolEnd = (Start) + (Size); \
00207 (Pool)->PoolSize = (Size); \
00208 RtlZeroMemory(Start, Size); \
00209 }
00210
00211
#define IopAllocPoolAligned( \
00212
Memory, \
00213 Pool, \
00214 Size \
00215 ) \
00216 (Pool)->PoolStart = (PUCHAR) \
00217 (((ULONG_PTR) (Pool)->PoolStart + STRUCTURE_ALIGNMENT - 1) \
00218 & ~(STRUCTURE_ALIGNMENT - 1)); \
00219 IopAllocPool(Memory, Pool, Size);
00220
00221
#define IopAllocPool( \
00222
Memory, \
00223 Pool, \
00224 Size \
00225 ) \
00226 *(Memory) = (PVOID) (Pool)->PoolStart; \
00227 (Pool)->PoolStart += (Size); \
00228 ASSERT((Pool)->PoolStart <= (Pool)->PoolEnd);
00229
00230
00231
00232
00233
00234 LIST_ENTRY
PiActiveArbiterList;
00235 LIST_ENTRY
PiBestArbiterList;
00236 ULONG
PiBestPriority;
00237 PIOP_RESOURCE_REQUEST PiAssignTable;
00238 ULONG
PiAssignTableCount;
00239 PDEVICE_NODE IopLegacyDeviceNode;
00240
00241 BOOLEAN
PiNoRetest;
00242
#if DBG
00243
BOOLEAN
PiUseTimeout =
FALSE;
00244
#else
00245 BOOLEAN
PiUseTimeout =
TRUE;
00246
#endif
00247
00248
00249
00250
00251
00252 #define FIND_BEST_ASSIGNMENT_TIMEOUT 5000
00253
00254
00255
00256
00257
00258 extern WCHAR
IopWstrTranslated[];
00259 extern WCHAR
IopWstrRaw[];
00260
00261
00262
00263
00264
00265
#if DBG_SCOPE
00266
00267 #define DUMP_ERROR 0x0001
00268 #define DUMP_INFO 0x0002
00269 #define DUMP_DETAIL 0x0004
00270 #define STOP_ERROR 0x1000
00271
00272
00273 ULONG
PnpResDebugLevel = 0;
00274
00275 #define DebugMessage(Level,Message) \
00276
if (PnpResDebugLevel & (Level)) { \
00277
DbgPrint Message; \
00278
}
00279
00280 typedef struct {
00281 PDEVICE_NODE devnode;
00282 CM_PARTIAL_RESOURCE_DESCRIPTOR resource;
00283 }
PNPRESDEBUGTRANSLATIONFAILURE;
00284
00285 ULONG
PnpResDebugTranslationFailureCount = 32;
00286 PNPRESDEBUGTRANSLATIONFAILURE PnpResDebugTranslationFailureArray[32];
00287 PNPRESDEBUGTRANSLATIONFAILURE *
PnpResDebugTranslationFailure =
PnpResDebugTranslationFailureArray;
00288
00289
#else
00290
00291
#define DebugMessage(Level,Message)
00292
00293
#endif
00294
00295
00296
00297
00298
00299 PCM_RESOURCE_LIST
00300
IopCreateCmResourceList(
00301 IN PCM_RESOURCE_LIST ResourceList,
00302 IN INTERFACE_TYPE InterfaceType,
00303 IN ULONG BusNumber,
00304 OUT PCM_RESOURCE_LIST *RemainingList
00305 );
00306
00307 PCM_RESOURCE_LIST
00308
IopCombineCmResourceList(
00309 IN PCM_RESOURCE_LIST ResourceListA,
00310 IN PCM_RESOURCE_LIST ResourceListB
00311 );
00312
00313
VOID
00314
IopRemoveLegacyDeviceNode (
00315 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
00316 IN
PDEVICE_NODE LegacyDeviceNode
00317 );
00318
00319
NTSTATUS
00320
IopFindLegacyDeviceNode (
00321 IN
PDRIVER_OBJECT DriverObject,
00322 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
00323 OUT
PDEVICE_NODE *LegacyDeviceNode,
00324 OUT
PDEVICE_OBJECT *LegacyPDO
00325 );
00326
00327
PDEVICE_NODE
00328
IopFindBusDeviceNodeInternal (
00329 IN
PDEVICE_NODE DeviceNode,
00330 IN INTERFACE_TYPE InterfaceType,
00331 IN ULONG BusNumber
00332 );
00333
00334
NTSTATUS
00335
IopGetResourceRequirementsForAssignTable(
00336 IN
PIOP_RESOURCE_REQUEST AssignTable,
00337 IN
PIOP_RESOURCE_REQUEST AssignTableEnd,
00338 OUT PULONG DeviceCount
00339 );
00340
00341
NTSTATUS
00342
IopResourceRequirementsListToReqList(
00343 IN ARBITER_REQUEST_SOURCE AllocationType,
00344 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources,
00345 IN
PDEVICE_OBJECT PhysicalDevice,
00346 OUT PVOID *ResReqList
00347 );
00348
00349
VOID
00350
IopRearrangeReqList (
00351 IN PREQ_LIST ReqList
00352 );
00353
00354
VOID
00355
IopRearrangeAssignTable (
00356 IN
PIOP_RESOURCE_REQUEST AssignTable,
00357 IN ULONG Count
00358 );
00359
00360
int
00361 __cdecl
00362
IopComparePriority(
00363
const void *arg1,
00364
const void *arg2
00365 );
00366
00367
VOID
00368
IopFreeResourceRequirementsForAssignTable(
00369 IN
PIOP_RESOURCE_REQUEST AssignTable,
00370 IN
PIOP_RESOURCE_REQUEST AssignTableEnd
00371 );
00372
00373
VOID
00374
IopFreeReqAlternative (
00375 IN PREQ_ALTERNATIVE ReqAlternative
00376 );
00377
00378
VOID
00379
IopFreeReqList (
00380 IN PREQ_LIST ReqList
00381 );
00382
00383
NTSTATUS
00384
IopAssign(
00385 IN ULONG AssignTableCount,
00386 IN
PIOP_RESOURCE_REQUEST AssignTable,
00387 IN BOOLEAN Rebalance
00388 );
00389
00390
VOID
00391
IopBuildCmResourceLists(
00392 IN
PIOP_RESOURCE_REQUEST AssignTable,
00393 IN
PIOP_RESOURCE_REQUEST AssignTableEnd
00394 );
00395
00396
VOID
00397
IopBuildCmResourceList (
00398 IN
PIOP_RESOURCE_REQUEST AssignEntry
00399 );
00400
00401
NTSTATUS
00402
IopAssignInner(
00403 IN ULONG AssignTableCount,
00404 IN
PIOP_RESOURCE_REQUEST AssignTable,
00405 IN BOOLEAN Rebalance
00406 );
00407
00408
NTSTATUS
00409
IopPlacement(
00410 IN ARBITER_ACTION ArbiterAction,
00411 IN BOOLEAN Rebalance
00412 );
00413
00414
VOID
00415
IopAddReqDescsToArbiters (
00416 IN ULONG ReqDescCount,
00417 IN PREQ_DESC *ReqDescTable
00418 );
00419
00420
VOID
00421
IopRemoveReqDescsFromArbiters (
00422 ULONG ReqDescCount,
00423 PREQ_DESC *ReqDescTable
00424 );
00425
00426 BOOLEAN
00427
IopIsBestConfiguration(
00428 IN VOID
00429 );
00430
00431
VOID
00432
IopSaveCurrentConfiguration (
00433 IN VOID
00434 );
00435
00436
VOID
00437
IopRestoreBestConfiguration(
00438 IN VOID
00439 );
00440
00441 BOOLEAN
00442
IopFindResourceHandlerInfo(
00443 IN RESOURCE_HANDLER_TYPE HandlerType,
00444 IN
PDEVICE_NODE DeviceNode,
00445 IN UCHAR ResourceType,
00446 OUT PVOID *HandlerEntry
00447 );
00448
00449
NTSTATUS
00450
IopSetupArbiterAndTranslators(
00451 IN PREQ_DESC ReqDesc
00452 );
00453
00454
NTSTATUS
00455
IopParentToRawTranslation(
00456 IN OUT PREQ_DESC ReqDesc
00457 );
00458
00459
NTSTATUS
00460
IopChildToRootTranslation(
00461 IN
PDEVICE_NODE DeviceNode, OPTIONAL
00462 IN INTERFACE_TYPE InterfaceType,
00463 IN ULONG BusNumber,
00464 IN ARBITER_REQUEST_SOURCE ArbiterRequestSource,
00465 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
00466 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *Target
00467 );
00468
00469
NTSTATUS
00470
IopTranslateAndAdjustReqDesc(
00471 IN PREQ_DESC ReqDesc,
00472 IN
PPI_RESOURCE_TRANSLATOR_ENTRY TranslatorEntry,
00473 OUT PREQ_DESC *TranslatedReqDesc
00474 );
00475
00476
NTSTATUS
00477
IopCallArbiter(
00478
PPI_RESOURCE_ARBITER_ENTRY ArbiterEntry,
00479 ARBITER_ACTION Command,
00480 PVOID Input1,
00481 PVOID Input2,
00482 PVOID Input3
00483 );
00484
00485
VOID
00486
IopQueryRebalance (
00487 IN
PDEVICE_NODE DeviceNode,
00488 IN ULONG Phase,
00489 IN PULONG RebalanceCount,
00490 IN
PDEVICE_OBJECT **DeviceTable
00491 );
00492
00493
VOID
00494
IopQueryRebalanceWorker (
00495 IN
PDEVICE_NODE DeviceNode,
00496 IN ULONG RebalancePhase,
00497 IN PULONG RebalanceCount,
00498 IN
PDEVICE_OBJECT **DeviceTable
00499 );
00500
00501
VOID
00502
IopTestForReconfiguration (
00503 IN
PDEVICE_NODE DeviceNode,
00504 IN ULONG RebalancePhase,
00505 IN PULONG RebalanceCount,
00506 IN
PDEVICE_OBJECT **DeviceTable
00507 );
00508
00509
NTSTATUS
00510
IopPlacementForRebalance (
00511 IN
PDEVICE_NODE DeviceNode,
00512 IN ARBITER_ACTION ArbiterAction
00513 );
00514
00515
NTSTATUS
00516
IopArbitrateDeviceResources (
00517 IN
PDEVICE_NODE DeviceNode,
00518 IN ARBITER_ACTION ArbiterAction
00519 );
00520
00521
NTSTATUS
00522
IopRebalance (
00523 IN ULONG AssignTableCont,
00524 IN
PIOP_RESOURCE_REQUEST AssignTable
00525 );
00526
00527
NTSTATUS
00528
IopFindResourcesForArbiter (
00529 IN
PDEVICE_NODE DeviceNode,
00530 IN UCHAR ResourceType,
00531 OUT ULONG *Count,
00532 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *CmDesc
00533 );
00534
00535
VOID
00536
IopReleaseResourcesInternal (
00537 IN
PDEVICE_NODE DeviceNode
00538 );
00539
00540
VOID
00541
IopReleaseResources (
00542 IN
PDEVICE_NODE DeviceNode
00543 );
00544
00545
NTSTATUS
00546
IopRestoreResourcesInternal (
00547 IN
PDEVICE_NODE DeviceNode
00548 );
00549
00550
VOID
00551
IopSetLegacyDeviceInstance (
00552 IN
PDRIVER_OBJECT DriverObject,
00553 IN
PDEVICE_NODE DeviceNode
00554 );
00555
00556 PCM_RESOURCE_LIST
00557
IopCombineLegacyResources (
00558 IN
PDEVICE_NODE DeviceNode
00559 );
00560
00561
NTSTATUS
00562
IopPlacementForReservation(
00563 VOID
00564 );
00565
00566
NTSTATUS
00567
IopReserve(
00568 IN PREQ_LIST ReqList
00569 );
00570
00571
NTSTATUS
00572
IopReserveBootResourcesInternal (
00573 IN ARBITER_REQUEST_SOURCE ArbiterRequestSource,
00574 IN
PDEVICE_OBJECT DeviceObject,
00575 IN PCM_RESOURCE_LIST BootResources
00576 );
00577
00578 BOOLEAN
00579
IopNeedToReleaseBootResources(
00580 IN
PDEVICE_NODE DeviceNode,
00581 IN PCM_RESOURCE_LIST AllocatedResources
00582 );
00583
00584
VOID
00585
IopReleaseFilteredBootResources(
00586 IN
PIOP_RESOURCE_REQUEST AssignTable,
00587 IN
PIOP_RESOURCE_REQUEST AssignTableEnd
00588 );
00589
00590
#if DBG_SCOPE
00591
VOID
00592
IopDumpResourceRequirementsList(
00593 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources
00594 );
00595
00596
VOID
00597
IopDumpResourceDescriptor (
00598 IN PUCHAR Indent,
00599 IN PIO_RESOURCE_DESCRIPTOR Desc
00600 );
00601
00602
#endif
00603
00604
#if DBG_SCOPE
00605
VOID
00606
IopCheckDataStructures (
00607 IN
PDEVICE_NODE DeviceNode
00608 );
00609
00610
VOID
00611
IopCheckDataStructuresWorker (
00612 IN
PDEVICE_NODE Device
00613 );
00614
00615
#endif
00616
00617
NTSTATUS
00618
IopQueryConflictListInternal(
00619
PDEVICE_OBJECT PhysicalDeviceObject,
00620 IN PCM_RESOURCE_LIST ResourceList,
00621 IN ULONG ResourceListSize,
00622 OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList,
00623 IN ULONG ConflictListSize,
00624 IN ULONG Flags
00625 );
00626
00627
NTSTATUS
00628
IopQueryConflictFillConflicts(
00629
PDEVICE_OBJECT PhysicalDeviceObject,
00630 IN ULONG ConflictCount,
00631 IN
PARBITER_CONFLICT_INFO ConflictInfoList,
00632 OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList,
00633 IN ULONG ConflictListSize,
00634 IN ULONG Flags
00635 );
00636
00637
NTSTATUS
00638
IopQueryConflictFillString(
00639 IN
PDEVICE_OBJECT DeviceObject,
00640 IN PWSTR Buffer,
00641 IN OUT PULONG Length,
00642 IN OUT PULONG Flags
00643 );
00644
00645 BOOLEAN
00646
IopEliminateBogusConflict(
00647 IN
PDEVICE_OBJECT PhysicalDeviceObject,
00648 IN
PDEVICE_OBJECT ConflictDeviceObject
00649 );
00650
00651
00652
#ifdef ALLOC_PRAGMA
00653
#pragma alloc_text(PAGE, IopAllocateResources)
00654
#pragma alloc_text(PAGE, IopGetResourceRequirementsForAssignTable)
00655
#pragma alloc_text(PAGE, IopResourceRequirementsListToReqList)
00656
#pragma alloc_text(PAGE, IopComparePriority)
00657
#pragma alloc_text(PAGE, IopRearrangeReqList)
00658
#pragma alloc_text(PAGE, IopRearrangeAssignTable)
00659
#pragma alloc_text(PAGE, IopFreeResourceRequirementsForAssignTable)
00660
#pragma alloc_text(PAGE, IopFreeReqList)
00661
#pragma alloc_text(PAGE, IopFreeReqAlternative)
00662
#pragma alloc_text(PAGE, IopAssign)
00663
#pragma alloc_text(PAGE, IopBuildCmResourceLists)
00664
#pragma alloc_text(PAGE, IopBuildCmResourceList)
00665
#pragma alloc_text(PAGE, IopAssignInner)
00666
#pragma alloc_text(PAGE, IopPlacement)
00667
#pragma alloc_text(PAGE, IopAddReqDescsToArbiters)
00668
#pragma alloc_text(PAGE, IopRemoveReqDescsFromArbiters)
00669
#pragma alloc_text(PAGE, IopIsBestConfiguration)
00670
#pragma alloc_text(PAGE, IopSaveCurrentConfiguration)
00671
#pragma alloc_text(PAGE, IopRestoreBestConfiguration)
00672
#pragma alloc_text(PAGE, IopFindResourceHandlerInfo)
00673
#pragma alloc_text(PAGE, IopSetupArbiterAndTranslators)
00674
#pragma alloc_text(PAGE, IopParentToRawTranslation)
00675
#pragma alloc_text(PAGE, IopChildToRootTranslation)
00676
#pragma alloc_text(PAGE, IopTranslateAndAdjustReqDesc)
00677
#pragma alloc_text(PAGE, IopCallArbiter)
00678
#pragma alloc_text(PAGE, IopQueryRebalance)
00679
#pragma alloc_text(PAGE, IopTestForReconfiguration)
00680
#pragma alloc_text(PAGE, IopPlacementForRebalance)
00681
#pragma alloc_text(PAGE, IopArbitrateDeviceResources)
00682
#pragma alloc_text(PAGE, IopRebalance)
00683
#pragma alloc_text(PAGE, IopFindResourcesForArbiter)
00684
00685
#pragma alloc_text(PAGE, IopFindLegacyDeviceNode)
00686
#pragma alloc_text(PAGE, IopRemoveLegacyDeviceNode)
00687
#pragma alloc_text(PAGE, IopFindBusDeviceNode)
00688
#pragma alloc_text(PAGE, IopFindBusDeviceNodeInternal)
00689
#pragma alloc_text(PAGE, IopDuplicateDetection)
00690
#pragma alloc_text(PAGE, IopReleaseResourcesInternal)
00691
#pragma alloc_text(PAGE, IopRestoreResourcesInternal)
00692
#pragma alloc_text(PAGE, IopSetLegacyDeviceInstance)
00693
#pragma alloc_text(PAGE, IopCombineLegacyResources)
00694
#pragma alloc_text(PAGE, IopReserve)
00695
#pragma alloc_text(PAGE, IopPlacementForReservation)
00696
#pragma alloc_text(PAGE, IopAllocateBootResources)
00697
#pragma alloc_text(PAGE, IopReserveBootResourcesInternal)
00698
#pragma alloc_text(PAGE, IopReleaseResources)
00699
#pragma alloc_text(PAGE, IopReallocateResources)
00700
#pragma alloc_text(PAGE, IopReleaseFilteredBootResources)
00701
#pragma alloc_text(PAGE, IopNeedToReleaseBootResources)
00702
#pragma alloc_text(PAGE, IopQueryConflictList)
00703
#pragma alloc_text(PAGE, IopQueryConflictListInternal)
00704
#pragma alloc_text(PAGE, IopQueryConflictFillConflicts)
00705
#pragma alloc_text(PAGE, IopQueryConflictFillString)
00706
#pragma alloc_text(PAGE, IopEliminateBogusConflict)
00707
#pragma alloc_text(PAGE, IopCreateCmResourceList)
00708
#pragma alloc_text(PAGE, IopCombineCmResourceList)
00709
#pragma alloc_text(INIT, IopReserveLegacyBootResources)
00710
#pragma alloc_text(INIT, IopReserveBootResources)
00711
#if DBG_SCOPE
00712
#pragma alloc_text(PAGE, IopCheckDataStructures)
00713
#pragma alloc_text(PAGE, IopCheckDataStructuresWorker)
00714
#pragma alloc_text(PAGE, IopDumpResourceRequirementsList)
00715
#pragma alloc_text(PAGE, IopDumpResourceDescriptor)
00716
#endif
00717
#endif
00718
00719
NTSTATUS
00720 IopAllocateResources(
00721 IN PULONG DeviceCountP,
00722 IN OUT
PIOP_RESOURCE_REQUEST *AssignTablePP,
00723 IN BOOLEAN Locked,
00724 IN BOOLEAN BootConfigsOK
00725 )
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 {
00752
PIOP_RESOURCE_REQUEST AssignTable;
00753
PIOP_RESOURCE_REQUEST AssignTableEnd;
00754
PIOP_RESOURCE_REQUEST AssignTableTail;
00755
PIOP_RESOURCE_REQUEST AssignEntry;
00756
PIOP_RESOURCE_REQUEST AssignEntryOriginal;
00757 ULONG AssignTableCount;
00758 ULONG DeviceCount;
00759
NTSTATUS Status;
00760 BOOLEAN FreeAssignTable;
00761 BOOLEAN tryRebalance;
00762
00763
PAGED_CODE();
00764
00765 DeviceCount = *DeviceCountP;
00766 FreeAssignTable =
FALSE;
00767 tryRebalance =
TRUE;
00768 AssignTable = *AssignTablePP;
00769 AssignTableEnd = AssignTable + DeviceCount;
00770
00771
00772
00773
00774
00775
00776
00777
if ((DeviceCount == 1) && (AssignTable->
Flags &
IOP_ASSIGN_NO_REBALANCE)) {
00778
00779 tryRebalance =
FALSE;
00780
00781 }
00782
00783
00784
00785
00786
00787
00788
if (!Locked) {
00789
00790
KeEnterCriticalRegion();
00791
00792
Status =
KeWaitForSingleObject( &
IopRegistrySemaphore,
00793
DelayExecution,
00794
KernelMode,
00795
FALSE,
00796
NULL );
00797
00798
if (!
NT_SUCCESS(
Status)) {
00799
00800
DebugMessage(
DUMP_ERROR, (
"IopAllocateResources: Get RegistrySemaphore failed. Status %x\n",
Status));
00801
KeLeaveCriticalRegion();
00802
return Status;
00803
00804 }
00805 }
00806
00807
00808
00809
00810
00811
Status =
IopGetResourceRequirementsForAssignTable(AssignTable, AssignTableEnd, &DeviceCount);
00812
if (DeviceCount == 0) {
00813
00814
DebugMessage(
DUMP_INFO, (
"IopAllocateResources: Get Requirements for Assign Table found nothing. status %x\n",
Status));
00815
00816
if (!Locked) {
00817
00818
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
00819
KeLeaveCriticalRegion();
00820
00821 }
00822
00823
return Status;
00824
00825 }
00826
00827
00828
00829
00830
00831
if (BootConfigsOK) {
00832
00833
if (!
IopBootConfigsReserved) {
00834
00835
00836
00837
00838
00839
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
00840
00841
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)AssignEntry->
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
00842
00843
if (deviceNode->
Flags &
DNF_HAS_BOOT_CONFIG) {
00844
00845
break;
00846 }
00847 }
00848
00849
if (AssignEntry != AssignTableEnd) {
00850
00851
00852
00853
00854
00855
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
00856
00857
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)AssignEntry->
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
00858
00859
if ( !(AssignEntry->
Flags &
IOP_ASSIGN_IGNORE) &&
00860 !(deviceNode->
Flags &
DNF_HAS_BOOT_CONFIG) &&
00861 AssignEntry->
ResourceRequirements &&
00862 AssignEntry->
AllocationType !=
ArbiterRequestPnpDetected) {
00863
00864 DeviceCount--;
00865
DebugMessage(
DUMP_INFO, (
"Delaying non BOOT config device %ws...\n", deviceNode->
InstancePath.Buffer));
00866 AssignEntry->
Status = STATUS_RETRY;
00867 AssignEntry->
Flags |=
IOP_ASSIGN_IGNORE;
00868
IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1);
00869
00870 }
00871 }
00872 }
00873
00874
if (DeviceCount == 0) {
00875
00876
if (!Locked) {
00877
00878
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
00879
KeLeaveCriticalRegion();
00880
00881 }
00882
00883
return Status;
00884 }
00885 }
00886
00887
00888
00889
00890
00891
if (DeviceCount != *DeviceCountP) {
00892
00893
00894
00895
00896
00897 AssignTable = (
PIOP_RESOURCE_REQUEST)
ExAllocatePoolAT(
PagedPool,
00898
sizeof(
IOP_RESOURCE_REQUEST) * DeviceCount);
00899
if (AssignTable ==
NULL) {
00900
00901
IopFreeResourceRequirementsForAssignTable(*AssignTablePP, AssignTableEnd);
00902
00903
if (!Locked) {
00904
00905
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
00906
KeLeaveCriticalRegion();
00907
00908 }
00909
00910
return STATUS_INSUFFICIENT_RESOURCES;
00911 }
00912
00913 FreeAssignTable =
TRUE;
00914
00915
00916
00917
00918
00919 AssignEntryOriginal = *AssignTablePP;
00920 AssignTableEnd = AssignTable + DeviceCount;
00921
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd;) {
00922
00923
if (!(AssignEntryOriginal->
Flags &
IOP_ASSIGN_IGNORE)) {
00924
00925 *AssignEntry = *AssignEntryOriginal;
00926 AssignEntry++;
00927
00928 }
00929 AssignEntryOriginal++;
00930 }
00931 }
00932
00933 }
else {
00934
00935
00936
00937
00938
00939
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
00940
00941
if ( !(AssignEntry->
Flags &
IOP_ASSIGN_IGNORE) &&
00942 AssignEntry->
ResourceRequirements) {
00943
00944
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)AssignEntry->
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
00945
00946
DebugMessage(
DUMP_INFO, (
"Delaying resources requiring device %ws...\n", deviceNode->
InstancePath.Buffer));
00947
IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1);
00948 AssignEntry->
Status = STATUS_RETRY;
00949
00950 }
00951 }
00952
00953
00954
00955
00956
00957
if (!Locked) {
00958
00959
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
00960
KeLeaveCriticalRegion();
00961
00962 }
00963
00964
return Status;
00965 }
00966 AssignTableCount = (ULONG)(AssignTableEnd - AssignTable);
00967
ASSERT(AssignTableCount == DeviceCount);
00968
00969
00970
00971
00972
00973
IopRearrangeAssignTable(AssignTable, DeviceCount);
00974
00975
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
00976
00977
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)AssignEntry->
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
00978
00979
DebugMessage(
DUMP_INFO, (
"Pnpres: Trying to allocate resources for %ws.\n", deviceNode->
InstancePath.Buffer));
00980
00981
Status =
IopAssignInner(1, AssignEntry,
FALSE);
00982
if (
NT_SUCCESS(
Status)) {
00983
00984
IopBuildCmResourceLists(AssignEntry, AssignEntry + 1);
00985
if (AssignEntry->
AllocationType ==
ArbiterRequestPnpEnumerated) {
00986
00987
IopReleaseFilteredBootResources(AssignEntry, AssignEntry + 1);
00988 }
00989 }
else if (
Status == STATUS_INSUFFICIENT_RESOURCES) {
00990
00991
DebugMessage(
DUMP_ERROR, (
"IopAllocateResource: Failed to allocate Pool.\n"));
00992
break;
00993
00994 }
else if (tryRebalance) {
00995
00996
DebugMessage(
DUMP_INFO, (
"IopAllocateResources: Initiating REBALANCE...\n"));
00997
00998 deviceNode->
Flags |=
DNF_NEEDS_REBALANCE;
00999
Status =
IopRebalance(1, AssignEntry);
01000 deviceNode->
Flags &= ~
DNF_NEEDS_REBALANCE;
01001
if (!
NT_SUCCESS(
Status)) {
01002 AssignEntry->
Status = STATUS_CONFLICTING_ADDRESSES;
01003 }
01004 }
else {
01005 AssignEntry->
Status = STATUS_CONFLICTING_ADDRESSES;
01006 }
01007 }
01008
01009
01010
01011
01012
01013
01014
for (; AssignEntry < AssignTableEnd; AssignEntry++) {
01015
01016 AssignEntry->
Status = STATUS_RETRY;
01017 }
01018
01019
IopFreeResourceRequirementsForAssignTable(AssignTable, AssignTableEnd);
01020
01021
01022
01023
01024
01025
if (!Locked) {
01026
KeReleaseSemaphore( &
IopRegistrySemaphore, 0, 1,
FALSE );
01027
KeLeaveCriticalRegion( );
01028 }
01029
01030
01031
01032
01033
01034
if (FreeAssignTable) {
01035 AssignEntryOriginal = *AssignTablePP;
01036
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd;) {
01037
if (AssignEntryOriginal->
Flags & (
IOP_ASSIGN_IGNORE |
IOP_ASSIGN_RETRY)) {
01038 AssignEntryOriginal++;
01039
continue;
01040 }
01041 *AssignEntryOriginal = *AssignEntry;
01042 AssignEntry++;
01043 AssignEntryOriginal++;
01044 }
01045
ASSERT(AssignEntryOriginal <= *AssignTablePP + *DeviceCountP);
01046
ExFreePool(AssignTable);
01047 }
01048
01049 AssignEntry = *AssignTablePP;
01050
while (AssignEntry < *AssignTablePP + *DeviceCountP) {
01051
if (AssignEntry->
Flags & (
IOP_ASSIGN_IGNORE |
IOP_ASSIGN_RETRY)) {
01052 AssignEntry++;
01053
continue;
01054 }
01055
if ((AssignEntry->
Flags &
IOP_ASSIGN_EXCLUDE) || AssignEntry->
ResourceAssignment ==
NULL) {
01056
01057 AssignEntry->
Status = STATUS_CONFLICTING_ADDRESSES;
01058 }
01059 AssignEntry++;
01060 }
01061
01062
return Status;
01063 }
01064
01065
NTSTATUS
01066 IopGetResourceRequirementsForAssignTable(
01067 IN
PIOP_RESOURCE_REQUEST AssignTable,
01068 IN
PIOP_RESOURCE_REQUEST AssignTableEnd,
01069 OUT PULONG DeviceCount
01070 )
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 {
01092
NTSTATUS Status, FinalStatus = STATUS_UNSUCCESSFUL;
01093
PIOP_RESOURCE_REQUEST AssignEntry;
01094
PDEVICE_OBJECT PhysicalDevice;
01095
PDEVICE_NODE DeviceNode;
01096 ULONG Length,
Count = 0;
01097
01098
PAGED_CODE();
01099
01100
01101
01102
01103
01104
01105
01106
01107
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; ++AssignEntry) {
01108
01109 AssignEntry->
ReqList =
NULL;
01110
if (AssignEntry->
Flags &
IOP_ASSIGN_IGNORE) {
01111 FinalStatus = STATUS_SUCCESS;
01112
continue;
01113 }
01114
01115 AssignEntry->
ResourceAssignment =
NULL;
01116 AssignEntry->
TranslatedResourceAssignment =
NULL;
01117 PhysicalDevice = AssignEntry->
PhysicalDevice;
01118 DeviceNode = (
PDEVICE_NODE)PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
01119
01120
if (DeviceNode->
Flags &
DNF_RESOURCE_REQUIREMENTS_CHANGED) {
01121
if (DeviceNode->
ResourceRequirements) {
01122
ExFreePool(DeviceNode->
ResourceRequirements);
01123 DeviceNode->
ResourceRequirements =
NULL;
01124
01125
01126
01127
01128
01129
01130 AssignEntry->
Flags |=
IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG;
01131 DeviceNode->
Flags &= ~
DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED;
01132
01133 }
01134 }
01135
01136
if (!AssignEntry->
ResourceRequirements) {
01137
if (DeviceNode->
ResourceRequirements &&
01138 !(DeviceNode->
Flags &
DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED)) {
01139
DebugMessage(
DUMP_DETAIL, (
"Pnpres: Resource requirements list already exists for %ws\n", DeviceNode->
InstancePath.Buffer));
01140 AssignEntry->
ResourceRequirements = DeviceNode->
ResourceRequirements;
01141 AssignEntry->
AllocationType =
ArbiterRequestPnpEnumerated;
01142 }
else {
01143
DebugMessage(
DUMP_INFO,(
"Pnpres: Query Resource requirements list for %ws...\n", DeviceNode->
InstancePath.Buffer));
01144
Status =
IopQueryDeviceResources (PhysicalDevice,
01145
QUERY_RESOURCE_REQUIREMENTS,
01146 &AssignEntry->
ResourceRequirements,
01147 &Length
01148 );
01149
if (!
NT_SUCCESS(
Status)) {
01150 AssignEntry->
Flags |=
IOP_ASSIGN_IGNORE;
01151 AssignEntry->
Status =
Status;
01152
continue;
01153 }
else if (AssignEntry->
ResourceRequirements ==
NULL) {
01154
01155
01156
01157
01158
01159
01160 AssignEntry->
Flags |=
IOP_ASSIGN_IGNORE;
01161 AssignEntry->
Status =
Status;
01162
continue;
01163 }
01164
if (DeviceNode->
ResourceRequirements) {
01165
ExFreePool(DeviceNode->
ResourceRequirements);
01166 DeviceNode->
Flags &= ~
DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED;
01167 }
01168 DeviceNode->
ResourceRequirements = AssignEntry->
ResourceRequirements;
01169 }
01170 }
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
if (AssignEntry->
Flags &
IOP_ASSIGN_KEEP_CURRENT_CONFIG) {
01181 PIO_RESOURCE_REQUIREMENTS_LIST filteredList;
01182 BOOLEAN exactMatch;
01183
01184
Status =
IopFilterResourceRequirementsList (
01185 AssignEntry->
ResourceRequirements,
01186 DeviceNode->
ResourceList,
01187 &filteredList,
01188 &exactMatch
01189 );
01190
if (
NT_SUCCESS(
Status)) {
01191
01192
01193
01194
01195
01196
01197 AssignEntry->
ResourceRequirements = filteredList;
01198 }
else {
01199 AssignEntry->
Flags &= ~
IOP_ASSIGN_KEEP_CURRENT_CONFIG;
01200 }
01201 }
01202
01203
#if DBG_SCOPE
01204
if (
PnpResDebugLevel &
DUMP_INFO) {
01205
IopDumpResourceRequirementsList(AssignEntry->
ResourceRequirements);
01206 }
01207
#endif
01208
01209
01210
01211
01212
01213
Status =
IopResourceRequirementsListToReqList(
01214 AssignEntry->
AllocationType,
01215 AssignEntry->
ResourceRequirements,
01216 PhysicalDevice,
01217 &AssignEntry->
ReqList);
01218
01219
if (!
NT_SUCCESS(
Status) || AssignEntry->
ReqList ==
NULL) {
01220 AssignEntry->
Flags |=
IOP_ASSIGN_IGNORE;
01221 AssignEntry->
Status =
Status;
01222
continue;
01223 }
else {
01224
PREQ_LIST ReqList;
01225
01226 ReqList = (
PREQ_LIST)AssignEntry->
ReqList;
01227 ReqList->AssignEntry = AssignEntry;
01228
01229
01230
01231
01232
01233
01234
IopRearrangeReqList(ReqList);
01235
if (ReqList->ReqBestAlternative ==
NULL) {
01236
01237 AssignEntry->
Flags |=
IOP_ASSIGN_IGNORE;
01238 AssignEntry->
Status = STATUS_DEVICE_CONFIGURATION_ERROR;
01239
IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1);
01240
continue;
01241
01242 }
else if (ReqList->ReqAlternativeCount < 3) {
01243
01244 AssignEntry->
Priority = 0;
01245
01246 }
else {
01247
01248 AssignEntry->
Priority = ReqList->ReqAlternativeCount;
01249
01250 }
01251 }
01252
01253 AssignEntry->
Status = STATUS_SUCCESS;
01254
Count++;
01255
01256
01257
01258
01259
01260 FinalStatus = STATUS_SUCCESS;
01261 }
01262 *DeviceCount =
Count;
01263
return FinalStatus;
01264 }
01265
01266
NTSTATUS
01267 IopResourceRequirementsListToReqList(
01268 IN ARBITER_REQUEST_SOURCE AllocationType,
01269 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources,
01270 IN
PDEVICE_OBJECT PhysicalDevice,
01271 OUT PVOID *ResReqList
01272 )
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 {
01297
NTSTATUS status;
01298 PIO_RESOURCE_LIST IoResourceList = IoResources->List;
01299 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor, BaseDescriptor, firstDescriptor;
01300 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptorEnd;
01301 LONG IoResourceListCount = (LONG) IoResources->AlternativeLists;
01302 PUCHAR CoreEnd = (PUCHAR) IoResources + IoResources->ListSize;
01303 ULONG ReqAlternativeCount = IoResourceListCount;
01304 ULONG ReqDescAlternativeCount = 0;
01305 ULONG AlternativeDescriptorCount = 0;
01306
PREQ_LIST ReqList;
01307 BOOLEAN NoAlternativeDescriptor;
01308 INTERFACE_TYPE interfaceType;
01309 ULONG busNumber;
01310
NTSTATUS failureStatus = STATUS_UNSUCCESSFUL;
01311
NTSTATUS finalStatus = STATUS_SUCCESS;
01312
01313
PAGED_CODE();
01314
01315 *ResReqList =
NULL;
01316
01317
01318
01319
01320
01321
if (IoResourceListCount == 0) {
01322
DebugMessage(
DUMP_INFO, (
"PnpRes: No ResReqList to convert to ReqList\n"));
01323
return STATUS_SUCCESS;
01324 }
01325
01326
01327
01328
01329
01330
01331
01332
01333
while (--IoResourceListCount >= 0) {
01334
01335 IoResourceDescriptor = firstDescriptor = IoResourceList->Descriptors;
01336 IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count;
01337
01338
if (IoResourceDescriptor == IoResourceDescriptorEnd) {
01339
01340
01341
01342
01343
01344
return STATUS_SUCCESS;
01345 }
01346
01347
01348
01349
01350
01351
if ((PUCHAR) IoResourceDescriptor > CoreEnd) {
01352
01353
01354
01355
01356
01357
01358
DebugMessage(
DUMP_ERROR, (
"PnpRes: Invalid ResReqList\n"));
01359
goto InvalidParameter;
01360 }
01361
01362
if (IoResourceDescriptor > IoResourceDescriptorEnd ||
01363 (PUCHAR) IoResourceDescriptorEnd > CoreEnd) {
01364
01365
01366
01367
01368
01369
01370
DebugMessage(
DUMP_ERROR, (
"PnpRes: Invalid ResReqList\n"));
01371
goto InvalidParameter;
01372 }
01373
01374
if (IoResourceDescriptor->Type == CmResourceTypeConfigData) {
01375 IoResourceDescriptor++;
01376 firstDescriptor++;
01377 }
01378 NoAlternativeDescriptor =
TRUE;
01379
while (IoResourceDescriptor < IoResourceDescriptorEnd) {
01380
switch (IoResourceDescriptor->Type) {
01381
case CmResourceTypeConfigData:
01382
#if DBG_SCOPE
01383
if (
PnpResDebugLevel &
DUMP_ERROR) {
01384
DbgPrint(
"PnPRes: Invalid ResReq list !!!\n");
01385
DbgPrint(
" ConfigData descriptors are per-LogConf and\n");
01386
DbgPrint(
" should be at the beginning of an AlternativeList\n");
01387
ASSERT(0);
01388 }
01389
#endif
01390
goto InvalidParameter;
01391
01392
case CmResourceTypeDevicePrivate:
01393
while (IoResourceDescriptor < IoResourceDescriptorEnd &&
01394 IoResourceDescriptor->Type == CmResourceTypeDevicePrivate) {
01395
if (IoResourceDescriptor == firstDescriptor) {
01396
#if DBG_SCOPE
01397
if (
PnpResDebugLevel &
DUMP_ERROR) {
01398
DbgPrint(
"PnPRes: Invalid ResReq list !!!\n");
01399
DbgPrint(
" The first descriptor of a LogConf can not be\n");
01400
DbgPrint(
" a DevicePrivate descriptor.\n");
01401
ASSERT(0);
01402 }
01403
#endif
01404
goto InvalidParameter;
01405 }
01406 ReqDescAlternativeCount++;
01407 IoResourceDescriptor++;
01408 }
01409 NoAlternativeDescriptor =
TRUE;
01410
break;
01411
01412
default:
01413
01414 ++ReqDescAlternativeCount;
01415
01416
01417
01418
01419
01420
01421
if ((IoResourceDescriptor->Type & CmResourceTypeNonArbitrated) ||
01422 (IoResourceDescriptor->Type == CmResourceTypeNull)) {
01423
01424
if (IoResourceDescriptor->Type ==
CmResourceTypeReserved) {
01425 --ReqDescAlternativeCount;
01426 }
01427 IoResourceDescriptor->Option = IO_RESOURCE_PREFERRED;
01428 IoResourceDescriptor++;
01429 NoAlternativeDescriptor =
TRUE;
01430
break;
01431 }
01432
if (IoResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
01433
if (NoAlternativeDescriptor) {
01434
#if DBG_SCOPE
01435
if (
PnpResDebugLevel &
DUMP_ERROR) {
01436
DbgPrint(
"PnPRes: Invalid ResReq list !!!\n");
01437
DbgPrint(
" Alternative descriptor without Default or Preferred descriptor.\n");
01438
ASSERT(0);
01439 }
01440
#endif
01441
goto InvalidParameter;
01442 }
01443 ++AlternativeDescriptorCount;
01444 }
else {
01445 NoAlternativeDescriptor =
FALSE;
01446 }
01447 IoResourceDescriptor++;
01448
break;
01449 }
01450 }
01451
ASSERT(IoResourceDescriptor == IoResourceDescriptorEnd);
01452 IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd;
01453 }
01454
01455
01456
01457
01458
01459
01460
01461 {
01462 ULONG ReqDescCount = ReqDescAlternativeCount - AlternativeDescriptorCount;
01463 PUCHAR PoolStart;
01464 ULONG PoolSize;
01465
IOP_POOL OuterPool;
01466
IOP_POOL ReqAlternativePool;
01467
IOP_POOL ReqDescPool;
01468
01469
PREQ_ALTERNATIVE ReqAlternative;
01470
PREQ_ALTERNATIVE *ReqAlternativePP;
01471
#if DBG
01472
PREQ_ALTERNATIVE *ReqAlternativeEndPP;
01473
#endif
01474
PREQ_DESC ReqDesc;
01475
PREQ_DESC *ReqDescPP;
01476 ULONG ReqAlternativeIndex;
01477 ULONG ReqDescIndex;
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489 {
01490 ULONG ReqListPoolSize =
01491 (FIELD_OFFSET(REQ_LIST, ReqAlternativeTable) +
01492
sizeof(PVOID) * ReqAlternativeCount +
STRUCTURE_ALIGNMENT - 1) &
01493 ~(
STRUCTURE_ALIGNMENT - 1);
01494
01495 ULONG ReqAlternativePoolSize = (ReqAlternativeCount *
01496 (FIELD_OFFSET(REQ_ALTERNATIVE, ReqDescTable) +
01497 +
sizeof(PVOID) * ReqDescCount +
STRUCTURE_ALIGNMENT - 1))
01498 & ~(
STRUCTURE_ALIGNMENT - 1);
01499
01500 ULONG ReqDescPoolSize = (ReqDescCount * (
sizeof(REQ_DESC) +
STRUCTURE_ALIGNMENT - 1))
01501 & ~(
STRUCTURE_ALIGNMENT - 1);
01502
01503 PoolSize = ReqListPoolSize + ReqAlternativePoolSize + ReqDescPoolSize;
01504
01505 PoolStart =
ExAllocatePoolRD(
PagedPool, PoolSize);
01506
if (!PoolStart) {
01507
return STATUS_INSUFFICIENT_RESOURCES;
01508 }
01509
IopInitPool(&OuterPool, PoolStart, PoolSize);
01510
01511
01512
01513
01514
01515
IopAllocPoolAligned(&ReqList, &OuterPool, ReqListPoolSize);
01516
01517
IopAllocPoolAligned(&PoolStart, &OuterPool, ReqAlternativePoolSize);
01518
IopInitPool(&ReqAlternativePool, PoolStart, ReqAlternativePoolSize);
01519
01520
IopAllocPoolAligned(&PoolStart, &OuterPool, ReqDescPoolSize);
01521
IopInitPool(&ReqDescPool, PoolStart, ReqDescPoolSize);
01522 }
01523
01524
01525
01526
01527
01528 ReqAlternativePP = ReqList->ReqAlternativeTable;
01529 RtlZeroMemory(ReqAlternativePP, ReqAlternativeCount *
sizeof(
PREQ_ALTERNATIVE));
01530
#if DBG
01531
ReqAlternativeEndPP = ReqAlternativePP + ReqAlternativeCount;
01532
#endif
01533
ReqList->ReqAlternativeCount = ReqAlternativeCount;
01534 ReqList->PhysicalDevice = PhysicalDevice;
01535 ReqList->InterfaceType = IoResources->InterfaceType;
01536
if (ReqList->InterfaceType == InterfaceTypeUndefined) {
01537 ReqList->InterfaceType =
PnpDefaultInterfaceType;
01538 }
01539
01540 ReqList->BusNumber = IoResources->BusNumber;
01541 ReqList->SelectedAlternative =
NULL;
01542 ReqAlternativeIndex = 0;
01543
01544 interfaceType = IoResources->InterfaceType;
01545
if (interfaceType == InterfaceTypeUndefined) {
01546 interfaceType =
PnpDefaultInterfaceType;
01547 }
01548 busNumber = IoResources->BusNumber;
01549 IoResourceList = IoResources->List;
01550 IoResourceListCount = IoResources->AlternativeLists;
01551
01552
while (--IoResourceListCount >= 0) {
01553 ULONG arbiterFlag;
01554
01555 IoResourceDescriptor = IoResourceList->Descriptors;
01556 IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count;
01557
01558
01559
01560
01561
01562
IopAllocPoolAligned(&ReqAlternative, &ReqAlternativePool, FIELD_OFFSET(REQ_ALTERNATIVE, ReqDescTable));
01563 ReqAlternative->ReqList = ReqList;
01564 ReqAlternative->ReqAlternativeIndex = ReqAlternativeIndex++;
01565
ASSERT(ReqAlternativePP < ReqAlternativeEndPP);
01566 *ReqAlternativePP++ = ReqAlternative;
01567 ReqAlternative->ReqDescCount = 0;
01568 ReqAlternative->ReqDescTableEnd = ReqAlternative->ReqDescTable;
01569
01570
01571
01572
01573
01574
01575
if (IoResourceDescriptor->Type == CmResourceTypeConfigData) {
01576 ReqAlternative->Priority = IoResourceDescriptor->u.ConfigData.Priority;
01577 IoResourceDescriptor++;
01578 }
else {
01579 ReqAlternative->Priority = LCPRI_NORMAL;
01580 }
01581
01582
if (ReqAlternative->Priority == LCPRI_BOOTCONFIG) {
01583 arbiterFlag =
ARBITER_FLAG_BOOT_CONFIG;
01584 }
else {
01585 arbiterFlag = 0;
01586 }
01587
01588 ReqDescPP = ReqAlternative->ReqDescTable;
01589 ReqDescIndex = 0;
01590
01591
while (IoResourceDescriptor < IoResourceDescriptorEnd) {
01592
01593
PARBITER_LIST_ENTRY ArbiterListEntry;
01594
01595
if (IoResourceDescriptor->Type ==
CmResourceTypeReserved) {
01596 interfaceType = IoResourceDescriptor->u.DevicePrivate.Data[0];
01597
if (interfaceType == InterfaceTypeUndefined) {
01598 interfaceType =
PnpDefaultInterfaceType;
01599 }
01600 busNumber = IoResourceDescriptor->u.DevicePrivate.Data[1];
01601 IoResourceDescriptor++;
01602 }
else {
01603
IopAllocPoolAligned(&ReqDesc, &ReqDescPool,
sizeof(REQ_DESC));
01604 ReqDesc->ArbitrationRequired =
01605 (IoResourceDescriptor->Type & CmResourceTypeNonArbitrated ||
01606 IoResourceDescriptor->Type == CmResourceTypeNull) ?
FALSE :
TRUE;
01607 ReqDesc->ReqAlternative = ReqAlternative;
01608 ReqDesc->ReqDescIndex = ReqDescIndex++;
01609 ReqDesc->DevicePrivateCount = 0;
01610 ReqDesc->DevicePrivate =
NULL;
01611 ReqDesc->InterfaceType = interfaceType;
01612 ReqDesc->BusNumber = busNumber;
01613
01614
IopAllocPool(&PoolStart, &ReqAlternativePool,
sizeof(PVOID));
01615
01616
ASSERT(PoolStart == (PUCHAR) ReqDescPP);
01617
01618 *ReqDescPP++ = ReqDesc;
01619 ++ReqAlternative->ReqDescCount;
01620 ++ReqAlternative->ReqDescTableEnd;
01621
01622 ReqDesc->TranslatedReqDesc = ReqDesc;
01623
01624 ArbiterListEntry = &ReqDesc->AlternativeTable;
01625 InitializeListHead(&ArbiterListEntry->
ListEntry);
01626 ArbiterListEntry->
AlternativeCount = 0;
01627 ArbiterListEntry->
Alternatives = IoResourceDescriptor;
01628 ArbiterListEntry->
PhysicalDeviceObject = PhysicalDevice;
01629 ArbiterListEntry->
RequestSource = AllocationType;
01630 ArbiterListEntry->
Flags = arbiterFlag;
01631 ArbiterListEntry->
WorkSpace = 0;
01632 ArbiterListEntry->
InterfaceType = interfaceType;
01633 ArbiterListEntry->
SlotNumber = IoResources->SlotNumber;
01634 ArbiterListEntry->
BusNumber = IoResources->BusNumber;
01635 ArbiterListEntry->
Assignment = &ReqDesc->Allocation;
01636 ArbiterListEntry->
Result =
ArbiterResultUndefined;
01637
01638
if (ReqDesc->ArbitrationRequired) {
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648 ReqDesc->Allocation.Type = CmResourceTypeMaximum;
01649
01650
ASSERT((IoResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) == 0);
01651
01652 ArbiterListEntry->
AlternativeCount++;
01653 IoResourceDescriptor++;
01654
while (IoResourceDescriptor < IoResourceDescriptorEnd) {
01655
if (IoResourceDescriptor->Type == CmResourceTypeDevicePrivate) {
01656 ReqDesc->DevicePrivate = IoResourceDescriptor;
01657
while (IoResourceDescriptor < IoResourceDescriptorEnd &&
01658 IoResourceDescriptor->Type == CmResourceTypeDevicePrivate) {
01659 ReqDesc->DevicePrivateCount++;
01660 ++IoResourceDescriptor;
01661 }
01662
break;
01663 }
01664
if (IoResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
01665 ArbiterListEntry->
AlternativeCount++;
01666 IoResourceDescriptor++;
01667 }
else {
01668
break;
01669 }
01670 }
01671
01672
01673
01674
01675
01676 status =
IopSetupArbiterAndTranslators(ReqDesc);
01677
if (!
NT_SUCCESS(status)) {
01678
DebugMessage(
DUMP_ERROR, (
"PnpRes: Unable to setup Arbiter and Translators\n"));
01679 ReqAlternativeIndex--;
01680 ReqAlternativePP--;
01681 ReqList->ReqAlternativeCount--;
01682
IopFreeReqAlternative(ReqAlternative);
01683 failureStatus = status;
01684
break;
01685 }
01686 }
else {
01687 ReqDesc->Allocation.Type = IoResourceDescriptor->Type;
01688 ReqDesc->Allocation.ShareDisposition = IoResourceDescriptor->ShareDisposition;
01689 ReqDesc->Allocation.Flags = IoResourceDescriptor->Flags;
01690 ReqDesc->Allocation.u.DevicePrivate.Data[0] =
01691 IoResourceDescriptor->u.DevicePrivate.Data[0];
01692 ReqDesc->Allocation.u.DevicePrivate.Data[1] =
01693 IoResourceDescriptor->u.DevicePrivate.Data[1];
01694 ReqDesc->Allocation.u.DevicePrivate.Data[2] =
01695 IoResourceDescriptor->u.DevicePrivate.Data[2];
01696
01697 IoResourceDescriptor++;
01698 }
01699 }
01700
01701
if (IoResourceDescriptor >= IoResourceDescriptorEnd)
break;
01702 }
01703 IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd;
01704 }
01705
if (ReqAlternativeIndex == 0) {
01706 finalStatus = failureStatus;
01707
IopFreeReqList(ReqList);
01708 }
01709 }
01710
01711
if (finalStatus == STATUS_SUCCESS) {
01712 *ResReqList = ReqList;
01713 }
01714
01715
return finalStatus;
01716
01717 InvalidParameter:
01718
return STATUS_INVALID_PARAMETER;
01719 }
01720
01721
int
01722 __cdecl
01723 IopComparePriority(
01724
const void *arg1,
01725
const void *arg2
01726 )
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 {
01747
PREQ_ALTERNATIVE RA1 = *(
PREQ_ALTERNATIVE *)arg1;
01748
PREQ_ALTERNATIVE RA2 = *(
PREQ_ALTERNATIVE *)arg2;
01749
01750
PAGED_CODE();
01751
01752
if (RA1->Priority == RA2->Priority) {
01753
if ((ULONG_PTR)RA1 < (ULONG_PTR)RA2) {
01754
return -1;
01755 }
else {
01756
return 1;
01757 }
01758 }
01759
if (RA1->Priority > RA2->Priority) {
01760
return 1;
01761 }
else {
01762
return -1;
01763 }
01764 }
01765
int
01766 __cdecl
01767 IopCompareAlternativeCount(
01768
const void *arg1,
01769
const void *arg2
01770 )
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790 {
01791
PIOP_RESOURCE_REQUEST RR1 = (
PIOP_RESOURCE_REQUEST)arg1;
01792
PIOP_RESOURCE_REQUEST RR2 = (
PIOP_RESOURCE_REQUEST)arg2;
01793
01794
PAGED_CODE();
01795
01796
if (RR1->
Priority == RR2->
Priority) {
01797
if ((ULONG_PTR)RR1 < (ULONG_PTR)RR2) {
01798
return -1;
01799 }
else {
01800
return 1;
01801 }
01802 }
01803
if (RR1->
Priority > RR2->
Priority) {
01804
return 1;
01805 }
else {
01806
return -1;
01807 }
01808 }
01809
01810
VOID
01811 IopRearrangeReqList (
01812 IN PREQ_LIST ReqList
01813 )
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834 {
01835
PREQ_ALTERNATIVE *alternative;
01836
PREQ_ALTERNATIVE *lastAlternative;
01837
01838
PAGED_CODE();
01839
01840
if (ReqList->ReqAlternativeCount > 1) {
01841
01842 qsort( (
void *)ReqList->ReqAlternativeTable,
01843 ReqList->ReqAlternativeCount,
01844
sizeof(
PREQ_ALTERNATIVE),
01845
IopComparePriority);
01846
01847 }
01848
01849
01850
01851
01852
01853 alternative = &ReqList->ReqAlternativeTable[0];
01854
for (lastAlternative = alternative + ReqList->ReqAlternativeCount; alternative < lastAlternative; alternative++) {
01855
01856
if ((*alternative)->Priority > LCPRI_LASTSOFTCONFIG) {
01857
01858
break;
01859
01860 }
01861 }
01862
01863
if (alternative == &ReqList->ReqAlternativeTable[0]) {
01864
01865
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)ReqList->PhysicalDevice->DeviceObjectExtension->DeviceNode;
01866
01867
DebugMessage(
DUMP_ERROR, (
"PNPRES: Invalid priorities in the logical configs for %ws\n", deviceNode->
InstancePath.Buffer));
01868
01869 ReqList->ReqBestAlternative =
NULL;
01870
01871 }
else {
01872
01873 ReqList->ReqBestAlternative = alternative;
01874 }
01875 }
01876
01877
VOID
01878 IopRearrangeAssignTable (
01879 IN
PIOP_RESOURCE_REQUEST AssignTable,
01880 IN ULONG Count
01881 )
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902 {
01903
PAGED_CODE();
01904
01905
if (
Count == 1 ||
Count == 0) {
01906
01907
01908
01909
01910
01911
return;
01912 }
01913
01914 qsort((
void *)AssignTable,
01915
Count,
01916
sizeof(
IOP_RESOURCE_REQUEST),
01917
IopCompareAlternativeCount
01918 );
01919 }
01920
01921
VOID
01922 IopFreeReqAlternative (
01923 IN PREQ_ALTERNATIVE ReqAlternative
01924 )
01925 {
01926
PREQ_DESC reqDesc, reqDescx;
01927 ULONG i;
01928
01929
PAGED_CODE();
01930
01931
if (ReqAlternative) {
01932
for (i = 0; i < ReqAlternative->ReqDescCount; i++) {
01933 reqDesc = ReqAlternative->ReqDescTable[i];
01934 reqDescx = reqDesc->TranslatedReqDesc;
01935
while (reqDescx &&
IS_TRANSLATED_REQ_DESC(reqDescx)) {
01936 reqDesc = reqDescx;
01937
if (reqDescx->AlternativeTable.Alternatives) {
01938
ExFreePool(reqDescx->AlternativeTable.Alternatives);
01939 }
01940 reqDescx = reqDescx->TranslatedReqDesc;
01941
ExFreePool(reqDesc);
01942 }
01943 }
01944 }
01945 }
01946
01947
VOID
01948 IopFreeReqList (
01949 IN PREQ_LIST ReqList
01950 )
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968 {
01969 ULONG i;
01970
01971
PAGED_CODE();
01972
01973
if (ReqList) {
01974
01975
01976
01977
01978
01979
01980
for (i = 0; i < ReqList->ReqAlternativeCount; i++) {
01981
IopFreeReqAlternative(ReqList->ReqAlternativeTable[i]);
01982 }
01983
ExFreePool(ReqList);
01984 }
01985 }
01986
01987
VOID
01988 IopFreeResourceRequirementsForAssignTable(
01989 IN
PIOP_RESOURCE_REQUEST AssignTable,
01990 IN
PIOP_RESOURCE_REQUEST AssignTableEnd
01991 )
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011 {
02012
PIOP_RESOURCE_REQUEST AssignEntry;
02013
02014
PAGED_CODE();
02015
02016
for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; ++AssignEntry) {
02017
IopFreeReqList(AssignEntry->
ReqList);
02018 AssignEntry->
ReqList =
NULL;
02019
if (AssignEntry->
Flags &
IOP_ASSIGN_KEEP_CURRENT_CONFIG &&
02020 AssignEntry->
ResourceRequirements) {
02021
02022
02023
02024
02025
02026
02027
ExFreePool(AssignEntry->
ResourceRequirements);
02028 AssignEntry->
ResourceRequirements =
NULL;
02029 }
02030 }
02031 }
02032
02033
VOID
02034 IopBuildCmResourceList (
02035 IN
PIOP_RESOURCE_REQUEST AssignEntry
02036 )
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054 {
02055
NTSTATUS status;
02056 HANDLE resourceMapKey;
02057
PDEVICE_OBJECT physicalDevice;
02058
PREQ_LIST reqList = AssignEntry->ReqList;
02059
PREQ_ALTERNATIVE reqAlternative;
02060
PREQ_DESC reqDesc, reqDescx;
02061 PIO_RESOURCE_DESCRIPTOR privateData;
02062 ULONG count = 0, size, i;
02063 PCM_RESOURCE_LIST cmResources, cmResourcesRaw;
02064 PCM_FULL_RESOURCE_DESCRIPTOR cmFullResource, cmFullResourceRaw;
02065 PCM_PARTIAL_RESOURCE_LIST cmPartialList, cmPartialListRaw;
02066 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor, cmDescriptorRaw, assignment, tAssignment;
02067
#if DBG
02068
PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptorEnd, cmDescriptorEndRaw;
02069
#endif
02070
02071
PAGED_CODE();
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081 reqAlternative = *reqList->SelectedAlternative;
02082
for (i = 0; i < reqAlternative->ReqDescCount; i++) {
02083 reqDesc = reqAlternative->ReqDescTable[i];
02084 count += reqDesc->DevicePrivateCount + 1;
02085 }
02086
02087 size =
sizeof(CM_RESOURCE_LIST) +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (count - 1);
02088 cmResources = (PCM_RESOURCE_LIST)
ExAllocatePoolCMRL(
PagedPool, size);
02089
if (!cmResources) {
02090
02091
02092
02093
02094
02095
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not enough memory to build Translated CmResourceList\n"));
02096 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES;
02097 AssignEntry->ResourceAssignment =
NULL;
02098 AssignEntry->TranslatedResourceAssignment =
NULL;
02099
return;
02100 }
02101 cmResourcesRaw = (PCM_RESOURCE_LIST)
ExAllocatePoolCMRR(
PagedPool, size);
02102
if (!cmResourcesRaw) {
02103
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not enough memory to build Raw CmResourceList\n"));
02104
ExFreePool(cmResources);
02105 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES;
02106 AssignEntry->ResourceAssignment =
NULL;
02107 AssignEntry->TranslatedResourceAssignment =
NULL;
02108
return;
02109 }
02110 cmResources->Count = 1;
02111 cmFullResource = cmResources->List;
02112
02113
02114
02115
02116
02117
02118
02119
02120 cmFullResource->InterfaceType = reqList->InterfaceType;
02121 cmFullResource->BusNumber = reqList->BusNumber;
02122 cmPartialList = &cmFullResource->PartialResourceList;
02123 cmPartialList->Version = 0;
02124 cmPartialList->Revision = 0;
02125 cmPartialList->Count = count;
02126 cmDescriptor = cmPartialList->PartialDescriptors;
02127
#if DBG
02128
cmDescriptorEnd = cmDescriptor + count;
02129
#endif
02130
cmResourcesRaw->Count = 1;
02131 cmFullResourceRaw = cmResourcesRaw->List;
02132 cmFullResourceRaw->InterfaceType = reqList->InterfaceType;
02133 cmFullResourceRaw->BusNumber = reqList->BusNumber;
02134 cmPartialListRaw = &cmFullResourceRaw->PartialResourceList;
02135 cmPartialListRaw->Version = 0;
02136 cmPartialListRaw->Revision = 0;
02137 cmPartialListRaw->Count = count;
02138 cmDescriptorRaw = cmPartialListRaw->PartialDescriptors;
02139
#if DBG
02140
cmDescriptorEndRaw = cmDescriptorRaw + count;
02141
#endif
02142
02143
for (i = 0; i < reqAlternative->ReqDescCount; i++) {
02144 reqDesc = reqAlternative->ReqDescTable[i];
02145
02146
if (reqDesc->ArbitrationRequired) {
02147
02148
02149
02150
02151
02152 reqDescx = reqDesc->TranslatedReqDesc;
02153
if (reqDescx->AlternativeTable.Result !=
ArbiterResultNullRequest) {
02154 status =
IopParentToRawTranslation(reqDescx);
02155
if (!
NT_SUCCESS(status)) {
02156
DebugMessage(
DUMP_ERROR, (
"PnpRes: Parent To Raw translation failed\n"));
02157
ExFreePool(cmResources);
02158
ExFreePool(cmResourcesRaw);
02159 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES;
02160 AssignEntry->ResourceAssignment =
NULL;
02161
return;
02162 }
02163 assignment = reqDesc->AlternativeTable.Assignment;
02164 }
else {
02165 assignment = reqDescx->AlternativeTable.Assignment;
02166 }
02167 *cmDescriptorRaw = *assignment;
02168 cmDescriptorRaw++;
02169
02170
02171
02172
02173
if (reqDescx->AlternativeTable.Result !=
ArbiterResultNullRequest) {
02174 status =
IopChildToRootTranslation(
02175 (
PDEVICE_NODE)reqDesc->AlternativeTable.PhysicalDeviceObject->DeviceObjectExtension->DeviceNode,
02176 reqDesc->InterfaceType,
02177 reqDesc->BusNumber,
02178 reqDesc->AlternativeTable.RequestSource,
02179 &reqDesc->Allocation,
02180 &tAssignment
02181 );
02182
if (!
NT_SUCCESS(status)) {
02183
DebugMessage(
DUMP_ERROR, (
"PnpRes: Child to Root translation failed\n"));
02184
ExFreePool(cmResources);
02185
ExFreePool(cmResourcesRaw);
02186 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES;
02187 AssignEntry->ResourceAssignment =
NULL;
02188
return;
02189 }
02190 *cmDescriptor = *tAssignment;
02191
ExFreePool(tAssignment);
02192 }
else {
02193 *cmDescriptor = *(reqDescx->AlternativeTable.Assignment);
02194 }
02195 cmDescriptor++;
02196
02197 }
else {
02198 *cmDescriptorRaw = reqDesc->Allocation;
02199 *cmDescriptor = reqDesc->Allocation;
02200 cmDescriptorRaw++;
02201 cmDescriptor++;
02202 }
02203
02204
02205
02206
02207
02208 count = reqDesc->DevicePrivateCount;
02209 privateData = reqDesc->DevicePrivate;
02210
while (count != 0) {
02211
02212 cmDescriptor->Type = cmDescriptorRaw->Type = CmResourceTypeDevicePrivate;
02213 cmDescriptor->ShareDisposition = cmDescriptorRaw->ShareDisposition =
02214 CmResourceShareDeviceExclusive;
02215 cmDescriptor->Flags = cmDescriptorRaw->Flags = privateData->Flags;
02216 RtlMoveMemory(&cmDescriptorRaw->u.DevicePrivate,
02217 &privateData->u.DevicePrivate,
02218
sizeof(cmDescriptorRaw->u.DevicePrivate.Data)
02219 );
02220 RtlMoveMemory(&cmDescriptor->u.DevicePrivate,
02221 &privateData->u.DevicePrivate,
02222
sizeof(cmDescriptor->u.DevicePrivate.Data)
02223 );
02224 privateData++;
02225 cmDescriptorRaw++;
02226 cmDescriptor++;
02227 count--;
02228
ASSERT(cmDescriptorRaw <= cmDescriptorEndRaw);
02229
ASSERT(cmDescriptor <= cmDescriptorEnd);
02230 }
02231
ASSERT(cmDescriptor <= cmDescriptorEnd);
02232
ASSERT(cmDescriptorRaw <= cmDescriptorEndRaw);
02233
02234 }
02235
02236
02237
02238
02239
02240 physicalDevice = AssignEntry->PhysicalDevice;
02241
02242
02243
02244
02245
02246 status =
IopCreateRegistryKeyEx( &resourceMapKey,
02247 (HANDLE)
NULL,
02248 &
CmRegistryMachineHardwareResourceMapName,
02249 KEY_READ | KEY_WRITE,
02250 REG_OPTION_VOLATILE,
02251
NULL
02252 );
02253
if (
NT_SUCCESS(status )) {
02254 WCHAR DeviceBuffer[256];
02255 POBJECT_NAME_INFORMATION NameInformation;
02256 ULONG NameLength;
02257 UNICODE_STRING UnicodeClassName;
02258 UNICODE_STRING UnicodeDriverName;
02259 UNICODE_STRING UnicodeDeviceName;
02260
02261
RtlInitUnicodeString(&UnicodeClassName, PNPMGR_STR_PNP_MANAGER);
02262
02263
RtlInitUnicodeString(&UnicodeDriverName, REGSTR_KEY_PNP_DRIVER);
02264
02265 NameInformation = (POBJECT_NAME_INFORMATION) DeviceBuffer;
02266 status =
ObQueryNameString( physicalDevice,
02267 NameInformation,
02268
sizeof( DeviceBuffer ),
02269 &NameLength );
02270
if (
NT_SUCCESS(status)) {
02271 NameInformation->Name.MaximumLength =
sizeof(DeviceBuffer) -
sizeof(OBJECT_NAME_INFORMATION);
02272
if (NameInformation->Name.Length == 0) {
02273 NameInformation->Name.Buffer = (PVOID)((ULONG_PTR)DeviceBuffer +
sizeof(OBJECT_NAME_INFORMATION));
02274 }
02275
02276 UnicodeDeviceName = NameInformation->Name;
02277
RtlAppendUnicodeToString(&UnicodeDeviceName,
IopWstrRaw);
02278
02279
02280
02281
02282
02283
02284 status =
IopWriteResourceList(
02285 resourceMapKey,
02286 &UnicodeClassName,
02287 &UnicodeDriverName,
02288 &UnicodeDeviceName,
02289 cmResourcesRaw,
02290 size
02291 );
02292
if (
NT_SUCCESS(status)) {
02293 UnicodeDeviceName = NameInformation->Name;
02294
RtlAppendUnicodeToString (&UnicodeDeviceName,
IopWstrTranslated);
02295 status =
IopWriteResourceList(
02296 resourceMapKey,
02297 &UnicodeClassName,
02298 &UnicodeDriverName,
02299 &UnicodeDeviceName,
02300 cmResources,
02301 size
02302 );
02303 }
02304 }
02305 ZwClose(resourceMapKey);
02306 }
02307
#if 0 // Ignore the registry writing status.
02308
if (!
NT_SUCCESS(status)) {
02309
ExFreePool(cmResources);
02310
ExFreePool(cmResourcesRaw);
02311 cmResources =
NULL;
02312 cmResourcesRaw =
NULL;
02313 }
02314
#endif
02315
AssignEntry->ResourceAssignment = cmResourcesRaw;
02316 AssignEntry->TranslatedResourceAssignment = cmResources;
02317 }
02318
02319
VOID
02320 IopBuildCmResourceLists(
02321 IN
PIOP_RESOURCE_REQUEST AssignTable,
02322 IN
PIOP_RESOURCE_REQUEST AssignTableEnd
02323 )
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344 {
02345
NTSTATUS status;
02346
PIOP_RESOURCE_REQUEST assignEntry;
02347
PDEVICE_OBJECT physicalDevice;
02348
PDEVICE_NODE deviceNode;
02349
02350
PAGED_CODE();
02351
02352
02353
02354
02355
02356
02357
for (assignEntry = AssignTable; assignEntry < AssignTableEnd; ++assignEntry) {
02358
02359 assignEntry->
ResourceAssignment =
NULL;
02360
if (assignEntry->
Flags &
IOP_ASSIGN_IGNORE || assignEntry->
Flags &
IOP_ASSIGN_RETRY) {
02361
continue;
02362 }
02363
if (assignEntry->
Flags &
IOP_ASSIGN_EXCLUDE) {
02364 assignEntry->
Status = STATUS_UNSUCCESSFUL;
02365
continue;
02366 }
02367 assignEntry->
Status = STATUS_SUCCESS;
02368
IopBuildCmResourceList (assignEntry);
02369
if (assignEntry->
ResourceAssignment) {
02370 physicalDevice = assignEntry->
PhysicalDevice;
02371 deviceNode = (
PDEVICE_NODE)physicalDevice->
DeviceObjectExtension->
DeviceNode;
02372
IopWriteAllocatedResourcesToRegistry(
02373 deviceNode,
02374 assignEntry->
ResourceAssignment,
02375
IopDetermineResourceListSize(assignEntry->
ResourceAssignment)
02376 );
02377
#if DBG_SCOPE
02378
DebugMessage(
DUMP_INFO,(
"Pnpres: Building CM resource lists for %ws...\n", deviceNode->
InstancePath.Buffer));
02379
if (
PnpResDebugLevel &
DUMP_INFO) {
02380
DbgPrint(
"Raw resources ");
02381
IopDumpCmResourceList(assignEntry->
ResourceAssignment);
02382
DbgPrint(
"Translated resources ");
02383
IopDumpCmResourceList(assignEntry->
TranslatedResourceAssignment);
02384 }
02385
#endif
02386
}
02387 }
02388 }
02389
02390 BOOLEAN
02391 IopNeedToReleaseBootResources(
02392 IN
PDEVICE_NODE DeviceNode,
02393 IN PCM_RESOURCE_LIST AllocatedResources
02394 )
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417 {
02418 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc_a, cmFullDesc_b;
02419 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor_a, cmDescriptor_b;
02420 ULONG size_a, size_b, i, j, k;
02421 BOOLEAN returnValue =
FALSE, found;
02422 PCM_RESOURCE_LIST bootResources;
02423
02424
PAGED_CODE();
02425
02426 bootResources = DeviceNode->BootResources;
02427
if (AllocatedResources->Count == 1 && bootResources && bootResources->Count != 0) {
02428
02429 cmFullDesc_a = &AllocatedResources->List[0];
02430 cmFullDesc_b = &bootResources->List[0];
02431
for (i = 0; i < bootResources->Count; i++) {
02432 cmDescriptor_b = &cmFullDesc_b->PartialResourceList.PartialDescriptors[0];
02433
for (j = 0; j < cmFullDesc_b->PartialResourceList.Count; j++) {
02434 size_b = 0;
02435
switch (cmDescriptor_b->Type) {
02436
case CmResourceTypeNull:
02437
break;
02438
case CmResourceTypeDeviceSpecific:
02439 size_b = cmDescriptor_b->u.DeviceSpecificData.DataSize;
02440
break;
02441
default:
02442
if (cmDescriptor_b->Type < CmResourceTypeMaximum) {
02443 found =
FALSE;
02444 cmDescriptor_a = &cmFullDesc_a->PartialResourceList.PartialDescriptors[0];
02445
for (k = 0; k < cmFullDesc_a->PartialResourceList.Count; k++) {
02446 size_a = 0;
02447
if (cmDescriptor_a->Type == CmResourceTypeDeviceSpecific) {
02448 size_a = cmDescriptor_a->u.DeviceSpecificData.DataSize;
02449 }
else if (cmDescriptor_b->Type == cmDescriptor_a->Type) {
02450 found =
TRUE;
02451
break;
02452 }
02453 cmDescriptor_a++;
02454 cmDescriptor_a = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor_a + size_a);
02455 }
02456
if (found ==
FALSE) {
02457 returnValue =
TRUE;
02458
goto exit;
02459 }
02460 }
02461 }
02462 cmDescriptor_b++;
02463 cmDescriptor_b = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor_b + size_b);
02464 }
02465 cmFullDesc_b = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor_b;
02466 }
02467 }
02468
exit:
02469
return returnValue;
02470 }
02471
02472
02473
VOID
02474 IopReleaseFilteredBootResources(
02475 IN
PIOP_RESOURCE_REQUEST AssignTable,
02476 IN
PIOP_RESOURCE_REQUEST AssignTableEnd
02477 )
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498 {
02499
NTSTATUS status;
02500
PIOP_RESOURCE_REQUEST assignEntry;
02501
PDEVICE_OBJECT physicalDevice;
02502
PDEVICE_NODE deviceNode;
02503
02504
PAGED_CODE();
02505
02506
02507
02508
02509
02510
02511
for (assignEntry = AssignTable; assignEntry < AssignTableEnd; ++assignEntry) {
02512
02513
if (assignEntry->
ResourceAssignment) {
02514 physicalDevice = assignEntry->
PhysicalDevice;
02515 deviceNode = (
PDEVICE_NODE)physicalDevice->
DeviceObjectExtension->
DeviceNode;
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
if (
IopNeedToReleaseBootResources(deviceNode, assignEntry->
ResourceAssignment)) {
02527
IopReleaseResourcesInternal(deviceNode);
02528
IopReserveBootResourcesInternal(
02529
ArbiterRequestPnpEnumerated,
02530 physicalDevice,
02531 assignEntry->
ResourceAssignment);
02532 deviceNode->
Flags &= ~
DNF_BOOT_CONFIG_RESERVED;
02533 deviceNode->
ResourceList = assignEntry->
ResourceAssignment;
02534 status =
IopRestoreResourcesInternal(deviceNode);
02535
ASSERT(status == STATUS_SUCCESS);
02536
if (!
NT_SUCCESS(status)) {
02537
02538
02539
02540
02541
02542 assignEntry->
Flags =
IOP_ASSIGN_EXCLUDE;
02543 assignEntry->
Status = status;
02544
ExFreePool(assignEntry->
ResourceAssignment);
02545 assignEntry->
ResourceAssignment =
NULL;
02546 }
02547 deviceNode->
ResourceList =
NULL;
02548 }
02549 }
02550 }
02551 }
02552
02553
NTSTATUS
02554 IopPlacement(
02555 IN ARBITER_ACTION ArbiterAction,
02556 IN BOOLEAN Rebalance
02557 )
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576 {
02577 PLIST_ENTRY listEntry;
02578
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
02579
NTSTATUS status;
02580
02581
ASSERT((ArbiterAction ==
ArbiterActionTestAllocation) ||
02582 (ArbiterAction ==
ArbiterActionRetestAllocation) ||
02583 (ArbiterAction ==
ArbiterActionCommitAllocation));
02584
02585
if (Rebalance) {
02586
02587
02588
02589
02590
02591 status =
IopPlacementForRebalance (
IopRootDeviceNode, ArbiterAction);
02592 }
else {
02593 listEntry =
PiActiveArbiterList.Flink;
02594
while (listEntry != &
PiActiveArbiterList) {
02595 arbiterEntry = CONTAINING_RECORD(listEntry,
PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList);
02596 listEntry = listEntry->Flink;
02597
ASSERT(IsListEmpty(&arbiterEntry->
ResourceList) ==
FALSE);
02598
if (arbiterEntry->
ResourcesChanged ==
FALSE) {
02599
02600
02601
02602
02603
02604
02605
if (arbiterEntry->
State &
PI_ARBITER_TEST_FAILED) {
02606
return STATUS_UNSUCCESSFUL;
02607 }
02608 }
else {
02609
02610
02611
02612
02613
02614 status =
IopCallArbiter(arbiterEntry,
02615 ArbiterAction,
02616 &arbiterEntry->
ResourceList,
02617 0,
02618
NULL
02619 );
02620
if (!
NT_SUCCESS(status)) {
02621
ASSERT(ArbiterAction ==
ArbiterActionTestAllocation);
02622 arbiterEntry->
State |=
PI_ARBITER_TEST_FAILED;
02623
return status;
02624 }
else {
02625 arbiterEntry->
State &= ~
PI_ARBITER_TEST_FAILED;
02626 arbiterEntry->
ResourcesChanged =
FALSE;
02627
if (ArbiterAction ==
ArbiterActionTestAllocation) {
02628 arbiterEntry->
State |=
PI_ARBITER_HAS_SOMETHING;
02629 }
else {
02630
if (ArbiterAction ==
ArbiterActionRetestAllocation) {
02631 status =
IopCallArbiter(arbiterEntry,
ArbiterActionCommitAllocation,
NULL,
NULL,
NULL);
02632
ASSERT(status == STATUS_SUCCESS);
02633 }
02634 arbiterEntry->
State = 0;
02635 InitializeListHead(&arbiterEntry->
ActiveArbiterList);
02636 InitializeListHead(&arbiterEntry->
BestConfig);
02637 InitializeListHead(&arbiterEntry->
ResourceList);
02638 InitializeListHead(&arbiterEntry->
BestResourceList);
02639 }
02640 }
02641 }
02642 }
02643 status = STATUS_SUCCESS;
02644 }
02645
return status;
02646 }
02647
02648
NTSTATUS
02649 IopPlacementForReservation(
02650 VOID
02651 )
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670 {
02671 PLIST_ENTRY listEntry;
02672
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
02673
NTSTATUS status, returnStatus = STATUS_SUCCESS;
02674
02675 listEntry =
PiActiveArbiterList.Flink;
02676
while (listEntry != &
PiActiveArbiterList) {
02677 arbiterEntry = CONTAINING_RECORD(listEntry,
PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList);
02678 listEntry = listEntry->Flink;
02679
ASSERT(IsListEmpty(&arbiterEntry->
ResourceList) ==
FALSE);
02680
if (arbiterEntry->
ResourcesChanged) {
02681
02682
02683
02684
02685
02686 status =
IopCallArbiter(arbiterEntry,
02687
ArbiterActionBootAllocation,
02688 &arbiterEntry->
ResourceList,
02689 0,
02690
NULL
02691 );
02692
if (!
NT_SUCCESS(status)) {
02693
#if MYDBG
02694
PARBITER_LIST_ENTRY arbiterListEntry = (
PARBITER_LIST_ENTRY) arbiterEntry->
ResourceList.Flink;
02695
DbgPrint(
"Allocate Boot Resources Failed ::\n");
02696
DbgPrint(
" Count = %x, PDO = %x\n",
02697 arbiterListEntry->
AlternativeCount, arbiterListEntry->
PhysicalDeviceObject);
02698
IopDumpResourceDescriptor(
02699
" ",
02700 arbiterListEntry->
Alternatives);
02701
#endif
02702
returnStatus = status;
02703 }
02704 arbiterEntry->
ResourcesChanged =
FALSE;
02705 arbiterEntry->
State = 0;
02706 InitializeListHead(&arbiterEntry->
ActiveArbiterList);
02707 InitializeListHead(&arbiterEntry->
BestConfig);
02708 InitializeListHead(&arbiterEntry->
ResourceList);
02709 InitializeListHead(&arbiterEntry->
BestResourceList);
02710 }
02711 }
02712
return returnStatus;
02713 }
02714
02715
VOID
02716 IopAddReqDescsToArbiters (
02717 IN ULONG ReqDescCount,
02718 IN PREQ_DESC *ReqDescTable
02719 )
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736 {
02737
PREQ_DESC reqDesc;
02738
PREQ_DESC reqDescTranslated;
02739 PLIST_ENTRY listHead;
02740
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
02741
PREQ_DESC *reqDescTableEnd;
02742
02743
for (reqDescTableEnd = ReqDescTable + ReqDescCount; ReqDescTable < reqDescTableEnd; ReqDescTable++) {
02744
02745
02746
02747
02748
02749 reqDesc = *ReqDescTable;
02750
if (reqDesc->ArbitrationRequired) {
02751
02752 reqDescTranslated = reqDesc->
TranslatedReqDesc;
02753
02754 InitializeListHead(&reqDescTranslated->AlternativeTable.ListEntry);
02755 arbiterEntry = reqDesc->u.Arbiter;
02756
ASSERT(arbiterEntry);
02757 listHead = &arbiterEntry->
ResourceList;
02758 InsertTailList(listHead, &reqDescTranslated->AlternativeTable.ListEntry);
02759
02760 arbiterEntry->
ResourcesChanged =
TRUE;
02761
if (arbiterEntry->
State &
PI_ARBITER_HAS_SOMETHING) {
02762
02763
IopCallArbiter(arbiterEntry,
ArbiterActionRollbackAllocation,
NULL,
NULL,
NULL);
02764 arbiterEntry->
State &= ~
PI_ARBITER_HAS_SOMETHING;
02765 }
02766
02767
02768
02769
02770
02771
if (IsListEmpty(&arbiterEntry->
ActiveArbiterList)) {
02772
02773 InsertTailList(&
PiActiveArbiterList, &arbiterEntry->
ActiveArbiterList);
02774 }
02775 }
02776 }
02777 }
02778
02779
VOID
02780 IopRemoveReqDescsFromArbiters (
02781 ULONG ReqDescCount,
02782 PREQ_DESC *ReqDescTable
02783 )
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800 {
02801
PREQ_DESC reqDesc;
02802
PREQ_DESC reqDescTranslated;
02803 PLIST_ENTRY listHead;
02804
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
02805
PREQ_DESC *reqDescTableEnd;
02806
02807
for (reqDescTableEnd = ReqDescTable + ReqDescCount; ReqDescTable < reqDescTableEnd; ReqDescTable++) {
02808
02809
02810
02811
02812
02813 reqDesc = *ReqDescTable;
02814
if (reqDesc->ArbitrationRequired) {
02815
02816 reqDescTranslated = reqDesc->
TranslatedReqDesc;
02817 arbiterEntry = reqDesc->u.Arbiter;
02818
ASSERT(IsListEmpty(&arbiterEntry->
ResourceList) ==
FALSE);
02819
02820 arbiterEntry->
ResourcesChanged =
TRUE;
02821
if (arbiterEntry->
State &
PI_ARBITER_HAS_SOMETHING) {
02822
02823
IopCallArbiter(arbiterEntry,
ArbiterActionRollbackAllocation,
NULL,
NULL,
NULL);
02824 arbiterEntry->
State &= ~
PI_ARBITER_HAS_SOMETHING;
02825 }
02826
02827 RemoveEntryList(&reqDescTranslated->AlternativeTable.ListEntry);
02828 InitializeListHead(&reqDescTranslated->AlternativeTable.ListEntry);
02829 listHead = &arbiterEntry->
ResourceList;
02830
if (IsListEmpty(listHead)) {
02831
02832
02833
02834
02835
02836
02837 RemoveEntryList(&arbiterEntry->
ActiveArbiterList);
02838 InitializeListHead(&arbiterEntry->
ActiveArbiterList);
02839 }
02840 }
02841 }
02842 }
02843
02844 BOOLEAN
02845 IopIsBestConfiguration(
02846 IN VOID
02847 )
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866 {
02867 ULONG i, priority = 0;
02868
PREQ_ALTERNATIVE reqAlternative;
02869
PIOP_RESOURCE_REQUEST assignEntry;
02870
02871
02872
02873
02874
02875
if (
PiNoRetest) {
02876
return TRUE;
02877 }
02878
02879
02880
02881
02882
02883
for (i = 0; i <
PiAssignTableCount; i++) {
02884 assignEntry =
PiAssignTable + i;
02885
02886
if (!(assignEntry->
Flags &
IOP_ASSIGN_EXCLUDE)) {
02887 reqAlternative = *((
PREQ_LIST)assignEntry->
ReqList)->SelectedAlternative;
02888 priority += reqAlternative->
Priority;
02889 }
02890 }
02891
02892
02893
02894
02895
02896
02897
if (priority <
PiBestPriority) {
02898
PiBestPriority = priority;
02899
return TRUE;
02900 }
else {
02901
return FALSE;
02902 }
02903 }
02904
02905
VOID
02906 IopSaveCurrentConfiguration(
02907 IN VOID
02908 )
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927 {
02928
PREQ_ALTERNATIVE reqAlternative;
02929
PIOP_RESOURCE_REQUEST assignEntry;
02930
PREQ_DESC reqDesc, *reqDescpp;
02931
PREQ_LIST reqList;
02932 PLIST_ENTRY listEntry;
02933
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
02934 ULONG i;
02935
02936
02937
02938
02939
02940
if (
PiNoRetest) {
02941
PiBestArbiterList =
PiActiveArbiterList;
02942
return;
02943 }
02944
02945
02946
02947
02948
02949
02950
for (i = 0; i <
PiAssignTableCount; i++) {
02951 assignEntry =
PiAssignTable + i;
02952
02953
if (!(assignEntry->
Flags &
IOP_ASSIGN_EXCLUDE)) {
02954 reqList = assignEntry->
ReqList;
02955
02956
02957
02958
02959
02960 reqAlternative = *reqList->SelectedAlternative;
02961 reqList->ReqBestAlternative = reqList->SelectedAlternative;
02962
02963
02964
02965
02966
02967
02968
for (reqDescpp = reqAlternative->ReqDescTable;
02969 reqDescpp < reqAlternative->ReqDescTableEnd;
02970 reqDescpp++) {
02971
02972
if ((*reqDescpp)->ArbitrationRequired) {
02973 reqDesc = (*reqDescpp)->TranslatedReqDesc;
02974 reqDesc->BestAlternativeTable = reqDesc->AlternativeTable;
02975 reqDesc->BestAllocation = reqDesc->Allocation;
02976 }
02977 }
02978 }
02979 }
02980
02981
02982
02983
02984
02985
02986 listEntry =
PiActiveArbiterList.Flink;
02987
while (listEntry != &
PiActiveArbiterList) {
02988 arbiterEntry = CONTAINING_RECORD(listEntry,
PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList);
02989 arbiterEntry->
BestResourceList = arbiterEntry->
ResourceList;
02990 arbiterEntry->
BestConfig = arbiterEntry->
ActiveArbiterList;
02991 listEntry = listEntry->Flink;
02992 }
02993
PiBestArbiterList =
PiActiveArbiterList;
02994 }
02995
02996
VOID
02997 IopRestoreBestConfiguration(
02998 IN VOID
02999 )
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018 {
03019
PREQ_ALTERNATIVE reqAlternative;
03020
PIOP_RESOURCE_REQUEST assignEntry;
03021
PREQ_DESC reqDesc, *reqDescpp;
03022
PREQ_LIST reqList;
03023 PLIST_ENTRY listEntry;
03024
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
03025 ULONG i;
03026
03027
if (
PiNoRetest ==
FALSE) {
03028
03029
03030
03031
03032
03033
for (i = 0; i <
PiAssignTableCount; i++) {
03034 assignEntry =
PiAssignTable + i;
03035
03036
if (!(assignEntry->
Flags &
IOP_ASSIGN_EXCLUDE)) {
03037 reqList = assignEntry->
ReqList;
03038
03039
03040
03041
03042
03043 reqAlternative = *reqList->ReqBestAlternative;
03044 reqList->SelectedAlternative = reqList->ReqBestAlternative;
03045
03046
03047
03048
03049
03050
03051
for (reqDescpp = reqAlternative->ReqDescTable;
03052 reqDescpp < reqAlternative->ReqDescTableEnd;
03053 reqDescpp++) {
03054
03055
if ((*reqDescpp)->ArbitrationRequired) {
03056 reqDesc = (*reqDescpp)->TranslatedReqDesc;
03057 reqDesc->AlternativeTable = reqDesc->BestAlternativeTable;
03058 reqDesc->Allocation = reqDesc->BestAllocation;
03059 }
03060 }
03061 }
03062 }
03063
PiActiveArbiterList =
PiBestArbiterList;
03064 }
03065
03066
03067
03068
03069
03070
03071 listEntry =
PiActiveArbiterList.Flink;
03072
while (listEntry != &
PiActiveArbiterList) {
03073 arbiterEntry = CONTAINING_RECORD(listEntry,
PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList);
03074
if (
PiNoRetest ==
FALSE) {
03075 arbiterEntry->
ResourceList = arbiterEntry->
BestResourceList;
03076 arbiterEntry->
ActiveArbiterList = arbiterEntry->
BestConfig;
03077 }
03078 arbiterEntry->
ResourcesChanged =
TRUE;
03079 listEntry = listEntry->Flink;
03080 }
03081 }
03082
03083
NTSTATUS
03084 IopAssign(
03085 IN ULONG AssignTableCount,
03086 IN
PIOP_RESOURCE_REQUEST AssignTable,
03087 IN BOOLEAN Rebalance
03088 )
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108 {
03109
NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
03110 LONG tableIndex;
03111
PREQ_LIST reqList;
03112
PREQ_ALTERNATIVE reqAlternative;
03113
PDEVICE_NODE deviceNode;
03114 LARGE_INTEGER startTime;
03115 BOOLEAN timeoutExpired;
03116 ULONG spewCount = 0;
03117
03118
PAGED_CODE();
03119
03120 timeoutExpired =
FALSE;
03121
03122
03123
03124
03125
03126
KeQuerySystemTime(&startTime);
03127
03128
03129
03130
03131
03132
03133
for (tableIndex = 0; tableIndex < (LONG)AssignTableCount; tableIndex++) {
03134
03135
if (!(AssignTable[tableIndex].Flags &
IOP_ASSIGN_EXCLUDE)) {
03136
03137 reqList = AssignTable[tableIndex].ReqList;
03138 reqList->SelectedAlternative = &reqList->ReqAlternativeTable[0];
03139 }
03140 }
03141
03142
03143
03144
03145
03146
while (tableIndex >= 0) {
03147
03148
03149
03150
03151
03152
03153
for (tableIndex = AssignTableCount - 1; tableIndex >= 0;) {
03154
03155
if (AssignTable[tableIndex].Flags &
IOP_ASSIGN_EXCLUDE) {
03156
03157 tableIndex--;
03158 }
else {
03159
03160 reqList = AssignTable[tableIndex].ReqList;
03161 reqAlternative = *reqList->SelectedAlternative;
03162 deviceNode = (
PDEVICE_NODE)AssignTable[tableIndex].PhysicalDevice->DeviceObjectExtension->DeviceNode;
03163
DebugMessage(
DUMP_DETAIL, (
"PnpRes: Adding %d/%d req alt to the arbiters for %ws.\n", reqAlternative->ReqAlternativeIndex + 1, reqList->ReqAlternativeCount, deviceNode->
InstancePath.Buffer));
03164
IopAddReqDescsToArbiters( reqAlternative->ReqDescCount,
03165 reqAlternative->ReqDescTable);
03166
if (reqList->SelectedAlternative == &reqList->ReqAlternativeTable[0]) {
03167
03168 tableIndex--;
03169 }
else {
03170
03171
break;
03172 }
03173 }
03174 }
03175
03176
03177
03178
03179
03180 status =
IopPlacement(
ArbiterActionTestAllocation, Rebalance);
03181
if (
NT_SUCCESS(status)) {
03182
03183
03184
03185
03186
if (
IopIsBestConfiguration()) {
03187
03188
03189
03190
03191
03192
03193
DebugMessage(
DUMP_DETAIL, (
"PnpRes: Found a best assignment. Save it\n"));
03194
IopSaveCurrentConfiguration();
03195
03196
03197
03198
03199
03200
03201
03202
03203 }
03204
03205
03206
03207
03208
03209
if (
PiNoRetest) {
03210
03211
break;
03212 }
03213 }
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
for (tableIndex = AssignTableCount - 1; tableIndex >= 0; ) {
03226
03227
if (AssignTable[tableIndex].Flags &
IOP_ASSIGN_EXCLUDE) {
03228
03229 tableIndex--;
03230 }
else {
03231
03232 reqList = AssignTable[tableIndex].ReqList;
03233 reqAlternative = *reqList->SelectedAlternative;
03234 deviceNode = (
PDEVICE_NODE)AssignTable[tableIndex].PhysicalDevice->DeviceObjectExtension->DeviceNode;
03235
DebugMessage(
DUMP_DETAIL, (
"PnpRes: Removing %d/%d req alt from the arbiters for %ws.\n", reqAlternative->ReqAlternativeIndex + 1, reqList->ReqAlternativeCount, deviceNode->
InstancePath.Buffer));
03236
IopRemoveReqDescsFromArbiters( reqAlternative->ReqDescCount,
03237 reqAlternative->ReqDescTable);
03238
if (++reqList->SelectedAlternative < reqList->ReqBestAlternative && !timeoutExpired) {
03239
03240
break;
03241 }
else {
03242
03243 reqList->SelectedAlternative = &reqList->ReqAlternativeTable[0];
03244 tableIndex--;
03245 }
03246 }
03247
03248 }
03249
03250
03251
03252
03253
03254
if (tableIndex >= 0) {
03255
03256 LARGE_INTEGER currentTime;
03257 ULONG timeDiff;
03258
03259
03260
03261
03262
03263
KeQuerySystemTime(¤tTime);
03264 timeDiff = (ULONG)((currentTime.QuadPart - startTime.QuadPart) / 10000);
03265
03266
03267
03268
03269
03270
if (timeDiff >=
FIND_BEST_ASSIGNMENT_TIMEOUT)
03271 {
03272
if (
PiUseTimeout) {
03273
03274
DebugMessage(
DUMP_ERROR, (
"PnpRes: Timeout expired, bailing out!\n"));
03275 timeoutExpired =
TRUE;
03276
03277 }
else {
03278
03279 spewCount = (spewCount + 1) % 50;
03280
if (spewCount == 0) {
03281
DbgPrint(
"PnpRes: Timeout expired.\n");
03282 }
03283 }
03284 }
03285 }
03286 }
03287
03288
return (status);
03289 }
03290
03291
NTSTATUS
03292 IopAssignInner(
03293 IN ULONG AssignTableCount,
03294 IN
PIOP_RESOURCE_REQUEST AssignTable,
03295 IN BOOLEAN Rebalance
03296 )
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317 {
03318
NTSTATUS status;
03319
ARBITER_ACTION arbiterAction;
03320
03321
03322
03323
03324
03325 InitializeListHead(&
PiBestArbiterList);
03326 InitializeListHead(&
PiActiveArbiterList);
03327
PiAssignTableCount = AssignTableCount;
03328
PiAssignTable = AssignTable;
03329
PiBestPriority = (ULONG) -1;
03330
if (AssignTableCount == 1) {
03331
PiNoRetest =
TRUE;
03332 arbiterAction =
ArbiterActionCommitAllocation;
03333 }
else {
03334
PiNoRetest =
FALSE;
03335 arbiterAction =
ArbiterActionRetestAllocation;
03336 }
03337
03338
03339
03340
03341
03342
IopAssign(AssignTableCount, AssignTable, Rebalance);
03343
#if DBG_SCOPE
03344
if ((
PnpResDebugLevel &
STOP_ERROR) &&
PiNoRetest ==
FALSE) {
03345
IopCheckDataStructures(
IopRootDeviceNode);
03346 }
03347
#endif
03348
if (IsListEmpty(&
PiBestArbiterList)) {
03349
DebugMessage(
DUMP_DETAIL, (
"PnpRes: IoAssignInner failed to find an assignment.\n"));
03350 status = STATUS_UNSUCCESSFUL;
03351 }
else {
03352
03353
if (Rebalance) {
03354
DebugMessage(
DUMP_DETAIL, (
"PnpRes: Restore the best assignment.\n"));
03355 }
else {
03356
DebugMessage(
DUMP_DETAIL, (
"PnpRes: Restore the best assignment and commit it.\n"));
03357 }
03358
03359
IopRestoreBestConfiguration();
03360 status =
IopPlacement(arbiterAction, Rebalance);
03361
#if DBG_SCOPE
03362
if (!Rebalance) {
03363
if (
PnpResDebugLevel &
STOP_ERROR) {
03364
IopCheckDataStructures(
IopRootDeviceNode);
03365 }
03366 }
03367
#endif
03368
ASSERT(status == STATUS_SUCCESS);
03369 }
03370
PiNoRetest =
FALSE;
03371
return status;
03372 }
03373
03374
03375
NTSTATUS
03376 IopReserve(
03377 IN PREQ_LIST ReqList
03378 )
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395 {
03396
NTSTATUS status;
03397
PREQ_ALTERNATIVE RA;
03398
PREQ_ALTERNATIVE *reqAlternative;
03399
03400
PAGED_CODE();
03401
03402
03403
03404
03405
03406 InitializeListHead(&
PiBestArbiterList);
03407 InitializeListHead(&
PiActiveArbiterList);
03408
03409 reqAlternative = ReqList->ReqAlternativeTable;
03410
03411
RA = *reqAlternative;
03412 ReqList->SelectedAlternative = reqAlternative;
03413
IopAddReqDescsToArbiters(
RA->ReqDescCount,
RA->ReqDescTable);
03414 status =
IopPlacementForReservation();
03415
#if DBG_SCOPE
03416
if (
PnpResDebugLevel &
STOP_ERROR) {
03417
IopCheckDataStructures(
IopRootDeviceNode);
03418 }
03419
#endif
03420
return status;
03421 }
03422
03423 BOOLEAN
03424 IopFindResourceHandlerInfo(
03425 IN RESOURCE_HANDLER_TYPE HandlerType,
03426 IN
PDEVICE_NODE DeviceNode,
03427 IN UCHAR ResourceType,
03428 OUT PVOID *HandlerEntry
03429 )
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455 {
03456
USHORT resourceMask;
03457
USHORT noHandlerMask, queryHandlerMask;
03458 PLIST_ENTRY listHead, nextEntry;
03459
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
03460
03461 *HandlerEntry =
NULL;
03462
03463
switch (HandlerType) {
03464
case ResourceArbiter:
03465 noHandlerMask = DeviceNode->NoArbiterMask;
03466 queryHandlerMask = DeviceNode->QueryArbiterMask;
03467 listHead = &DeviceNode->DeviceArbiterList;
03468
break;
03469
03470
case ResourceTranslator:
03471 noHandlerMask = DeviceNode->NoTranslatorMask;
03472 queryHandlerMask = DeviceNode->QueryTranslatorMask;
03473 listHead = &DeviceNode->DeviceTranslatorList;
03474
break;
03475
03476
default:
03477
return FALSE;
03478 }
03479
03480 resourceMask = 1 << ResourceType;
03481
if (noHandlerMask & resourceMask) {
03482
03483
03484
03485
03486
03487
return TRUE;
03488 }
03489
03490
if (queryHandlerMask & resourceMask) {
03491
03492
03493
03494
03495
03496
03497 nextEntry = listHead->Flink;
03498
for (; nextEntry != listHead; nextEntry = nextEntry->Flink) {
03499 arbiterEntry = CONTAINING_RECORD(nextEntry,
PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList);
03500
if (arbiterEntry->
ResourceType == ResourceType) {
03501
break;
03502 }
03503 }
03504
ASSERT(nextEntry != listHead);
03505 *HandlerEntry = arbiterEntry;
03506
return TRUE;
03507
03508 }
else {
03509
03510
03511
03512
03513
03514
03515
03516
03517
if (ResourceType >
PI_MAXIMUM_RESOURCE_TYPE_TRACKED) {
03518 nextEntry = listHead->Flink;
03519
for (; nextEntry != listHead; nextEntry = nextEntry->Flink) {
03520 arbiterEntry = CONTAINING_RECORD(nextEntry,
PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList);
03521
if (arbiterEntry->
ResourceType == ResourceType) {
03522
if (arbiterEntry->
ArbiterInterface) {
03523 *HandlerEntry = arbiterEntry;
03524 }
03525
return TRUE;
03526 }
03527 }
03528 }
03529
return FALSE;
03530 }
03531 }
03532
03533
NTSTATUS
03534 IopSetupArbiterAndTranslators(
03535 IN PREQ_DESC ReqDesc
03536 )
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556 {
03557 PLIST_ENTRY listHead, nextEntry;
03558
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
03559
PDEVICE_OBJECT deviceObject = ReqDesc->AlternativeTable.PhysicalDeviceObject;
03560
PDEVICE_NODE deviceNode;
03561
PREQ_DESC reqDesc = ReqDesc, translatedReqDesc;
03562 BOOLEAN found, arbiterFound =
FALSE, restartedAlready;
03563 BOOLEAN searchTranslator =
TRUE, translatorFound =
FALSE;
03564
NTSTATUS status;
03565
PPI_RESOURCE_TRANSLATOR_ENTRY translatorEntry;
03566 UCHAR resourceType = ReqDesc->TranslatedReqDesc->AlternativeTable.Alternatives->Type;
03567
PINTERFACE interface;
03568
USHORT resourceMask;
03569
03570
if ((ReqDesc->AlternativeTable.RequestSource ==
ArbiterRequestHalReported) &&
03571 (ReqDesc->InterfaceType == Internal)) {
03572
03573
03574
03575 restartedAlready =
TRUE;
03576 }
else {
03577 restartedAlready =
FALSE;
03578 }
03579
03580
03581
03582
03583
03584
03585
if (deviceObject && ReqDesc->AlternativeTable.RequestSource !=
ArbiterRequestHalReported) {
03586 deviceNode = (
PDEVICE_NODE)deviceObject->
DeviceObjectExtension->
DeviceNode;
03587
03588
03589
03590 }
else {
03591
03592
03593
03594
03595
03596
03597 deviceNode =
IopRootDeviceNode;
03598 }
03599
while (deviceNode) {
03600
if ((deviceNode ==
IopRootDeviceNode) && (translatorFound ==
FALSE)) {
03601
03602
03603
03604
03605
03606
03607
if (restartedAlready ==
FALSE) {
03608 restartedAlready =
TRUE;
03609
03610 deviceNode =
IopFindBusDeviceNode (
03611
IopRootDeviceNode,
03612 ReqDesc->
InterfaceType,
03613 ReqDesc->BusNumber,
03614 0
03615 );
03616
03617
03618
03619
03620
03621
03622
03623
if ((deviceNode ==
IopRootDeviceNode) &&
03624 (ReqDesc->ReqAlternative->ReqList->InterfaceType == Internal)) {
03625 deviceNode =
IopFindBusDeviceNode(
03626
IopRootDeviceNode,
03627 Isa,
03628 0,
03629 0
03630 );
03631 }
03632
03633
03634
03635
03636
continue;
03637
03638 }
03639 }
03640
03641
03642
03643
03644
03645
03646
03647
if ((arbiterFound ==
FALSE) && (deviceNode->
PhysicalDeviceObject != deviceObject)) {
03648 found =
IopFindResourceHandlerInfo(
03649
ResourceArbiter,
03650 deviceNode,
03651 resourceType,
03652 &arbiterEntry);
03653
if (found ==
FALSE) {
03654
03655
03656
03657
03658
03659
if (resourceType <=
PI_MAXIMUM_RESOURCE_TYPE_TRACKED) {
03660 resourceMask = 1 << resourceType;
03661 }
else {
03662 resourceMask = 0;
03663 }
03664 status =
IopQueryResourceHandlerInterface(
ResourceArbiter,
03665 deviceNode->
PhysicalDeviceObject,
03666 resourceType,
03667 &interface);
03668 deviceNode->
QueryArbiterMask |= resourceMask;
03669
if (!
NT_SUCCESS(status)) {
03670 deviceNode->
NoArbiterMask |= resourceMask;
03671
if (resourceType <=
PI_MAXIMUM_RESOURCE_TYPE_TRACKED) {
03672 found =
TRUE;
03673 }
else {
03674 interface =
NULL;
03675 }
03676 }
03677
if (found ==
FALSE) {
03678 arbiterEntry = (
PPI_RESOURCE_ARBITER_ENTRY)
ExAllocatePoolAE(
03679
PagedPool,
03680
sizeof(
PI_RESOURCE_ARBITER_ENTRY));
03681
if (!arbiterEntry) {
03682 status = STATUS_INSUFFICIENT_RESOURCES;
03683
return status;
03684 }
03685 InitializeListHead(&arbiterEntry->
ActiveArbiterList);
03686 InitializeListHead(&arbiterEntry->
DeviceArbiterList);
03687 InitializeListHead(&arbiterEntry->
BestConfig);
03688 InitializeListHead(&arbiterEntry->
ResourceList);
03689 InitializeListHead(&arbiterEntry->
BestResourceList);
03690 arbiterEntry->
ResourceType =resourceType;
03691 arbiterEntry->
State = 0;
03692 arbiterEntry->
ResourcesChanged =
FALSE;
03693 listHead = &deviceNode->
DeviceArbiterList;
03694 InsertTailList(listHead, &arbiterEntry->
DeviceArbiterList);
03695 arbiterEntry->
ArbiterInterface = (
PARBITER_INTERFACE)interface;
03696
if (!interface) {
03697
03698
03699
03700
03701
03702 arbiterEntry =
NULL;
03703 }
03704 }
03705 }
03706
03707
03708
03709
03710
03711
03712
if (arbiterEntry) {
03713 arbiterFound =
TRUE;
03714
if (arbiterEntry->
ArbiterInterface->
Flags &
ARBITER_PARTIAL) {
03715
03716
03717
03718
03719
03720
03721 status =
IopCallArbiter(
03722 arbiterEntry,
03723
ArbiterActionQueryArbitrate,
03724 ReqDesc->TranslatedReqDesc,
03725
NULL,
03726
NULL
03727 );
03728
if (!
NT_SUCCESS(status)) {
03729 arbiterFound =
FALSE;
03730 }
03731 }
03732 }
03733
if (arbiterFound) {
03734 ReqDesc->u.Arbiter = arbiterEntry;
03735
03736
03737
03738
03739
03740 arbiterEntry->
State = 0;
03741 arbiterEntry->
ResourcesChanged =
FALSE;
03742 }
03743
03744 }
03745
03746
if (searchTranslator) {
03747
03748
03749
03750
03751
03752
03753 found =
IopFindResourceHandlerInfo(
03754
ResourceTranslator,
03755 deviceNode,
03756 resourceType,
03757 &translatorEntry);
03758
03759
if (found ==
FALSE) {
03760
03761
03762
03763
03764
03765
if (resourceType <=
PI_MAXIMUM_RESOURCE_TYPE_TRACKED) {
03766 resourceMask = 1 << resourceType;
03767 }
else {
03768 resourceMask = 0;
03769 }
03770 status =
IopQueryResourceHandlerInterface(
ResourceTranslator,
03771 deviceNode->
PhysicalDeviceObject,
03772 resourceType,
03773 &interface);
03774 deviceNode->
QueryTranslatorMask |= resourceMask;
03775
if (!
NT_SUCCESS(status)) {
03776 deviceNode->
NoTranslatorMask |= resourceMask;
03777
if (resourceType <=
PI_MAXIMUM_RESOURCE_TYPE_TRACKED) {
03778 found =
TRUE;
03779 }
else {
03780 interface =
NULL;
03781 }
03782 }
03783
if (found ==
FALSE) {
03784 translatorEntry = (
PPI_RESOURCE_TRANSLATOR_ENTRY)
ExAllocatePoolTE(
03785
PagedPool,
03786
sizeof(
PI_RESOURCE_TRANSLATOR_ENTRY));
03787
if (!translatorEntry) {
03788 status = STATUS_INSUFFICIENT_RESOURCES;
03789
return status;
03790 }
03791 translatorEntry->
ResourceType = resourceType;
03792 InitializeListHead(&translatorEntry->
DeviceTranslatorList);
03793 translatorEntry->
TranslatorInterface = (
PTRANSLATOR_INTERFACE)interface;
03794 translatorEntry->
DeviceNode = deviceNode;
03795 listHead = &deviceNode->
DeviceTranslatorList;
03796 InsertTailList(listHead, &translatorEntry->
DeviceTranslatorList);
03797
if (!interface) {
03798
03799
03800
03801
03802
03803 translatorEntry =
NULL;
03804 }
03805 }
03806 }
03807
if (translatorEntry) {
03808 translatorFound =
TRUE;
03809 }
03810
if ((arbiterFound ==
FALSE) && translatorEntry) {
03811
03812
03813
03814
03815
03816
03817
03818 reqDesc = ReqDesc->TranslatedReqDesc;
03819 status =
IopTranslateAndAdjustReqDesc(
03820 reqDesc,
03821 translatorEntry,
03822 &translatedReqDesc);
03823
if (
NT_SUCCESS(status)) {
03824
ASSERT(translatedReqDesc);
03825 resourceType = translatedReqDesc->AlternativeTable.Alternatives->Type;
03826 translatedReqDesc->TranslatedReqDesc = ReqDesc->TranslatedReqDesc;
03827 ReqDesc->TranslatedReqDesc = translatedReqDesc;
03828
03829
03830
03831
03832
03833
03834
if (status == STATUS_TRANSLATION_COMPLETE) {
03835 searchTranslator =
FALSE;
03836 }
03837 }
else {
03838
DebugMessage(
DUMP_INFO, (
"PnpResr: resreq list TranslationAndAdjusted failed\n"));
03839
return status;
03840 }
03841 }
03842
03843 }
03844
03845
03846
03847
03848
03849 deviceNode = deviceNode->
Parent;
03850 }
03851
03852
if (arbiterFound) {
03853
return STATUS_SUCCESS;
03854 }
else {
03855
03856
03857
03858
03859
03860
DebugMessage(
DUMP_ERROR, (
"PnpResr: can not find resource type %x arbiter\n", resourceType));
03861
ASSERT(0);
03862
return STATUS_UNSUCCESSFUL;
03863 }
03864
03865 }
03866
03867
NTSTATUS
03868 IopParentToRawTranslation(
03869 IN OUT PREQ_DESC ReqDesc
03870 )
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888 {
03889
PTRANSLATOR_INTERFACE translator;
03890
NTSTATUS status = STATUS_SUCCESS;
03891
PREQ_DESC rawReqDesc;
03892
03893
if (ReqDesc->AlternativeTable.AlternativeCount == 0 ||
03894 ReqDesc->Allocation.Type == CmResourceTypeMaximum) {
03895
DebugMessage(
DUMP_ERROR, (
"PnpRes : Invalid ReqDesc for parent-to-raw translation.\n"));
03896
return STATUS_INVALID_PARAMETER;
03897 }
03898
03899
03900
03901
03902
03903
03904
03905
if (
IS_TRANSLATED_REQ_DESC(ReqDesc)) {
03906 rawReqDesc = ReqDesc->TranslatedReqDesc;
03907 translator = ReqDesc->u.Translator->TranslatorInterface;
03908 status = (translator->
TranslateResources)(
03909 translator->
Context,
03910 ReqDesc->AlternativeTable.Assignment,
03911
TranslateParentToChild,
03912 rawReqDesc->AlternativeTable.AlternativeCount,
03913 rawReqDesc->AlternativeTable.Alternatives,
03914 rawReqDesc->AlternativeTable.PhysicalDeviceObject,
03915 rawReqDesc->AlternativeTable.Assignment
03916 );
03917
if (
NT_SUCCESS(status)) {
03918
03919
03920
03921
03922
03923
03924
03925
ASSERT(status != STATUS_TRANSLATION_COMPLETE);
03926 status =
IopParentToRawTranslation(rawReqDesc);
03927 }
03928 }
03929
return status;
03930 }
03931
03932
NTSTATUS
03933 IopChildToRootTranslation(
03934 IN
PDEVICE_NODE DeviceNode, OPTIONAL
03935 IN INTERFACE_TYPE InterfaceType,
03936 IN ULONG BusNumber,
03937 IN ARBITER_REQUEST_SOURCE ArbiterRequestSource,
03938 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
03939 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *Target
03940 )
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971 {
03972
PDEVICE_NODE deviceNode;
03973 PLIST_ENTRY listHead, nextEntry;
03974 PCM_PARTIAL_RESOURCE_DESCRIPTOR target, source, tmp;
03975
PPI_RESOURCE_TRANSLATOR_ENTRY translatorEntry;
03976
PTRANSLATOR_INTERFACE translator;
03977
NTSTATUS status = STATUS_SUCCESS;
03978 BOOLEAN done =
FALSE, foundTranslator =
FALSE, restartedAlready;
03979
03980
if (ArbiterRequestSource ==
ArbiterRequestHalReported) {
03981 restartedAlready =
TRUE;
03982 }
else {
03983 restartedAlready =
FALSE;
03984 }
03985
03986 source = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
ExAllocatePoolPRD(
03987
PagedPool,
03988
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)
03989 );
03990
if (source ==
NULL) {
03991
return STATUS_INSUFFICIENT_RESOURCES;
03992 }
03993 target = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
ExAllocatePoolPRD(
03994
PagedPool,
03995
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)
03996 );
03997
if (target ==
NULL) {
03998
ExFreePool(source);
03999
return STATUS_INSUFFICIENT_RESOURCES;
04000 }
04001 *source = *Source;
04002
04003
04004
04005
04006
04007
if (!ARGUMENT_PRESENT(DeviceNode)) {
04008 deviceNode =
IopFindBusDeviceNode (
IopRootDeviceNode,
InterfaceType,
BusNumber, 0);
04009 }
else {
04010
04011
04012 deviceNode = DeviceNode;
04013 }
04014
while (deviceNode && !done) {
04015
04016
if ((deviceNode ==
IopRootDeviceNode) && (foundTranslator ==
FALSE)) {
04017
if (restartedAlready ==
FALSE) {
04018 restartedAlready =
TRUE;
04019 deviceNode =
IopFindBusDeviceNode (
IopRootDeviceNode,
InterfaceType,
BusNumber, 0);
04020
04021
04022
04023
04024
04025
04026
04027
if ((deviceNode ==
IopRootDeviceNode) && (
InterfaceType == Internal)) {
04028 deviceNode =
IopFindBusDeviceNode(
IopRootDeviceNode, Isa, 0, 0);
04029 }
04030
04031
continue;
04032 }
04033 }
04034
04035
04036
04037
04038
04039
04040 listHead = &deviceNode->
DeviceTranslatorList;
04041 nextEntry = listHead->Flink;
04042
for (; nextEntry != listHead; nextEntry = nextEntry->Flink) {
04043 translatorEntry = CONTAINING_RECORD(nextEntry,
PI_RESOURCE_TRANSLATOR_ENTRY, DeviceTranslatorList);
04044
if (translatorEntry->
ResourceType == Source->Type) {
04045
if (translator = translatorEntry->
TranslatorInterface) {
04046
04047
04048
04049
04050
04051
04052 doitagain:
04053 status = (translator->
TranslateResources) (
04054 translator->
Context,
04055 source,
04056
TranslateChildToParent,
04057 0,
04058
NULL,
04059 DeviceNode ? DeviceNode->PhysicalDeviceObject :
NULL,
04060 target
04061 );
04062
if (
NT_SUCCESS(status)) {
04063 tmp = source;
04064 source = target;
04065 target = tmp;
04066
04067
04068
04069
04070
04071
04072
04073
if (status == STATUS_TRANSLATION_COMPLETE) {
04074 done =
TRUE;
04075 }
04076
04077 }
else {
04078
#if DBG_SCOPE
04079
04080
DbgPrint(
"PnpRes: Child to Root Translation failed\n");
04081
if (DeviceNode) {
04082
DbgPrint(
04083
" DeviceNode %08x (PDO %08x)\n",
04084 DeviceNode,
04085 DeviceNode->PhysicalDeviceObject
04086 );
04087 }
04088
DbgPrint(
04089
" Resource Type %02x Data %08x %08x %08x\n",
04090 source->Type,
04091 source->u.DevicePrivate.Data[0],
04092 source->u.DevicePrivate.Data[1],
04093 source->u.DevicePrivate.Data[2]
04094 );
04095
if (
PnpResDebugTranslationFailureCount) {
04096
PnpResDebugTranslationFailureCount--;
04097
PnpResDebugTranslationFailure->
devnode = DeviceNode;
04098
PnpResDebugTranslationFailure->
resource = *source;
04099
PnpResDebugTranslationFailure++;
04100 }
04101
if (
PnpResDebugLevel &
STOP_ERROR) {
04102 DbgBreakPoint();
04103
goto doitagain;
04104 }
04105
#endif
04106
goto exit;
04107 }
04108 }
04109
break;
04110 }
04111 }
04112
04113
04114
04115
04116
04117 deviceNode = deviceNode->
Parent;
04118 }
04119 *Target = source;
04120
ExFreePool(target);
04121
return status;
04122
exit:
04123
ExFreePool(source);
04124
ExFreePool(target);
04125
return status;
04126 }
04127
04128
NTSTATUS
04129 IopTranslateAndAdjustReqDesc(
04130 IN PREQ_DESC ReqDesc,
04131 IN
PPI_RESOURCE_TRANSLATOR_ENTRY TranslatorEntry,
04132 OUT PREQ_DESC *TranslatedReqDesc
04133 )
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156 {
04157 ULONG i, total = 0, *targetCount;
04158
PTRANSLATOR_INTERFACE translator = TranslatorEntry->TranslatorInterface;
04159 PIO_RESOURCE_DESCRIPTOR ioDesc, *target, tIoDesc;
04160
PREQ_DESC tReqDesc;
04161
PARBITER_LIST_ENTRY arbiterEntry;
04162
NTSTATUS status, returnStatus = STATUS_SUCCESS;
04163 BOOLEAN reqTranslated =
FALSE;
04164
04165
if (ReqDesc->AlternativeTable.AlternativeCount == 0) {
04166
return STATUS_INVALID_PARAMETER;
04167 }
04168
04169 *TranslatedReqDesc =
NULL;
04170
04171 target = (PIO_RESOURCE_DESCRIPTOR *)
ExAllocatePoolIORD(
04172
PagedPool,
04173
sizeof(PIO_RESOURCE_DESCRIPTOR) * ReqDesc->AlternativeTable.AlternativeCount
04174 );
04175
if (target ==
NULL) {
04176
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not Enough memory to perform resreqlist adjustment\n"));
04177
return STATUS_INSUFFICIENT_RESOURCES;
04178 }
04179 RtlZeroMemory(target,
sizeof(PIO_RESOURCE_DESCRIPTOR) * ReqDesc->AlternativeTable.AlternativeCount);
04180
04181 targetCount = (PULONG)
ExAllocatePool(
04182
PagedPool,
04183
sizeof(ULONG) * ReqDesc->AlternativeTable.AlternativeCount
04184 );
04185
if (targetCount ==
NULL) {
04186
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not Enough memory to perform resreqlist adjustment\n"));
04187
ExFreePool(target);
04188
return STATUS_INSUFFICIENT_RESOURCES;
04189 }
04190
04191 RtlZeroMemory(targetCount,
sizeof(ULONG) * ReqDesc->AlternativeTable.AlternativeCount);
04192
04193
04194
04195
04196
04197 ioDesc = ReqDesc->AlternativeTable.Alternatives;
04198
for (i = 0; i < ReqDesc->AlternativeTable.AlternativeCount; i++) {
04199 status = (translator->
TranslateResourceRequirements)(
04200 translator->
Context,
04201 ioDesc,
04202 ReqDesc->AlternativeTable.PhysicalDeviceObject,
04203 &targetCount[i],
04204 &target[i]
04205 );
04206
if (!
NT_SUCCESS(status) || targetCount[i] == 0) {
04207
DebugMessage(
DUMP_ERROR, (
"PnpRes:Translator failed to adjust resreqlist\n"));
04208 target[i] = ioDesc;
04209 targetCount[i] = 0;
04210 total++;
04211 }
else {
04212 total += targetCount[i];
04213 reqTranslated =
TRUE;
04214 }
04215 ioDesc++;
04216
if (
NT_SUCCESS(status) && (returnStatus != STATUS_TRANSLATION_COMPLETE)) {
04217 returnStatus = status;
04218 }
04219 }
04220
04221
if (!reqTranslated) {
04222
DebugMessage(
DUMP_ERROR, (
"PnpRes:Failed to translate any requirement for %ws!\n", ((
PDEVICE_NODE)(ReqDesc->AlternativeTable.PhysicalDeviceObject->DeviceObjectExtension->DeviceNode))->InstancePath.Buffer));
04223 returnStatus = status;
04224 }
04225
04226
04227
04228
04229
04230 tIoDesc = (PIO_RESOURCE_DESCRIPTOR)
ExAllocatePoolIORD(
04231
PagedPool,
04232 total *
sizeof(IO_RESOURCE_DESCRIPTOR));
04233
if (!tIoDesc) {
04234
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not Enough memory to perform resreqlist adjustment\n"));
04235 returnStatus = STATUS_INSUFFICIENT_RESOURCES;
04236
goto exit;
04237 }
04238
04239 tReqDesc = (
PREQ_DESC)
ExAllocatePool1RD (
PagedPool,
sizeof(REQ_DESC));
04240
if (tReqDesc ==
NULL) {
04241
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not Enough memory to perform resreqlist adjustment\n"));
04242
ExFreePool(tIoDesc);
04243 returnStatus = STATUS_INSUFFICIENT_RESOURCES;
04244
goto exit;
04245 }
04246
04247
04248
04249
04250
04251 RtlMoveMemory(tReqDesc, ReqDesc,
sizeof(REQ_DESC));
04252
04253
04254
04255
04256
04257
04258 tReqDesc->ReqAlternative =
NULL;
04259
04260 tReqDesc->u.Translator = TranslatorEntry;
04261 tReqDesc->TranslatedReqDesc =
NULL;
04262 arbiterEntry = &tReqDesc->AlternativeTable;
04263 InitializeListHead(&arbiterEntry->
ListEntry);
04264 arbiterEntry->
AlternativeCount = total;
04265 arbiterEntry->
Alternatives = tIoDesc;
04266 arbiterEntry->
Assignment = &tReqDesc->Allocation;
04267
04268 ioDesc = ReqDesc->AlternativeTable.Alternatives;
04269
for (i = 0; i < ReqDesc->AlternativeTable.AlternativeCount; i++) {
04270
if (targetCount[i] != 0) {
04271 RtlMoveMemory(tIoDesc, target[i], targetCount[i] *
sizeof(IO_RESOURCE_DESCRIPTOR));
04272 tIoDesc += targetCount[i];
04273 }
else {
04274
04275
04276
04277
04278
04279 RtlMoveMemory(tIoDesc, ioDesc,
sizeof(IO_RESOURCE_DESCRIPTOR));
04280
switch (tIoDesc->Type) {
04281
case CmResourceTypePort:
04282
case CmResourceTypeMemory:
04283 tIoDesc->u.Port.MinimumAddress.LowPart = 2;
04284 tIoDesc->u.Port.MinimumAddress.HighPart = 0;
04285 tIoDesc->u.Port.MaximumAddress.LowPart = 1;
04286 tIoDesc->u.Port.MaximumAddress.HighPart = 0;
04287
break;
04288
case CmResourceTypeBusNumber:
04289 tIoDesc->u.BusNumber.MinBusNumber = 2;
04290 tIoDesc->u.BusNumber.MaxBusNumber = 1;
04291
break;
04292
04293
case CmResourceTypeInterrupt:
04294 tIoDesc->u.Interrupt.MinimumVector = 2;
04295 tIoDesc->u.Interrupt.MaximumVector = 1;
04296
break;
04297
04298
case CmResourceTypeDma:
04299 tIoDesc->u.Dma.MinimumChannel = 2;
04300 tIoDesc->u.Dma.MaximumChannel = 1;
04301
break;
04302
default:
04303
ASSERT(0);
04304
break;
04305 }
04306 tIoDesc += 1;
04307 }
04308 ioDesc++;
04309
04310 }
04311
04312
#if DBG
04313
04314
04315
04316
04317 ioDesc = arbiterEntry->
Alternatives;
04318
ASSERT((ioDesc->Option & IO_RESOURCE_ALTERNATIVE) == 0);
04319 ioDesc++;
04320
for (i = 1; i < total; i++) {
04321
ASSERT(ioDesc->Option & IO_RESOURCE_ALTERNATIVE);
04322 ioDesc++;
04323 }
04324
#endif
04325
*TranslatedReqDesc = tReqDesc;
04326
exit:
04327
for (i = 0; i < ReqDesc->AlternativeTable.AlternativeCount; i++) {
04328
if (targetCount[i] != 0) {
04329
ASSERT(target[i]);
04330
ExFreePool(target[i]);
04331 }
04332 }
04333
ExFreePool(target);
04334
ExFreePool(targetCount);
04335
return returnStatus;
04336 }
04337
04338
NTSTATUS
04339 IopCallArbiter(
04340
PPI_RESOURCE_ARBITER_ENTRY ArbiterEntry,
04341 ARBITER_ACTION Command,
04342 PVOID Input1,
04343 PVOID Input2,
04344 PVOID Input3
04345 )
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368 {
04369
ARBITER_PARAMETERS parameters;
04370
PARBITER_INTERFACE arbiterInterface = ArbiterEntry->
ArbiterInterface;
04371
NTSTATUS status;
04372
PARBITER_LIST_ENTRY arbiterListEntry;
04373 LIST_ENTRY listHead;
04374 PVOID *ExtParams;
04375
04376
switch (Command) {
04377
case ArbiterActionTestAllocation:
04378
case ArbiterActionRetestAllocation:
04379
04380
04381
04382
04383
04384
04385 parameters.
Parameters.TestAllocation.ArbitrationList = (PLIST_ENTRY)Input1;
04386 parameters.
Parameters.TestAllocation.AllocateFromCount = (ULONG)((ULONG_PTR)Input2);
04387 parameters.
Parameters.TestAllocation.AllocateFrom =
04388 (PCM_PARTIAL_RESOURCE_DESCRIPTOR)Input3;
04389 status = (arbiterInterface->
ArbiterHandler)(
04390 arbiterInterface->
Context,
04391 Command,
04392 ¶meters
04393 );
04394
break;
04395
04396
case ArbiterActionBootAllocation:
04397
04398
04399
04400
04401
04402
04403 parameters.
Parameters.BootAllocation.ArbitrationList = (PLIST_ENTRY)Input1;
04404
04405 status = (arbiterInterface->
ArbiterHandler)(
04406 arbiterInterface->
Context,
04407 Command,
04408 ¶meters
04409 );
04410
break;
04411
04412
case ArbiterActionQueryArbitrate:
04413
04414
04415
04416
04417
04418 arbiterListEntry = &((
PREQ_DESC)Input1)->AlternativeTable;
04419
ASSERT(IsListEmpty(&arbiterListEntry->
ListEntry));
04420 listHead = arbiterListEntry->
ListEntry;
04421 arbiterListEntry->
ListEntry.Flink = arbiterListEntry->
ListEntry.Blink = &listHead;
04422 parameters.
Parameters.QueryArbitrate.ArbitrationList = &listHead;
04423 status = (arbiterInterface->
ArbiterHandler)(
04424 arbiterInterface->
Context,
04425 Command,
04426 ¶meters
04427 );
04428 arbiterListEntry->
ListEntry = listHead;
04429
break;
04430
04431
case ArbiterActionCommitAllocation:
04432
case ArbiterActionRollbackAllocation:
04433
case ArbiterActionWriteReservedResources:
04434
04435
04436
04437
04438
04439 status = (arbiterInterface->
ArbiterHandler)(
04440 arbiterInterface->
Context,
04441 Command,
04442
NULL
04443 );
04444
break;
04445
04446
case ArbiterActionQueryAllocatedResources:
04447 status = STATUS_NOT_IMPLEMENTED;
04448
break;
04449
04450
case ArbiterActionQueryConflict:
04451
04452
04453
04454
04455
04456
04457 ExtParams = (PVOID*)Input1;
04458
04459 parameters.
Parameters.QueryConflict.PhysicalDeviceObject = (
PDEVICE_OBJECT)ExtParams[0];
04460 parameters.
Parameters.QueryConflict.ConflictingResource = (PIO_RESOURCE_DESCRIPTOR)ExtParams[1];
04461 parameters.
Parameters.QueryConflict.ConflictCount = (PULONG)ExtParams[2];
04462 parameters.
Parameters.QueryConflict.Conflicts = (
PARBITER_CONFLICT_INFO *)ExtParams[3];
04463 status = (arbiterInterface->
ArbiterHandler)(
04464 arbiterInterface->
Context,
04465 Command,
04466 ¶meters
04467 );
04468
break;
04469
04470
default:
04471 status = STATUS_INVALID_PARAMETER;
04472
break;
04473 }
04474
04475
return status;
04476 }
04477
04478
#if DBG_SCOPE
04479
VOID
04480 IopDumpResourceRequirementsList(
04481 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources
04482 )
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500 {
04501 PIO_RESOURCE_LIST IoResourceList;
04502 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor;
04503 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptorEnd;
04504 LONG IoResourceListCount;
04505
04506
if (IoResources ==
NULL) {
04507
return;
04508 }
04509 IoResourceList = IoResources->List;
04510 IoResourceListCount = (LONG) IoResources->AlternativeLists;
04511
04512
04513
04514
04515
04516
DbgPrint(
"** ResReqList: Interface: %x, Bus: %x, Slot: %x, AlternativeLists: %x\n",
04517 IoResources->InterfaceType,
04518 IoResources->BusNumber,
04519 IoResources->SlotNumber,
04520 IoResources->AlternativeLists);
04521
while (--IoResourceListCount >= 0) {
04522
DbgPrint (
" Alternative List: DescCount: %x\n", IoResourceList->Count);
04523 IoResourceDescriptor = IoResourceList->Descriptors;
04524 IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count;
04525
for (; IoResourceDescriptor < IoResourceDescriptorEnd; ++IoResourceDescriptor) {
04526
IopDumpResourceDescriptor(
" ", IoResourceDescriptor);
04527 }
04528 IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd;
04529 }
04530
DbgPrint(
"\n");
04531 }
04532
VOID
04533 IopDumpResourceDescriptor (
04534 IN PUCHAR Indent,
04535 IN PIO_RESOURCE_DESCRIPTOR Desc
04536 )
04537 {
04538
DbgPrint(
"%sOpt: %x, Share: %x\t", Indent, Desc->Option, Desc->ShareDisposition);
04539
switch (Desc->Type) {
04540
case CmResourceTypePort:
04541
DbgPrint (
"IO Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n",
04542 Desc->u.Port.MinimumAddress.HighPart, Desc->u.Port.MinimumAddress.LowPart,
04543 Desc->u.Port.MaximumAddress.HighPart, Desc->u.Port.MaximumAddress.LowPart,
04544 Desc->u.Port.Alignment,
04545 Desc->u.Port.Length
04546 );
04547
break;
04548
04549
case CmResourceTypeMemory:
04550
DbgPrint (
"MEM Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n",
04551 Desc->u.Memory.MinimumAddress.HighPart, Desc->u.Memory.MinimumAddress.LowPart,
04552 Desc->u.Memory.MaximumAddress.HighPart, Desc->u.Memory.MaximumAddress.LowPart,
04553 Desc->u.Memory.Alignment,
04554 Desc->u.Memory.Length
04555 );
04556
break;
04557
04558
case CmResourceTypeInterrupt:
04559
DbgPrint (
"INT Min: %x, Max: %x\n",
04560 Desc->u.Interrupt.MinimumVector,
04561 Desc->u.Interrupt.MaximumVector
04562 );
04563
break;
04564
04565
case CmResourceTypeDma:
04566
DbgPrint (
"DMA Min: %x, Max: %x\n",
04567 Desc->u.Dma.MinimumChannel,
04568 Desc->u.Dma.MaximumChannel
04569 );
04570
break;
04571
04572
case CmResourceTypeDevicePrivate:
04573
DbgPrint (
"DevicePrivate Data: %x, %x, %x\n",
04574 Desc->u.DevicePrivate.Data[0],
04575 Desc->u.DevicePrivate.Data[1],
04576 Desc->u.DevicePrivate.Data[2]
04577 );
04578
break;
04579
04580
default:
04581
DbgPrint (
"Unknown Descriptor type %x\n",
04582 Desc->Type
04583 );
04584
break;
04585 }
04586 }
04587
#endif
04588
VOID
04589 IopQueryRebalance (
04590 IN
PDEVICE_NODE DeviceNode,
04591 IN ULONG Phase,
04592 IN PULONG RebalanceCount,
04593 IN
PDEVICE_OBJECT **DeviceTable
04594 )
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623 {
04624 LONG oldState;
04625
PDEVICE_OBJECT *deviceList, *deviceTable, *device;
04626 ULONG count;
04627
PDEVICE_NODE deviceNode;
04628
04629
04630
04631
04632
04633
04634 deviceTable = *DeviceTable;
04635
IopQueryRebalanceWorker (DeviceNode, Phase, RebalanceCount, DeviceTable);
04636
04637 count = *RebalanceCount;
04638
if (count != 0 && Phase == 0) {
04639
04640
04641
04642
04643
04644
04645 deviceList = (
PDEVICE_OBJECT *)
ExAllocatePoolPDO(
PagedPool, count *
sizeof(
PDEVICE_OBJECT));
04646
if (deviceList ==
NULL) {
04647 *RebalanceCount = 0;
04648
return;
04649 }
04650 RtlMoveMemory(deviceList, deviceTable,
sizeof(
PDEVICE_OBJECT) * count);
04651
04652
04653
04654
04655
04656 *RebalanceCount = 0;
04657 *DeviceTable = deviceTable;
04658
for (device = deviceList; device < (deviceList + count); device++) {
04659 deviceNode = (
PDEVICE_NODE)((*device)->DeviceObjectExtension->DeviceNode);
04660
IopQueryRebalanceWorker (deviceNode, 1, RebalanceCount, DeviceTable);
04661 }
04662
ExFreePool(deviceList);
04663 }
04664
return;
04665 }
04666
VOID
04667 IopQueryRebalanceWorker (
04668 IN
PDEVICE_NODE DeviceNode,
04669 IN ULONG Phase,
04670 IN PULONG RebalanceCount,
04671 IN
PDEVICE_OBJECT **DeviceTable
04672 )
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698 {
04699
PDEVICE_NODE node;
04700
04701
if (DeviceNode ==
NULL)
04702 {
04703
ASSERT(DeviceNode);
04704
return;
04705 }
04706
04707
04708
04709
04710
04711
04712
04713
04714
if (((DeviceNode->Flags &
DNF_ASYNC_REQUEST_PENDING) ||
04715 (DeviceNode->Flags &
DNF_STOPPED) ||
04716 (
IopDoesDevNodeHaveProblem(DeviceNode)) ||
04717 (DeviceNode->Flags &
DNF_LEGACY_DRIVER) ||
04718 (DeviceNode->Flags &
DNF_ASSIGNING_RESOURCES)) &&
04719 !(DeviceNode->Flags &
DNF_NEEDS_REBALANCE)) {
04720
04721 node = DeviceNode->
Sibling;
04722
04723 }
else {
04724
04725 node = DeviceNode;
04726
04727 }
04728
04729
for (; node; node = node->
Sibling) {
04730
04731
if (node->
Child) {
04732
04733
04734
04735
04736
04737
if (node->
LockCount == 0) {
04738
04739
KeWaitForSingleObject( &node->
EnumerationMutex,
04740
Executive,
04741
KernelMode,
04742
FALSE,
04743
NULL);
04744
04745
IopQueryRebalanceWorker (node->
Child, Phase, RebalanceCount, DeviceTable);
04746
04747
KeSetEvent(&node->
EnumerationMutex, 0,
FALSE);
04748 }
04749 }
04750 }
04751
04752
for (node = DeviceNode; node; node = node->
Sibling) {
04753
04754
if (node->
LockCount == 0) {
04755
04756
IopTestForReconfiguration (node, Phase, RebalanceCount, DeviceTable);
04757
04758 }
else {
04759
04760
DebugMessage(
DUMP_ERROR, (
"PNPRES: %ws enum lock is taken, skipping during REBALANCE!\n", node->
InstancePath.Buffer));
04761
04762 }
04763 }
04764 }
04765
04766
VOID
04767 IopTestForReconfiguration (
04768 IN
PDEVICE_NODE DeviceNode,
04769 IN ULONG Phase,
04770 IN PULONG RebalanceCount,
04771 IN
PDEVICE_OBJECT **DeviceTable
04772 )
04773
04774
04775
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797 {
04798
PDEVICE_NODE nodex;
04799
NTSTATUS status;
04800 BOOLEAN addToList =
FALSE;
04801
04802
04803
04804
04805
04806
if ((DeviceNode->Flags &
DNF_ASYNC_REQUEST_PENDING) ||
04807 (DeviceNode->Flags &
DNF_STOPPED) ||
04808 (
IopDoesDevNodeHaveProblem(DeviceNode)) ||
04809 (DeviceNode->Flags &
DNF_LEGACY_DRIVER) ||
04810 (DeviceNode->Flags &
DNF_ASSIGNING_RESOURCES)) {
04811
return;
04812 }
04813
04814
if (Phase == 0) {
04815
04816
04817
04818
04819
04820
04821
if (DeviceNode->Flags &
DNF_RESOURCE_REQUIREMENTS_CHANGED &&
04822 !(DeviceNode->Flags &
DNF_NON_STOPPED_REBALANCE) ) {
04823
04824
04825
04826
04827
04828
04829 addToList =
TRUE;
04830 }
else {
04831
04832
if (DeviceNode->Flags &
DNF_STARTED) {
04833 status =
IopQueryReconfiguration (
IRP_MN_QUERY_STOP_DEVICE, DeviceNode->PhysicalDeviceObject);
04834
if (
NT_SUCCESS(status)) {
04835
if (status == STATUS_RESOURCE_REQUIREMENTS_CHANGED) {
04836
04837
04838
04839
04840
04841
04842
04843 DeviceNode->Flags |=
DNF_RESOURCE_REQUIREMENTS_CHANGED;
04844 addToList =
TRUE;
04845 }
04846 }
04847
IopQueryReconfiguration (
IRP_MN_CANCEL_STOP_DEVICE, DeviceNode->PhysicalDeviceObject);
04848 }
04849 }
04850
if (addToList) {
04851 *RebalanceCount = *RebalanceCount + 1;
04852 **DeviceTable = DeviceNode->PhysicalDeviceObject;
04853 *DeviceTable = *DeviceTable + 1;
04854 }
04855 }
else {
04856
04857
04858
04859
04860
04861
if (DeviceNode->Flags &
DNF_STARTED) {
04862
04863
04864
04865
04866
04867 nodex = DeviceNode->
Child;
04868
while (nodex) {
04869
if (!(nodex->
Flags & (
DNF_STARTED |
DNF_ASSIGNING_RESOURCES)) ||
04870 (nodex->
Flags &
DNF_STOPPED) ||
04871 (nodex->
Flags &
DNF_NEEDS_REBALANCE)) {
04872 nodex = nodex->
Sibling;
04873 }
else {
04874
break;
04875 }
04876 }
04877
if (nodex) {
04878
04879
04880
04881
04882
04883
04884
04885
DebugMessage(
DUMP_INFO, (
"Rebalance: Child %ws not stopped for %ws\n", nodex->
InstancePath.Buffer, DeviceNode->InstancePath.Buffer));
04886
return;
04887 }
04888 }
else if ((DeviceNode->Flags &
DNF_HAS_BOOT_CONFIG) == 0 ||
04889 !(DeviceNode->Flags &
DNF_ADDED) ||
04890 DeviceNode->Flags &
DNF_MADEUP) {
04891
04892
04893
04894
04895
04896
04897
04898
04899
04900
04901
04902
return;
04903 }
04904 status =
IopQueryReconfiguration (
IRP_MN_QUERY_STOP_DEVICE, DeviceNode->PhysicalDeviceObject);
04905
if (
NT_SUCCESS(status)) {
04906
DebugMessage(
DUMP_INFO, (
"Rebalance: %ws succeeded QueryStop\n", DeviceNode->InstancePath.Buffer));
04907
if (DeviceNode->Flags &
DNF_STARTED) {
04908
04909
04910 DeviceNode->Flags |=
DNF_STOPPED;
04911 *RebalanceCount = *RebalanceCount + 1;
04912 **DeviceTable = DeviceNode->PhysicalDeviceObject;
04913
04914
04915
04916
04917
04918
ObReferenceObject(DeviceNode->PhysicalDeviceObject);
04919 *DeviceTable = *DeviceTable + 1;
04920 }
else {
04921
04922
04923
04924
04925
04926
04927
ASSERT(DeviceNode->Flags &
DNF_HAS_BOOT_CONFIG);
04928 status =
IopQueryReconfiguration (
IRP_MN_STOP_DEVICE, DeviceNode->PhysicalDeviceObject);
04929
ASSERT(
NT_SUCCESS(status));
04930
IopReleaseBootResources(DeviceNode);
04931
04932
04933
04934
04935
04936 DeviceNode->Flags &= ~(
DNF_HAS_BOOT_CONFIG +
DNF_BOOT_CONFIG_RESERVED);
04937 }
04938 }
else {
04939
IopQueryReconfiguration (
IRP_MN_CANCEL_STOP_DEVICE, DeviceNode->PhysicalDeviceObject);
04940 }
04941 }
04942
04943 }
04944
04945
NTSTATUS
04946 IopPlacementForRebalance (
04947 IN
PDEVICE_NODE DeviceNode,
04948 IN ARBITER_ACTION ArbiterAction
04949 )
04950
04951
04952
04953
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964
04965
04966
04967
04968
04969
04970 {
04971
NTSTATUS status = STATUS_SUCCESS;
04972
PDEVICE_NODE node;
04973
04974
04975
04976
04977
04978
04979 node = DeviceNode;
04980
while (node) {
04981
04982
04983
04984
04985
04986
if (node->
LockCount == 0) {
04987
04988 status =
IopArbitrateDeviceResources (node, ArbiterAction);
04989
if (!
NT_SUCCESS(status)) {
04990
return status;
04991 }
04992 }
04993 node = node->
Sibling;
04994 }
04995 node = DeviceNode;
04996
while (node) {
04997
04998
04999
05000
05001
05002
if (node->
Child && node->
LockCount == 0) {
05003
05004 status =
IopPlacementForRebalance (node->
Child, ArbiterAction);
05005
if (!
NT_SUCCESS(status)) {
05006
return status;
05007 }
05008 }
05009 node = node->
Sibling;
05010 }
05011
05012
return status;
05013 }
05014
05015
NTSTATUS
05016 IopArbitrateDeviceResources (
05017 IN
PDEVICE_NODE DeviceNode,
05018 IN ARBITER_ACTION ArbiterAction
05019 )
05020
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036
05037 {
05038 PLIST_ENTRY listEntry, listHead;
05039
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
05040 ULONG count = 0;
05041 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDesc =
NULL;
05042
NTSTATUS status;
05043
05044
ASSERT((ArbiterAction ==
ArbiterActionTestAllocation) ||
05045 (ArbiterAction ==
ArbiterActionRetestAllocation) ||
05046 (ArbiterAction ==
ArbiterActionCommitAllocation));
05047
05048
05049 listHead = &DeviceNode->DeviceArbiterList;
05050 listEntry = listHead->Flink;
05051
while (listEntry != listHead) {
05052 arbiterEntry = CONTAINING_RECORD(listEntry,
PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList);
05053 listEntry = listEntry->Flink;
05054
if (IsListEmpty(&arbiterEntry->
ResourceList) ==
FALSE) {
05055
05056
if (ArbiterAction ==
ArbiterActionCommitAllocation) {
05057
05058 status =
IopCallArbiter(arbiterEntry,
ArbiterActionCommitAllocation,
NULL,
NULL,
NULL);
05059
ASSERT(status == STATUS_SUCCESS);
05060 arbiterEntry->
State = 0;
05061 InitializeListHead(&arbiterEntry->
ActiveArbiterList);
05062 InitializeListHead(&arbiterEntry->
BestConfig);
05063 InitializeListHead(&arbiterEntry->
ResourceList);
05064 InitializeListHead(&arbiterEntry->
BestResourceList);
05065
05066 }
else if (arbiterEntry->
ResourcesChanged ==
FALSE) {
05067
05068
05069
05070
05071
05072
05073
if (arbiterEntry->
State &
PI_ARBITER_TEST_FAILED) {
05074
return STATUS_UNSUCCESSFUL;
05075 }
05076 }
else {
05077
05078
05079
05080
05081
05082
05083
05084
05085 status =
IopFindResourcesForArbiter(
05086 DeviceNode,
05087 arbiterEntry->
ResourceType,
05088 &count,
05089 &cmDesc
05090 );
05091
if (!
NT_SUCCESS(status)) {
05092
DebugMessage(
DUMP_ERROR, (
"Rebalance: Failed to find required resources for Arbiter\n"));
05093
return status;
05094 }
05095 status =
IopCallArbiter(arbiterEntry,
05096 ArbiterAction,
05097 &arbiterEntry->
ResourceList,
05098 (PVOID)ULongToPtr(count),
05099 cmDesc
05100 );
05101
if (cmDesc) {
05102
ExFreePool(cmDesc);
05103 }
05104
if (!
NT_SUCCESS(status)) {
05105 arbiterEntry->
State |=
PI_ARBITER_TEST_FAILED;
05106
return status;
05107 }
else {
05108 arbiterEntry->
State &= ~
PI_ARBITER_TEST_FAILED;
05109 arbiterEntry->
ResourcesChanged =
FALSE;
05110
if (ArbiterAction ==
ArbiterActionTestAllocation) {
05111 arbiterEntry->
State |=
PI_ARBITER_HAS_SOMETHING;
05112 }
05113 }
05114 }
05115 }
05116 }
05117
return STATUS_SUCCESS;
05118 }
05119
05120
NTSTATUS
05121 IopFindResourcesForArbiter (
05122 IN
PDEVICE_NODE DeviceNode,
05123 IN UCHAR ResourceType,
05124 OUT ULONG *Count,
05125 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *CmDesc
05126 )
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138
05139
05140
05141
05142
05143
05144
05145
05146
05147
05148
05149
05150 {
05151
PIOP_RESOURCE_REQUEST assignEntry;
05152
PREQ_ALTERNATIVE reqAlternative;
05153
PREQ_DESC reqDesc;
05154 ULONG i, count = 0;
05155 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor;
05156
05157 *
Count = 0;
05158 *CmDesc =
NULL;
05159
if (DeviceNode->Flags &
DNF_STARTED) {
05160
return STATUS_SUCCESS;
05161 }
05162
05163
05164
05165
05166
05167
for (assignEntry =
PiAssignTable +
PiAssignTableCount - 1;
05168 assignEntry >=
PiAssignTable;
05169 assignEntry--) {
05170
if (assignEntry->
PhysicalDevice == DeviceNode->PhysicalDeviceObject) {
05171
break;
05172 }
05173 }
05174
if (assignEntry <
PiAssignTable) {
05175
DebugMessage(
DUMP_ERROR, (
"Rebalance: No resreqlist for Arbiter? Can not find Arbiter assign table entry\n"));
05176
return STATUS_UNSUCCESSFUL;
05177 }
05178
05179 reqAlternative = *((
PREQ_LIST)assignEntry->
ReqList)->SelectedAlternative;
05180
for (i = 0; i < reqAlternative->ReqDescCount; i++) {
05181 reqDesc = reqAlternative->ReqDescTable[i]->TranslatedReqDesc;
05182
if (reqDesc->Allocation.Type == ResourceType) {
05183 count++;
05184 }
05185 }
05186
05187 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
ExAllocatePoolPRD(
05188
PagedPool,
05189
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * count
05190 );
05191
if (!cmDescriptor) {
05192
05193
05194
05195
05196
05197
DebugMessage(
DUMP_ERROR, (
"Rebalance: Not enough memory to perform rebalance\n"));
05198
return STATUS_INSUFFICIENT_RESOURCES;
05199 }
05200
05201 *
Count = count;
05202 *CmDesc = cmDescriptor;
05203
05204
for (i = 0; i < reqAlternative->ReqDescCount; i++) {
05205 reqDesc = reqAlternative->ReqDescTable[i]->TranslatedReqDesc;
05206
if (reqDesc->Allocation.Type == ResourceType) {
05207 *cmDescriptor = reqDesc->Allocation;
05208 cmDescriptor++;
05209 }
05210 }
05211
return STATUS_SUCCESS;
05212 }
05213
05214
NTSTATUS
05215 IopRebalance (
05216 IN ULONG AssignTableCount,
05217 IN
PIOP_RESOURCE_REQUEST AssignTable
05218 )
05219
05220
05221
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243 {
05244 ULONG count, i;
05245
PIOP_RESOURCE_REQUEST table =
NULL, tableEnd, newEntry;
05246
PIOP_RESOURCE_REQUEST requestTable =
NULL, requestTableEnd, entry1, entry2;
05247 ULONG phase0RebalanceCount = 0, rebalanceCount = 0, deviceCount;
05248
NTSTATUS status, statusx;
05249
PDEVICE_OBJECT *deviceTable, *deviceTablex;
05250
PDEVICE_NODE deviceNode;
05251 ULONG rebalancePhase = 0;
05252
05253
05254
05255
05256
05257
05258 deviceTable = (
PDEVICE_OBJECT *)
ExAllocatePoolPDO(
05259
PagedPool,
05260
sizeof(
PDEVICE_OBJECT) *
IopNumberDeviceNodes);
05261
if (deviceTable ==
NULL) {
05262
DebugMessage(
DUMP_ERROR, (
"Rebalance: Not enough memory to perform rebalance\n"));
05263
return STATUS_INSUFFICIENT_RESOURCES;
05264 }
05265
05266
05267 tryAgain:
05268 deviceTablex = deviceTable + phase0RebalanceCount;
05269
05270
05271
05272
05273
05274
05275
05276
05277
IopQueryRebalance (
IopRootDeviceNode, rebalancePhase, &rebalanceCount, &deviceTablex);
05278
if (rebalanceCount == 0) {
05279
05280
05281
05282
05283
05284
05285
if (rebalancePhase == 0 && AssignTableCount != 0) {
05286 rebalancePhase = 1;
05287
goto tryAgain;
05288 }
05289
DebugMessage(
DUMP_INFO, (
"Rebalance: No device participates in rebalance phase %x\n", rebalancePhase));
05290
ExFreePool(deviceTable);
05291 deviceTable =
NULL;
05292 status = STATUS_UNSUCCESSFUL;
05293
goto exit;
05294 }
05295
if (rebalanceCount == phase0RebalanceCount) {
05296
05297
05298
05299
05300
05301 status = STATUS_UNSUCCESSFUL;
05302
goto exit;
05303 }
05304
if (rebalancePhase == 0) {
05305 phase0RebalanceCount = rebalanceCount;
05306 }
05307
05308
05309
05310
05311
05312 table = (
PIOP_RESOURCE_REQUEST)
ExAllocatePoolIORR(
05313
PagedPool,
05314
sizeof(
IOP_RESOURCE_REQUEST) * (AssignTableCount + rebalanceCount)
05315 );
05316
if (table ==
NULL) {
05317
DebugMessage(
DUMP_ERROR, (
"Rebalance: Not enough memory to perform rebalance\n"));
05318 status = STATUS_INSUFFICIENT_RESOURCES;
05319
goto exit;
05320 }
05321 tableEnd = table + AssignTableCount + rebalanceCount;
05322
05323
05324
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334
if (AssignTableCount != 0) {
05335 RtlMoveMemory(table, AssignTable,
sizeof(
IOP_RESOURCE_REQUEST) * AssignTableCount);
05336 }
05337
05338
05339
05340
05341
05342 newEntry = table + AssignTableCount;
05343 RtlZeroMemory(newEntry,
sizeof(
IOP_RESOURCE_REQUEST) * rebalanceCount);
05344
for (i = 0, deviceTablex = deviceTable; i < rebalanceCount; i++, deviceTablex++) {
05345 newEntry[i].
AllocationType =
ArbiterRequestPnpEnumerated;
05346 newEntry[i].
PhysicalDevice = *deviceTablex;
05347 }
05348
05349 status =
IopGetResourceRequirementsForAssignTable(
05350 newEntry,
05351 tableEnd ,
05352 &deviceCount);
05353
if (!
NT_SUCCESS(status) || deviceCount == 0) {
05354
DebugMessage(
DUMP_ERROR, (
"Rebalance: GetResourceRequirementsForAssignTable failed\n"));
05355 status =
NT_SUCCESS(status)? STATUS_UNSUCCESSFUL : status;
05356
goto exit;
05357 }
05358
05359
05360
05361
05362
05363
if (deviceCount != rebalanceCount) {
05364
05365 deviceCount += AssignTableCount;
05366 requestTable = (
PIOP_RESOURCE_REQUEST)
ExAllocatePoolIORR(
05367
PagedPool,
05368
sizeof(
IOP_RESOURCE_REQUEST) * deviceCount
05369 );
05370
if (requestTable ==
NULL) {
05371
IopFreeResourceRequirementsForAssignTable(newEntry, tableEnd);
05372 status = STATUS_INSUFFICIENT_RESOURCES;
05373
goto exit;
05374 }
05375
for (entry1 = table, entry2 = requestTable; entry1 < tableEnd; entry1++) {
05376
if (!(entry1->
Flags &
IOP_ASSIGN_IGNORE)) {
05377 *entry2 = *entry1;
05378 entry2++;
05379 }
else {
05380
05381
05382
05383
05384
ASSERT(entry1 >= newEntry);
05385 }
05386 }
05387 requestTableEnd = requestTable + deviceCount;
05388 }
else {
05389 requestTable = table;
05390 requestTableEnd = tableEnd;
05391 deviceCount += AssignTableCount;
05392 }
05393
05394
05395
05396
05397
05398
05399
05400
#if 0
05401
05402
05403
05404
05405
05406
for (entry1 = newEntry; entry1 < tableEnd; entry1++) {
05407
if (!(entry1->
Flags &
IOP_ASSIGN_IGNORE) &&
05408 !(entry1->
Flags &
IOP_ASSIGN_RESOURCES_RELEASED)) {
05409 deviceNode = (
PDEVICE_NODE)entry1->
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
05410
if (deviceNode->
ResourceList) {
05411
05412
05413
05414
05415
05416
05417
05418
IopReleaseResourcesInternal(deviceNode);
05419 entry1->
Flags |=
IOP_ASSIGN_RESOURCES_RELEASED;
05420 }
05421 }
05422 }
05423
05424
#endif
05425
05426
05427
05428
05429
05430
05431 status =
IopAssignInner(deviceCount, requestTable,
TRUE);
05432
if (
NT_SUCCESS(status)) {
05433
05434
05435
05436
05437
05438
05439
05440
IopBuildCmResourceLists(requestTable, requestTableEnd);
05441
05442
05443
05444
05445
05446
if (AssignTableCount != 0) {
05447 RtlMoveMemory(AssignTable, requestTable,
sizeof(
IOP_RESOURCE_REQUEST) * AssignTableCount);
05448 }
05449
05450
05451
05452
IopFreeResourceRequirementsForAssignTable(requestTable+AssignTableCount, requestTableEnd);
05453
05454
if (table != requestTable) {
05455
05456
05457
05458
05459
05460
05461
for (entry1 = table, entry2 = requestTable; entry2 < requestTableEnd;) {
05462
05463
if (entry1->
Flags &
IOP_ASSIGN_IGNORE) {
05464 entry1++;
05465
continue;
05466 }
05467 *entry1 = *entry2;
05468
if (entry2->Flags &
IOP_ASSIGN_EXCLUDE) {
05469 entry1->
Status = STATUS_CONFLICTING_ADDRESSES;
05470 }
05471 entry2++;
05472 entry1++;
05473 }
05474 }
05475
05476
05477
05478
05479
05480
DebugMessage(
DUMP_DETAIL, (
"PnpRes: STOP reconfigured devices during REBALANCE.\n"));
05481
05482
for (entry1 = newEntry; entry1 < tableEnd; entry1++) {
05483
if (
NT_SUCCESS(entry1->
Status)) {
05484
IopQueryReconfiguration (
IRP_MN_STOP_DEVICE, entry1->
PhysicalDevice);
05485 }
else {
05486
IopQueryReconfiguration (
IRP_MN_CANCEL_STOP_DEVICE, entry1->
PhysicalDevice);
05487 deviceNode = (
PDEVICE_NODE)entry1->
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
05488 deviceNode->
Flags &= ~
DNF_STOPPED;
05489 }
05490 }
05491
05492
05493
05494
05495
05496
DebugMessage(
DUMP_DETAIL, (
"PnpRes: Commit the new allocation during REBALANCE.\n"));
05497
05498
IopPlacement(
ArbiterActionCommitAllocation,
TRUE);
05499
05500
#if DBG_SCOPE
05501
if (
PnpResDebugLevel &
STOP_ERROR) {
05502
IopCheckDataStructures(
IopRootDeviceNode);
05503 }
05504
#endif
05505
05506
05507
05508
05509
05510
for (entry1 = tableEnd - 1; entry1 >= newEntry; entry1--) {
05511 deviceNode = (
PDEVICE_NODE)entry1->
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
05512
05513
if (
NT_SUCCESS(entry1->
Status)) {
05514
05515
05516
05517
05518
05519
05520
if (deviceNode->
ResourceList) {
05521
ExFreePool(deviceNode->
ResourceList);
05522 }
05523 deviceNode->
ResourceList = entry1->
ResourceAssignment;
05524
if (deviceNode->
ResourceListTranslated) {
05525
ExFreePool(deviceNode->
ResourceListTranslated);
05526 }
05527 deviceNode->
ResourceListTranslated = entry1->
TranslatedResourceAssignment;
05528
if (deviceNode->
ResourceList) {
05529 deviceNode->
Flags |=
DNF_RESOURCE_ASSIGNED;
05530 deviceNode->
Flags &= ~
DNF_RESOURCE_REPORTED;
05531 }
else {
05532 deviceNode->
Flags |=
DNF_NO_RESOURCE_REQUIRED;
05533 }
05534
if (entry1->
Flags &
IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG) {
05535
05536
05537
05538
05539
05540
05541 deviceNode->
Flags &= ~(
DNF_RESOURCE_REQUIREMENTS_CHANGED |
DNF_NON_STOPPED_REBALANCE);
05542 }
05543
05544
05545
05546
05547
05548
05549
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
05550
KeLeaveCriticalRegion();
05551
IopStartDevice(entry1->
PhysicalDevice);
05552
KeEnterCriticalRegion();
05553
KeWaitForSingleObject( &
IopRegistrySemaphore,
05554
DelayExecution,
05555
KernelMode,
05556
FALSE,
05557
NULL );
05558 }
05559 }
05560
05561
05562
05563
05564
05565
for (deviceTablex = (deviceTable + rebalanceCount - 1);
05566 deviceTablex >= deviceTable;
05567 deviceTablex--) {
05568
ObDereferenceObject(*deviceTablex);
05569 }
05570 status = STATUS_SUCCESS;
05571 }
else {
05572
05573
05574
05575
05576
05577
05578
05579
IopFreeResourceRequirementsForAssignTable(requestTable + AssignTableCount, requestTableEnd);
05580
if (rebalancePhase == 0) {
05581 rebalancePhase++;
05582
if (requestTable) {
05583
ExFreePool(requestTable);
05584 }
05585
if (table && (table != requestTable)) {
05586
ExFreePool(table);
05587 }
05588 table = requestTable =
NULL;
05589
goto tryAgain;
05590 }
05591
05592
05593
05594
05595
05596
05597
05598
for (deviceTablex = (deviceTable + rebalanceCount - 1);
05599 deviceTablex >= deviceTable;
05600 deviceTablex--) {
05601 deviceNode = (
PDEVICE_NODE)((*deviceTablex)->DeviceObjectExtension->DeviceNode);
05602
#if 0
05603
statusx =
IopRestoreResourcesInternal(deviceNode);
05604
if (
NT_SUCCESS(statusx)) {
05605
IopQueryReconfiguration (
IRP_MN_CANCEL_STOP_DEVICE, *deviceTablex);
05606 deviceNode->
Flags &= ~
DNF_STOPPED;
05607 }
else {
05608
ASSERT(0);
05609
IopRequestDeviceRemoval(*deviceTablex);
05610 }
05611
#else
05612
IopQueryReconfiguration (
IRP_MN_CANCEL_STOP_DEVICE, *deviceTablex);
05613 deviceNode->
Flags &= ~
DNF_STOPPED;
05614
#endif
05615
ObDereferenceObject(*deviceTablex);
05616 }
05617 }
05618
ExFreePool(deviceTable);
05619 deviceTable =
NULL;
05620
05621
exit:
05622
05623
if (!
NT_SUCCESS(status) && deviceTable) {
05624
05625
05626
05627
05628
05629
05630
DebugMessage(
DUMP_INFO, (
"Rebalance: Rebalance failed\n"));
05631
05632
05633
05634
05635
05636
05637
for (deviceTablex = (deviceTable + rebalanceCount - 1);
05638 deviceTablex >= deviceTable;
05639 deviceTablex--) {
05640
05641 deviceNode = (
PDEVICE_NODE)((*deviceTablex)->DeviceObjectExtension->DeviceNode);
05642
IopQueryReconfiguration (
IRP_MN_CANCEL_STOP_DEVICE, *deviceTablex);
05643 deviceNode->
Flags &= ~
DNF_STOPPED;
05644
ObDereferenceObject(*deviceTablex);
05645 }
05646 }
05647
if (deviceTable) {
05648
ExFreePool(deviceTable);
05649 }
05650
if (requestTable) {
05651
ExFreePool(requestTable);
05652 }
05653
if (table && (table != requestTable)) {
05654
ExFreePool(table);
05655 }
05656
return status;
05657 }
05658
05659
NTSTATUS
05660 IopRestoreResourcesInternal (
05661 IN
PDEVICE_NODE DeviceNode
05662 )
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680 {
05681
IOP_RESOURCE_REQUEST requestTable;
05682
NTSTATUS status;
05683
05684
if (DeviceNode->ResourceList ==
NULL) {
05685
return STATUS_SUCCESS;
05686 }
05687 requestTable.
ResourceRequirements =
05688
IopCmResourcesToIoResources (0, DeviceNode->ResourceList, LCPRI_FORCECONFIG);
05689
if (requestTable.
ResourceRequirements ==
NULL) {
05690
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not enough memory to clean up rebalance failure\n"));
05691
return STATUS_INSUFFICIENT_RESOURCES;
05692 }
05693 requestTable.
Priority = 0;
05694 requestTable.
Flags = 0;
05695 requestTable.
AllocationType =
ArbiterRequestPnpEnumerated;
05696 requestTable.
PhysicalDevice = DeviceNode->PhysicalDeviceObject;
05697 requestTable.
ReqList =
NULL;
05698 requestTable.
ResourceAssignment =
NULL;
05699 requestTable.
TranslatedResourceAssignment =
NULL;
05700 requestTable.
Status = 0;
05701
05702
05703
05704
05705
05706 status =
IopResourceRequirementsListToReqList(
05707 requestTable.
AllocationType,
05708 requestTable.
ResourceRequirements,
05709 requestTable.
PhysicalDevice,
05710 &requestTable.
ReqList);
05711
05712
if (!
NT_SUCCESS(status) || requestTable.
ReqList ==
NULL) {
05713
DebugMessage(
DUMP_ERROR, (
"PnpRes: Not enough memory to restore previous resources\n"));
05714
ExFreePool (requestTable.
ResourceRequirements);
05715
return status;
05716 }
else {
05717
PREQ_LIST reqList;
05718
05719 reqList = (
PREQ_LIST)requestTable.
ReqList;
05720 reqList->AssignEntry = &requestTable;
05721
05722
05723
05724
05725
05726
05727
IopRearrangeReqList(reqList);
05728
if (reqList->ReqBestAlternative ==
NULL) {
05729
05730
IopFreeResourceRequirementsForAssignTable(&requestTable, (&requestTable) + 1);
05731
return STATUS_DEVICE_CONFIGURATION_ERROR;
05732
05733 }
05734 }
05735
05736 status =
IopAssignInner(1, &requestTable,
FALSE);
05737
IopFreeResourceRequirementsForAssignTable(&requestTable, (&requestTable) + 1);
05738
if (!
NT_SUCCESS(status)) {
05739
DbgPrint(
"IopRestoreResourcesInternal: BOOT conflict for %ws\n", DeviceNode->InstancePath.Buffer);
05740
ASSERT(
NT_SUCCESS(status));
05741 }
05742
if (requestTable.
ResourceAssignment) {
05743
ExFreePool(requestTable.
ResourceAssignment);
05744 }
05745
if (requestTable.
TranslatedResourceAssignment) {
05746
ExFreePool(requestTable.
TranslatedResourceAssignment);
05747 }
05748
IopWriteAllocatedResourcesToRegistry (
05749 DeviceNode,
05750 DeviceNode->ResourceList,
05751
IopDetermineResourceListSize(DeviceNode->ResourceList)
05752 );
05753
return status;
05754 }
05755
05756
VOID
05757 IopReleaseResourcesInternal (
05758 IN
PDEVICE_NODE DeviceNode
05759 )
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776
05777
05778 {
05779
PDEVICE_NODE device;
05780 PLIST_ENTRY listHead, listEntry;
05781
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
05782
ARBITER_LIST_ENTRY arbiterListEntry;
05783 INTERFACE_TYPE interfaceType;
05784 ULONG busNumber, listCount, i, j, size;
05785 PCM_RESOURCE_LIST resourceList;
05786 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
05787 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
05788 BOOLEAN search =
TRUE;
05789
#if DBG
05790
NTSTATUS status;
05791
#endif
05792
05793 InitializeListHead(&arbiterListEntry.
ListEntry);
05794 arbiterListEntry.
AlternativeCount = 0;
05795 arbiterListEntry.
Alternatives =
NULL;
05796 arbiterListEntry.
PhysicalDeviceObject = DeviceNode->PhysicalDeviceObject;
05797 arbiterListEntry.
Flags = 0;
05798 arbiterListEntry.
WorkSpace = 0;
05799 arbiterListEntry.
Assignment =
NULL;
05800 arbiterListEntry.
RequestSource =
ArbiterRequestPnpEnumerated;
05801
05802 resourceList = DeviceNode->ResourceList;
05803
if (resourceList ==
NULL) {
05804 resourceList = DeviceNode->BootResources;
05805 }
05806
if (resourceList && resourceList->Count > 0) {
05807 listCount = resourceList->Count;
05808 cmFullDesc = &resourceList->List[0];
05809 }
else {
05810 listCount = 1;
05811 resourceList =
NULL;
05812 }
05813
for (i = 0; i < listCount; i++) {
05814
05815
if (resourceList) {
05816 interfaceType = cmFullDesc->InterfaceType;
05817 busNumber = cmFullDesc->BusNumber;
05818
if (interfaceType == InterfaceTypeUndefined) {
05819 interfaceType =
PnpDefaultInterfaceType;
05820 }
05821 }
else {
05822 interfaceType =
PnpDefaultInterfaceType;
05823 busNumber = 0;
05824 }
05825
05826 device = DeviceNode->
Parent;
05827
while (device) {
05828
if ((device ==
IopRootDeviceNode) && search) {
05829 device =
IopFindBusDeviceNode (
05830
IopRootDeviceNode,
05831 interfaceType,
05832 busNumber,
05833 0
05834 );
05835
05836
05837
05838
05839
05840
05841
05842
if ((device ==
IopRootDeviceNode) && (interfaceType == Internal)) {
05843 device =
IopFindBusDeviceNode(
IopRootDeviceNode, Isa, 0, 0);
05844 }
05845 search =
FALSE;
05846
05847 }
05848 listHead = &device->
DeviceArbiterList;
05849 listEntry = listHead->Flink;
05850
while (listEntry != listHead) {
05851 arbiterEntry = CONTAINING_RECORD(listEntry,
PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList);
05852
if (arbiterEntry->
ArbiterInterface !=
NULL) {
05853 search =
FALSE;
05854
ASSERT(IsListEmpty(&arbiterEntry->
ResourceList));
05855 InitializeListHead(&arbiterEntry->
ResourceList);
05856 InsertTailList(&arbiterEntry->
ResourceList, &arbiterListEntry.
ListEntry);
05857
#if DBG
05858
status =
05859
#endif
05860
IopCallArbiter(arbiterEntry,
05861
ArbiterActionTestAllocation,
05862 &arbiterEntry->
ResourceList,
05863
NULL,
05864
NULL
05865 );
05866
#if DBG
05867
ASSERT(status == STATUS_SUCCESS);
05868 status =
05869
#endif
05870
IopCallArbiter(arbiterEntry,
05871
ArbiterActionCommitAllocation,
05872
NULL,
05873
NULL,
05874
NULL
05875 );
05876
#if DBG
05877
ASSERT(status == STATUS_SUCCESS);
05878
#endif
05879
RemoveEntryList(&arbiterListEntry.
ListEntry);
05880 InitializeListHead(&arbiterListEntry.
ListEntry);
05881 }
05882 listEntry = listEntry->Flink;
05883 }
05884 device = device->
Parent;
05885 }
05886
05887
05888
05889
05890
05891
if (listCount > 1) {
05892 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
05893
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
05894 size = 0;
05895
switch (cmPartDesc->Type) {
05896
case CmResourceTypeDeviceSpecific:
05897 size = cmPartDesc->u.DeviceSpecificData.DataSize;
05898
break;
05899 }
05900 cmPartDesc++;
05901 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
05902 }
05903 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
05904 }
05905 }
05906
05907
IopWriteAllocatedResourcesToRegistry (DeviceNode,
NULL, 0);
05908 }
05909
05910
NTSTATUS
05911 IopFindLegacyDeviceNode (
05912 IN
PDRIVER_OBJECT DriverObject,
05913 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
05914 OUT
PDEVICE_NODE *LegacyDeviceNode,
05915 OUT
PDEVICE_OBJECT *LegacyPDO
05916 )
05917
05918
05919
05920
05921
05922
05923
05924
05925
05926
05927
05928
05929
05930
05931
05932
05933
05934
05935
05936
05937
05938
05939
05940
05941
05942 {
05943
NTSTATUS status = STATUS_UNSUCCESSFUL;
05944
PDEVICE_NODE deviceNode;
05945
05946
ASSERT(LegacyDeviceNode && LegacyPDO);
05947
05948
05949
05950
05951
05952
05953
if (DeviceObject) {
05954
05955 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
05956
if (deviceNode) {
05957
05958 *LegacyPDO = DeviceObject;
05959 *LegacyDeviceNode = deviceNode;
05960 status = STATUS_SUCCESS;
05961
05962 }
else if (!(DeviceObject->Flags &
DO_BUS_ENUMERATED_DEVICE)) {
05963
05964 deviceNode =
IopAllocateDeviceNode(DeviceObject);
05965
if (deviceNode) {
05966
05967 deviceNode->
Flags |=
DNF_LEGACY_RESOURCE_DEVICENODE;
05968
IopSetLegacyDeviceInstance (DriverObject, deviceNode);
05969 *LegacyPDO = DeviceObject;
05970 *LegacyDeviceNode = deviceNode;
05971 status = STATUS_SUCCESS;
05972
05973 }
else {
05974
05975
DebugMessage(
DUMP_ERROR, (
"PNPRES: Failed to allocate device node for PDO %08X\n", DeviceObject));
05976 status = STATUS_INSUFFICIENT_RESOURCES;
05977
05978 }
05979
05980 }
else {
05981
05982
DebugMessage(
DUMP_ERROR, (
"PNPRES: %08X PDO without a device node!\n", DeviceObject));
05983
ASSERT(DeviceObject->DeviceObjectExtension->DeviceNode);
05984
05985 }
05986
05987 }
else {
05988
05989
05990
05991
05992
05993
for ( deviceNode =
IopLegacyDeviceNode;
05994 deviceNode && deviceNode->
DuplicatePDO != (
PDEVICE_OBJECT)DriverObject;
05995 deviceNode = deviceNode->NextDeviceNode);
05996
05997
if (deviceNode) {
05998
05999 *LegacyPDO = deviceNode->
PhysicalDeviceObject;
06000 *LegacyDeviceNode = deviceNode;
06001 status = STATUS_SUCCESS;
06002
06003 }
else {
06004
06005 WCHAR buffer[60];
06006 UNICODE_STRING deviceName;
06007 LARGE_INTEGER tickCount;
06008 ULONG length;
06009
PDEVICE_OBJECT pdo;
06010
06011
06012
06013
06014
06015
06016
KeQueryTickCount(&tickCount);
06017 length = _snwprintf(buffer,
sizeof(buffer) /
sizeof(WCHAR),
L"\\Device\\Resource%04u%x",
IopNumberDeviceNodes, tickCount.LowPart);
06018 deviceName.MaximumLength =
sizeof(buffer);
06019 deviceName.Length = (
USHORT)(length *
sizeof(WCHAR));
06020 deviceName.Buffer = buffer;
06021
06022
DebugMessage(
DUMP_INFO, (
"PNPRES: Creating dummy PDO %ws\n", deviceName.Buffer));
06023
06024 status =
IoCreateDevice(
IoPnpDriverObject,
06025
sizeof(
IOPNP_DEVICE_EXTENSION),
06026 &deviceName,
06027 FILE_DEVICE_CONTROLLER,
06028 0,
06029
FALSE,
06030 &pdo);
06031
06032
if (
NT_SUCCESS(status)) {
06033
06034 pdo->
Flags |=
DO_BUS_ENUMERATED_DEVICE;
06035 deviceNode =
IopAllocateDeviceNode(pdo);
06036
if (deviceNode) {
06037
06038
06039
06040
06041
06042
06043
06044 pdo->
DriverObject = DriverObject;
06045 deviceNode->
Flags =
DNF_MADEUP |
DNF_PROCESSED |
DNF_LEGACY_RESOURCE_DEVICENODE;
06046 deviceNode->
DuplicatePDO = (
PDEVICE_OBJECT)DriverObject;
06047
IopSetLegacyDeviceInstance (DriverObject, deviceNode);
06048
06049
06050
06051
06052
06053 deviceNode->NextDeviceNode =
IopLegacyDeviceNode;
06054
if (
IopLegacyDeviceNode) {
06055
06056
IopLegacyDeviceNode->PreviousDeviceNode = deviceNode;
06057
06058 }
06059
IopLegacyDeviceNode = deviceNode;
06060 *LegacyPDO = pdo;
06061 *LegacyDeviceNode = deviceNode;
06062
06063 }
else {
06064
06065
DebugMessage(
DUMP_ERROR, (
"PNPRES: Failed to allocate device node for PDO %08X\n", pdo));
06066
IoDeleteDevice(pdo);
06067 status = STATUS_INSUFFICIENT_RESOURCES;
06068
06069 }
06070
06071 }
else {
06072
06073
DebugMessage(
DUMP_ERROR, (
"PNPRES: IoCreateDevice failed for %ws with status %08X\n", deviceName.Buffer, status));
06074
06075 }
06076 }
06077 }
06078
06079
return status;
06080 }
06081
06082
VOID
06083 IopRemoveLegacyDeviceNode (
06084 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
06085 IN
PDEVICE_NODE LegacyDeviceNode
06086 )
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105
06106
06107 {
06108
ASSERT(LegacyDeviceNode);
06109
06110
06111
if (!DeviceObject) {
06112
06113
if (LegacyDeviceNode->DuplicatePDO) {
06114
06115 LegacyDeviceNode->DuplicatePDO =
NULL;
06116
if (LegacyDeviceNode->PreviousDeviceNode) {
06117
06118 LegacyDeviceNode->PreviousDeviceNode->NextDeviceNode = LegacyDeviceNode->NextDeviceNode;
06119
06120 }
06121
06122
if (LegacyDeviceNode->NextDeviceNode) {
06123
06124 LegacyDeviceNode->NextDeviceNode->PreviousDeviceNode = LegacyDeviceNode->PreviousDeviceNode;
06125
06126 }
06127
06128
if (
IopLegacyDeviceNode == LegacyDeviceNode) {
06129
06130
IopLegacyDeviceNode = LegacyDeviceNode->NextDeviceNode;
06131
06132 }
06133
06134 }
else {
06135
06136
DebugMessage(
DUMP_ERROR, (
"PNPRES: %ws does not have a duplicate PDO\n", LegacyDeviceNode->InstancePath.Buffer));
06137
ASSERT(LegacyDeviceNode->DuplicatePDO);
06138
return;
06139
06140 }
06141 }
06142
06143
if (!(DeviceObject && (DeviceObject->Flags &
DO_BUS_ENUMERATED_DEVICE))) {
06144
06145
PDEVICE_NODE resourceDeviceNode;
06146
PDEVICE_OBJECT pdo;
06147
06148
for ( resourceDeviceNode = (
PDEVICE_NODE)LegacyDeviceNode->
OverUsed1.LegacyDeviceNode;
06149 resourceDeviceNode;
06150 resourceDeviceNode = resourceDeviceNode->
OverUsed2.NextResourceDeviceNode) {
06151
06152
if (resourceDeviceNode->
OverUsed2.NextResourceDeviceNode == LegacyDeviceNode) {
06153
06154 resourceDeviceNode->
OverUsed2.NextResourceDeviceNode = LegacyDeviceNode->OverUsed2.NextResourceDeviceNode;
06155
break;
06156
06157 }
06158 }
06159
06160 LegacyDeviceNode->Parent = LegacyDeviceNode->Sibling =
06161 LegacyDeviceNode->Child = LegacyDeviceNode->LastChild =
NULL;
06162
06163
06164
06165
06166
06167 pdo = LegacyDeviceNode->PhysicalDeviceObject;
06168
IopDestroyDeviceNode(LegacyDeviceNode);
06169
06170
if (!DeviceObject) {
06171
06172 pdo->
DriverObject =
IoPnpDriverObject;
06173
IoDeleteDevice(pdo);
06174 }
06175 }
06176 }
06177
06178
06179
NTSTATUS
06180 IopLegacyResourceAllocation (
06181 IN ARBITER_REQUEST_SOURCE AllocationType,
06182 IN
PDRIVER_OBJECT DriverObject,
06183 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
06184 IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements,
06185 IN OUT PCM_RESOURCE_LIST *AllocatedResources OPTIONAL
06186 )
06187
06188
06189
06190
06191
06192
06193
06194
06195
06196
06197
06198
06199
06200
06201
06202
06203
06204
06205
06206
06207
06208
06209
06210
06211
06212
06213 {
06214
PDEVICE_OBJECT pdo;
06215
PDEVICE_NODE deviceNode;
06216
PDEVICE_NODE legacyDeviceNode;
06217
NTSTATUS status;
06218 PCM_RESOURCE_LIST combinedResources;
06219 KIRQL irql;
06220
06221
ASSERT(DriverObject);
06222
06223
06224
06225
06226
06227
06228
KeEnterCriticalRegion();
06229
06230 status =
KeWaitForSingleObject( &
IopRegistrySemaphore,
06231
DelayExecution,
06232
KernelMode,
06233
FALSE,
06234
NULL);
06235
if (
NT_SUCCESS(status)) {
06236
06237 status =
IopFindLegacyDeviceNode(DriverObject, DeviceObject, &deviceNode, &pdo);
06238
if (
NT_SUCCESS(status)) {
06239
06240 legacyDeviceNode =
NULL;
06241
if (!deviceNode->
Parent && ResourceRequirements) {
06242
06243
06244
06245
06246
06247
06248
if (ResourceRequirements->InterfaceType == InterfaceTypeUndefined) {
06249
06250 ResourceRequirements->InterfaceType =
PnpDefaultInterfaceType;
06251
06252 }
06253 deviceNode->
Parent =
IopRootDeviceNode;
06254
06255 }
06256
06257
06258
06259
06260
06261
if ( (!ResourceRequirements && deviceNode->
Parent) ||
06262 (deviceNode->
Flags & (
DNF_RESOURCE_REPORTED |
DNF_RESOURCE_ASSIGNED))) {
06263
06264
IopReleaseResources(deviceNode);
06265
06266 }
06267
06268
if (ResourceRequirements) {
06269
06270
IOP_RESOURCE_REQUEST requestTable;
06271
IOP_RESOURCE_REQUEST *requestTablep;
06272 ULONG count;
06273
06274
06275
06276
06277
06278 count = 1;
06279 RtlZeroMemory(&requestTable,
sizeof(
IOP_RESOURCE_REQUEST));
06280 requestTable.
ResourceRequirements = ResourceRequirements;
06281 requestTable.
PhysicalDevice = pdo;
06282 requestTable.
Flags =
IOP_ASSIGN_NO_REBALANCE;
06283 requestTable.
AllocationType = AllocationType;
06284
06285 deviceNode->
Flags |=
DNF_ASSIGNING_RESOURCES;
06286 requestTablep = &requestTable;
06287
IopAllocateResources(&count, &requestTablep,
TRUE,
TRUE);
06288 deviceNode->
Flags &= ~
DNF_ASSIGNING_RESOURCES;
06289 status = requestTable.Status;
06290
if (
NT_SUCCESS(status)) {
06291
06292 deviceNode->
Flags |=
DNF_RESOURCE_REPORTED;
06293
06294 deviceNode->
ResourceListTranslated = requestTable.TranslatedResourceAssignment;
06295 count =
IopDetermineResourceListSize((*AllocatedResources) ? *AllocatedResources : requestTable.ResourceAssignment);
06296 deviceNode->
ResourceList =
ExAllocatePoolIORL(
PagedPool, count);
06297
if (deviceNode->
ResourceList) {
06298
06299
if (*AllocatedResources) {
06300
06301
06302
06303
06304
06305
ASSERT(requestTable.ResourceAssignment);
06306
ExFreePool(requestTable.ResourceAssignment);
06307
06308 }
else {
06309
06310
06311
06312
06313
06314 *AllocatedResources = requestTable.ResourceAssignment;
06315
06316 }
06317 RtlCopyMemory(deviceNode->
ResourceList, *AllocatedResources, count);
06318 legacyDeviceNode = (
PDEVICE_NODE)deviceNode->
OverUsed1.LegacyDeviceNode;
06319
06320 }
else {
06321
06322 deviceNode->
ResourceList = requestTable.ResourceAssignment;
06323
IopReleaseResources(deviceNode);
06324 status = STATUS_INSUFFICIENT_RESOURCES;
06325
06326 }
06327 }
06328
06329
06330
06331
06332
06333
if (!
NT_SUCCESS(status)) {
06334
06335
IopRemoveLegacyDeviceNode(DeviceObject, deviceNode);
06336
06337 }
06338
06339 }
else {
06340
06341
06342
06343
06344
06345 legacyDeviceNode = (
PDEVICE_NODE)deviceNode->
OverUsed1.LegacyDeviceNode;
06346
IopRemoveLegacyDeviceNode(DeviceObject, deviceNode);
06347
06348 }
06349
06350
if (
NT_SUCCESS(status)) {
06351
06352
if (legacyDeviceNode) {
06353
06354
06355
06356
06357
06358
06359 combinedResources =
IopCombineLegacyResources(legacyDeviceNode);
06360
if (combinedResources) {
06361
06362
IopWriteAllocatedResourcesToRegistry( legacyDeviceNode,
06363 combinedResources,
06364
IopDetermineResourceListSize(combinedResources));
06365
ExFreePool(combinedResources);
06366 }
06367 }
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
if (AllocationType !=
ArbiterRequestPnpDetected && DriverObject !=
IoPnpDriverObject) {
06378
06379
06380
06381 ExAcquireFastLock(&
IopDatabaseLock, &irql);
06382
if (ResourceRequirements) {
06383
06384
06385
06386
06387
06388 DriverObject->Flags |=
DRVO_LEGACY_RESOURCES;
06389 }
06390 ExReleaseFastLock(&
IopDatabaseLock, irql);
06391 }
06392 }
06393 }
06394
06395
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
06396
06397 }
else {
06398
06399
DebugMessage(
DUMP_ERROR, (
"PNPRES: IopLegacyResourceAllocation: Failed to acquire registry semaphore, status %08X\n", status));
06400 }
06401
06402
KeLeaveCriticalRegion();
06403
06404
return status;
06405 }
06406
06407
PDEVICE_NODE
06408 IopFindBusDeviceNode (
06409 IN
PDEVICE_NODE DeviceNode,
06410 IN INTERFACE_TYPE InterfaceType,
06411 IN ULONG BusNumber,
06412 IN ULONG SlotNumber
06413 )
06414
06415
06416
06417
06418
06419
06420
06421
06422
06423
06424
06425
06426
06427
06428
06429
06430
06431
06432
06433
06434
06435
06436
06437
06438 {
06439
PDEVICE_NODE busDeviceNode =
NULL;
06440
06441 UNREFERENCED_PARAMETER(SlotNumber);
06442
06443
if (DeviceNode &&
InterfaceType != InterfaceTypeUndefined) {
06444
06445
if (
InterfaceType == PNPBus) {
06446
06447
06448
06449
06450 busDeviceNode =
NULL;
06451 }
else {
06452
06453
06454
06455 busDeviceNode =
IopFindBusDeviceNodeInternal(DeviceNode, (
InterfaceType == Eisa) ? Isa :
InterfaceType,
BusNumber);
06456 }
06457
06458
if (busDeviceNode ==
NULL && DeviceNode ==
IopRootDeviceNode) {
06459
06460
DebugMessage(
DUMP_DETAIL, (
"IopFindBusDeviceNode: Found %ws with interface=%08X & bus=%08X\n", DeviceNode->InstancePath.Buffer,
InterfaceType,
BusNumber));
06461
return DeviceNode;
06462 }
06463
06464
if (busDeviceNode) {
06465
06466
DebugMessage(
DUMP_DETAIL, (
"IopFindBusDeviceNode: Found %ws with interface=%08X & bus=%08X\n", busDeviceNode->
InstancePath.Buffer,
InterfaceType,
BusNumber));
06467 }
06468 }
06469
06470
return busDeviceNode;
06471 }
06472
06473
PDEVICE_NODE
06474 IopFindBusDeviceNodeInternal (
06475 IN
PDEVICE_NODE DeviceNode,
06476 IN INTERFACE_TYPE InterfaceType,
06477 IN ULONG BusNumber
06478 )
06479
06480
06481
06482
06483
06484
06485
06486
06487
06488
06489
06490
06491
06492
06493
06494
06495
06496
06497
06498
06499
06500
06501 {
06502
PDEVICE_NODE current;
06503
06504
for (current = DeviceNode; current; current = current->
Sibling) {
06505
06506
if (
BusNumber == current->
BusNumber &&
06507 (
InterfaceType == current->
InterfaceType ||
06508 (
InterfaceType == Isa && current->
InterfaceType == Eisa))) {
06509
06510
return current;
06511 }
06512
06513
if (current->
Child) {
06514
06515
PDEVICE_NODE busDeviceNode =
IopFindBusDeviceNodeInternal(current->
Child,
InterfaceType,
BusNumber);
06516
06517
if (busDeviceNode) {
06518
06519
return busDeviceNode;
06520 }
06521 }
06522 }
06523
06524
return NULL;
06525 }
06526
06527
NTSTATUS
06528 IopDuplicateDetection (
06529 IN INTERFACE_TYPE LegacyBusType,
06530 IN ULONG BusNumber,
06531 IN ULONG SlotNumber,
06532 OUT
PDEVICE_NODE *DeviceNode
06533 )
06534
06535
06536
06537
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555
06556
06557
06558
06559 {
06560
PDEVICE_NODE deviceNode;
06561
PDEVICE_OBJECT busDeviceObject;
06562
PLEGACY_DEVICE_DETECTION_INTERFACE interface;
06563
NTSTATUS status;
06564
PDEVICE_OBJECT deviceObject;
06565
06566
06567
06568
06569
06570 *DeviceNode =
NULL;
06571
06572
06573
06574
06575
06576 deviceNode =
IopFindBusDeviceNode(
06577
IopRootDeviceNode,
06578 LegacyBusType,
06579
BusNumber,
06580 SlotNumber
06581 );
06582
06583
06584
06585
06586
06587
06588
06589
if (deviceNode ==
NULL) {
06590
06591
return STATUS_INVALID_DEVICE_REQUEST;
06592
06593 }
06594
06595
06596
06597
06598
06599
06600 busDeviceObject = deviceNode->
PhysicalDeviceObject;
06601
06602 status =
IopQueryResourceHandlerInterface(
06603
ResourceLegacyDeviceDetection,
06604 busDeviceObject,
06605 0,
06606 (
PINTERFACE *)&interface
06607 );
06608
06609
06610
06611
06612
06613
if (!
NT_SUCCESS(status) || interface ==
NULL) {
06614
06615
return STATUS_INVALID_DEVICE_REQUEST;
06616
06617 }
06618
06619
06620
06621
06622
06623 status = (*interface->LegacyDeviceDetection)(
06624 interface->
Context,
06625 LegacyBusType,
06626
BusNumber,
06627 SlotNumber,
06628 &deviceObject
06629 );
06630
06631
06632
06633
06634
06635
if (
NT_SUCCESS(status) && deviceObject !=
NULL) {
06636
06637 *DeviceNode =
06638 (
PDEVICE_NODE)deviceObject->
DeviceObjectExtension->
DeviceNode;
06639
06640 status = STATUS_SUCCESS;
06641
06642 }
else {
06643
06644 status = STATUS_INVALID_DEVICE_REQUEST;
06645
06646 }
06647
06648
06649
06650
06651
06652 (*interface->
InterfaceDereference)(interface->
Context);
06653
06654
ExFreePool(interface);
06655
06656
return status;
06657 }
06658
06659
VOID
06660 IopSetLegacyDeviceInstance (
06661 IN
PDRIVER_OBJECT DriverObject,
06662 IN
PDEVICE_NODE DeviceNode
06663 )
06664
06665
06666
06667
06668
06669
06670
06671
06672
06673
06674
06675
06676
06677
06678
06679
06680
06681
06682
06683
06684
06685 {
06686
NTSTATUS status;
06687 UNICODE_STRING instancePath, rootString;
06688 HANDLE handle;
06689
PDEVICE_NODE legacyDeviceNode;
06690
PDEVICE_OBJECT legacyPdo;
06691
06692
PAGED_CODE();
06693
06694 DeviceNode->OverUsed1.LegacyDeviceNode = 0;
06695 instancePath.Length = 0;
06696 instancePath.Buffer =
NULL;
06697
06698 status =
IopServiceInstanceToDeviceInstance (
06699
NULL,
06700 &DriverObject->DriverExtension->ServiceKeyName,
06701 0,
06702 &instancePath,
06703 &handle,
06704 KEY_READ
06705 );
06706
if (
NT_SUCCESS(status) && (instancePath.Length != 0)) {
06707
RtlInitUnicodeString(&rootString,
L"ROOT\\LEGACY");
06708
if (
RtlPrefixUnicodeString(&rootString, &instancePath,
TRUE) ==
FALSE) {
06709
RtlFreeUnicodeString(&instancePath);
06710 }
else {
06711 DeviceNode->InstancePath = instancePath;
06712 legacyPdo =
IopDeviceObjectFromDeviceInstance (handle,
NULL);
06713
if (legacyPdo) {
06714 legacyDeviceNode = (
PDEVICE_NODE)legacyPdo->
DeviceObjectExtension->
DeviceNode;
06715 DeviceNode->OverUsed2.NextResourceDeviceNode =
06716 legacyDeviceNode->
OverUsed2.NextResourceDeviceNode;
06717 legacyDeviceNode->
OverUsed2.NextResourceDeviceNode = DeviceNode;
06718 DeviceNode->OverUsed1.LegacyDeviceNode = legacyDeviceNode;
06719 }
06720 }
06721 ZwClose(handle);
06722 }
06723 }
06724
06725 PCM_RESOURCE_LIST
06726 IopCombineLegacyResources (
06727 IN
PDEVICE_NODE DeviceNode
06728 )
06729
06730
06731
06732
06733
06734
06735
06736
06737
06738
06739
06740
06741
06742
06743
06744
06745
06746
06747
06748
06749
06750 {
06751
NTSTATUS status;
06752 PCM_RESOURCE_LIST combinedList =
NULL;
06753
PDEVICE_NODE devNode = DeviceNode;
06754 ULONG size = 0;
06755 PUCHAR p;
06756
06757
PAGED_CODE();
06758
06759
if (DeviceNode) {
06760
06761
06762
06763
06764
06765
while (devNode) {
06766
if (devNode->
ResourceList) {
06767 size +=
IopDetermineResourceListSize(devNode->
ResourceList);
06768 }
06769 devNode = (
PDEVICE_NODE)devNode->
OverUsed2.NextResourceDeviceNode;
06770 }
06771
if (size != 0) {
06772 combinedList = (PCM_RESOURCE_LIST)
ExAllocatePoolCMRL(
PagedPool, size);
06773 devNode = DeviceNode;
06774
if (combinedList) {
06775 combinedList->Count = 0;
06776 p = (PUCHAR)combinedList;
06777 p +=
sizeof(ULONG);
06778
while (devNode) {
06779
if (devNode->
ResourceList) {
06780 size =
IopDetermineResourceListSize(devNode->
ResourceList);
06781
if (size != 0) {
06782 size -=
sizeof(ULONG);
06783 RtlMoveMemory(
06784 p,
06785 devNode->
ResourceList->List,
06786 size
06787 );
06788 p += size;
06789 combinedList->Count += devNode->
ResourceList->Count;
06790 }
06791 }
06792 devNode = (
PDEVICE_NODE)devNode->
OverUsed2.NextResourceDeviceNode;
06793 }
06794 }
06795 }
06796 }
06797
return combinedList;
06798 }
06799
06800 PCM_RESOURCE_LIST
06801 IopCreateCmResourceList(
06802 IN PCM_RESOURCE_LIST ResourceList,
06803 IN INTERFACE_TYPE InterfaceType,
06804 IN ULONG BusNumber,
06805 OUT PCM_RESOURCE_LIST *RemainingList
06806 )
06807 {
06808 PCM_RESOURCE_LIST newList =
NULL;
06809 ULONG i, j;
06810 ULONG totalSize, matchSize, remainingSize, listSize;
06811 PCM_FULL_RESOURCE_DESCRIPTOR fullResourceDesc, newFullResourceDesc, remainingFullResourceDesc;
06812 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor;
06813
06814
06815
06816
06817
06818
06819 fullResourceDesc = &ResourceList->List[0];
06820 totalSize = FIELD_OFFSET(CM_RESOURCE_LIST,
List);
06821 matchSize = 0;
06822
for (i = 0; i < ResourceList->Count; i++) {
06823
06824
06825
06826
06827
06828 listSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
06829 PartialResourceList) +
06830 FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
06831 PartialDescriptors);
06832
06833 partialDescriptor = &fullResourceDesc->PartialResourceList.PartialDescriptors[0];
06834
for (j = 0; j < fullResourceDesc->PartialResourceList.Count; j++) {
06835
06836 ULONG descriptorSize =
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
06837
06838
if (partialDescriptor->Type == CmResourceTypeDeviceSpecific) {
06839
06840 descriptorSize += partialDescriptor->u.DeviceSpecificData.DataSize;
06841 }
06842
06843 listSize += descriptorSize;
06844 partialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
06845 ((PUCHAR)partialDescriptor + descriptorSize);
06846
06847 }
06848
06849
if ( fullResourceDesc->InterfaceType ==
InterfaceType &&
06850 fullResourceDesc->BusNumber ==
BusNumber) {
06851
06852
06853 matchSize += listSize;
06854 }
06855
06856 totalSize += listSize;
06857 fullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)
06858 ((PUCHAR)fullResourceDesc + listSize);
06859 }
06860
06861
if (totalSize) {
06862
06863
if (matchSize) {
06864
06865 matchSize += FIELD_OFFSET(CM_RESOURCE_LIST,
List);
06866
06867 }
06868
if (matchSize == totalSize) {
06869
06870 *RemainingList =
NULL;
06871 newList = ResourceList;
06872
06873 }
else if (matchSize == 0) {
06874
06875 *RemainingList = ResourceList;
06876
06877 }
else {
06878
06879
06880
06881
06882
06883 newList = (PCM_RESOURCE_LIST)
ExAllocatePoolIORRR(
PagedPool, matchSize);
06884
06885
if (newList) {
06886
06887 *RemainingList = (PCM_RESOURCE_LIST)
ExAllocatePoolIORRR(
PagedPool, totalSize - matchSize + FIELD_OFFSET(CM_RESOURCE_LIST,
List));
06888
06889
if (*RemainingList) {
06890
06891 newList->Count = 0;
06892 (*RemainingList)->Count = 0;
06893 newFullResourceDesc = &newList->List[0];
06894 remainingFullResourceDesc = &(*RemainingList)->List[0];
06895 fullResourceDesc = &ResourceList->List[0];
06896
for (i = 0; i < ResourceList->Count; i++) {
06897
06898 listSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
06899 PartialResourceList) +
06900 FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
06901 PartialDescriptors);
06902
06903 partialDescriptor = &fullResourceDesc->PartialResourceList.PartialDescriptors[0];
06904
for (j = 0; j < fullResourceDesc->PartialResourceList.Count; j++) {
06905
06906 ULONG descriptorSize =
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
06907
06908
if (partialDescriptor->Type == CmResourceTypeDeviceSpecific) {
06909
06910 descriptorSize += partialDescriptor->u.DeviceSpecificData.DataSize;
06911 }
06912
06913 listSize += descriptorSize;
06914 partialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
06915 ((PUCHAR)partialDescriptor + descriptorSize);
06916
06917 }
06918
06919
if ( fullResourceDesc->InterfaceType ==
InterfaceType &&
06920 fullResourceDesc->BusNumber ==
BusNumber) {
06921
06922 newList->Count++;
06923 RtlMoveMemory(newFullResourceDesc, fullResourceDesc, listSize);
06924 newFullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)
06925 ((PUCHAR)newFullResourceDesc + listSize);
06926 }
else {
06927
06928 (*RemainingList)->Count++;
06929 RtlMoveMemory(remainingFullResourceDesc, fullResourceDesc, listSize);
06930 remainingFullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)
06931 ((PUCHAR)remainingFullResourceDesc + listSize);
06932 }
06933
06934 fullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)
06935 ((PUCHAR)fullResourceDesc + listSize);
06936 }
06937
06938 }
else {
06939
06940
ExFreePool(newList);
06941 newList =
NULL;
06942
06943 }
06944
06945 }
else {
06946
06947 *RemainingList =
NULL;
06948 }
06949 }
06950 }
06951
return newList;
06952 }
06953
06954 PCM_RESOURCE_LIST
06955 IopCombineCmResourceList(
06956 IN PCM_RESOURCE_LIST ResourceListA,
06957 IN PCM_RESOURCE_LIST ResourceListB
06958 )
06959 {
06960 PCM_RESOURCE_LIST newList =
NULL;
06961 ULONG sizeA, sizeB, size;
06962
06963
if (ResourceListA ==
NULL) {
06964
06965
return ResourceListB;
06966
06967 }
06968
06969
if (ResourceListB ==
NULL) {
06970
06971
return ResourceListA;
06972
06973 }
06974
06975 sizeA =
IopDetermineResourceListSize(ResourceListA);
06976 sizeB =
IopDetermineResourceListSize(ResourceListB);
06977
06978
if (sizeA && sizeB) {
06979
06980 size = sizeA + sizeB - (
sizeof(CM_RESOURCE_LIST) -
sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
06981 newList = (PCM_RESOURCE_LIST)
ExAllocatePoolIORRR(
PagedPool, size);
06982
if (newList) {
06983
06984 RtlMoveMemory(newList, ResourceListA, sizeA);
06985 RtlMoveMemory( (PUCHAR)newList + sizeA,
06986 (PUCHAR)ResourceListB + (
sizeof(CM_RESOURCE_LIST) -
sizeof(CM_FULL_RESOURCE_DESCRIPTOR)),
06987 sizeB - (
sizeof(CM_RESOURCE_LIST) -
sizeof(CM_FULL_RESOURCE_DESCRIPTOR)));
06988 newList->Count += ResourceListB->Count;
06989 }
06990 }
06991
06992
return newList;
06993 }
06994
06995
NTSTATUS
06996 IopReserveLegacyBootResources(
06997 IN INTERFACE_TYPE InterfaceType,
06998 IN ULONG BusNumber
06999 )
07000
07001
07002
07003
07004
07005
07006
07007
07008
07009
07010
07011
07012
07013
07014
07015
07016
07017
07018
07019
07020 {
07021
NTSTATUS status;
07022
PIOP_RESERVED_RESOURCES_RECORD resourceRecord, prevRecord;
07023 PCM_RESOURCE_LIST newList, remainingList;
07024
07025
if (
IopInitHalDeviceNode &&
IopInitHalResources) {
07026
07027 remainingList =
NULL;
07028 newList =
IopCreateCmResourceList(
IopInitHalResources,
InterfaceType,
BusNumber, &remainingList);
07029
if (newList) {
07030
07031
if (remainingList ==
NULL) {
07032
07033
07034
07035
07036
07037
ASSERT(newList ==
IopInitHalResources);
07038
07039 }
else {
07040
07041
07042
07043
07044
07045
ASSERT(
IopInitHalResources != newList);
07046
ASSERT(
IopInitHalResources != remainingList);
07047
07048 }
07049
07050
DebugMessage(
DUMP_INFO, (
"IopReserveLegacyBootResources: Allocating HAL BOOT config for interface %08X and bus %08X...\n",
InterfaceType,
BusNumber));
07051
if (
PnpResDebugLevel &
DUMP_INFO) {
07052
07053
IopDumpCmResourceList(newList);
07054
07055 }
07056
if (remainingList) {
07057
ExFreePool(
IopInitHalResources);
07058 }
07059
IopInitHalResources = remainingList;
07060 remainingList =
IopInitHalDeviceNode->
BootResources;
07061
IopInitHalDeviceNode->
Flags |=
DNF_HAS_BOOT_CONFIG;
07062 status =
IopAllocateBootResources(
ArbiterRequestHalReported,
07063
IopInitHalDeviceNode->
PhysicalDeviceObject,
07064 newList);
07065
ASSERT(
NT_SUCCESS(status));
07066
IopInitHalDeviceNode->
BootResources =
IopCombineCmResourceList(remainingList, newList);
07067
ASSERT(
IopInitHalDeviceNode->
BootResources);
07068
07069
07070
07071
07072
07073
if (remainingList) {
07074
07075
ExFreePool(remainingList);
07076
07077 }
07078 }
else {
07079
07080
07081
07082
07083
07084
ASSERT(remainingList && remainingList ==
IopInitHalResources);
07085 }
07086 }
07087
07088
for (prevRecord =
NULL, resourceRecord =
IopInitReservedResourceList; resourceRecord;) {
07089
07090
if ( resourceRecord->ReservedResources &&
07091 resourceRecord->ReservedResources->List[0].InterfaceType ==
InterfaceType &&
07092 resourceRecord->ReservedResources->List[0].BusNumber ==
BusNumber) {
07093
07094
DebugMessage(
DUMP_INFO, (
"IopReserveLegacyBootResources: Allocating BOOT config...\n"));
07095
if (
PnpResDebugLevel &
DUMP_INFO) {
07096
07097
IopDumpCmResourceList(resourceRecord->ReservedResources);
07098
07099 }
07100
07101 status =
IopAllocateBootResources(
ArbiterRequestPnpEnumerated,
07102 resourceRecord->DeviceObject,
07103 resourceRecord->ReservedResources);
07104
if (!
NT_SUCCESS(status)) {
07105
07106
DbgPrint(
"IopReserveLegacyBootResources: IopAllocateBootResources failed with status = %08X\n", status);
07107
ASSERT(
NT_SUCCESS(status));
07108
07109 }
07110
07111
if (resourceRecord->DeviceObject ==
NULL) {
07112
07113
ExFreePool(resourceRecord->ReservedResources);
07114
07115 }
07116
07117
if (prevRecord) {
07118
07119 prevRecord->Next = resourceRecord->Next;
07120
07121 }
else {
07122
07123
IopInitReservedResourceList = resourceRecord->Next;
07124
07125 }
07126
ExFreePool(resourceRecord);
07127 resourceRecord = (prevRecord)? prevRecord->Next :
IopInitReservedResourceList;
07128
07129 }
else {
07130
07131 prevRecord = resourceRecord;
07132 resourceRecord = resourceRecord->Next;
07133
07134 }
07135 }
07136
07137
return STATUS_SUCCESS;
07138 }
07139
07140
NTSTATUS
07141 IopAllocateBootResources (
07142 IN ARBITER_REQUEST_SOURCE ArbiterRequestSource,
07143 IN
PDEVICE_OBJECT DeviceObject,
07144 IN PCM_RESOURCE_LIST BootResources
07145 )
07146
07147
07148
07149
07150
07151
07152
07153
07154
07155
07156
07157
07158
07159
07160
07161
07162
07163
07164
07165
07166
07167
07168
07169 {
07170
NTSTATUS status;
07171
07172
PAGED_CODE();
07173
07174
KeEnterCriticalRegion( );
07175
07176 status =
KeWaitForSingleObject( &
IopRegistrySemaphore,
07177
DelayExecution,
07178
KernelMode,
07179
FALSE,
07180
NULL );
07181
07182
if (
NT_SUCCESS(status)) {
07183
07184 status =
IopReserveBootResourcesInternal(ArbiterRequestSource, DeviceObject, BootResources);
07185
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
07186
07187 }
else {
07188
07189
DebugMessage(
DUMP_ERROR, (
"IopReserveBootResources: Get RegustrySemaphore failed. Status %x\n", status));
07190 }
07191
07192
KeLeaveCriticalRegion();
07193
07194
return status;
07195 }
07196
07197
NTSTATUS
07198 IopReserveBootResourcesInternal (
07199 IN ARBITER_REQUEST_SOURCE ArbiterRequestSource,
07200 IN
PDEVICE_OBJECT DeviceObject,
07201 IN PCM_RESOURCE_LIST BootResources
07202 )
07203
07204
07205
07206
07207
07208
07209
07210
07211
07212
07213
07214
07215
07216
07217
07218
07219
07220
07221
07222
07223
07224
07225
07226 {
07227 PIO_RESOURCE_REQUIREMENTS_LIST ioResources;
07228
PREQ_LIST reqList;
07229
NTSTATUS status = STATUS_SUCCESS;
07230
PDEVICE_NODE deviceNode;
07231
07232
PAGED_CODE();
07233
07234
if (DeviceObject) {
07235 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
07236 }
07237 ioResources =
IopCmResourcesToIoResources(0, BootResources, LCPRI_BOOTCONFIG);
07238
if (ioResources) {
07239
#if MYDBG
07240
if (deviceNode) {
07241
DbgPrint(
"\n===================================\n");
07242
DbgPrint(
"PreAllocate Resource List for %wZ :: \n", &deviceNode->
InstancePath);
07243 }
else {
07244
DbgPrint(
"Reserve Resource List :: ");
07245 }
07246
IopDumpResourceRequirementsList(ioResources);
07247
DbgPrint(
" ++++++++++++++++++++++++++++++\n");
07248
#endif
07249
07250 status =
IopResourceRequirementsListToReqList(
07251 ArbiterRequestSource,
07252 ioResources,
07253 DeviceObject,
07254 &reqList);
07255
07256
if (
NT_SUCCESS(status) && reqList) {
07257
IopReserve(reqList);
07258
if (DeviceObject) {
07259 deviceNode->
Flags |=
DNF_BOOT_CONFIG_RESERVED;
07260
if (deviceNode->
BootResources ==
NULL) {
07261 ULONG size;
07262
07263
07264
07265
07266
07267
07268
07269 size =
IopDetermineResourceListSize (BootResources);
07270 deviceNode->
BootResources =
ExAllocatePoolIORL(
PagedPool, size);
07271
if (deviceNode->
BootResources) {
07272 RtlMoveMemory(deviceNode->
BootResources, BootResources, size);
07273 }
else {
07274 status = STATUS_INSUFFICIENT_RESOURCES;
07275 }
07276 }
07277 }
07278
IopFreeReqList(reqList);
07279 }
else {
07280
#if MYDBG
07281
ASSERT(0);
07282
#endif
07283
}
07284
ExFreePool(ioResources);
07285 }
07286
07287
return status;
07288 }
07289
07290
NTSTATUS
07291 IopReserveBootResources (
07292 IN ARBITER_REQUEST_SOURCE ArbiterRequestSource,
07293 IN
PDEVICE_OBJECT DeviceObject,
07294 IN PCM_RESOURCE_LIST BootResources
07295 )
07296
07297
07298
07299
07300
07301
07302
07303
07304
07305
07306
07307
07308
07309
07310
07311
07312
07313
07314
07315
07316
07317
07318
07319 {
07320
PIOP_RESERVED_RESOURCES_RECORD resourceRecord;
07321
PDEVICE_NODE deviceNode;
07322 ULONG size;
07323
NTSTATUS status;
07324
07325 status = STATUS_SUCCESS;;
07326 size =
IopDetermineResourceListSize(BootResources);
07327
if (size != 0) {
07328
07329 deviceNode = (
PDEVICE_NODE)((DeviceObject)? DeviceObject->DeviceObjectExtension->DeviceNode :
NULL);
07330
07331
07332
07333
07334
07335
if (DeviceObject && !(deviceNode->
Flags &
DNF_MADEUP)) {
07336
07337
return IopAllocateBootResources(ArbiterRequestSource, DeviceObject, BootResources);
07338
07339 }
07340
07341
07342
if (DeviceObject) {
07343
07344
ASSERT(deviceNode);
07345 deviceNode->
BootResources =
ExAllocatePoolIORL(
PagedPool, size);
07346
if (deviceNode->
BootResources) {
07347
07348 RtlMoveMemory(deviceNode->
BootResources, BootResources, size);
07349
07350 }
else {
07351
07352
return STATUS_INSUFFICIENT_RESOURCES;
07353
07354 }
07355 }
07356
07357 resourceRecord = (
PIOP_RESERVED_RESOURCES_RECORD)
ExAllocatePoolIORRR(
PagedPool,
07358
sizeof(IOP_RESERVED_RESOURCES_RECORD));
07359
if (resourceRecord) {
07360
07361 resourceRecord->ReservedResources = (DeviceObject)? deviceNode->
BootResources : BootResources;
07362 resourceRecord->DeviceObject = DeviceObject;
07363 resourceRecord->Next =
IopInitReservedResourceList;
07364
IopInitReservedResourceList = resourceRecord;
07365
07366 }
else {
07367
07368
if (deviceNode && deviceNode->
BootResources) {
07369
07370
ExFreePool(deviceNode->
BootResources);
07371
07372 }
07373
07374
return STATUS_INSUFFICIENT_RESOURCES;
07375
07376 }
07377 }
07378
07379
return status;
07380 }
07381
07382
VOID
07383 IopReleaseResources (
07384 IN
PDEVICE_NODE DeviceNode
07385 )
07386
07387
07388
07389
07390
07391
07392
07393
07394
07395
07396
07397
07398
07399
07400
07401
07402
07403
07404
07405
07406
07407
07408
07409 {
07410
07411
07412
07413
07414
07415
IopReleaseResourcesInternal(DeviceNode);
07416 DeviceNode->Flags &= ~
DNF_RESOURCE_ASSIGNED;
07417 DeviceNode->Flags &= ~
DNF_RESOURCE_REPORTED;
07418
07419
#if DBG_SCOPE
07420
07421
if (DeviceNode->PreviousResourceList) {
07422
ExFreePool(DeviceNode->PreviousResourceList);
07423 DeviceNode->PreviousResourceList =
NULL;
07424 }
07425
if (DeviceNode->PreviousResourceRequirements) {
07426
ExFreePool(DeviceNode->PreviousResourceRequirements);
07427 DeviceNode->PreviousResourceRequirements =
NULL;
07428 }
07429
#endif
07430
07431
if (DeviceNode->ResourceList) {
07432
07433
#if DBG_SCOPE
07434
if (!
NT_SUCCESS(DeviceNode->FailureStatus)) {
07435 DeviceNode->PreviousResourceList = DeviceNode->ResourceList;
07436 }
else {
07437
ExFreePool(DeviceNode->ResourceList);
07438 }
07439
#else
07440
ExFreePool(DeviceNode->ResourceList);
07441
#endif
07442
07443 DeviceNode->ResourceList =
NULL;
07444 }
07445
if (DeviceNode->ResourceListTranslated) {
07446
ExFreePool(DeviceNode->ResourceListTranslated);
07447 DeviceNode->ResourceListTranslated =
NULL;
07448 }
07449
07450
07451
07452
07453
07454
if ((DeviceNode->Flags & (
DNF_MADEUP |
DNF_DEVICE_GONE)) ==
DNF_MADEUP) {
07455
if (DeviceNode->Flags &
DNF_HAS_BOOT_CONFIG && DeviceNode->BootResources) {
07456
IopReserveBootResourcesInternal(
ArbiterRequestPnpEnumerated,
07457 DeviceNode->PhysicalDeviceObject,
07458 DeviceNode->BootResources);
07459 }
07460 }
else {
07461 DeviceNode->Flags &= ~(
DNF_HAS_BOOT_CONFIG |
DNF_BOOT_CONFIG_RESERVED);
07462
if (DeviceNode->BootResources) {
07463
ExFreePool(DeviceNode->BootResources);
07464 DeviceNode->BootResources =
NULL;
07465 }
07466 }
07467 }
07468
07469
VOID
07470 IopReallocateResources (
07471 IN
PDEVICE_OBJECT DeviceObject
07472 )
07473
07474
07475
07476
07477
07478
07479
07480
07481
07482
07483
07484
07485
07486
07487
07488
07489 {
07490
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
07491
IOP_RESOURCE_REQUEST requestTable, *requestTablep;
07492 ULONG deviceCount, oldFlags;
07493
NTSTATUS status;
07494
07495
PAGED_CODE();
07496
07497
07498
07499
07500
07501
07502
KeEnterCriticalRegion();
07503 status =
KeWaitForSingleObject( &
IopRegistrySemaphore,
07504
DelayExecution,
07505
KernelMode,
07506
FALSE,
07507
NULL);
07508
if (
NT_SUCCESS(status)) {
07509
07510
07511
07512
07513
07514
ExAcquireResourceShared(&
IopDeviceTreeLock,
TRUE);
07515
07516
07517
07518
07519
07520
if (deviceNode->
Flags &
DNF_RESOURCE_REQUIREMENTS_CHANGED) {
07521
07522
07523
07524
07525 oldFlags = deviceNode->
Flags &
DNF_HAS_RESOURCE;
07526 deviceNode->
Flags &= ~(
DNF_HAS_RESOURCE);
07527
07528
if (deviceNode->
Flags &
DNF_NON_STOPPED_REBALANCE) {
07529
07530
IopAcquireEnumerationLock(deviceNode);
07531
07532
07533
07534
07535
07536 deviceNode->
Flags |=
DNF_ASSIGNING_RESOURCES;
07537
07538 RtlZeroMemory(&requestTable,
sizeof(
IOP_RESOURCE_REQUEST));
07539 requestTable.
PhysicalDevice = DeviceObject;
07540 requestTablep = &requestTable;
07541 requestTable.
Flags |=
IOP_ASSIGN_NO_REBALANCE +
IOP_ASSIGN_KEEP_CURRENT_CONFIG;
07542
07543 status =
IopGetResourceRequirementsForAssignTable( requestTablep,
07544 requestTablep + 1,
07545 &deviceCount);
07546
if (
NT_SUCCESS(status) && deviceCount) {
07547
07548
07549
07550
07551
07552
07553
if (deviceNode->
ResourceList) {
07554
07555
IopReleaseResourcesInternal(deviceNode);
07556 }
07557
07558
07559
07560
07561
07562 status =
IopAssignInner(deviceCount, requestTablep,
FALSE);
07563
if (
NT_SUCCESS(status)) {
07564
07565 deviceNode->
Flags &= ~(
DNF_RESOURCE_REQUIREMENTS_CHANGED |
DNF_NON_STOPPED_REBALANCE);
07566
07567
IopBuildCmResourceLists(requestTablep, requestTablep + 1);
07568
07569
07570
07571
07572
07573
07574
if (deviceNode->
ResourceList) {
07575
07576
ExFreePool(deviceNode->
ResourceList);
07577
07578 }
07579
if (deviceNode->
ResourceListTranslated) {
07580
07581
ExFreePool(deviceNode->
ResourceListTranslated);
07582
07583 }
07584
07585 deviceNode->
ResourceList = requestTablep->
ResourceAssignment;
07586 deviceNode->
ResourceListTranslated = requestTablep->
TranslatedResourceAssignment;
07587 deviceNode->
Flags |=
DNF_RESOURCE_ASSIGNED;
07588 deviceNode->
Flags &= ~
DNF_RESOURCE_REPORTED;
07589
07590
IopStartDevice(deviceNode->
PhysicalDeviceObject);
07591
07592 }
else {
07593
07594
NTSTATUS restoreResourcesStatus;
07595
07596 restoreResourcesStatus =
IopRestoreResourcesInternal(deviceNode);
07597
if (!
NT_SUCCESS(restoreResourcesStatus)) {
07598
07599
ASSERT(
NT_SUCCESS(restoreResourcesStatus));
07600
IopRequestDeviceRemoval(DeviceObject, CM_PROB_NORMAL_CONFLICT);
07601
07602 }
07603
07604
07605
07606
07607 }
07608
07609
IopFreeResourceRequirementsForAssignTable(requestTablep, requestTablep + 1);
07610
07611
07612 }
else {
07613
07614 status =
NT_SUCCESS(status)? STATUS_UNSUCCESSFUL : status;
07615
07616 }
07617
07618 deviceNode->
Flags &= ~
DNF_ASSIGNING_RESOURCES;
07619
IopReleaseEnumerationLock(deviceNode);
07620
07621 }
else {
07622
07623
07624
07625
07626
07627 status =
IopRebalance(0,
NULL);
07628
07629 }
07630
07631
07632
07633
07634
07635
if (!
NT_SUCCESS(status)) {
07636
07637 deviceNode->
Flags &= ~
DNF_HAS_RESOURCE;
07638 deviceNode->
Flags |= oldFlags;
07639
07640 }
07641
07642 }
else {
07643
07644
DebugMessage(
DUMP_ERROR, (
"PNPRES: Resource requirements not changed in IopReallocateResources, returning error!\n"));
07645 }
07646
07647
ExReleaseResource(&
IopDeviceTreeLock);
07648
KeReleaseSemaphore(&
IopRegistrySemaphore, 0, 1,
FALSE);
07649
07650 }
else {
07651
07652
DebugMessage(
DUMP_ERROR, (
"PNPRES: IopReallocateResources failed to acquire Registry semaphore, status %08X\n", status));
07653
07654 }
07655
07656
KeLeaveCriticalRegion();
07657 }
07658
07659
#if DBG_SCOPE
07660
07661
VOID
07662 IopCheckDataStructures (
07663 IN
PDEVICE_NODE DeviceNode
07664 )
07665
07666 {
07667
if (DeviceNode) {
07668
IopCheckDataStructuresWorker (DeviceNode);
07669
IopCheckDataStructures (DeviceNode->Sibling);
07670
IopCheckDataStructures (DeviceNode->Child);
07671 }
07672 }
07673
VOID
07674 IopCheckDataStructuresWorker (
07675 IN
PDEVICE_NODE Device
07676 )
07677
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687
07688
07689
07690
07691
07692
07693
07694
07695 {
07696 PLIST_ENTRY listHead, listEntry;
07697
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
07698
07699 listHead = &Device->DeviceArbiterList;
07700 listEntry = listHead->Flink;
07701
while (listEntry != listHead) {
07702 arbiterEntry = CONTAINING_RECORD(listEntry,
PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList);
07703
if (arbiterEntry->
ArbiterInterface !=
NULL) {
07704
ASSERT(IsListEmpty(&arbiterEntry->
ResourceList));
07705
ASSERT(IsListEmpty(&arbiterEntry->
ActiveArbiterList));
07706 InitializeListHead(&arbiterEntry->
ActiveArbiterList);
07707 InitializeListHead(&arbiterEntry->
ResourceList);
07708 }
07709 listEntry = listEntry->Flink;
07710 }
07711 }
07712
07713
#endif
07714
07715
07716
NTSTATUS
07717 IopQueryConflictList(
07718
PDEVICE_OBJECT PhysicalDeviceObject,
07719 IN PCM_RESOURCE_LIST ResourceList,
07720 IN ULONG ResourceListSize,
07721 OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList,
07722 IN ULONG ConflictListSize,
07723 IN ULONG Flags
07724 )
07725
07726
07727
07728
07729
07730
07731
07732
07733
07734
07735
07736
07737
07738
07739
07740
07741
07742
07743
07744
07745
07746 {
07747
NTSTATUS status;
07748
07749
PAGED_CODE();
07750
07751
KeEnterCriticalRegion( );
07752
07753 status =
KeWaitForSingleObject( &
IopRegistrySemaphore,
07754
DelayExecution,
07755
KernelMode,
07756
FALSE,
07757
NULL );
07758
07759
if (!
NT_SUCCESS( status )) {
07760
DebugMessage(
DUMP_ERROR, (
"IopQueryConflictList: Get RegustrySemaphore failed. Status %x\n", status));
07761
KeLeaveCriticalRegion( );
07762
return status;
07763 }
else {
07764 status =
IopQueryConflictListInternal(PhysicalDeviceObject, ResourceList, ResourceListSize, ConflictList, ConflictListSize, Flags);
07765
KeReleaseSemaphore( &
IopRegistrySemaphore, 0, 1,
FALSE );
07766
KeLeaveCriticalRegion( );
07767 }
07768
07769
return status;
07770 }
07771
07772
07773
07774 BOOLEAN
07775 IopEliminateBogusConflict(
07776 IN
PDEVICE_OBJECT PhysicalDeviceObject,
07777 IN
PDEVICE_OBJECT ConflictDeviceObject
07778 )
07779
07780
07781
07782
07783
07784
07785
07786
07787
07788
07789
07790
07791
07792
07793
07794
07795
07796 {
07797
NTSTATUS status = STATUS_SUCCESS;
07798
PDEVICE_NODE deviceNode;
07799
PDRIVER_OBJECT driverObject;
07800 KIRQL irql;
07801
PDEVICE_OBJECT attachedDevice;
07802
07803
PAGED_CODE();
07804
07805
07806
07807
07808
if (PhysicalDeviceObject ==
NULL || ConflictDeviceObject ==
NULL) {
07809
return FALSE;
07810 }
07811
07812
07813
07814
07815 ExAcquireFastLock( &
IopDatabaseLock, &irql );
07816
07817
for (attachedDevice = PhysicalDeviceObject;
07818 attachedDevice;
07819 attachedDevice = attachedDevice->
AttachedDevice) {
07820
07821
if (attachedDevice == ConflictDeviceObject) {
07822 ExReleaseFastLock( &
IopDatabaseLock, irql );
07823
return TRUE;
07824 }
07825 }
07826
07827 ExReleaseFastLock( &
IopDatabaseLock, irql );
07828
07829
07830
07831
07832 deviceNode = PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
07833
ASSERT(deviceNode);
07834
if (deviceNode->
Flags &
DNF_LEGACY_DRIVER) {
07835
07836
07837
07838
if (ConflictDeviceObject->Flags &
DO_BUS_ENUMERATED_DEVICE) {
07839
07840
07841
07842
return FALSE;
07843 }
07844
07845
07846
07847 driverObject = ConflictDeviceObject->DriverObject;
07848
if(driverObject ==
NULL) {
07849
07850
07851
07852
ASSERT(driverObject);
07853
return FALSE;
07854 }
07855
07856
07857
07858
if (deviceNode->
ServiceName.Length != 0 &&
07859 deviceNode->
ServiceName.Length == driverObject->
DriverExtension->
ServiceKeyName.Length &&
07860
RtlCompareUnicodeString(&deviceNode->
ServiceName,&driverObject->
DriverExtension->
ServiceKeyName,
TRUE)==0) {
07861
07862
07863
07864
07865
07866
07867
return TRUE;
07868 }
07869
07870 }
07871
return FALSE;
07872 }
07873
07874
07875
NTSTATUS
07876 IopQueryConflictFillString(
07877 IN
PDEVICE_OBJECT DeviceObject,
07878 IN PWSTR Buffer,
07879 IN OUT PULONG Length,
07880 IN OUT PULONG Flags
07881 )
07882
07883
07884
07885
07886
07887
07888
07889
07890
07891
07892
07893
07894
07895
07896
07897
07898
07899
07900 {
07901
NTSTATUS status = STATUS_SUCCESS;
07902
PDEVICE_NODE deviceNode;
07903
PDRIVER_OBJECT driverObject;
07904 PUNICODE_STRING infoString =
NULL;
07905 ULONG MaxLength = 0;
07906 ULONG ReqLength = 0;
07907 ULONG flags = 0;
07908
07909
PAGED_CODE();
07910
07911
if (Length !=
NULL) {
07912 MaxLength = *Length;
07913 }
07914
07915
if (Flags !=
NULL) {
07916 flags = *Flags;
07917 }
07918
07919
if (DeviceObject ==
NULL) {
07920
07921
07922
07923
goto final;
07924
07925 }
07926
07927
if ((DeviceObject->Flags &
DO_BUS_ENUMERATED_DEVICE) == 0 ) {
07928
07929
07930
07931 driverObject = DeviceObject->DriverObject;
07932
if(driverObject ==
NULL) {
07933
07934
07935
07936
ASSERT(driverObject);
07937
goto final;
07938 }
07939 infoString = & (driverObject->
DriverName);
07940 flags |= PNP_CE_LEGACY_DRIVER;
07941
goto final;
07942 }
07943
07944
07945
07946
07947
if (DeviceObject->DeviceObjectExtension ==
NULL) {
07948
07949
07950
07951
ASSERT(DeviceObject->DeviceObjectExtension);
07952
goto final;
07953 }
07954
07955 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
07956
if (deviceNode ==
NULL) {
07957
07958
07959
07960
ASSERT(deviceNode);
07961
goto final;
07962 }
07963
07964
if (deviceNode ==
IopRootDeviceNode) {
07965
07966
07967
07968 flags |= PNP_CE_ROOT_OWNED;
07969
07970 }
else if (deviceNode -> Parent ==
NULL) {
07971
07972
07973
07974 driverObject = (
PDRIVER_OBJECT)(deviceNode->
DuplicatePDO);
07975
if(driverObject ==
NULL) {
07976
07977
07978
07979
ASSERT(driverObject);
07980
goto final;
07981 }
07982 infoString = & (driverObject->
DriverName);
07983 flags |= PNP_CE_LEGACY_DRIVER;
07984
goto final;
07985 }
07986
07987
07988
07989
07990 infoString = &deviceNode->
InstancePath;
07991
07992
final:
07993
07994
if (infoString !=
NULL) {
07995
07996
07997
07998
if ((
Buffer !=
NULL) && (MaxLength*
sizeof(WCHAR) > infoString->Length)) {
07999 RtlCopyMemory(
Buffer, infoString->Buffer, infoString->Length);
08000 }
08001 ReqLength += infoString->Length /
sizeof(WCHAR);
08002 }
08003
08004
if ((
Buffer !=
NULL) && (MaxLength > ReqLength)) {
08005
Buffer[ReqLength] = 0;
08006 }
08007
08008 ReqLength++;
08009
08010
if (Length !=
NULL) {
08011 *Length = ReqLength;
08012 }
08013
if (Flags !=
NULL) {
08014 *Flags = flags;
08015 }
08016
08017
return status;
08018 }
08019
08020
08021
NTSTATUS
08022 IopQueryConflictFillConflicts(
08023
PDEVICE_OBJECT PhysicalDeviceObject,
08024 IN ULONG ConflictCount,
08025 IN
PARBITER_CONFLICT_INFO ConflictInfoList,
08026 OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList,
08027 IN ULONG ConflictListSize,
08028 IN ULONG Flags
08029 )
08030
08031
08032
08033
08034
08035
08036
08037
08038
08039
08040
08041
08042
08043
08044
08045
08046
08047
08048
08049
08050 {
08051
NTSTATUS status = STATUS_SUCCESS;
08052 ULONG ConflictListIdealSize;
08053 ULONG ConflictListBaseSize;
08054 ULONG ConflictListCount;
08055 ULONG
Index;
08056 ULONG ConflictIndex;
08057 ULONG EntrySize;
08058 ULONG ConflictStringsOffset;
08059 ULONG stringSize;
08060 ULONG stringTotalSize;
08061 ULONG DummyCount;
08062 PPLUGPLAY_CONTROL_CONFLICT_STRINGS ConfStrings;
08063
08064
PAGED_CODE();
08065
08066
08067
08068
08069
08070
08071
08072
08073
08074
08075
08076
08077
08078
08079
08080
for(
Index = 0;
Index < ConflictCount;
Index++) {
08081
if (
IopEliminateBogusConflict(PhysicalDeviceObject,ConflictInfoList[
Index].OwningObject)) {
08082
08083
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: eliminating \"identical\" PDO %08x conflicting with self (%08x)\n",
08084 ConflictInfoList[
Index].OwningObject,PhysicalDeviceObject));
08085
08086
08087
08088
if (
Index+1 < ConflictCount) {
08089 RtlCopyMemory(&ConflictInfoList[
Index],&ConflictInfoList[ConflictCount-1],
sizeof(
ARBITER_CONFLICT_INFO));
08090 }
08091
08092
08093
08094 ConflictCount--;
08095
Index--;
08096 }
08097 }
08098
08099
08100
08101
08102
08103
08104 RestartScan:
08105
08106
for(
Index = 0;
Index < ConflictCount;
Index++) {
08107
if (ConflictInfoList[
Index].OwningObject !=
NULL) {
08108
08109 ULONG Index2;
08110
08111
for (Index2 =
Index+1; Index2 < ConflictCount; Index2++) {
08112
if (
IopEliminateBogusConflict(ConflictInfoList[
Index].OwningObject,ConflictInfoList[Index2].OwningObject)) {
08113
08114
08115
08116
08117
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: eliminating \"identical\" PDO %08x conflicting with PDO %08x\n",
08118 ConflictInfoList[Index2].OwningObject,ConflictInfoList[
Index].OwningObject));
08119
08120
08121
08122
if (Index2+1 < ConflictCount) {
08123 RtlCopyMemory(&ConflictInfoList[Index2],&ConflictInfoList[ConflictCount-1],
sizeof(
ARBITER_CONFLICT_INFO));
08124 }
08125
08126
08127
08128 ConflictCount--;
08129 Index2--;
08130 }
else if (
IopEliminateBogusConflict(ConflictInfoList[Index2].OwningObject,ConflictInfoList[
Index].OwningObject)) {
08131
08132
08133
08134
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: eliminating \"identical\" PDO %08x conflicting with PDO %08x\n",
08135 ConflictInfoList[Index2].OwningObject,ConflictInfoList[
Index].OwningObject));
08136
08137
08138
08139 RtlCopyMemory(&ConflictInfoList[
Index],&ConflictInfoList[Index2],
sizeof(
ARBITER_CONFLICT_INFO));
08140
08141
08142
08143
if (Index2+1 < ConflictCount) {
08144 RtlCopyMemory(&ConflictInfoList[Index2],&ConflictInfoList[ConflictCount-1],
sizeof(
ARBITER_CONFLICT_INFO));
08145 }
08146
08147
08148
08149 ConflictCount--;
08150
08151
08152
08153
goto RestartScan;
08154 }
08155 }
08156 }
08157 }
08158
08159
08160
08161
08162
08163
for(
Index = 0;
Index < ConflictCount;
Index++) {
08164
08165
08166
08167
if (ConflictInfoList[
Index].OwningObject ==
NULL) {
08168
08169
08170
08171
08172 ULONG Index2;
08173
08174
for (Index2 =
Index+1; Index2 < ConflictCount; Index2++) {
08175
if (ConflictInfoList[Index2].OwningObject ==
NULL) {
08176
08177
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: eliminating extra unknown\n"));
08178
08179
08180
08181
if (Index2+1 < ConflictCount) {
08182 RtlCopyMemory(&ConflictInfoList[Index2],&ConflictInfoList[ConflictCount-1],
sizeof(
ARBITER_CONFLICT_INFO));
08183 }
08184
08185
08186
08187 ConflictCount--;
08188 Index2--;
08189 }
08190 }
08191
08192
if(ConflictCount != 1) {
08193
08194
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: eliminating first unknown\n"));
08195
08196
08197
08198
if (
Index+1 < ConflictCount) {
08199 RtlCopyMemory(&ConflictInfoList[
Index],&ConflictInfoList[ConflictCount-1],
sizeof(
ARBITER_CONFLICT_INFO));
08200 }
08201 ConflictCount --;
08202 }
08203
08204
break;
08205 }
08206 }
08207
08208
08209
08210
08211
08212 ConflictListIdealSize = (
sizeof(PLUGPLAY_CONTROL_CONFLICT_LIST) -
sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY)) +
sizeof(PLUGPLAY_CONTROL_CONFLICT_STRINGS);
08213 ConflictListCount = 0;
08214 stringTotalSize = 0;
08215 DummyCount = 0;
08216
08217
ASSERT(ConflictListSize >= ConflictListIdealSize);
08218
08219
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: Detected %d conflicts\n", ConflictCount));
08220
08221
08222
08223
08224
if (Flags) {
08225
08226
08227
08228 stringSize = 1;
08229 DummyCount ++;
08230 EntrySize =
sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY);
08231 EntrySize +=
sizeof(WCHAR) * stringSize;
08232
08233
if((ConflictListIdealSize+EntrySize) <= ConflictListSize) {
08234
08235
08236
08237 ConflictListCount++;
08238 stringTotalSize += stringSize;
08239 }
08240 ConflictListIdealSize += EntrySize;
08241 }
08242
08243
08244
08245
for(
Index = 0;
Index < ConflictCount;
Index ++) {
08246
08247 stringSize = 0;
08248
IopQueryConflictFillString(ConflictInfoList[
Index].OwningObject,
NULL,&stringSize,
NULL);
08249
08250
08251
08252
08253 EntrySize =
sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY);
08254 EntrySize +=
sizeof(WCHAR) * stringSize;
08255
08256
if((ConflictListIdealSize+EntrySize) <= ConflictListSize) {
08257
08258
08259
08260 ConflictListCount++;
08261 stringTotalSize += stringSize;
08262 }
08263 ConflictListIdealSize += EntrySize;
08264 }
08265
08266 ConflictList->ConflictsCounted = ConflictCount+DummyCount;
08267 ConflictList->ConflictsListed = ConflictListCount;
08268 ConflictList->RequiredBufferSize = ConflictListIdealSize;
08269
08270
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: Listing %d conflicts\n", ConflictListCount));
08271
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: Need %08x bytes to list all conflicts\n", ConflictListIdealSize));
08272
08273 ConfStrings = (PPLUGPLAY_CONTROL_CONFLICT_STRINGS)&(ConflictList->ConflictEntry[ConflictListCount]);
08274 ConfStrings->NullDeviceInstance = (ULONG)(-1);
08275 ConflictStringsOffset = 0;
08276
08277
for(ConflictIndex = 0; ConflictIndex < DummyCount; ConflictIndex++) {
08278
08279
08280
08281
if (Flags && ConflictIndex == 0) {
08282 ConflictList->ConflictEntry[ConflictIndex].DeviceInstance = ConflictStringsOffset;
08283 ConflictList->ConflictEntry[ConflictIndex].DeviceFlags = Flags;
08284 ConflictList->ConflictEntry[ConflictIndex].ResourceType = 0;
08285 ConflictList->ConflictEntry[ConflictIndex].ResourceStart = 0;
08286 ConflictList->ConflictEntry[ConflictIndex].ResourceEnd = 0;
08287 ConflictList->ConflictEntry[ConflictIndex].ResourceFlags = 0;
08288
08289 ConfStrings->DeviceInstanceStrings[ConflictStringsOffset] = 0;
08290 stringTotalSize --;
08291 ConflictStringsOffset ++;
08292
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: Listing flags %08x\n", Flags));
08293 }
08294 }
08295
08296
08297
08298
for(
Index = 0; ConflictIndex < ConflictListCount ;
Index ++, ConflictIndex++) {
08299
08300
ASSERT(
Index < ConflictCount);
08301
08302
08303
08304 ConflictList->ConflictEntry[ConflictIndex].DeviceInstance = ConflictStringsOffset;
08305 ConflictList->ConflictEntry[ConflictIndex].DeviceFlags = 0;
08306 ConflictList->ConflictEntry[ConflictIndex].ResourceType = 0;
08307 ConflictList->ConflictEntry[ConflictIndex].ResourceStart = (ULONGLONG)(1);
08308 ConflictList->ConflictEntry[ConflictIndex].ResourceEnd = 0;
08309 ConflictList->ConflictEntry[ConflictIndex].ResourceFlags = 0;
08310
08311
08312
08313
08314 stringSize = stringTotalSize;
08315
IopQueryConflictFillString(ConflictInfoList[
Index].OwningObject,
08316 &(ConfStrings->DeviceInstanceStrings[ConflictStringsOffset]),
08317 &stringSize,
08318 &(ConflictList->ConflictEntry[ConflictIndex].DeviceFlags));
08319 stringTotalSize -= stringSize;
08320
DebugMessage(
DUMP_DETAIL, (
"IopQueryConflictFillConflicts: Listing \"%S\"\n", &(ConfStrings->DeviceInstanceStrings[ConflictStringsOffset])));
08321 ConflictStringsOffset += stringSize;
08322 }
08323
08324
08325
08326
08327 ConfStrings->DeviceInstanceStrings[ConflictStringsOffset] = 0;
08328
08329
08330 ;
08331
return status;
08332 }
08333
08334
08335
NTSTATUS
08336 IopQueryConflictListInternal(
08337
PDEVICE_OBJECT PhysicalDeviceObject,
08338 IN PCM_RESOURCE_LIST ResourceList,
08339 IN ULONG ResourceListSize,
08340 OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList,
08341 IN ULONG ConflictListSize,
08342 IN ULONG Flags
08343 )
08344
08345
08346
08347
08348
08349
08350
08351 {
08352
08353
NTSTATUS status = STATUS_SUCCESS;
08354
PDEVICE_NODE deviceNode =
NULL;
08355 PIO_RESOURCE_REQUIREMENTS_LIST ioResources;
08356
PREQ_LIST reqList;
08357
PREQ_DESC reqDesc, reqDescTranslated;
08358 PLIST_ENTRY listHead;
08359
PPI_RESOURCE_ARBITER_ENTRY arbiterEntry;
08360
PREQ_ALTERNATIVE RA;
08361
PREQ_ALTERNATIVE *reqAlternative;
08362 ULONG ConflictCount = 0;
08363
PARBITER_CONFLICT_INFO ConflictInfoList =
NULL;
08364 PIO_RESOURCE_DESCRIPTOR ConflictDesc =
NULL;
08365 ULONG ReqDescCount = 0;
08366
PREQ_DESC *ReqDescTable =
NULL;
08367 PIO_RESOURCE_REQUIREMENTS_LIST pIoReqList =
NULL;
08368 PVOID ExtParams[4];
08369
08370
PAGED_CODE();
08371
08372
ASSERT(PhysicalDeviceObject);
08373
ASSERT(ResourceList);
08374
ASSERT(ResourceListSize);
08375
08376
08377
08378
08379
ASSERT(ResourceList->Count == 1);
08380
ASSERT(ResourceList->List[0].PartialResourceList.Count == 1);
08381
08382
if (ConflictList ==
NULL || (ConflictListSize < (
sizeof(PLUGPLAY_CONTROL_CONFLICT_LIST) -
sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY)) +
sizeof(PLUGPLAY_CONTROL_CONFLICT_STRINGS))) {
08383
08384
08385
08386 status = STATUS_BUFFER_TOO_SMALL;
08387
goto Clean0;
08388 }
08389
08390
08391
08392
08393 ConflictList->ConflictsCounted = 0;
08394 ConflictList->ConflictsListed = 0;
08395 ConflictList->RequiredBufferSize = (
sizeof(PLUGPLAY_CONTROL_CONFLICT_LIST) -
sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY)) +
sizeof(PLUGPLAY_CONTROL_CONFLICT_STRINGS);
08396
08397
08398
08399
08400 deviceNode = (
PDEVICE_NODE)PhysicalDeviceObject->
DeviceObjectExtension->
DeviceNode;
08401
if (!deviceNode) {
08402 status = STATUS_NO_SUCH_DEVICE;
08403
goto Clean0;
08404 }
08405
08406
08407
08408
08409
switch(ResourceList->List[0].PartialResourceList.PartialDescriptors[0].Type) {
08410
case CmResourceTypePort:
08411
case CmResourceTypeMemory:
08412
if(ResourceList->List[0].PartialResourceList.PartialDescriptors[0].u.Generic.Length == 0) {
08413
08414
08415
08416 status = STATUS_SUCCESS;
08417
goto Clean0;
08418 }
08419
break;
08420
case CmResourceTypeInterrupt:
08421
case CmResourceTypeDma:
08422
break;
08423
default:
08424
ASSERT(0);
08425 status = STATUS_INVALID_PARAMETER;
08426
goto Clean0;
08427 }
08428
08429
08430
08431
08432
if (deviceNode->
ChildInterfaceType == InterfaceTypeUndefined) {
08433
08434
08435
08436 pIoReqList = deviceNode->
ResourceRequirements;
08437
if (pIoReqList !=
NULL && pIoReqList->InterfaceType != InterfaceTypeUndefined) {
08438 ResourceList->List[0].InterfaceType = pIoReqList->InterfaceType;
08439 }
else {
08440
08441
08442
08443
08444
08445
#if MYDBG
08446
ASSERT(0);
08447
#endif
08448
ResourceList->List[0].InterfaceType =
PnpDefaultInterfaceType;
08449 }
08450
08451 }
else {
08452
08453
08454
08455 ResourceList->List[0].InterfaceType = deviceNode->
ChildInterfaceType;
08456 }
08457
08458
08459
08460
switch(ResourceList->List[0].InterfaceType) {
08461
case InterfaceTypeUndefined:
08462
case PCMCIABus:
08463 ResourceList->List[0].InterfaceType =
PnpDefaultInterfaceType;
08464 }
08465
if ((deviceNode->
ChildBusNumber & 0x80000000) == 0x80000000) {
08466
08467
08468
08469 pIoReqList = deviceNode->
ResourceRequirements;
08470
if (pIoReqList !=
NULL && (pIoReqList->BusNumber & 0x80000000) != 0x80000000) {
08471 ResourceList->List[0].BusNumber = pIoReqList->BusNumber;
08472 }
else {
08473
08474
08475
08476
08477
#if MYDBG
08478
ASSERT(0);
08479
#endif
08480
ResourceList->List[0].BusNumber = 0;
08481 }
08482
08483 }
else {
08484
08485
08486
08487 ResourceList->List[0].BusNumber = deviceNode->
ChildBusNumber;
08488 }
08489
08490
08491
08492
08493 ioResources =
IopCmResourcesToIoResources(0, ResourceList, LCPRI_FORCECONFIG);
08494
if (!ioResources) {
08495 status = STATUS_INVALID_PARAMETER;
08496
goto Clean0;
08497 }
08498
08499
08500
08501
08502 status =
IopResourceRequirementsListToReqList(
08503
ArbiterRequestUndefined,
08504 ioResources,
08505 PhysicalDeviceObject,
08506 &reqList);
08507
08508
08509
08510
08511
08512
if (
NT_SUCCESS(status) && reqList) {
08513
08514 reqAlternative = reqList->ReqAlternativeTable;
08515
RA = *reqAlternative;
08516 reqList->SelectedAlternative = reqAlternative;
08517
08518 ReqDescCount =
RA->ReqDescCount;
08519 ReqDescTable =
RA->ReqDescTable;
08520
08521
08522
08523
08524
if (ReqDescCount>0) {
08525
08526
08527
08528
08529
08530 reqDesc = *ReqDescTable;
08531
if (reqDesc->ArbitrationRequired) {
08532 reqDescTranslated = reqDesc->TranslatedReqDesc;
08533
08534 arbiterEntry = reqDesc->u.Arbiter;
08535
ASSERT(arbiterEntry);
08536
08537
08538
08539 ConflictDesc = reqDescTranslated->AlternativeTable.Alternatives;
08540
08541
08542
08543
08544
if(ConflictDesc->Type == CmResourceTypeConfigData || ConflictDesc->Type ==
CmResourceTypeReserved)
08545 ConflictDesc++;
08546
08547
08548
08549
08550 ExtParams[0] = PhysicalDeviceObject;
08551 ExtParams[1] = ConflictDesc;
08552 ExtParams[2] = &ConflictCount;
08553 ExtParams[3] = &ConflictInfoList;
08554 status =
IopCallArbiter(arbiterEntry,
ArbiterActionQueryConflict , ExtParams,
NULL ,
NULL);
08555
08556
if (
NT_SUCCESS(status)) {
08557
08558
08559
08560 status =
IopQueryConflictFillConflicts(PhysicalDeviceObject,ConflictCount,ConflictInfoList,ConflictList,ConflictListSize,0);
08561
if(ConflictInfoList !=
NULL) {
08562
ExFreePool(ConflictInfoList);
08563 }
08564 }
08565
else if(status == STATUS_RANGE_NOT_FOUND) {
08566
08567
08568
08569
08570 status =
IopQueryConflictFillConflicts(
NULL,0,
NULL,ConflictList,ConflictListSize,PNP_CE_TRANSLATE_FAILED);
08571 }
08572
08573 }
else {
08574
#if MYDBG
08575
ASSERT(0);
08576
#endif
08577
status = STATUS_INVALID_PARAMETER;
08578 }
08579 }
else {
08580
#if MYDBG
08581
ASSERT(0);
08582
#endif
08583
status = STATUS_INVALID_PARAMETER;
08584 }
08585
08586
#if DBG_SCOPE
08587
if (
PnpResDebugLevel &
STOP_ERROR) {
08588
IopCheckDataStructures(
IopRootDeviceNode);
08589 }
08590
#endif
08591
08592
IopFreeReqList(reqList);
08593 }
else {
08594
#if MYDBG
08595
ASSERT(0);
08596
#endif
08597
if(
NT_SUCCESS(status)) {
08598
08599
08600
08601 status = STATUS_INVALID_PARAMETER;
08602 }
08603
08604 }
08605
ExFreePool(ioResources);
08606
08607 Clean0:
08608 ;
08609
08610
return status;
08611 }