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
#include "iop.h"
00027
#pragma hdrstop
00028
00029
#ifdef POOL_TAGGING
00030
#undef ExAllocatePool
00031
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'ddpP')
00032
#endif
00033
00034
00035
00036
00037
00038 typedef struct _DEVICE_LIST_CONTEXT {
00039 ULONG
DeviceCount;
00040 BOOLEAN
Reallocation;
00041 PDEVICE_OBJECT DeviceList[1];
00042 }
DEVICE_LIST_CONTEXT, *
PDEVICE_LIST_CONTEXT;
00043
00044 BOOLEAN
00045
IopAddDevicesToBootDriverWorker(
00046 IN HANDLE DeviceInstanceHandle,
00047 IN PUNICODE_STRING DeviceInstancePath,
00048 IN OUT PVOID Context
00049 );
00050
00051
NTSTATUS
00052
IopProcessAddDevicesWorker (
00053 IN
PDEVICE_NODE DeviceNode,
00054 IN PVOID Context
00055 );
00056
00057
NTSTATUS
00058
IopProcessAssignResourcesWorker (
00059 IN
PDEVICE_NODE DeviceNode,
00060 IN PVOID Context
00061 );
00062
00063
VOID
00064
IopPnPCompleteRequest(
00065 IN OUT
PIRP Irp,
00066 IN NTSTATUS Status,
00067 IN ULONG_PTR Information
00068 );
00069
00070
NTSTATUS
00071
IopGetDriverDeviceList (
00072 IN
PDRIVER_OBJECT DriverObject,
00073 OUT PDEVICE_LIST_CONTEXT *DeviceList
00074 );
00075
00076 BOOLEAN
00077
IopGetDriverDeviceListWorker(
00078 IN HANDLE DeviceInstanceHandle,
00079 IN PUNICODE_STRING DeviceInstancePath,
00080 IN OUT PVOID Context
00081 );
00082
00083
NTSTATUS
00084
IopAssignResourcesToDevices (
00085 IN ULONG DeviceCount,
00086 IN
PIOP_RESOURCE_REQUEST RequestTable,
00087 IN BOOLEAN BootConfigsOK
00088 );
00089
00090 BOOLEAN
00091
IopIsFirmwareDisabled (
00092 IN
PDEVICE_NODE DeviceNode
00093 );
00094
00095
00096
#ifdef ALLOC_PRAGMA
00097
#pragma alloc_text(INIT, IopAddDevicesToBootDriver)
00098
#pragma alloc_text(INIT, IopAddDevicesToBootDriverWorker)
00099
00100
#pragma alloc_text(PAGE, IopReleaseDeviceResources)
00101
#pragma alloc_text(PAGE, IopPnPAddDevice)
00102
#pragma alloc_text(PAGE, IopPnPDispatch)
00103
#pragma alloc_text(INIT, IopProcessAddDevices)
00104
#pragma alloc_text(INIT, IopProcessAddDevicesWorker)
00105
#pragma alloc_text(PAGE, IopProcessAssignResources)
00106
#pragma alloc_text(PAGE, IopProcessAssignResourcesWorker)
00107
#pragma alloc_text(PAGE, IopGetDriverDeviceList)
00108
#pragma alloc_text(PAGE, IopGetDriverDeviceListWorker)
00109
#pragma alloc_text(PAGE, IopNewDevice)
00110
#pragma alloc_text(PAGE, IopStartDriverDevices)
00111
#pragma alloc_text(PAGE, IopAssignResourcesToDevices)
00112
#pragma alloc_text(PAGE, IopWriteAllocatedResourcesToRegistry)
00113
#pragma alloc_text(PAGE, IopIsFirmwareDisabled)
00114
#endif
00115
00116
NTSTATUS
00117 IopAddDevicesToBootDriver (
00118 IN
PDRIVER_OBJECT DriverObject
00119 )
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 {
00139
NTSTATUS status;
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 status =
IopApplyFunctionToServiceInstances(
00153
NULL,
00154 &DriverObject->DriverExtension->ServiceKeyName,
00155 KEY_ALL_ACCESS,
00156
TRUE,
00157
IopAddDevicesToBootDriverWorker,
00158 DriverObject,
00159
NULL
00160 );
00161
00162
return status;
00163 }
00164
00165 BOOLEAN
00166 IopAddDevicesToBootDriverWorker(
00167 IN HANDLE DeviceInstanceHandle,
00168 IN PUNICODE_STRING DeviceInstancePath,
00169 IN OUT PVOID Context
00170 )
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 {
00204
NTSTATUS status;
00205
00206
PDEVICE_OBJECT physicalDevice;
00207
PDEVICE_NODE deviceNode;
00208 ULONG length;
00209 BOOLEAN conflict;
00210 PCM_RESOURCE_LIST cmResource;
00211
00212
ADD_CONTEXT addContext;
00213
00214
00215
00216
00217
00218
00219 physicalDevice =
IopDeviceObjectFromDeviceInstance(DeviceInstanceHandle,
00220 DeviceInstancePath);
00221
if (!physicalDevice) {
00222
return TRUE;
00223 }
00224
00225 deviceNode = (
PDEVICE_NODE)physicalDevice->
DeviceObjectExtension->
DeviceNode;
00226
ASSERT(deviceNode && (deviceNode->
PhysicalDeviceObject == physicalDevice));
00227
00228
00229
00230
00231
00232
if (!
OK_TO_ADD_DEVICE(deviceNode)) {
00233
goto exit;
00234 }
00235
00236
00237
00238
00239
00240
00241
if ((deviceNode->
Flags &
DNF_DUPLICATE) && (deviceNode->
DuplicatePDO)) {
00242
goto exit;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 addContext.
GroupsToStart = 0xffff;
00252 addContext.
GroupToStartNext = 0;
00253 addContext.
DriverStartType = SERVICE_BOOT_START;
00254
00255
IopCallDriverAddDevice(deviceNode,
FALSE, &addContext);
00256
00257
exit:
00258
ObDereferenceObject(physicalDevice);
00259
return TRUE;
00260 }
00261
00262
NTSTATUS
00263 IopReleaseDeviceResources (
00264 IN
PDEVICE_NODE DeviceNode,
00265 IN BOOLEAN ReserveResources
00266 )
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 {
00287 BOOLEAN conflict;
00288
NTSTATUS status= STATUS_SUCCESS;
00289 PCM_RESOURCE_LIST cmResource;
00290 ULONG cmLength;
00291
00292
PAGED_CODE();
00293
00294
if (DeviceNode->ResourceList || (DeviceNode->Flags &
DNF_BOOT_CONFIG_RESERVED)) {
00295
00296 cmResource =
NULL;
00297 cmLength = 0;
00298
00299
00300
00301
00302
00303
00304
00305
if (ReserveResources && !(DeviceNode->Flags &
DNF_MADEUP)) {
00306
00307
00308
00309
00310
00311 status =
IopQueryDeviceResources ( DeviceNode->PhysicalDeviceObject,
00312
QUERY_RESOURCE_LIST,
00313 &cmResource,
00314 &cmLength);
00315
00316
if (!
NT_SUCCESS(status)) {
00317
00318 cmResource =
NULL;
00319 cmLength = 0;
00320
00321 }
00322 }
00323
00324
00325
00326
00327
00328 status =
IopLegacyResourceAllocation(
ArbiterRequestUndefined,
00329
IoPnpDriverObject,
00330 DeviceNode->PhysicalDeviceObject,
00331
NULL,
00332
NULL);
00333
if (
NT_SUCCESS(status)) {
00334
00335
IopResourcesReleased =
TRUE;
00336
00337
00338
00339
00340
00341
00342
00343
if (ReserveResources && !(DeviceNode->Flags &
DNF_MADEUP)) {
00344
00345 UNICODE_STRING unicodeName;
00346 HANDLE logConfHandle;
00347 HANDLE handle;
00348
00349
ASSERT(DeviceNode->BootResources ==
NULL);
00350
00351 status =
IopDeviceObjectToDeviceInstance(DeviceNode->PhysicalDeviceObject, &handle, KEY_ALL_ACCESS);
00352 logConfHandle =
NULL;
00353
if (
NT_SUCCESS(status)) {
00354
00355
00356 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
00357 status =
IopCreateRegistryKeyEx( &logConfHandle,
00358 handle,
00359 &unicodeName,
00360 KEY_ALL_ACCESS,
00361 REG_OPTION_NON_VOLATILE,
00362
NULL);
00363
if (!
NT_SUCCESS(status)) {
00364
00365 logConfHandle =
NULL;
00366
00367 }
00368 }
00369
00370
if (logConfHandle) {
00371
00372 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG);
00373
KeEnterCriticalRegion();
00374
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
00375
if (cmResource) {
00376
00377 ZwSetValueKey( logConfHandle,
00378 &unicodeName,
00379
TITLE_INDEX_VALUE,
00380 REG_RESOURCE_LIST,
00381 cmResource,
00382 cmLength);
00383 }
else {
00384
00385 ZwDeleteValueKey(logConfHandle, &unicodeName);
00386
00387 }
00388
ExReleaseResource(&
PpRegistryDeviceResource);
00389
KeLeaveCriticalRegion();
00390
00391 ZwClose(logConfHandle);
00392 }
00393
00394
00395
00396
00397
00398
if (cmResource) {
00399
00400 DeviceNode->Flags |=
DNF_HAS_BOOT_CONFIG;
00401 DeviceNode->BootResources = cmResource;
00402
00403
00404
00405
00406
00407 (*IopReserveResourcesRoutine)(
ArbiterRequestPnpEnumerated,
00408 DeviceNode->PhysicalDeviceObject,
00409 cmResource);
00410 }
00411 }
00412 }
00413 }
00414
00415
return status;
00416 }
00417
00418
NTSTATUS
00419 IopPnPAddDevice(
00420 IN
PDRIVER_OBJECT DriverObject,
00421 IN
PDEVICE_OBJECT DeviceObject
00422 )
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 {
00442
PAGED_CODE();
00443
00444
#if DBG
00445
00446
00447
00448
00449
00450 DbgBreakPoint();
00451
00452
#endif
00453
00454
return STATUS_SUCCESS;
00455 }
00456
00457
00458
NTSTATUS
00459 IopArbiterHandlerxx (
00460 IN PVOID Context,
00461 IN ARBITER_ACTION Action,
00462 IN OUT
PARBITER_PARAMETERS Parameters
00463 )
00464 {
00465 PLIST_ENTRY listHead, listEntry;
00466 PIO_RESOURCE_DESCRIPTOR ioDesc;
00467 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDesc;
00468
PARBITER_LIST_ENTRY arbiterListEntry;
00469
00470
if (
Action ==
ArbiterActionQueryArbitrate) {
00471
return STATUS_SUCCESS;
00472 }
00473
if (Parameters ==
NULL) {
00474
return STATUS_SUCCESS;
00475 }
00476 listHead = Parameters->Parameters.TestAllocation.ArbitrationList;
00477
if (IsListEmpty(listHead)) {
00478
return STATUS_SUCCESS;
00479 }
00480 listEntry = listHead->Flink;
00481
while (listEntry != listHead) {
00482 arbiterListEntry = (
PARBITER_LIST_ENTRY)listEntry;
00483 cmDesc = arbiterListEntry->
Assignment;
00484 ioDesc = arbiterListEntry->
Alternatives;
00485
if (cmDesc ==
NULL || ioDesc ==
NULL) {
00486
return STATUS_SUCCESS;
00487 }
00488 cmDesc->Type = ioDesc->Type;
00489 cmDesc->ShareDisposition = ioDesc->ShareDisposition;
00490 cmDesc->Flags = ioDesc->Flags;
00491
if (ioDesc->Type == CmResourceTypePort) {
00492 cmDesc->u.Port.Start = ioDesc->u.Port.MinimumAddress;
00493 cmDesc->u.Port.Length = ioDesc->u.Port.Length;
00494 }
else if (ioDesc->Type == CmResourceTypeInterrupt) {
00495 cmDesc->u.Interrupt.Level = ioDesc->u.Interrupt.MinimumVector;
00496 cmDesc->u.Interrupt.Vector = ioDesc->u.Interrupt.MinimumVector;
00497 cmDesc->u.Interrupt.Affinity = (ULONG) -1;
00498 }
else if (ioDesc->Type == CmResourceTypeMemory) {
00499 cmDesc->u.Memory.Start = ioDesc->u.Memory.MinimumAddress;
00500 cmDesc->u.Memory.Length = ioDesc->u.Memory.Length;
00501 }
else if (ioDesc->Type == CmResourceTypeDma) {
00502 cmDesc->u.Dma.Channel = ioDesc->u.Dma.MinimumChannel;
00503 cmDesc->u.Dma.Port = 0;
00504 cmDesc->u.Dma.Reserved1 = 0;
00505 }
00506 listEntry = listEntry->Flink;
00507 }
00508
return STATUS_SUCCESS;
00509 }
00510
NTSTATUS
00511 IopTranslatorHandlerCm (
00512 IN PVOID Context,
00513 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
00514 IN RESOURCE_TRANSLATION_DIRECTION Direction,
00515 IN ULONG AlternativesCount, OPTIONAL
00516 IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
00517 IN
PDEVICE_OBJECT DeviceObject,
00518 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
00519 )
00520 {
00521 *Target = *Source;
00522
#if 0
00523
if (Direction ==
TranslateChildToParent) {
00524
if (Target->Type == CmResourceTypePort) {
00525 Target->u.Port.Start.LowPart += 0x10000;
00526 }
else if (Target->Type == CmResourceTypeMemory) {
00527 Target->u.Memory.Start.LowPart += 0x100000;
00528 }
00529 }
else {
00530
if (Target->Type == CmResourceTypePort) {
00531 Target->u.Port.Start.LowPart -= 0x10000;
00532 }
else if (Target->Type == CmResourceTypeMemory) {
00533 Target->u.Memory.Start.LowPart -= 0x100000;
00534 }
00535 }
00536
#endif
00537
return STATUS_SUCCESS;
00538 }
00539
NTSTATUS
00540 IopTranslatorHandlerIo (
00541 IN PVOID Context,
00542 IN PIO_RESOURCE_DESCRIPTOR Source,
00543 IN
PDEVICE_OBJECT DeviceObject,
00544 OUT PULONG TargetCount,
00545 OUT PIO_RESOURCE_DESCRIPTOR *Target
00546 )
00547 {
00548 PIO_RESOURCE_DESCRIPTOR newDesc;
00549
00550 newDesc = (PIO_RESOURCE_DESCRIPTOR)
ExAllocatePool(
PagedPool,
sizeof(IO_RESOURCE_DESCRIPTOR));
00551
if (newDesc ==
NULL) {
00552
return STATUS_INSUFFICIENT_RESOURCES;
00553 }
00554 *TargetCount = 1;
00555 *newDesc = *Source;
00556
#if 0
00557
if (newDesc->Type == CmResourceTypePort) {
00558 newDesc->u.Port.MinimumAddress.LowPart += 0x10000;
00559 newDesc->u.Port.MaximumAddress.LowPart += 0x10000;
00560 }
else if (newDesc->Type == CmResourceTypeMemory) {
00561 newDesc->u.Memory.MinimumAddress.LowPart += 0x100000;
00562 newDesc->u.Memory.MaximumAddress.LowPart += 0x100000;
00563 }
00564
#endif
00565
*Target = newDesc;
00566
return STATUS_SUCCESS;
00567 }
00568
00569
NTSTATUS
00570 IopPowerDispatch(
00571 IN
PDEVICE_OBJECT DeviceObject,
00572 IN OUT
PIRP Irp
00573 )
00574 {
00575
PIO_STACK_LOCATION IrpSp;
00576
PPOWER_SEQUENCE PowerSequence;
00577
NTSTATUS Status;
00578
00579
00580 UNREFERENCED_PARAMETER( DeviceObject );
00581
00582 IrpSp =
IoGetCurrentIrpStackLocation (
Irp);
00583
Status =
Irp->
IoStatus.Status;
00584
00585
switch (IrpSp->
MinorFunction) {
00586
case IRP_MN_WAIT_WAKE:
00587
Status = STATUS_NOT_SUPPORTED;
00588
break;
00589
00590
case IRP_MN_POWER_SEQUENCE:
00591 PowerSequence = IrpSp->
Parameters.PowerSequence.PowerSequence;
00592 PowerSequence->
SequenceD1 =
PoPowerSequence;
00593 PowerSequence->
SequenceD2 =
PoPowerSequence;
00594 PowerSequence->
SequenceD3 =
PoPowerSequence;
00595
Status = STATUS_SUCCESS;
00596
break;
00597
00598
case IRP_MN_QUERY_POWER:
00599
Status = STATUS_SUCCESS;
00600
break;
00601
00602
case IRP_MN_SET_POWER:
00603
switch (IrpSp->
Parameters.Power.Type) {
00604
case SystemPowerState:
00605
Status = STATUS_SUCCESS;
00606
break;
00607
00608
case DevicePowerState:
00609
00610
00611
00612
00613
00614
00615
Status = STATUS_SUCCESS;
00616
break;
00617
00618
default:
00619
00620
Status = STATUS_NOT_SUPPORTED;
00621
break;
00622 }
00623
break;
00624
00625
default:
00626
00627
Status = STATUS_NOT_SUPPORTED;
00628
break;
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
PoStartNextPowerIrp(
Irp);
00638
if (
Status != STATUS_NOT_SUPPORTED) {
00639
Irp->
IoStatus.Status =
Status;
00640 }
else {
00641
Status =
Irp->
IoStatus.Status;
00642 }
00643
IoCompleteRequest(
Irp,
IO_NO_INCREMENT );
00644
return Status;
00645 }
00646
00647
NTSTATUS
00648 IopPnPDispatch(
00649 IN
PDEVICE_OBJECT DeviceObject,
00650 IN OUT
PIRP Irp
00651 )
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 {
00671
PIOPNP_DEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
00672
PIO_STACK_LOCATION irpSp;
00673
NTSTATUS status;
00674 PVOID information =
NULL;
00675 ULONG length;
00676 PWCHAR
id, wp;
00677
PDEVICE_NODE deviceNode;
00678
PARBITER_INTERFACE arbiterInterface;
00679
PTRANSLATOR_INTERFACE translatorInterface;
00680
00681
PAGED_CODE();
00682
00683
00684
00685
00686
00687
00688 irpSp =
IoGetCurrentIrpStackLocation(
Irp);
00689
switch (irpSp->
MinorFunction){
00690
00691
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
00692
case IRP_MN_START_DEVICE:
00693
00694
00695
00696
00697
00698
00699 status = STATUS_SUCCESS;
00700
break;
00701
00702
case IRP_MN_CANCEL_STOP_DEVICE:
00703
00704
00705
00706
00707
00708 status = STATUS_SUCCESS;
00709
break;
00710
00711
case IRP_MN_QUERY_STOP_DEVICE:
00712
case IRP_MN_STOP_DEVICE:
00713
00714
00715
00716
00717
00718 status = STATUS_UNSUCCESSFUL ;
00719
break;
00720
00721
case IRP_MN_QUERY_RESOURCES:
00722
00723 status =
IopGetDeviceResourcesFromRegistry(
00724 DeviceObject,
00725
QUERY_RESOURCE_LIST,
00726
REGISTRY_BOOT_CONFIG,
00727 &information,
00728 &length);
00729
if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
00730 status = STATUS_SUCCESS;
00731 information =
NULL;
00732 }
00733
break;
00734
00735
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
00736
00737 status =
IopGetDeviceResourcesFromRegistry(
00738 DeviceObject,
00739
QUERY_RESOURCE_REQUIREMENTS,
00740
REGISTRY_BASIC_CONFIGVECTOR,
00741 &information,
00742 &length);
00743
if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
00744 status = STATUS_SUCCESS;
00745 information =
NULL;
00746 }
00747
break;
00748
00749
case IRP_MN_QUERY_REMOVE_DEVICE:
00750
case IRP_MN_REMOVE_DEVICE:
00751
case IRP_MN_CANCEL_REMOVE_DEVICE:
00752
00753
00754
00755
00756
00757
00758
00759 status = STATUS_SUCCESS;
00760
break;
00761
00762
case IRP_MN_QUERY_DEVICE_RELATIONS:
00763
00764
if (DeviceObject ==
IopRootDeviceNode->
PhysicalDeviceObject &&
00765 irpSp->
Parameters.QueryDeviceRelations.Type ==
BusRelations) {
00766 status =
IopGetRootDevices((
PDEVICE_RELATIONS *)&information);
00767 }
else {
00768
if (irpSp->
Parameters.QueryDeviceRelations.Type ==
TargetDeviceRelation) {
00769
PDEVICE_RELATIONS deviceRelations;
00770
00771 deviceRelations =
ExAllocatePool(
PagedPool,
sizeof(
DEVICE_RELATIONS));
00772
if (deviceRelations ==
NULL) {
00773 status = STATUS_INSUFFICIENT_RESOURCES;
00774 }
else {
00775 deviceRelations->
Count = 1;
00776 deviceRelations->
Objects[0] = DeviceObject;
00777
ObReferenceObject(DeviceObject);
00778 information = (PVOID)deviceRelations;
00779 status = STATUS_SUCCESS;
00780 }
00781 }
else {
00782 information = (PVOID)
Irp->
IoStatus.Information;
00783 status =
Irp->
IoStatus.Status;
00784 }
00785 }
00786
break;
00787
00788
case IRP_MN_QUERY_INTERFACE:
00789 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
00790
if (deviceNode ==
IopRootDeviceNode) {
00791
if (
IopCompareGuid((PVOID)irpSp->
Parameters.QueryInterface.InterfaceType, (PVOID)&GUID_ARBITER_INTERFACE_STANDARD)) {
00792 status = STATUS_SUCCESS;
00793 arbiterInterface = (
PARBITER_INTERFACE) irpSp->
Parameters.QueryInterface.Interface;
00794 arbiterInterface->
ArbiterHandler =
ArbArbiterHandler;
00795
switch ((UCHAR)((ULONG_PTR)irpSp->
Parameters.QueryInterface.InterfaceSpecificData)) {
00796
case CmResourceTypePort:
00797 arbiterInterface->
Context = (PVOID) &
IopRootPortArbiter;
00798
break;
00799
case CmResourceTypeMemory:
00800 arbiterInterface->
Context = (PVOID) &
IopRootMemArbiter;
00801
break;
00802
case CmResourceTypeInterrupt:
00803 arbiterInterface->
Context = (PVOID) &
IopRootIrqArbiter;
00804
break;
00805
case CmResourceTypeDma:
00806 arbiterInterface->
Context = (PVOID) &
IopRootDmaArbiter;
00807
break;
00808
case CmResourceTypeBusNumber:
00809 arbiterInterface->
Context = (PVOID) &
IopRootBusNumberArbiter;
00810
break;
00811
default:
00812 status = STATUS_INVALID_PARAMETER;
00813
break;
00814 }
00815 }
else if (
IopCompareGuid((PVOID)irpSp->
Parameters.QueryInterface.InterfaceType, (PVOID)&GUID_TRANSLATOR_INTERFACE_STANDARD)) {
00816 translatorInterface = (
PTRANSLATOR_INTERFACE) irpSp->
Parameters.QueryInterface.Interface;
00817 translatorInterface->
TranslateResources =
IopTranslatorHandlerCm;
00818 translatorInterface->
TranslateResourceRequirements =
IopTranslatorHandlerIo;
00819 status = STATUS_SUCCESS;
00820 }
00821
break;
00822 }
00823
00824 status =
Irp->
IoStatus.Status;
00825
break;
00826
00827
case IRP_MN_QUERY_CAPABILITIES:
00828
00829 {
00830 ULONG i;
00831 PDEVICE_POWER_STATE state;
00832
PDEVICE_CAPABILITIES deviceCapabilities;
00833
00834 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
00835
00836 deviceCapabilities = irpSp->
Parameters.DeviceCapabilities.Capabilities;
00837 deviceCapabilities->
Size =
sizeof(
DEVICE_CAPABILITIES);
00838 deviceCapabilities->
Version = 1;
00839
00840 deviceCapabilities->
DeviceState[PowerSystemUnspecified]=PowerDeviceUnspecified;
00841 deviceCapabilities->
DeviceState[PowerSystemWorking]=PowerDeviceD0;
00842
00843 state = &deviceCapabilities->
DeviceState[PowerSystemSleeping1];
00844
00845
for (i = PowerSystemSleeping1; i < PowerSystemMaximum; i++) {
00846
00847
00848
00849
00850
00851 *state++ = PowerDeviceD3;
00852 }
00853
00854
00855
if(
IopIsFirmwareDisabled(deviceNode)) {
00856
00857
00858
00859 deviceCapabilities->
HardwareDisabled =
TRUE;
00860 }
00861
00862 status = STATUS_SUCCESS;
00863 }
00864
break;
00865
00866
case IRP_MN_QUERY_ID:
00867
if (DeviceObject !=
IopRootDeviceNode->
PhysicalDeviceObject &&
00868 (!
NT_SUCCESS(
Irp->
IoStatus.Status) || !
Irp->
IoStatus.Information)) {
00869
00870 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
00871
switch (irpSp->
Parameters.QueryId.IdType) {
00872
00873
case BusQueryInstanceID:
00874
case BusQueryDeviceID:
00875
00876
id = (PWCHAR)
ExAllocatePool(
PagedPool, deviceNode->
InstancePath.Length);
00877
if (
id) {
00878 ULONG separatorCount = 0;
00879
00880 RtlZeroMemory(
id, deviceNode->
InstancePath.Length);
00881 information =
id;
00882 status = STATUS_SUCCESS;
00883 wp = deviceNode->
InstancePath.Buffer;
00884
if (irpSp->
Parameters.QueryId.IdType ==
BusQueryDeviceID) {
00885
while(*wp) {
00886
if (*wp == OBJ_NAME_PATH_SEPARATOR) {
00887 separatorCount++;
00888
if (separatorCount == 2) {
00889
break;
00890 }
00891 }
00892 *
id = *wp;
00893
id++;
00894 wp++;
00895 }
00896 }
else {
00897
while(*wp) {
00898
if (*wp == OBJ_NAME_PATH_SEPARATOR) {
00899 separatorCount++;
00900
if (separatorCount == 2) {
00901 wp++;
00902
break;
00903 }
00904 }
00905 wp++;
00906 }
00907
while (*wp) {
00908 *
id = *wp;
00909
id++;
00910 wp++;
00911 }
00912 }
00913 }
else {
00914 status = STATUS_INSUFFICIENT_RESOURCES;
00915 }
00916
break;
00917
00918
case BusQueryCompatibleIDs:
00919
00920
if((
Irp->
IoStatus.Status != STATUS_NOT_SUPPORTED) ||
00921 (deviceExtension ==
NULL)) {
00922
00923
00924
00925
00926
00927
00928 status =
Irp->
IoStatus.Status;
00929
break;
00930 }
00931
00932
if(deviceExtension->
CompatibleIdListSize != 0) {
00933
00934
id =
ExAllocatePool(
PagedPool,
00935 deviceExtension->
CompatibleIdListSize);
00936
00937
if(
id ==
NULL) {
00938 status = STATUS_INSUFFICIENT_RESOURCES;
00939
break;
00940 }
00941
00942 RtlCopyMemory(
id,
00943 deviceExtension->
CompatibleIdList,
00944 deviceExtension->
CompatibleIdListSize);
00945
00946 information =
id;
00947 status = STATUS_SUCCESS;
00948
break;
00949 }
00950
00951
default:
00952
00953 information = (PVOID)
Irp->
IoStatus.Information;
00954 status =
Irp->
IoStatus.Status;
00955 }
00956 }
else {
00957 information = (PVOID)
Irp->
IoStatus.Information;
00958 status =
Irp->
IoStatus.Status;
00959 }
00960
00961
break;
00962
#if 0
00963
case IRP_MN_QUERY_BUS_INFORMATION:
00964 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
00965
if (deviceNode ==
IopRootDeviceNode) {
00966
PPNP_BUS_INFORMATION busInfo;
00967
00968 busInfo = (
PPNP_BUS_INFORMATION)
ExAllocatePool(
PagedPool,
sizeof(
PNP_BUS_INFORMATION));
00969
if (busInfo) {
00970 busInfo->
LegacyBusType =
PnpDefaultInterfaceType;
00971 busInfo->
BusNumber = 0;
00972
if (
PnpDefaultInterfaceType == Isa) {
00973 busInfo->
BusTypeGuid = GUID_BUS_TYPE_ISAPNP;
00974 }
else if (
PnpDefaultInterfaceType == Eisa) {
00975 busInfo->
BusTypeGuid = GUID_BUS_TYPE_EISA;
00976 }
else {
00977 busInfo->
BusTypeGuid = GUID_BUS_TYPE_MCA;
00978 }
00979 information = busInfo;
00980 status = STATUS_SUCCESS;
00981 }
else {
00982 status = STATUS_INSUFFICIENT_RESOURCES;
00983 information =
NULL;
00984 }
00985
break;
00986 }
00987
#endif
00988
00989
00990
00991
00992
00993
default:
00994
00995 information = (PVOID)
Irp->
IoStatus.Information;
00996 status =
Irp->
IoStatus.Status;
00997
break;
00998 }
00999
01000
01001
01002
01003
01004
IopPnPCompleteRequest(
Irp, status, (ULONG_PTR)information);
01005
return status;
01006 }
01007
01008
VOID
01009 IopPnPCompleteRequest(
01010 IN OUT
PIRP Irp,
01011 IN NTSTATUS Status,
01012 IN ULONG_PTR Information
01013 )
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 {
01036 KIRQL oldIrql;
01037
01038
01039
01040
01041
01042
Irp->
IoStatus.Status =
Status;
01043
Irp->
IoStatus.Information = Information;
01044
01045
01046
01047
01048
01049
IoCompleteRequest(
Irp,
IO_NO_INCREMENT);
01050 }
01051
01052
USHORT
01053 IopProcessAddDevices (
01054 IN
PDEVICE_NODE DeviceNode,
01055 IN USHORT StartOrder,
01056 IN ULONG DriverStartType
01057 )
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 {
01082
PDEVICE_NODE deviceNode, nextDeviceNode;
01083
USHORT returnValue =
NO_MORE_GROUP;
01084
ADD_CONTEXT context;
01085
01086 context.
GroupsToStart = StartOrder;
01087 context.
GroupToStartNext =
NO_MORE_GROUP;
01088 context.
DriverStartType = DriverStartType;
01089
01090
01091
01092
01093
01094
if (DeviceNode !=
IopRootDeviceNode) {
01095
IopAcquireEnumerationLock(DeviceNode);
01096 }
01097
01098 deviceNode = DeviceNode->
Child;
01099
while (deviceNode) {
01100
01101
01102
01103
01104
01105
01106 nextDeviceNode = deviceNode->
Sibling;
01107
IopProcessAddDevicesWorker(deviceNode, &context);
01108 deviceNode = nextDeviceNode;
01109 }
01110
if (DeviceNode !=
IopRootDeviceNode) {
01111
IopReleaseEnumerationLock(DeviceNode);
01112 }
01113
return context.
GroupToStartNext;
01114 }
01115
01116
NTSTATUS
01117 IopProcessAddDevicesWorker (
01118 IN
PDEVICE_NODE DeviceNode,
01119 IN PVOID Context
01120 )
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142 {
01143
PADD_CONTEXT addContext = (
PADD_CONTEXT)Context;
01144
01145
01146
if (DeviceNode->Flags &
DNF_ADDED) {
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
IopAcquireEnumerationLock(DeviceNode);
01159
01160
01161
01162
01163
01164
IopForAllChildDeviceNodes(DeviceNode,
IopProcessAddDevicesWorker, Context);
01165
01166
01167
01168
01169
01170
IopReleaseEnumerationLock(DeviceNode);
01171
01172 }
else if (
OK_TO_ADD_DEVICE(DeviceNode)) {
01173
01174
01175
01176
01177
01178
01179
IopCallDriverAddDevice(DeviceNode,
TRUE, addContext);
01180 }
01181
return STATUS_SUCCESS;
01182 }
01183
01184 BOOLEAN
01185 IopProcessAssignResources (
01186 IN
PDEVICE_NODE DeviceNode,
01187 IN BOOLEAN Reallocation,
01188 IN BOOLEAN BootConfigsOK
01189 )
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 {
01216
PDEVICE_NODE deviceNode;
01217
PDEVICE_LIST_CONTEXT context;
01218 BOOLEAN again =
FALSE;
01219 ULONG count, i;
01220
PIOP_RESOURCE_REQUEST requestTable;
01221
01222
PAGED_CODE();
01223
01224
01225
01226
01227
01228 context = (
PDEVICE_LIST_CONTEXT)
ExAllocatePool(
01229
PagedPool,
01230
sizeof(
DEVICE_LIST_CONTEXT) +
01231
sizeof(
PDEVICE_OBJECT) *
IopNumberDeviceNodes
01232 );
01233
if (!context) {
01234
return again;
01235 }
01236 context->
DeviceCount = 0;
01237 context->
Reallocation = Reallocation;
01238
01239
01240
01241
01242
01243
IopAcquireEnumerationLock(DeviceNode);
01244 deviceNode = DeviceNode->
Child;
01245
01246
while (deviceNode) {
01247
IopProcessAssignResourcesWorker(deviceNode, context);
01248 deviceNode = deviceNode->
Sibling;
01249 }
01250
IopReleaseEnumerationLock(DeviceNode);
01251 count = context->
DeviceCount;
01252
if (count == 0) {
01253
ExFreePool(context);
01254
return again;
01255 }
01256
01257
01258
01259
01260
01261
01262 requestTable = (
PIOP_RESOURCE_REQUEST)
ExAllocatePool(
01263
PagedPool,
01264
sizeof(
IOP_RESOURCE_REQUEST) * count
01265 );
01266
if (requestTable) {
01267
01268
for (i = 0; i < count; i++) {
01269 requestTable[i].
Priority = 0;
01270 requestTable[i].
PhysicalDevice = context->
DeviceList[i];
01271 }
01272
01273
01274
01275
01276
01277
ExAcquireResourceShared(&
IopDeviceTreeLock,
TRUE);
01278
IopAssignResourcesToDevices(count, requestTable, BootConfigsOK);
01279
01280
01281
01282
01283
01284
for (i = 0; i < count; i++) {
01285
01286 deviceNode = (
PDEVICE_NODE)
01287 requestTable[i].
PhysicalDevice->
DeviceObjectExtension->
DeviceNode;
01288
if (
NT_SUCCESS(requestTable[i].
Status)) {
01289
if (requestTable[i].
ResourceAssignment) {
01290
if (!(deviceNode->
Flags &
DNF_RESOURCE_REPORTED)) {
01291 deviceNode->
Flags |=
DNF_RESOURCE_ASSIGNED;
01292 }
01293
01294 deviceNode->
ResourceList = requestTable[i].
ResourceAssignment;
01295 deviceNode->
ResourceListTranslated = requestTable[i].
TranslatedResourceAssignment;
01296 }
else {
01297 deviceNode->
Flags |=
DNF_NO_RESOURCE_REQUIRED;
01298 }
01299 }
else if (requestTable[i].
Status == STATUS_RETRY) {
01300 again =
TRUE;
01301 }
else if (requestTable[i].
Status == STATUS_DEVICE_CONFIGURATION_ERROR) {
01302
IopSetDevNodeProblem(deviceNode, CM_PROB_NO_SOFTCONFIG);
01303 }
else if (requestTable[i].
Status == STATUS_PNP_BAD_MPS_TABLE) {
01304
IopSetDevNodeProblem(deviceNode, CM_PROB_BIOS_TABLE);
01305 }
else if (requestTable[i].
Status == STATUS_PNP_TRANSLATION_FAILED) {
01306
IopSetDevNodeProblem(deviceNode, CM_PROB_TRANSLATION_FAILED);
01307 }
else if (requestTable[i].
Status == STATUS_PNP_IRQ_TRANSLATION_FAILED) {
01308
IopSetDevNodeProblem(deviceNode, CM_PROB_IRQ_TRANSLATION_FAILED);
01309 }
else {
01310
IopSetDevNodeProblem(deviceNode, CM_PROB_NORMAL_CONFLICT);
01311 }
01312
01313
01314
01315
01316
01317
01318 deviceNode->
Flags &= ~
DNF_ASSIGNING_RESOURCES;
01319 }
01320
ExReleaseResource(&
IopDeviceTreeLock);
01321
ExFreePool(requestTable);
01322 }
01323
ExFreePool(context);
01324
return again;
01325 }
01326
01327
NTSTATUS
01328 IopProcessAssignResourcesWorker (
01329 IN
PDEVICE_NODE DeviceNode,
01330 IN PVOID Context
01331 )
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352 {
01353
PDEVICE_LIST_CONTEXT resourceContext = (
PDEVICE_LIST_CONTEXT) Context;
01354
01355
PAGED_CODE();
01356
01357
01358
01359
01360
01361
if (!(DeviceNode->Flags &
DNF_ADDED)) {
01362
return STATUS_SUCCESS;
01363 }
01364
01365
if (resourceContext->
Reallocation &&
01366 (
IopIsDevNodeProblem(DeviceNode, CM_PROB_NORMAL_CONFLICT) ||
01367
IopIsDevNodeProblem(DeviceNode, CM_PROB_TRANSLATION_FAILED) ||
01368
IopIsDevNodeProblem(DeviceNode, CM_PROB_IRQ_TRANSLATION_FAILED))) {
01369
IopClearDevNodeProblem(DeviceNode);
01370 }
01371
01372
01373
01374
01375
01376
01377
if ( !(DeviceNode->Flags &
DNF_START_PHASE) &&
01378 !(DeviceNode->Flags &
DNF_ASSIGN_RESOURCE_PHASE)) {
01379
01380 resourceContext->
DeviceList[resourceContext->
DeviceCount] =
01381 DeviceNode->PhysicalDeviceObject;
01382 DeviceNode->
Flags |=
DNF_ASSIGNING_RESOURCES;
01383 resourceContext->
DeviceCount++;
01384
01385 }
else {
01386
01387
01388
01389
01390
01391
01392
01393
IopAcquireEnumerationLock(DeviceNode);
01394
01395
01396
01397
01398
01399
IopForAllChildDeviceNodes(DeviceNode,
IopProcessAssignResourcesWorker, Context);
01400
01401
01402
01403
01404
01405
IopReleaseEnumerationLock(DeviceNode);
01406 }
01407
return STATUS_SUCCESS;
01408 }
01409
01410
NTSTATUS
01411 IopGetDriverDeviceList (
01412 IN
PDRIVER_OBJECT DriverObject,
01413 OUT PDEVICE_LIST_CONTEXT *DeviceList
01414 )
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435 {
01436
NTSTATUS status;
01437 HANDLE enumHandle;
01438 ULONG count = 0;
01439 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
01440
PDEVICE_LIST_CONTEXT deviceList;
01441
01442
PAGED_CODE();
01443
01444 *DeviceList =
NULL;
01445
KeEnterCriticalRegion();
01446
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
01447
01448
01449
01450
01451
01452 status =
IopOpenServiceEnumKeys (
01453 &DriverObject->DriverExtension->ServiceKeyName,
01454 KEY_READ,
01455
NULL,
01456 &enumHandle,
01457
FALSE
01458 );
01459
if (!
NT_SUCCESS(status)) {
01460
goto exit;
01461 }
01462
01463
01464
01465
01466
01467
01468 status =
IopGetRegistryValue(enumHandle, REGSTR_VALUE_COUNT, &keyValueInformation);
01469 ZwClose(enumHandle);
01470
if (
NT_SUCCESS(status)) {
01471
if (keyValueInformation->DataLength != 0) {
01472 count = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01473 }
01474
ExFreePool(keyValueInformation);
01475 }
01476
01477
if (count == 0) {
01478
goto exit;
01479 }
01480
01481 deviceList = (
PDEVICE_LIST_CONTEXT)
ExAllocatePool(
01482
PagedPool,
01483
sizeof(
DEVICE_LIST_CONTEXT) +
01484
sizeof(
PDEVICE_OBJECT) * count * 2
01485 );
01486
01487
if (!deviceList) {
01488 status = STATUS_INSUFFICIENT_RESOURCES;
01489
goto exit;
01490 }
01491
01492 deviceList->
DeviceCount = 0;
01493
01494
01495
01496
01497
01498
01499 status =
IopApplyFunctionToServiceInstances(
01500
NULL,
01501 &DriverObject->DriverExtension->ServiceKeyName,
01502 KEY_ALL_ACCESS,
01503
TRUE,
01504
IopGetDriverDeviceListWorker,
01505 deviceList,
01506
NULL
01507 );
01508 *DeviceList = deviceList;
01509
exit:
01510
ExReleaseResource(&
PpRegistryDeviceResource);
01511
KeLeaveCriticalRegion();
01512
return status;
01513 }
01514
01515 BOOLEAN
01516 IopGetDriverDeviceListWorker(
01517 IN HANDLE DeviceInstanceHandle,
01518 IN PUNICODE_STRING DeviceInstancePath,
01519 IN OUT PVOID Context
01520 )
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548 {
01549
PDEVICE_LIST_CONTEXT deviceList = (
PDEVICE_LIST_CONTEXT)Context;
01550
PDEVICE_OBJECT physicalDevice;
01551
PDEVICE_NODE deviceNode;
01552
01553
PAGED_CODE();
01554
01555
01556
01557
01558
01559 physicalDevice =
IopDeviceObjectFromDeviceInstance(DeviceInstanceHandle,
01560 DeviceInstancePath);
01561
if (!physicalDevice) {
01562
return TRUE;
01563 }
01564
01565 deviceNode = (
PDEVICE_NODE)physicalDevice->
DeviceObjectExtension->
DeviceNode;
01566
01567
01568
01569
01570
01571
if (
IopDoesDevNodeHaveProblem(deviceNode)) {
01572
goto exit;
01573 }
else if (!
IopIsDeviceInstanceEnabled(DeviceInstanceHandle, DeviceInstancePath,
TRUE)) {
01574
goto exit;
01575 }
01576
01577
01578
01579
01580
01581
01582
if ((deviceNode->
Flags &
DNF_DUPLICATE) && (deviceNode->
DuplicatePDO)) {
01583
01584
goto exit;
01585 }
01586
01587 deviceList->
DeviceList[deviceList->
DeviceCount] = physicalDevice;
01588 deviceList->
DeviceCount++;
01589
return TRUE;
01590
exit:
01591
ObDereferenceObject(physicalDevice);
01592
return TRUE;
01593 }
01594
01595
VOID
01596 IopNewDevice(
01597 IN
PDEVICE_OBJECT DeviceObject
01598 )
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616 {
01617
PDEVICE_NODE deviceNode, parent;
01618
IOP_RESOURCE_REQUEST requestTable;
01619
NTSTATUS status;
01620 BOOLEAN newDevice;
01621
START_CONTEXT startContext;
01622
ADD_CONTEXT addContext;
01623
01624
PAGED_CODE();
01625
01626 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
01627
01628
01629
01630
01631
01632
if (deviceNode->
Flags &
DNF_ADDED) {
01633
goto exit;
01634 }
01635
01636
01637
01638
01639
01640
if (!(deviceNode->
Flags &
DNF_NEED_QUERY_IDS)) {
01641
01642
01643
01644
01645 addContext.
GroupsToStart = 0xffff;
01646 addContext.
GroupToStartNext = 0xffff;
01647 addContext.
DriverStartType = SERVICE_DEMAND_START;
01648
01649 status =
IopCallDriverAddDevice(deviceNode,
TRUE, &addContext);
01650
if (!
NT_SUCCESS(status) || (deviceNode->
Flags &
DNF_LEGACY_DRIVER)) {
01651
goto exit;
01652 }
else if (deviceNode->
Flags &
DNF_NEED_QUERY_IDS) {
01653
01654
01655
01656
01657
01658
goto enumerate;
01659 }
01660
01661
01662
01663
01664
01665 requestTable.
PhysicalDevice = DeviceObject;
01666 requestTable.
Priority = 0;
01667
01668
IopAssignResourcesToDevices(1, &requestTable,
TRUE);
01669
01670
if (
NT_SUCCESS(requestTable.
Status)) {
01671
if (requestTable.
ResourceAssignment) {
01672
if (!(deviceNode->
Flags &
DNF_RESOURCE_REPORTED)) {
01673 deviceNode->
Flags |=
DNF_RESOURCE_ASSIGNED;
01674 }
01675
01676 deviceNode->
ResourceList = requestTable.
ResourceAssignment;
01677 deviceNode->
ResourceListTranslated = requestTable.
TranslatedResourceAssignment;
01678 }
else {
01679 deviceNode->
Flags |=
DNF_NO_RESOURCE_REQUIRED;
01680 }
01681 }
else if (requestTable.
Status == STATUS_DEVICE_CONFIGURATION_ERROR) {
01682
IopSetDevNodeProblem(deviceNode, CM_PROB_NO_SOFTCONFIG);
01683
goto exit;
01684 }
else if (requestTable.
Status == STATUS_PNP_BAD_MPS_TABLE) {
01685
IopSetDevNodeProblem(deviceNode, CM_PROB_BIOS_TABLE);
01686
goto exit;
01687 }
else if (requestTable.
Status == STATUS_PNP_TRANSLATION_FAILED) {
01688
IopSetDevNodeProblem(deviceNode, CM_PROB_TRANSLATION_FAILED);
01689
goto exit;
01690 }
else if (requestTable.
Status == STATUS_PNP_IRQ_TRANSLATION_FAILED) {
01691
IopSetDevNodeProblem(deviceNode, CM_PROB_IRQ_TRANSLATION_FAILED);
01692
goto exit;
01693 }
else {
01694
IopSetDevNodeProblem(deviceNode, CM_PROB_NORMAL_CONFLICT);
01695
goto exit;
01696 }
01697 }
01698
01699 enumerate:
01700
01701
01702
01703
01704
01705 startContext.
LoadDriver =
TRUE;
01706 startContext.
NewDevice =
FALSE;
01707 startContext.
AddContext.
GroupsToStart =
NO_MORE_GROUP;
01708 startContext.
AddContext.
GroupToStartNext =
NO_MORE_GROUP;
01709 startContext.
AddContext.
DriverStartType = SERVICE_DEMAND_START;
01710
01711
IopStartAndEnumerateDevice(deviceNode, &startContext);
01712 newDevice = startContext.
NewDevice;
01713
while (newDevice) {
01714
01715 startContext.
NewDevice =
FALSE;
01716
01717
01718
01719
01720
01721
01722 newDevice =
IopProcessAssignResources(deviceNode,
FALSE,
TRUE);
01723
01724
01725
01726
01727
01728
01729
01730
IopProcessStartDevices(deviceNode, &startContext);
01731 newDevice |= startContext.
NewDevice;
01732
01733 }
01734
01735
exit:
01736 ;
01737 }
01738
01739
NTSTATUS
01740 IopStartDriverDevices(
01741 IN
PDRIVER_OBJECT DriverObject
01742 )
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763 {
01764 ULONG count, i;
01765
PDEVICE_LIST_CONTEXT deviceList;
01766
PDEVICE_NODE deviceNode;
01767
NTSTATUS status = STATUS_SUCCESS;
01768
PDRIVER_ADD_DEVICE addDeviceRoutine;
01769
01770
PAGED_CODE();
01771
01772
if (!
PnPInitialized) {
01773
01774
01775
01776
01777
01778
01779
01780
return status;
01781 }
01782
01783 addDeviceRoutine = DriverObject->DriverExtension->AddDevice;
01784
if (addDeviceRoutine ==
NULL) {
01785
ASSERT(addDeviceRoutine);
01786
return status;
01787 }
01788
01789
IopGetDriverDeviceList(DriverObject, &deviceList);
01790 count = deviceList ? deviceList->
DeviceCount : 0;
01791
if (count == 0) {
01792
01793
if (deviceList !=
NULL) {
01794
ExFreePool(deviceList);
01795 }
01796
01797
return STATUS_PLUGPLAY_NO_DEVICE;
01798 }
01799
01800
01801
01802
01803
01804
for (i = 0; i < count; i++) {
01805
01806 deviceNode = (
PDEVICE_NODE)deviceList->
DeviceList[i]->
DeviceObjectExtension->
DeviceNode;
01807
if (!deviceNode || !(deviceNode->
Flags &
DNF_NEED_QUERY_IDS) ) {
01808
ObDereferenceObject(deviceList->
DeviceList[i]);
01809
continue;
01810 }
01811
IopRequestDeviceAction(deviceList->
DeviceList[i],
StartDevice,
NULL,
NULL);
01812 }
01813
01814
ExFreePool(deviceList);
01815
return status;
01816 }
01817
01818
01819
01820
01821
01822
01823
NTSTATUS
01824 IopAssignResourcesToDevices (
01825 IN ULONG DeviceCount,
01826 IN OUT
PIOP_RESOURCE_REQUEST RequestTable,
01827 IN BOOLEAN BootConfigsOK
01828 )
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862 {
01863
NTSTATUS status;
01864 ULONG i;
01865
01866
PAGED_CODE();
01867
01868
ASSERT(DeviceCount != 0);
01869
01870
for (i = 0; i < DeviceCount; i++) {
01871
01872
01873
01874
01875
01876 RequestTable[i].ResourceAssignment =
NULL;
01877 RequestTable[i].Status = 0;
01878 RequestTable[i].Flags = 0;
01879 RequestTable[i].AllocationType =
ArbiterRequestPnpEnumerated;
01880
if (((
PDEVICE_NODE)(RequestTable[i].PhysicalDevice->DeviceObjectExtension->DeviceNode))->Flags &
DNF_MADEUP) {
01881
01882 ULONG reportedDevice = 0;
01883 HANDLE hInstance;
01884
01885 status =
IopDeviceObjectToDeviceInstance(RequestTable[i].PhysicalDevice, &hInstance, KEY_READ);
01886
if (
NT_SUCCESS(status)) {
01887
01888 ULONG resultSize = 0;
01889 UCHAR buffer[
sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
sizeof(ULONG)];
01890 UNICODE_STRING unicodeString;
01891
01892 PiWstrToUnicodeString(&unicodeString, REGSTR_VALUE_DEVICE_REPORTED);
01893 status = ZwQueryValueKey( hInstance,
01894 &unicodeString,
01895 KeyValuePartialInformation,
01896 (PVOID)buffer,
01897
sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
sizeof(ULONG),
01898 &resultSize);
01899
if (
NT_SUCCESS(status)) {
01900
01901 reportedDevice = *(PULONG)(((PKEY_VALUE_PARTIAL_INFORMATION)buffer)->Data);
01902
01903 }
01904
01905 ZwClose(hInstance);
01906 }
01907
01908
01909
01910
01911
01912
if (reportedDevice) {
01913
01914 RequestTable[i].AllocationType =
ArbiterRequestLegacyReported;
01915
01916 }
01917
01918 }
01919 RequestTable[i].ResourceRequirements =
NULL;
01920 }
01921
01922
01923
01924
01925
01926 status =
IopAllocateResources(&DeviceCount, &RequestTable,
FALSE, BootConfigsOK);
01927
return status;
01928 }
01929
01930
NTSTATUS
01931 IopWriteAllocatedResourcesToRegistry (
01932
PDEVICE_NODE DeviceNode,
01933 PCM_RESOURCE_LIST CmResourceList,
01934 ULONG Length
01935 )
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957 {
01958
NTSTATUS status;
01959
PDEVICE_OBJECT deviceObject = DeviceNode->
PhysicalDeviceObject;
01960 HANDLE handle, handlex;
01961 UNICODE_STRING unicodeName;
01962
01963
KeEnterCriticalRegion();
01964
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
01965
01966 status =
IopDeviceObjectToDeviceInstance(
01967 deviceObject,
01968 &handlex,
01969 KEY_ALL_ACCESS);
01970
if (
NT_SUCCESS(status)) {
01971
01972
01973
01974
01975
01976 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
01977 status =
IopCreateRegistryKeyEx( &handle,
01978 handlex,
01979 &unicodeName,
01980 KEY_ALL_ACCESS,
01981 REG_OPTION_VOLATILE,
01982
NULL
01983 );
01984 ZwClose(handlex);
01985
if (
NT_SUCCESS(status)) {
01986
01987
RtlInitUnicodeString(&unicodeName, REGSTR_VALUE_ALLOC_CONFIG);
01988
if (CmResourceList) {
01989 status = ZwSetValueKey(
01990 handle,
01991 &unicodeName,
01992
TITLE_INDEX_VALUE,
01993 REG_RESOURCE_LIST,
01994 CmResourceList,
01995 Length
01996 );
01997 }
else {
01998 status = ZwDeleteValueKey(handle, &unicodeName);
01999 }
02000 ZwClose(handle);
02001 }
02002 }
02003
ExReleaseResource(&
PpRegistryDeviceResource);
02004
KeLeaveCriticalRegion();
02005
return status;
02006 }
02007
02008 BOOLEAN
02009 IopIsFirmwareDisabled (
02010 IN
PDEVICE_NODE DeviceNode
02011 )
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028 {
02029
NTSTATUS status;
02030
PDEVICE_OBJECT deviceObject = DeviceNode->PhysicalDeviceObject;
02031 HANDLE handle, handlex;
02032 UNICODE_STRING unicodeName;
02033 UCHAR buffer[
sizeof(KEY_VALUE_PARTIAL_INFORMATION)+
sizeof(ULONG)];
02034 PKEY_VALUE_PARTIAL_INFORMATION value = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
02035 ULONG buflen;
02036 BOOLEAN FirmwareDisabled =
FALSE;
02037
02038
KeEnterCriticalRegion();
02039
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
02040
02041 status =
IopDeviceObjectToDeviceInstance(
02042 deviceObject,
02043 &handlex,
02044 KEY_ALL_ACCESS);
02045
if (
NT_SUCCESS(status)) {
02046
02047
02048
02049
02050
02051 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
02052 status =
IopCreateRegistryKeyEx( &handle,
02053 handlex,
02054 &unicodeName,
02055 KEY_ALL_ACCESS,
02056 REG_OPTION_VOLATILE,
02057
NULL
02058 );
02059 ZwClose(handlex);
02060
if (
NT_SUCCESS(status)) {
02061
02062
RtlInitUnicodeString(&unicodeName, REGSTR_VAL_FIRMWAREDISABLED);
02063 value = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
02064 buflen =
sizeof(buffer);
02065 status = ZwQueryValueKey(handle,
02066 &unicodeName,
02067 KeyValuePartialInformation,
02068 value,
02069
sizeof(buffer),
02070 &buflen
02071 );
02072
02073 ZwClose(handle);
02074
02075
02076
02077
02078
02079
02080
if (
NT_SUCCESS(status)
02081 && value->Type == REG_DWORD
02082 && value->DataLength ==
sizeof(ULONG)
02083 && (*(PULONG)(value->Data))!=0) {
02084
02085
02086
02087
02088 FirmwareDisabled =
TRUE;
02089 }
02090 }
02091 }
02092
ExReleaseResource(&
PpRegistryDeviceResource);
02093
KeLeaveCriticalRegion();
02094
return FirmwareDisabled;
02095 }
02096