00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include "iop.h"
00025
#pragma hdrstop
00026
#include <setupblk.h>
00027
00028
#ifdef POOL_TAGGING
00029
#undef ExAllocatePool
00030
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'nepP')
00031
#endif
00032
00033 typedef struct _DRIVER_LIST_ENTRY DRIVER_LIST_ENTRY, *
PDRIVER_LIST_ENTRY;
00034
00035 struct _DRIVER_LIST_ENTRY {
00036 PDRIVER_OBJECT DriverObject;
00037 PDRIVER_LIST_ENTRY NextEntry;
00038 };
00039
00040 typedef enum _ADD_DRIVER_STAGE {
00041
LowerDeviceFilters,
00042
LowerClassFilters,
00043
DeviceService,
00044
UpperDeviceFilters,
00045
UpperClassFilters,
00046
MaximumAddStage
00047 }
ADD_DRIVER_STAGE;
00048
00049 typedef struct {
00050 PDEVICE_NODE DeviceNode;
00051
00052 BOOLEAN LoadDriver;
00053
00054 PADD_CONTEXT AddContext;
00055
00056 PDRIVER_LIST_ENTRY DriverLists[
MaximumAddStage];
00057 }
QUERY_CONTEXT, *
PQUERY_CONTEXT;
00058
00059
#if 0
00060
#define ASSERT_INITED(x) \
00061
ASSERTMSG("DO_DEVICE_INITIALIZING not cleared on device object", \
00062
((((x)->Flags) & DO_DEVICE_INITIALIZING) == 0))
00063
#else
00064
#if DBG
00065
#define ASSERT_INITED(x) \
00066
if (((x)->Flags & DO_DEVICE_INITIALIZING) != 0) \
00067
DbgPrint("DO_DEVICE_INITIALIZING flag not cleared on DO %#08lx\n", x);
00068
#else
00069 #define ASSERT_INITED(x)
00070
#endif
00071
#endif
00072
00073
00074
NTSTATUS
00075
IopBusCheck(
00076 IN
PDEVICE_OBJECT DeviceObject,
00077 IN BOOLEAN LoadDriver,
00078 IN BOOLEAN AsyncOk
00079 );
00080
00081
VOID
00082
IopDeviceActionWorker (
00083 PVOID Context
00084 );
00085
00086
NTSTATUS
00087
IopEnumerateDevice(
00088 IN
PDEVICE_OBJECT DeviceObject,
00089 IN
PSTART_CONTEXT StartContext,
00090 IN BOOLEAN AsyncOk
00091 );
00092
00093
NTSTATUS
00094
IopCallDriverAddDeviceQueryRoutine(
00095 IN PWSTR ValueName,
00096 IN ULONG ValueType,
00097 IN PWCHAR ValueData,
00098 IN ULONG ValueLength,
00099 IN PQUERY_CONTEXT Context,
00100 IN ULONG ServiceType
00101 );
00102
00103
NTSTATUS
00104
IopProcessCriticalDeviceRoutine(
00105 IN HANDLE hDevInstance,
00106 IN PBOOLEAN FoundMatch,
00107 IN PUNICODE_STRING ServiceName,
00108 IN PUNICODE_STRING ClassGuid,
00109 IN PUNICODE_STRING LowerFilters,
00110 IN PUNICODE_STRING UpperFilters
00111 );
00112
00113 BOOLEAN
00114
IopProcessCriticalDevice(
00115 IN
PDEVICE_NODE DeviceNode
00116 );
00117
00118
NTSTATUS
00119
IopProcessNewChildren(
00120 IN
PDEVICE_NODE DeviceNode,
00121 IN
PSTART_CONTEXT StartContext
00122 );
00123
00124
NTSTATUS
00125
IopProcessStartDevicesWorker (
00126 IN
PDEVICE_NODE DeviceNode,
00127 OUT PVOID Context
00128 );
00129
00130
USHORT
00131
IopGetBusTypeGuidIndex(
00132 IN LPGUID busTypeGuid
00133 );
00134
00135 BOOLEAN
00136
IopFixupDeviceId(
00137 PWCHAR DeviceId
00138 );
00139
00140 BOOLEAN
00141
IopFixupIds(
00142 IN PWCHAR Ids,
00143 IN ULONG Length
00144 );
00145
00146 BOOLEAN
00147
IopGetRegistryDwordWithFallback(
00148 IN PUNICODE_STRING valueName,
00149 IN HANDLE PrimaryKey,
00150 IN HANDLE SecondaryKey,
00151 IN OUT PULONG Value);
00152
00153 PSECURITY_DESCRIPTOR
00154
IopGetRegistrySecurityWithFallback(
00155 IN PUNICODE_STRING valueName,
00156 IN HANDLE PrimaryKey,
00157 IN HANDLE SecondaryKey);
00158
00159
NTSTATUS
00160
IopChangeDeviceObjectFromRegistryProperties(
00161 IN
PDEVICE_OBJECT PhysicalDeviceObject,
00162 IN HANDLE DeviceClassPropKey,
00163 IN HANDLE DevicePropKey,
00164 IN BOOLEAN UsePdoCharacteristics
00165 );
00166
00167
#if DBG_SCOPE
00168 ULONG
PnpEnumDebugLevel = 0;
00169 #define DebugPrint(level, x) \
00170
if (level <= PnpEnumDebugLevel) { \
00171
DbgPrint x; \
00172
}
00173
#else
00174
#define DebugPrint(level, x)
00175
#endif
00176
00177
#ifdef ALLOC_PRAGMA
00178
#pragma alloc_text(PAGE, IopBusCheck)
00179
#pragma alloc_text(PAGE, IopEnumerateDevice)
00180
#pragma alloc_text(PAGE, IopProcessNewDeviceNode)
00181
#pragma alloc_text(PAGE, IopCallDriverAddDevice)
00182
#pragma alloc_text(PAGE, IopGetBusTypeGuidIndex)
00183
#pragma alloc_text(PAGE, IopFixupDeviceId)
00184
#pragma alloc_text(PAGE, IopFixupIds)
00185
#pragma alloc_text(PAGE, IopProcessStartDevices)
00186
#pragma alloc_text(PAGE, IopProcessStartDevicesWorker)
00187
#pragma alloc_text(PAGE, IopStartAndEnumerateDevice)
00188
#endif
00189
00190
00191
00192
00193
00194
00195 BOOLEAN
IopEnumerationInProgress =
FALSE;
00196 WORK_QUEUE_ITEM IopDeviceEnumerationWorkItem;
00197
00198
00199
00200
00201
00202
00203 #define DEVICE_PREFIX_STRING TEXT("\\Device\\")
00204 #define DOSDEVICES_PREFIX_STRING TEXT("\\DosDevices\\")
00205
00206
NTSTATUS
00207 IopRequestDeviceAction(
00208 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
00209 IN
DEVICE_REQUEST_TYPE RequestType,
00210 IN
PKEVENT CompletionEvent OPTIONAL,
00211 IN PNTSTATUS CompletionStatus OPTIONAL
00212 )
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 {
00236
PPI_DEVICE_REQUEST request;
00237
PDEVICE_NODE deviceNode;
00238 KIRQL oldIrql;
00239
00240
00241
00242
00243
00244 request =
ExAllocatePool(
NonPagedPool,
sizeof(
PI_DEVICE_REQUEST));
00245
00246
if (request) {
00247
00248
00249
00250
00251
if (DeviceObject) {
00252
ObReferenceObject(DeviceObject);
00253 }
00254
00255 request->
DeviceObject = DeviceObject;
00256 request->
RequestType = RequestType;
00257 request->
CompletionEvent = CompletionEvent;
00258 request->
CompletionStatus = (RequestType ==
ReenumerateBootDevices)?
NULL : CompletionStatus;
00259
00260 InitializeListHead(&request->
ListEntry);
00261
00262
00263
00264
00265
00266
00267 ExAcquireSpinLock(&
IopPnPSpinLock, &oldIrql);
00268
00269 InsertTailList(&
IopPnpEnumerationRequestList, &request->
ListEntry);
00270
00271
if ( RequestType ==
ReenumerateBootDevices ||
00272 RequestType ==
ReenumerateRootDevices) {
00273
00274
00275
00276
00277
00278
IopEnumerationInProgress =
TRUE;
00279
KeClearEvent(&
PiEnumerationLock);
00280 ExReleaseSpinLock(&
IopPnPSpinLock, oldIrql);
00281
00282
IopDeviceActionWorker((PVOID)CompletionStatus);
00283
00284 }
else if (
PnPBootDriversLoaded && !
IopEnumerationInProgress) {
00285
IopEnumerationInProgress =
TRUE;
00286
KeClearEvent(&
PiEnumerationLock);
00287 ExReleaseSpinLock(&
IopPnPSpinLock, oldIrql);
00288
00289
00290
00291
00292
00293
ExInitializeWorkItem(&
IopDeviceEnumerationWorkItem,
IopDeviceActionWorker,
NULL);
00294
ExQueueWorkItem(&
IopDeviceEnumerationWorkItem,
DelayedWorkQueue);
00295 }
else {
00296 ExReleaseSpinLock(&
IopPnPSpinLock, oldIrql);
00297 }
00298 }
else {
00299
return STATUS_INSUFFICIENT_RESOURCES;
00300 }
00301
00302
return STATUS_SUCCESS;
00303 }
00304
00305
00306
VOID
00307 IopDeviceActionWorker(
00308 PVOID Context
00309 )
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 {
00332
PPI_DEVICE_REQUEST request;
00333
PDEVICE_OBJECT deviceObject;
00334
PDEVICE_NODE deviceNode;
00335 PLIST_ENTRY entry;
00336 BOOLEAN assignResources =
FALSE, allocateResources =
FALSE;
00337 BOOLEAN bootConfigsOK =
TRUE, bootProcess =
FALSE;
00338 BOOLEAN newDevice, moreProcessing;
00339
START_CONTEXT startContext;
00340 KIRQL oldIrql;
00341
NTSTATUS status = STATUS_UNSUCCESSFUL;
00342
00343
PAGED_CODE();
00344
00345
for (; ;) {
00346
00347 ExAcquireSpinLock(&
IopPnPSpinLock, &oldIrql);
00348 entry = RemoveHeadList(&
IopPnpEnumerationRequestList);
00349
if (entry == &
IopPnpEnumerationRequestList) {
00350 entry =
NULL;
00351 }
00352 ExReleaseSpinLock(&
IopPnPSpinLock, oldIrql);
00353
00354
if (!entry) {
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
if ((allocateResources &&
IopResourcesReleased) || assignResources || bootProcess) {
00366
00367
00368
00369
00370
00371
00372 newDevice =
TRUE;
00373
00374 startContext.
LoadDriver =
PnPBootDriversInitialized;
00375 startContext.
AddContext.
GroupsToStart =
NO_MORE_GROUP;
00376 startContext.
AddContext.
GroupToStartNext =
NO_MORE_GROUP;
00377 startContext.
AddContext.
DriverStartType = SERVICE_DEMAND_START;
00378
00379
do {
00380
00381 startContext.
NewDevice =
FALSE;
00382
00383
00384
00385
00386
00387
00388 moreProcessing =
IopProcessAssignResources(
IopRootDeviceNode, newDevice, bootConfigsOK);
00389
00390
00391
00392
00393
00394
00395
00396
IopProcessStartDevices(
IopRootDeviceNode, &startContext);
00397 newDevice = startContext.
NewDevice;
00398
00399 }
while ((moreProcessing || newDevice) && !bootProcess);
00400
00401 allocateResources =
FALSE;
00402 assignResources =
FALSE;
00403 bootProcess =
FALSE;
00404
IopResourcesReleased =
FALSE;
00405
00406 }
else {
00407
00408 ExAcquireSpinLock(&
IopPnPSpinLock, &oldIrql);
00409
00410
if (IsListEmpty(&
IopPnpEnumerationRequestList)) {
00411
IopEnumerationInProgress =
FALSE;
00412
KeSetEvent(&
PiEnumerationLock, 0,
FALSE);
00413 ExReleaseSpinLock(&
IopPnPSpinLock, oldIrql);
00414
return;
00415 }
00416
00417 ExReleaseSpinLock(&
IopPnPSpinLock, oldIrql);
00418 }
00419
00420
continue;
00421 }
00422
00423 request = CONTAINING_RECORD(entry,
PI_DEVICE_REQUEST, ListEntry);
00424
if (request->
DeviceObject ==
NULL) {
00425
00426
00427
00428
00429
00430
00431
if (request->
RequestType ==
ReenumerateBootDevices) {
00432
00433
00434
00435
00436
00437 bootProcess =
TRUE;
00438
00439
00440
00441
00442
00443
if (Context) {
00444
00445 bootConfigsOK = *(PBOOLEAN)Context;
00446
00447 }
00448
00449 }
else if (request->
RequestType ==
ResourceRequirementsChanged) {
00450
00451
00452
00453
00454 assignResources =
TRUE;
00455 }
else {
00456
00457
00458
00459
00460 allocateResources =
TRUE;
00461 }
00462
ExFreePool(request);
00463
00464
00465
00466
00467
00468
continue;
00469 }
00470
00471
if (request->
RequestType ==
ResourceRequirementsChanged) {
00472
00473 deviceObject = request->
DeviceObject;
00474
00475
00476
00477
00478
00479
IopReallocateResources(deviceObject);
00480
00481 }
else if (request->
RequestType ==
StartDevice) {
00482
00483
PNEW_DEVICE_WORK_ITEM newDeviceWorkItem;
00484
PDEVICE_NODE parentNode;
00485
00486 deviceObject = request->
DeviceObject;
00487 deviceNode = deviceObject->
DeviceObjectExtension->
DeviceNode;
00488
00489
00490
00491
00492
00493
00494
00495
00496
ASSERT(deviceNode);
00497
00498
00499
00500
00501
00502
IopAcquireDeviceTreeLock();
00503
00504
KeEnterCriticalRegion();
00505
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
00506
00507 parentNode = deviceNode->
Parent;
00508
if (parentNode !=
NULL) {
00509
ObReferenceObject(parentNode->
PhysicalDeviceObject);
00510 }
00511
00512
ExReleaseResource(&
PpRegistryDeviceResource);
00513
KeLeaveCriticalRegion();
00514
00515
IopReleaseDeviceTreeLock();
00516
00517
if (parentNode ==
NULL) {
00518 status = STATUS_UNSUCCESSFUL;
00519
goto Clean0;
00520 }
00521
00522
IopAcquireEnumerationLock(parentNode);
00523
00524
if (deviceNode->
Flags &
DNF_STARTED) {
00525
00526
IopReleaseEnumerationLock(parentNode);
00527
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00528 status = STATUS_SUCCESS;
00529
goto Clean0;
00530 }
00531
00532
if ((parentNode->
Parent ==
NULL && parentNode !=
IopRootDeviceNode) ||
00533 !(parentNode->
Flags &
DNF_STARTED) ||
00534 !(deviceNode->
Flags &
DNF_ENUMERATED) ||
00535
IopDoesDevNodeHaveProblem(deviceNode) ||
00536 (deviceNode->
Flags &
DNF_ADDED) ||
00537 deviceNode->
LockCount != 0) {
00538
00539
00540
00541
00542
IopReleaseEnumerationLock(parentNode);
00543
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00544 status = STATUS_UNSUCCESSFUL;
00545
goto Clean0;
00546 }
00547
00548
IopRestartDeviceNode(deviceNode);
00549
00550 status =
IopProcessNewDeviceNode(deviceNode);
00551
00552
KeSetEvent( &parentNode->
EnumerationMutex, 0,
FALSE );
00553
00554
if (
NT_SUCCESS(status) && !
IopDoesDevNodeHaveProblem(deviceNode)) {
00555 PIDBGMSG( PIDBG_EVENTS,
00556 (
"IopDeviceActionWorker: START_REQUEST - calling IopNewDevice\n"));
00557
00558
IopNewDevice(deviceObject);
00559 }
00560
00561
IopReleaseDeviceTreeLock();
00562
00563
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00564 }
else {
00565
00566
PDEVICE_NODE RootNode, parentNode;
00567
00568
00569
00570
00571
00572
00573
ExAcquireResourceShared(&
IopDeviceTreeLock,
TRUE);
00574
00575
00576
00577
00578
00579 deviceNode = RootNode = request->
DeviceObject->
DeviceObjectExtension->
DeviceNode;
00580
while(1) {
00581
00582
00583
00584
00585
00586
KeEnterCriticalRegion();
00587
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
00588
00589 parentNode = deviceNode->
Parent;
00590
if (parentNode) {
00591
ObReferenceObject(parentNode->
PhysicalDeviceObject);
00592 }
00593
ObReferenceObject(deviceNode->
PhysicalDeviceObject);
00594
00595
ExReleaseResource(&
PpRegistryDeviceResource);
00596
KeLeaveCriticalRegion();
00597
00598
if (parentNode) {
00599
00600
PDEVICE_NODE tempNode;
00601
00602
IopAcquireEnumerationLock(parentNode);
00603 tempNode = deviceNode->
Parent;
00604
IopReleaseEnumerationLock(parentNode);
00605
if (!tempNode) {
00606
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00607 }
00608 parentNode = tempNode;
00609 }
00610
00611
if (!parentNode && deviceNode !=
IopRootDeviceNode) {
00612
ObDereferenceObject(deviceNode->
PhysicalDeviceObject);
00613
break;
00614 }
00615
00616
00617
00618
00619
00620
if (!
IopDoesDevNodeHaveProblem(deviceNode) &&
00621 (deviceNode->
Flags & (
DNF_ENUMERATED |
DNF_STARTED)) == (
DNF_ENUMERATED |
DNF_STARTED)) {
00622
00623
00624
00625
00626
00627 status =
IopBusCheck( deviceNode->
PhysicalDeviceObject,
00628
PnPBootDriversInitialized,
00629 (BOOLEAN)(request->
CompletionEvent !=
NULL ?
FALSE :
PnpAsyncOk));
00630
if (status == STATUS_PNP_RESTART_ENUMERATION) {
00631
00632
if (parentNode) {
00633
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00634 }
00635
ObDereferenceObject(deviceNode->
PhysicalDeviceObject);
00636
ExReleaseResource(&
IopDeviceTreeLock);
00637
PpSynchronizeDeviceEventQueue();
00638
ExAcquireResourceShared(&
IopDeviceTreeLock,
TRUE);
00639 deviceNode = RootNode;
00640
continue;
00641 }
00642 }
00643
00644
00645
00646
00647
00648
if (request->
RequestType !=
ReenumerateDeviceOnly) {
00649
00650
if (deviceNode->
Child) {
00651
00652
PDEVICE_NODE child = deviceNode->
Child;
00653
00654
if (parentNode) {
00655
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00656 }
00657
ObDereferenceObject(deviceNode->
PhysicalDeviceObject);
00658 deviceNode = child;
00659
00660 }
else {
00661
00662
while (deviceNode != RootNode) {
00663
00664
if (deviceNode->
Sibling) {
00665
00666
PDEVICE_NODE sibling = deviceNode->
Sibling;
00667
00668
if (parentNode) {
00669
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00670 }
00671
ObDereferenceObject(deviceNode->
PhysicalDeviceObject);
00672 deviceNode = sibling;
00673
break;
00674
00675 }
else {
00676
00677
ObDereferenceObject(deviceNode->
PhysicalDeviceObject);
00678 deviceNode = parentNode;
00679 parentNode = deviceNode->
Parent;
00680
if (parentNode) {
00681
ObReferenceObject(parentNode->PhysicalDeviceObject);
00682 }
00683 }
00684 }
00685 }
00686 }
00687
00688
00689
00690
00691
00692
if (deviceNode == RootNode) {
00693
00694
if (parentNode) {
00695
ObDereferenceObject(parentNode->
PhysicalDeviceObject);
00696 }
00697
ObDereferenceObject(deviceNode->
PhysicalDeviceObject);
00698
break;
00699 }
00700 }
00701
00702
00703
00704
00705
00706
ExReleaseResource(&
IopDeviceTreeLock);
00707 status = STATUS_SUCCESS;
00708 }
00709
00710 Clean0:
00711
00712
00713
00714
00715
if (request->
CompletionStatus) {
00716 *request->
CompletionStatus = status;
00717 }
00718
00719
if (request->
CompletionEvent) {
00720
KeSetEvent(request->
CompletionEvent, 0,
FALSE);
00721 }
00722
ObDereferenceObject(request->
DeviceObject);
00723
ExFreePool(request);
00724 }
00725 }
00726
00727
NTSTATUS
00728 IopBusCheck(
00729 IN
PDEVICE_OBJECT DeviceObject,
00730 IN BOOLEAN LoadDriver,
00731 IN BOOLEAN AsyncOk
00732 )
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 {
00760 BOOLEAN newDevice;
00761
PDEVICE_NODE deviceNode, parent =
NULL;
00762
NTSTATUS status;
00763
START_CONTEXT startContext;
00764
00765
PAGED_CODE();
00766
00767
00768
00769
00770
00771
ObReferenceObject(DeviceObject);
00772 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
00773
00774
00775
00776
00777
00778
00779
00780 startContext.
LoadDriver = LoadDriver;
00781 startContext.
NewDevice =
FALSE;
00782 startContext.
AddContext.
GroupsToStart =
NO_MORE_GROUP;
00783 startContext.
AddContext.
GroupToStartNext =
NO_MORE_GROUP;
00784 startContext.
AddContext.
DriverStartType = SERVICE_DEMAND_START;
00785
00786 status =
IopEnumerateDevice( deviceNode->
PhysicalDeviceObject,
00787 &startContext,
00788 AsyncOk);
00789
00790
if (status != STATUS_PNP_RESTART_ENUMERATION) {
00791
00792
do {
00793
00794 startContext.
NewDevice =
FALSE;
00795
00796
00797
00798
00799
00800
00801 newDevice =
IopProcessAssignResources(deviceNode,
FALSE,
TRUE);
00802
00803
00804
00805
00806
00807
00808
00809
IopProcessStartDevices(deviceNode, &startContext);
00810 newDevice |= startContext.
NewDevice;
00811
00812 }
while (newDevice);
00813 }
00814
00815
ObDereferenceObject(DeviceObject);
00816
00817
return status;
00818 }
00819
00820
VOID
00821 IopProcessStartDevices(
00822 IN
PDEVICE_NODE DeviceNode,
00823 IN
PSTART_CONTEXT StartContext
00824 )
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 {
00845
NTSTATUS status;
00846
PDEVICE_NODE deviceNode, nextDeviceNode;
00847
00848
PAGED_CODE();
00849
00850
00851
00852
00853
00854
ExAcquireResourceShared(&
IopDeviceTreeLock,
TRUE);
00855
if (DeviceNode->LockCount == 0) {
00856
00857
KeWaitForSingleObject( &DeviceNode->EnumerationMutex,
00858
Executive,
00859
KernelMode,
00860
FALSE,
00861
NULL );
00862
00863 deviceNode = DeviceNode->
Child;
00864
while (deviceNode) {
00865 nextDeviceNode = deviceNode->
Sibling;
00866 status =
IopProcessStartDevicesWorker(deviceNode, StartContext);
00867
00868
if (status == STATUS_PNP_RESTART_ENUMERATION) {
00869
00870
IopReleaseEnumerationLock(DeviceNode);
00871
00872
PpSynchronizeDeviceEventQueue();
00873
00874
ExAcquireResourceShared(&
IopDeviceTreeLock,
TRUE);
00875
if (DeviceNode->LockCount == 0) {
00876
00877
KeWaitForSingleObject( &DeviceNode->EnumerationMutex,
00878
Executive,
00879
KernelMode,
00880
FALSE,
00881
NULL );
00882
00883
00884
if (!(DeviceNode->Flags &
DNF_STARTED)) {
00885
break;
00886 }
00887
00888 deviceNode = DeviceNode->
Child;
00889
00890
continue;
00891
00892 }
else {
00893
00894
ExReleaseResource(&
IopDeviceTreeLock);
00895
return;
00896
00897 }
00898 }
00899
00900 deviceNode = nextDeviceNode;
00901 }
00902
00903
KeSetEvent( &DeviceNode->EnumerationMutex,
00904 0,
00905
FALSE );
00906 }
00907
00908
ExReleaseResource(&
IopDeviceTreeLock);
00909 }
00910
00911
NTSTATUS
00912 IopProcessStartDevicesWorker(
00913 IN
PDEVICE_NODE DeviceNode,
00914 OUT PVOID Context
00915 )
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 {
00936
NTSTATUS status = STATUS_SUCCESS;
00937
00938
PAGED_CODE();
00939
00940
if ( (DeviceNode->Flags &
DNF_NEED_QUERY_IDS) ||
00941 ((DeviceNode->Flags &
DNF_ADDED) &&
00942 !(DeviceNode->Flags &
DNF_START_PHASE) &&
00943 (DeviceNode->Flags &
DNF_HAS_RESOURCE)) ) {
00944
00945
00946
00947
00948
00949
00950 status =
IopStartAndEnumerateDevice(DeviceNode, (
PSTART_CONTEXT)Context);
00951
00952 }
else {
00953
00954
00955
00956
00957
00958
00959
00960
ExAcquireResourceShared(&
IopDeviceTreeLock,
TRUE);
00961
00962
if (DeviceNode->LockCount == 0) {
00963
00964
KeWaitForSingleObject( &DeviceNode->EnumerationMutex,
00965
Executive,
00966
KernelMode,
00967
FALSE,
00968
NULL );
00969
00970
00971
00972
00973
00974
00975
IopForAllChildDeviceNodes(DeviceNode,
IopProcessStartDevicesWorker, Context);
00976
00977
00978
00979
00980
00981
KeSetEvent( &DeviceNode->EnumerationMutex,
00982 0,
00983
FALSE );
00984
00985 }
00986
00987
ExReleaseResource(&
IopDeviceTreeLock);
00988 }
00989
00990
return status;
00991 }
00992
00993
NTSTATUS
00994 IopStartAndEnumerateDevice(
00995 IN
PDEVICE_NODE DeviceNode,
00996 IN
PSTART_CONTEXT StartContext
00997 )
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 {
01022
NTSTATUS status;
01023 UNICODE_STRING unicodeName;
01024
PDEVICE_OBJECT deviceObject;
01025 HANDLE handle;
01026
01027
PAGED_CODE();
01028
01029
01030
01031
01032
01033
ASSERT((DeviceNode->Flags &
DNF_ADDED) &&
01034 (DeviceNode->Flags & (
DNF_HAS_RESOURCE |
DNF_NO_RESOURCE_REQUIRED)) &&
01035 (!(DeviceNode->Flags &
DNF_START_PHASE) || (DeviceNode->Flags &
DNF_NEED_QUERY_IDS))
01036 );
01037
01038 deviceObject = DeviceNode->PhysicalDeviceObject;
01039
01040
01041
01042
01043
01044
if (!(DeviceNode->Flags &
DNF_STARTED)) {
01045
01046
IopStartDevice(deviceObject);
01047
01048
01049
01050
01051
01052
01053
01054
if (DeviceNode->Flags &
DNF_STARTED) {
01055
01056
IopDeviceNodeCapabilitiesToRegistry(DeviceNode);
01057
IopQueryDeviceState(deviceObject);
01058 }
01059 }
01060
01061
if (DeviceNode->Flags &
DNF_NEED_QUERY_IDS) {
01062
01063 PWCHAR compatibleIds, hwIds;
01064 ULONG hwIdLength, compatibleIdLength;
01065
01066
01067
01068
01069
01070
01071
01072 DeviceNode->Flags &= ~
DNF_NEED_QUERY_IDS;
01073 status =
IopDeviceObjectToDeviceInstance (deviceObject,
01074 &handle,
01075 KEY_READ
01076 );
01077
if (
NT_SUCCESS(status)) {
01078 status =
IopQueryCompatibleIds(deviceObject,
01079
BusQueryHardwareIDs,
01080 &hwIds,
01081 &hwIdLength);
01082
01083
if (!
NT_SUCCESS(status)) {
01084 hwIds =
NULL;
01085 }
01086
01087 status =
IopQueryCompatibleIds(deviceObject,
01088
BusQueryCompatibleIDs,
01089 &compatibleIds,
01090 &compatibleIdLength);
01091
if (!
NT_SUCCESS(status)) {
01092 compatibleIds =
NULL;
01093 }
01094
01095
if (hwIds || compatibleIds) {
01096
KeEnterCriticalRegion();
01097
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
01098
01099
if (hwIds) {
01100
01101
if (!
IopFixupIds(hwIds, hwIdLength)) {
01102
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
01103
PNP_ERR_BOGUS_ID,
01104 (ULONG_PTR)deviceObject,
01105 (ULONG_PTR)hwIds,
01106 3);
01107 }
01108 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_HARDWAREID);
01109 ZwSetValueKey(handle,
01110 &unicodeName,
01111
TITLE_INDEX_VALUE,
01112 REG_MULTI_SZ,
01113 hwIds,
01114 hwIdLength
01115 );
01116
ExFreePool(hwIds);
01117 }
01118
01119
01120
01121
01122
01123
if (compatibleIds) {
01124
01125
if (!
IopFixupIds(compatibleIds, compatibleIdLength)) {
01126
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
01127
PNP_ERR_BOGUS_ID,
01128 (ULONG_PTR)deviceObject,
01129 (ULONG_PTR)compatibleIds,
01130 4);
01131 }
01132
01133 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_COMPATIBLEIDS);
01134 ZwSetValueKey(handle,
01135 &unicodeName,
01136
TITLE_INDEX_VALUE,
01137 REG_MULTI_SZ,
01138 compatibleIds,
01139 compatibleIdLength
01140 );
01141
ExFreePool(compatibleIds);
01142 }
01143
01144
ExReleaseResource(&
PpRegistryDeviceResource);
01145
KeLeaveCriticalRegion();
01146 }
01147 ZwClose(handle);
01148 }
01149 }
01150
01151
if ((DeviceNode->Flags &
DNF_STARTED) &&
01152 (DeviceNode->Flags &
DNF_NEED_ENUMERATION_ONLY)) {
01153
01154 status =
IopEnumerateDevice(deviceObject, StartContext,
PnpAsyncOk);
01155 }
else {
01156 status = STATUS_SUCCESS;
01157 }
01158
01159
return status;
01160 }
01161
01162
NTSTATUS
01163 IopEnumerateDevice(
01164 IN
PDEVICE_OBJECT DeviceObject,
01165 IN
PSTART_CONTEXT StartContext,
01166 IN BOOLEAN AsyncOk
01167 )
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 {
01193
NTSTATUS status;
01194
PDEVICE_NODE deviceNode;
01195
PDEVICE_NODE childDeviceNode, nextChildDeviceNode;
01196
PDEVICE_OBJECT childDeviceObject;
01197
PDEVICE_RELATIONS deviceRelations;
01198 ULONG i;
01199 BOOLEAN childRemoved, newChildPostponed;
01200
01201
PAGED_CODE();
01202
01203
01204
01205
01206
01207
ObReferenceObject(DeviceObject);
01208
01209 deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
01210
01211
if (deviceNode->
Flags &
DNF_NEED_ENUMERATION_ONLY) {
01212
01213
01214
01215
01216
01217
01218 deviceNode->
Flags &= ~
DNF_NEED_ENUMERATION_ONLY;
01219
01220
01221
01222
01223
PpSetPlugPlayEvent( &GUID_DEVICE_ARRIVAL,
01224 deviceNode->
PhysicalDeviceObject);
01225
01226
IOP_DIAG_THROW_CHAFF_AT_STARTED_PDO_STACK(DeviceObject);
01227
#if DBG
01228
{
01229
01230
IO_STACK_LOCATION irpSp;
01231 ULONG
dummy;
01232
01233
01234
01235
01236
01237 RtlZeroMemory(&irpSp,
sizeof(
IO_STACK_LOCATION));
01238
01239
01240
01241
01242
01243 irpSp.
MajorFunction =
IRP_MJ_PNP;
01244 irpSp.
MinorFunction = 0xff;
01245
01246
01247
01248
01249
01250 status =
IopSynchronousCall(DeviceObject, &irpSp, (PVOID)&
dummy);
01251
if (
NT_SUCCESS(status) ||
dummy != 0) {
01252
if (deviceNode->
ServiceName.Buffer) {
01253
DbgPrint(
"*** BugBug : Driver %wZ returned status = %lx and Information = %lx\n",
01254 &deviceNode->
ServiceName, status,
dummy);
01255
DbgPrint(
" for IRP_MN_BOGUS. ");
01256
ASSERT(0);
01257 }
else {
01258
DbgPrint(
"*** BugBug : Driver returned status = %lx and Information = %lx\n", status,
dummy);
01259
DbgPrint(
" for IRP_MN_BOGUS. ");
01260
ASSERT(0);
01261 }
01262 }
01263 }
01264
01265
#endif
01266
}
01267
01268
01269
01270
01271
01272
IopAcquireEnumerationLock(deviceNode);
01273
01274
if ((deviceNode->
Flags & (
DNF_STARTED |
DNF_REMOVE_PENDING_CLOSES)) !=
DNF_STARTED) {
01275 status = STATUS_UNSUCCESSFUL;
01276 }
else if (deviceNode->
Flags &
DNF_ENUMERATION_REQUEST_PENDING) {
01277
if (!(deviceNode->
Flags &
DNF_BEING_ENUMERATED)) {
01278
01279
01280
01281
01282
01283
01284 deviceRelations = deviceNode->
OverUsed1.PendingDeviceRelations;
01285 deviceNode->
OverUsed1.PendingDeviceRelations =
NULL;
01286 deviceNode->
Flags &= ~
DNF_ENUMERATION_REQUEST_PENDING;
01287 status = STATUS_SUCCESS;
01288 }
else {
01289 status = STATUS_UNSUCCESSFUL;
01290 }
01291 }
else {
01292 status =
IopQueryDeviceRelations(
BusRelations, DeviceObject, AsyncOk, &deviceRelations);
01293 }
01294
if (!
NT_SUCCESS(status) || (status == STATUS_PENDING) || !deviceRelations) {
01295 status = STATUS_SUCCESS;
01296
goto exit;
01297 }
01298
01299
01300
01301
01302
01303 childDeviceNode = deviceNode->
Child;
01304
while (childDeviceNode) {
01305 childDeviceNode->
Flags &= ~
DNF_ENUMERATED;
01306 childDeviceNode = childDeviceNode->
Sibling;
01307 }
01308
01309
01310
01311
01312
01313
for (i = 0; i < deviceRelations->
Count; i++) {
01314
01315 childDeviceObject = deviceRelations->
Objects[i];
01316
01317
ASSERT_INITED(childDeviceObject);
01318
01319
if (childDeviceObject->
DeviceObjectExtension->
ExtensionFlags &
DOE_DELETE_PENDING) {
01320
01321
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
01322
PNP_ERR_PDO_ENUMERATED_AFTER_DELETION,
01323 (ULONG_PTR)childDeviceObject,
01324 0,
01325 0);
01326 }
01327
01328
01329
01330
01331
01332
01333 childDeviceNode = (
PDEVICE_NODE)childDeviceObject->
DeviceObjectExtension->
DeviceNode;
01334
if (childDeviceNode ==
NULL) {
01335
01336
01337
01338
01339
01340 childDeviceNode =
IopAllocateDeviceNode(childDeviceObject);
01341
01342
if (childDeviceNode !=
NULL) {
01343
01344
01345
01346
01347
01348
01349 childDeviceNode->
Flags |=
DNF_ENUMERATED;
01350
01351
01352
01353
01354
01355
01356 childDeviceObject->
Flags |=
DO_BUS_ENUMERATED_DEVICE;
01357
01358
01359
01360
01361
01362
01363
IopInsertTreeDeviceNode (
01364 deviceNode,
01365 childDeviceNode
01366 );
01367
01368 }
else {
01369
01370
01371
01372
01373
01374 KdPrint((
"IopEnumerateDevice: Failed to allocate device node space\n"));
01375
ObDereferenceObject(childDeviceObject);
01376 }
01377 }
else {
01378
01379
01380
01381
01382
01383 childDeviceNode->
Flags |=
DNF_ENUMERATED;
01384
01385
if (childDeviceNode->
DockInfo.DockStatus ==
DOCK_EJECTIRP_COMPLETED) {
01386
01387
01388
01389
01390
01391
01392
IopHardwareProfileCancelRemovedDock(childDeviceNode);
01393 }
01394
01395
ASSERT(!(childDeviceNode->
Flags &
DNF_DEVICE_GONE));
01396
01397
ObDereferenceObject(childDeviceObject);
01398 }
01399 }
01400
01401
ExFreePool(deviceRelations);
01402
01403
01404
01405
01406
01407
01408 childRemoved =
FALSE;
01409
01410
for (childDeviceNode = deviceNode->
Child;
01411 childDeviceNode !=
NULL;
01412 childDeviceNode = nextChildDeviceNode) {
01413
01414
01415
01416
01417
01418
01419 nextChildDeviceNode = childDeviceNode->
Sibling;
01420
01421
if (!(childDeviceNode->
Flags &
DNF_ENUMERATED)) {
01422
01423
if (!(childDeviceNode->
Flags &
DNF_DEVICE_GONE)) {
01424
01425 childDeviceNode->
Flags |=
DNF_DEVICE_GONE;
01426
01427
IopRequestDeviceRemoval( childDeviceNode->
PhysicalDeviceObject,
01428 CM_PROB_DEVICE_NOT_THERE);
01429
01430 childRemoved =
TRUE;
01431 }
01432 }
01433 }
01434
01435
01436
01437
01438
01439
01440
01441
01442
if (deviceNode->
Parent !=
NULL && childRemoved) {
01443
01444 status = STATUS_PNP_RESTART_ENUMERATION;
01445
01446
goto exit;
01447 }
01448
01449
01450
01451
01452
01453
if (!
IopBootConfigsReserved && deviceNode->
InterfaceType != InterfaceTypeUndefined) {
01454
01455
01456
01457
01458
01459
if (deviceNode->
InterfaceType == Isa) {
01460
01461
IopReserveLegacyBootResources(Eisa, deviceNode->
BusNumber);
01462
01463 }
01464
01465
IopReserveLegacyBootResources(deviceNode->
InterfaceType, deviceNode->
BusNumber);
01466
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
IopProcessNewChildren(deviceNode, StartContext);
01476
01477 status = STATUS_SUCCESS;
01478
01479
exit:
01480
01481
IopReleaseEnumerationLock(deviceNode);
01482
ObDereferenceObject(DeviceObject);
01483
01484
return status;
01485 }
01486
01487
NTSTATUS
01488 IopProcessNewChildren(
01489 IN
PDEVICE_NODE DeviceNode,
01490 IN
PSTART_CONTEXT StartContext
01491 )
01492 {
01493
NTSTATUS status;
01494
PDEVICE_NODE childDeviceNode;
01495
01496
for (childDeviceNode = DeviceNode->
Child;
01497 childDeviceNode !=
NULL;
01498 childDeviceNode = childDeviceNode->
Sibling) {
01499
01500
01501
if (childDeviceNode->
Flags &
DNF_ENUMERATED) {
01502
01503
01504
01505
01506
01507
ASSERT(!(childDeviceNode->
Flags &
DNF_DEVICE_GONE));
01508
01509
01510
01511
01512
01513
if (!(childDeviceNode->
Flags &
DNF_PROCESSED)) {
01514
01515
01516
01517
01518
01519
IopProcessNewDeviceNode(childDeviceNode);
01520 }
01521
01522
if (
OK_TO_ADD_DEVICE(childDeviceNode)) {
01523 status =
IopCallDriverAddDevice(childDeviceNode,
01524 StartContext->LoadDriver,
01525 &StartContext->AddContext);
01526
01527
if (
NT_SUCCESS(status)) {
01528 StartContext->NewDevice =
TRUE;
01529 }
01530 }
01531 }
01532 }
01533
01534
return STATUS_SUCCESS;
01535 }
01536
01537
NTSTATUS
01538 IopProcessNewDeviceNode(
01539 IN OUT
PDEVICE_NODE DeviceNode
01540 )
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 {
01561
NTSTATUS status;
01562 PWCHAR deviceId, busId, uniqueId, compatibleIds,
id, hwIds, deviceText, globallyUniqueId;
01563 HANDLE handle, enumHandle, busIdHandle, deviceIdHandle;
01564 HANDLE uniqueIdHandle, logConfHandle;
01565 UNICODE_STRING unicodeName, unicodeString, unicodeDeviceInstance;
01566 ULONG disposition, tmpValue, length, cmLength, ioLength, hwIdLength, compatibleIdLength;
01567 PCM_RESOURCE_LIST cmResource;
01568 PIO_RESOURCE_REQUIREMENTS_LIST ioResource;
01569 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
01570 PWCHAR buffer =
NULL;
01571
PDEVICE_OBJECT deviceObject;
01572
PDEVICE_NODE deviceNode;
01573
IO_STACK_LOCATION irpSp;
01574
DEVICE_CAPABILITIES capabilities;
01575 PVOID
dummy =
NULL;
01576 BOOLEAN globallyUnique =
FALSE;
01577 PWCHAR location =
NULL, description =
NULL;
01578 PKEY_VALUE_PARTIAL_INFORMATION keyValue;
01579 UCHAR CLSIDBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 128];
01580
01581 BOOLEAN processCriticalDevice =
FALSE;
01582 BOOLEAN isRemoteBootCard =
FALSE;
01583 BOOLEAN configuredBySetup;
01584 PWCHAR wp;
01585 GUID busTypeGuid;
01586
01587
PAGED_CODE();
01588
01589 deviceObject = DeviceNode->PhysicalDeviceObject;
01590
01591
01592
01593
01594
01595 status =
IopOpenRegistryKeyEx( &enumHandle,
01596
NULL,
01597 &
CmRegistryMachineSystemCurrentControlSetEnumName,
01598 KEY_ALL_ACCESS
01599 );
01600
if (!
NT_SUCCESS(status)) {
01601 KdPrint((
"IopProcessNewDeviceNode: Unable to open HKLM\\SYSTEM\\CCS\\ENUM\n"));
01602
return status;
01603 }
01604
01605
01606
01607
01608
01609 status =
IopQueryDeviceId(deviceObject, &
id);
01610
01611
if (!
NT_SUCCESS(status) ||
id ==
NULL) {
01612 ZwClose(enumHandle);
01613
return status;
01614 }
01615
01616
01617
01618
01619
if (!
IopFixupDeviceId(
id)) {
01620
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
01621
PNP_ERR_BOGUS_ID,
01622 (ULONG_PTR)deviceObject,
01623 (ULONG_PTR)
id,
01624 1);
01625
01626
01627 }
01628
01629
01630
01631
01632
01633
for (wp =
id; *wp != UNICODE_NULL; wp++) {
01634
if (*wp == OBJ_NAME_PATH_SEPARATOR) {
01635 deviceId = wp + 1;
01636 busId =
id;
01637
break;
01638 }
01639 }
01640
01641
if (*wp != OBJ_NAME_PATH_SEPARATOR) {
01642 ZwClose(enumHandle);
01643
ExFreePool(
id);
01644 KdPrint((
"IopProcessNewDevice: Invalid device id return by driver (not in bus\\device format)\n"));
01645
return STATUS_UNSUCCESSFUL;
01646 }
01647
01648 *wp = UNICODE_NULL;
01649
01650
KeEnterCriticalRegion();
01651
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
01652
01653
01654
01655
01656
01657
RtlInitUnicodeString(&unicodeName, busId);
01658
01659 status =
IopCreateRegistryKeyEx( &busIdHandle,
01660 enumHandle,
01661 &unicodeName,
01662 KEY_ALL_ACCESS,
01663 REG_OPTION_NON_VOLATILE,
01664
NULL
01665 );
01666
01667
if (!
NT_SUCCESS(status)) {
01668
ExFreePool(
id);
01669 ZwClose(enumHandle);
01670
goto exit;
01671 }
01672
01673
01674
01675
01676
01677
RtlInitUnicodeString(&unicodeName, deviceId);
01678 status =
IopCreateRegistryKeyEx( &deviceIdHandle,
01679 busIdHandle,
01680 &unicodeName,
01681 KEY_ALL_ACCESS,
01682 REG_OPTION_NON_VOLATILE,
01683
NULL
01684 );
01685
01686 ZwClose(busIdHandle);
01687
if (!
NT_SUCCESS(status)) {
01688
ExFreePool(
id);
01689 ZwClose(enumHandle);
01690
goto exit;
01691 }
01692
01693
ExReleaseResource(&
PpRegistryDeviceResource);
01694
KeLeaveCriticalRegion();
01695
01696
01697
01698
01699
01700
01701 status =
IopQueryDeviceCapabilities(DeviceNode, &capabilities);
01702
01703
if (capabilities.
NoDisplayInUI) {
01704
01705 DeviceNode->UserFlags |=
DNUF_DONT_SHOW_IN_UI;
01706 }
01707
01708
01709
01710
01711
01712
if (
NT_SUCCESS(status) && (capabilities.
UniqueID)) {
01713 globallyUnique =
TRUE;
01714 }
01715
01716
01717
01718
01719 DeviceNode->DockInfo.DockStatus =
01720 capabilities.
DockDevice ?
DOCK_QUIESCENT :
DOCK_NOTDOCKDEVICE;
01721
01722
01723
01724
01725
01726 RtlZeroMemory(&irpSp,
sizeof(
IO_STACK_LOCATION));
01727
01728
01729
01730
01731
01732 irpSp.
MajorFunction =
IRP_MJ_PNP;
01733 irpSp.
MinorFunction =
IRP_MN_QUERY_DEVICE_TEXT;
01734 irpSp.
Parameters.QueryDeviceText.DeviceTextType =
DeviceTextDescription;
01735 irpSp.
Parameters.QueryDeviceText.LocaleId =
PsDefaultSystemLocaleId;
01736 status =
IopSynchronousCall(deviceObject, &irpSp, &description);
01737
01738
if (!
NT_SUCCESS(status)) {
01739 description =
NULL;
01740 }
01741
01742
01743
01744
01745
01746 RtlZeroMemory(&irpSp,
sizeof(
IO_STACK_LOCATION));
01747
01748
01749
01750
01751
01752 irpSp.
MajorFunction =
IRP_MJ_PNP;
01753 irpSp.
MinorFunction =
IRP_MN_QUERY_DEVICE_TEXT;
01754 irpSp.
Parameters.QueryDeviceText.DeviceTextType =
DeviceTextLocationInformation;
01755 irpSp.
Parameters.QueryDeviceText.LocaleId =
PsDefaultSystemLocaleId;
01756 status =
IopSynchronousCall(deviceObject, &irpSp, &location);
01757
01758
if (!
NT_SUCCESS(status)) {
01759 location =
NULL;
01760 }
01761
01762
01763
01764
01765
01766
IopQueryUniqueId(deviceObject, &uniqueId);
01767
01768 deviceNode = (
PDEVICE_NODE)deviceObject->
DeviceObjectExtension->
DeviceNode;
01769
01770
if (!globallyUnique && deviceNode->
Parent !=
IopRootDeviceNode) {
01771 globallyUniqueId =
NULL;
01772
01773 status =
IopMakeGloballyUniqueId(deviceObject, uniqueId, &globallyUniqueId);
01774
01775
if (uniqueId !=
NULL) {
01776
ExFreePool(uniqueId);
01777 }
01778
01779 uniqueId = globallyUniqueId;
01780
01781 }
else {
01782
01783 status = STATUS_SUCCESS;
01784 }
01785
01786
if (!
NT_SUCCESS(status) || uniqueId ==
NULL) {
01787
if (description) {
01788
ExFreePool(description);
01789 }
01790
if (location) {
01791
ExFreePool(location);
01792 }
01793 ZwClose(deviceIdHandle);
01794 ZwClose(enumHandle);
01795
ExFreePool(
id);
01796
return status;
01797 }
01798
01799
KeEnterCriticalRegion();
01800
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
01801
01802 RetryDuplicateId:
01803
01804
01805
01806
01807
if (!
IopFixupDeviceId(uniqueId)) {
01808
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
01809
PNP_ERR_BOGUS_ID,
01810 (ULONG_PTR)deviceObject,
01811 (ULONG_PTR)uniqueId,
01812 2);
01813 }
01814
01815 length = (wcslen(busId) + wcslen(deviceId) + wcslen(uniqueId) + 5) *
sizeof(WCHAR);
01816 buffer = (PWCHAR)
ExAllocatePool(
PagedPool, length);
01817
if (!buffer) {
01818
01819
ExReleaseResource(&
PpRegistryDeviceResource);
01820
KeLeaveCriticalRegion();
01821
01822
if (description) {
01823
ExFreePool(description);
01824 }
01825
if (location) {
01826
ExFreePool(location);
01827 }
01828 ZwClose(deviceIdHandle);
01829 ZwClose(enumHandle);
01830
ExFreePool(
id);
01831
return STATUS_INSUFFICIENT_RESOURCES;
01832 }
01833 swprintf(buffer,
L"%s\\%s\\%s", busId, deviceId, uniqueId);
01834
RtlInitUnicodeString(&unicodeDeviceInstance, buffer);
01835
01836
if (DeviceNode->InstancePath.Buffer !=
NULL) {
01837
01838
ExFreePool(DeviceNode->InstancePath.Buffer);
01839
RtlInitUnicodeString(&DeviceNode->InstancePath,
NULL);
01840 }
01841
01842
IopConcatenateUnicodeStrings(&DeviceNode->InstancePath, &unicodeDeviceInstance,
NULL);
01843
01844
01845
01846
01847
01848
01849
RtlInitUnicodeString(&unicodeName, uniqueId);
01850 status =
IopCreateRegistryKeyEx( &uniqueIdHandle,
01851 deviceIdHandle,
01852 &unicodeName,
01853 KEY_ALL_ACCESS,
01854 REG_OPTION_NON_VOLATILE,
01855 &disposition
01856 );
01857
01858
if (!
NT_SUCCESS(status)) {
01859 ZwClose(enumHandle);
01860
ExFreePool(
id);
01861 ZwClose(deviceIdHandle);
01862
ExFreePool(uniqueId);
01863
goto exit;
01864 }
01865
01866 deviceObject->
DeviceObjectExtension->
ExtensionFlags |=
DOE_START_PENDING;
01867
01868 DeviceNode->Flags |=
DNF_PROCESSED;
01869
01870
01871
01872
01873
01874
if (disposition != REG_CREATED_NEW_KEY) {
01875
01876
PDEVICE_OBJECT dupCheckDeviceObject;
01877
01878
01879
01880
01881
01882
01883
01884 dupCheckDeviceObject =
IopDeviceObjectFromDeviceInstance(uniqueIdHandle,
NULL);
01885
01886
if (dupCheckDeviceObject) {
01887
01888
01889
01890
01891
01892
01893
ObDereferenceObject(dupCheckDeviceObject);
01894
01895
if (dupCheckDeviceObject != deviceObject) {
01896
01897
if (globallyUnique) {
01898 globallyUnique =
FALSE;
01899
01900
IopMakeGloballyUniqueId(deviceObject, uniqueId, &globallyUniqueId);
01901
01902
if (uniqueId !=
NULL) {
01903
ExFreePool(uniqueId);
01904 }
01905
01906 uniqueId = globallyUniqueId;
01907
01908
ExFreePool(buffer);
01909 buffer =
NULL;
01910 ZwClose(uniqueIdHandle);
01911
IopSetDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART);
01912
goto RetryDuplicateId;
01913 }
01914
01915
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
01916
PNP_ERR_DUPLICATE_PDO,
01917 (ULONG_PTR)deviceObject,
01918 (ULONG_PTR)dupCheckDeviceObject,
01919 0);
01920
01921
#if 0
01922
ZwClose(enumHandle);
01923 ZwClose(uniqueIdHandle);
01924
01925
if (DeviceNode->InstancePath.Length != 0) {
01926
ExFreePool(DeviceNode->InstancePath.Buffer);
01927 DeviceNode->InstancePath.Length = 0;
01928 DeviceNode->InstancePath.Buffer =
NULL;
01929 }
01930
01931
IopRequestDeviceRemoval(deviceObject, CM_PROB_DEVICE_NOT_THERE);
01932
goto exit;
01933
#endif
01934
}
01935 }
01936 }
else {
01937
01938
if (description) {
01939 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_DEVDESC);
01940 ZwSetValueKey(uniqueIdHandle,
01941 &unicodeName,
01942
TITLE_INDEX_VALUE,
01943 REG_SZ,
01944 description,
01945 (wcslen(description)+1) *
sizeof(WCHAR)
01946 );
01947
ExFreePool(description);
01948 description =
NULL;
01949 }
01950 }
01951
01952
ExFreePool(
id);
01953 ZwClose(deviceIdHandle);
01954
ExFreePool(uniqueId);
01955
01956
if (location) {
01957 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_LOCATION_INFORMATION);
01958 ZwSetValueKey(uniqueIdHandle,
01959 &unicodeName,
01960
TITLE_INDEX_VALUE,
01961 REG_SZ,
01962 location,
01963 (wcslen(location)+1) *
sizeof(WCHAR)
01964 );
01965
ExFreePool(location);
01966 location =
NULL;
01967 }
01968
01969
01970
01971
01972 status =
IopDeviceCapabilitiesToRegistry(DeviceNode, &capabilities);
01973
01974
#if DBG
01975
ASSERT(status == STATUS_SUCCESS);
01976
#endif
01977
01978 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
01979 status =
IopCreateRegistryKeyEx( &logConfHandle,
01980 uniqueIdHandle,
01981 &unicodeName,
01982 KEY_ALL_ACCESS,
01983 REG_OPTION_NON_VOLATILE,
01984
NULL
01985 );
01986
if (!
NT_SUCCESS(status)) {
01987 logConfHandle =
NULL;
01988 }
01989
01990
if (disposition == REG_CREATED_NEW_KEY) {
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
if (!
IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
02002
if (capabilities.
RawDeviceOK) {
02003 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_CONFIG_FLAGS);
02004 tmpValue = CONFIGFLAG_FINISH_INSTALL;
02005 ZwSetValueKey(uniqueIdHandle,
02006 &unicodeName,
02007
TITLE_INDEX_VALUE,
02008 REG_DWORD,
02009 &tmpValue,
02010
sizeof(tmpValue)
02011 );
02012 }
else {
02013
IopSetDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED);
02014 }
02015
02016
02017
02018
02019
02020
02021
02022 processCriticalDevice =
TRUE;
02023 }
02024
02025 }
else {
02026
02027 UCHAR buffer[
sizeof(KEY_VALUE_PARTIAL_INFORMATION)+
sizeof(ULONG)];
02028 PKEY_VALUE_PARTIAL_INFORMATION keyInfo =
02029 (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
02030
02031 ULONG length;
02032
02033 UNICODE_STRING valueName;
02034
02035
NTSTATUS tmpStatus;
02036
02037
if (!
IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
02038
02039
RtlInitUnicodeString(&valueName, REGSTR_VALUE_CONFIG_FLAGS);
02040 tmpStatus = ZwQueryValueKey(uniqueIdHandle,
02041 &valueName,
02042 KeyValuePartialInformation,
02043 keyInfo,
02044
sizeof(buffer),
02045 &length);
02046
02047
if (
NT_SUCCESS(tmpStatus)) {
02048
02049 ULONG configFlags = *(PULONG)keyInfo->Data;
02050
02051
02052
02053
02054
02055
02056
02057
02058
if (configFlags & CONFIGFLAG_REINSTALL) {
02059
IopSetDevNodeProblem(DeviceNode, CM_PROB_REINSTALL);
02060 processCriticalDevice =
TRUE;
02061 }
else if (configFlags & CONFIGFLAG_FAILEDINSTALL) {
02062
IopSetDevNodeProblem(DeviceNode, CM_PROB_FAILED_INSTALL);
02063 processCriticalDevice =
TRUE;
02064 }
02065 }
else {
02066
02067
02068
02069
IopSetDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED);
02070 }
02071 }
02072
02073
RtlInitUnicodeString(&valueName, REGSTR_VALUE_SERVICE);
02074
02075 tmpStatus = ZwQueryValueKey(uniqueIdHandle,
02076 &valueName,
02077 KeyValuePartialInformation,
02078 keyInfo,
02079
sizeof(buffer),
02080 &length);
02081
02082
02083
02084
02085
02086
02087
if (
NT_SUCCESS(tmpStatus) && (keyInfo->DataLength <=
sizeof(
L'\0'))) {
02088 processCriticalDevice =
TRUE;
02089 }
else if (tmpStatus == STATUS_OBJECT_NAME_NOT_FOUND) {
02090 processCriticalDevice =
TRUE;
02091 }
02092 }
02093
02094
if (capabilities.
HardwareDisabled &&
02095 !
IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) &&
02096 !
IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
02097
02098
02099
02100
IopClearDevNodeProblem(DeviceNode);
02101
IopSetDevNodeProblem(DeviceNode, CM_PROB_HARDWARE_DISABLED);
02102
02103
02104
02105
02106 status =
IopRemoveDevice(deviceObject,
IRP_MN_REMOVE_DEVICE);
02107
ASSERT(
NT_SUCCESS(status));
02108
02109 }
else {
02110
02111
02112
02113
ASSERT(!
IopDoesDevNodeHaveProblem(DeviceNode) ||
02114
IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) ||
02115
IopIsDevNodeProblem(DeviceNode, CM_PROB_REINSTALL) ||
02116
IopIsDevNodeProblem(DeviceNode, CM_PROB_FAILED_INSTALL) ||
02117
IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART));
02118 }
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
02130 status =
IopCreateRegistryKeyEx( &handle,
02131 uniqueIdHandle,
02132 &unicodeName,
02133 KEY_ALL_ACCESS,
02134 REG_OPTION_VOLATILE,
02135
NULL
02136 );
02137
if (
NT_SUCCESS(status)) {
02138
02139
02140
02141
02142
02143 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DEVICE_REFERENCE);
02144 status = ZwSetValueKey( handle,
02145 &unicodeName,
02146
TITLE_INDEX_VALUE,
02147 REG_DWORD,
02148 (PULONG_PTR)&deviceObject,
02149
sizeof(ULONG_PTR)
02150 );
02151 ZwClose(handle);
02152 }
02153
02154
if (!
NT_SUCCESS(status)) {
02155 ZwClose(enumHandle);
02156 ZwClose(uniqueIdHandle);
02157
if (logConfHandle) {
02158 ZwClose(logConfHandle);
02159 }
02160
goto exit;
02161 }
02162
02163 ZwClose(enumHandle);
02164
02165
02166
02167
02168
02169
ExReleaseResource(&
PpRegistryDeviceResource);
02170
KeLeaveCriticalRegion();
02171
02172 status =
IopQueryCompatibleIds( deviceObject,
02173
BusQueryHardwareIDs,
02174 &hwIds,
02175 &hwIdLength);
02176
02177
if (!
NT_SUCCESS(status)) {
02178 hwIds =
NULL;
02179 }
02180
02181 status =
IopQueryCompatibleIds( deviceObject,
02182
BusQueryCompatibleIDs,
02183 &compatibleIds,
02184 &compatibleIdLength);
02185
if (!
NT_SUCCESS(status)) {
02186 compatibleIds =
NULL;
02187 }
02188
02189
02190
02191
02192
02193
02194 RtlZeroMemory(&irpSp,
sizeof(
IO_STACK_LOCATION));
02195 irpSp.
MajorFunction =
IRP_MJ_PNP;
02196 irpSp.
MinorFunction =
IRP_MN_QUERY_RESOURCE_REQUIREMENTS;
02197 status =
IopSynchronousCall(deviceObject, &irpSp, &ioResource);
02198
02199
if (!
NT_SUCCESS(status)) {
02200 ioResource =
NULL;
02201 }
02202
if (ioResource) {
02203 ioLength = ioResource->ListSize;
02204 }
02205
02206
KeEnterCriticalRegion();
02207
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
02208
02209
02210
02211
02212
02213
if (logConfHandle) {
02214 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_BASIC_CONFIG_VECTOR);
02215
if (ioResource) {
02216 ZwSetValueKey(logConfHandle,
02217 &unicodeName,
02218
TITLE_INDEX_VALUE,
02219 REG_RESOURCE_REQUIREMENTS_LIST,
02220 ioResource,
02221 ioLength
02222 );
02223 DeviceNode->ResourceRequirements = ioResource;
02224 DeviceNode->Flags |=
DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED;
02225 }
else {
02226 ZwDeleteValueKey(logConfHandle, &unicodeName);
02227 }
02228 }
02229
02230
02231
02232
02233
02234
02235
02236
02237
if (
IoRemoteBootClient && (
IopLoaderBlock !=
NULL)) {
02238
02239
if (hwIds) {
02240 isRemoteBootCard =
IopIsRemoteBootCard(
02241 DeviceNode,
02242 (
PLOADER_PARAMETER_BLOCK)
IopLoaderBlock,
02243 hwIds);
02244 }
02245
if (!isRemoteBootCard && compatibleIds) {
02246 isRemoteBootCard =
IopIsRemoteBootCard(
02247 DeviceNode,
02248 (
PLOADER_PARAMETER_BLOCK)
IopLoaderBlock,
02249 compatibleIds);
02250 }
02251 }
02252
02253
02254
02255
02256
02257
if (hwIds) {
02258
02259
if (!
IopFixupIds(hwIds, hwIdLength)) {
02260
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
02261
PNP_ERR_BOGUS_ID,
02262 (ULONG_PTR)deviceObject,
02263 (ULONG_PTR)hwIds,
02264 3);
02265 }
02266 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_HARDWAREID);
02267 ZwSetValueKey(uniqueIdHandle,
02268 &unicodeName,
02269
TITLE_INDEX_VALUE,
02270 REG_MULTI_SZ,
02271 hwIds,
02272 hwIdLength
02273 );
02274
ExFreePool(hwIds);
02275 }
02276
02277
02278
02279
02280
02281
if (compatibleIds) {
02282
02283
if (!
IopFixupIds(compatibleIds, compatibleIdLength)) {
02284
KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
02285
PNP_ERR_BOGUS_ID,
02286 (ULONG_PTR)deviceObject,
02287 (ULONG_PTR)compatibleIds,
02288 4);
02289 }
02290 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_COMPATIBLEIDS);
02291 ZwSetValueKey(uniqueIdHandle,
02292 &unicodeName,
02293
TITLE_INDEX_VALUE,
02294 REG_MULTI_SZ,
02295 compatibleIds,
02296 compatibleIdLength
02297 );
02298
ExFreePool(compatibleIds);
02299 }
02300
02301
02302
02303
02304
02305
02306
if (isRemoteBootCard) {
02307
02308 status =
IopSetupRemoteBootCard(
02309 (
PLOADER_PARAMETER_BLOCK)
IopLoaderBlock,
02310 uniqueIdHandle,
02311 &unicodeDeviceInstance);
02312
02313
if (status != STATUS_SUCCESS) {
02314
goto exit;
02315 }
02316
02317
02318
02319
02320
02321
02322
02323 deviceObject->
DeviceObjectExtension->
ExtensionFlags &= ~
DOE_START_PENDING;
02324
02325 }
02326
02327
ExReleaseResource(&
PpRegistryDeviceResource);
02328
KeLeaveCriticalRegion();
02329
02330
02331
02332
02333
02334 status =
IopQueryPnpBusInformation(
02335 deviceObject,
02336 &busTypeGuid,
02337 &DeviceNode->ChildInterfaceType,
02338 &DeviceNode->ChildBusNumber
02339 );
02340
02341
if (
NT_SUCCESS(status)) {
02342
02343 DeviceNode->ChildBusTypeIndex =
IopGetBusTypeGuidIndex(&busTypeGuid);
02344
02345 }
else {
02346
02347 DeviceNode->ChildBusTypeIndex = 0xffff;
02348 DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
02349 DeviceNode->ChildBusNumber = 0xfffffff0;
02350
02351 }
02352
02353
02354
02355
02356
if (processCriticalDevice && !capabilities.
HardwareDisabled &&
02357 !
IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
02358
02359
IopProcessCriticalDevice(DeviceNode);
02360 }
02361
02362
02363
02364
02365
02366
ASSERT(!
IopDoesDevNodeHaveProblem(DeviceNode) ||
02367
IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) ||
02368
IopIsDevNodeProblem(DeviceNode, CM_PROB_REINSTALL) ||
02369
IopIsDevNodeProblem(DeviceNode, CM_PROB_FAILED_INSTALL) ||
02370
IopIsDevNodeProblem(DeviceNode, CM_PROB_PARTIAL_LOG_CONF) ||
02371
IopIsDevNodeProblem(DeviceNode, CM_PROB_HARDWARE_DISABLED) ||
02372
IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART));
02373
if (!
IopIsDevNodeProblem(DeviceNode, CM_PROB_DISABLED) &&
02374 !
IopIsDevNodeProblem(DeviceNode, CM_PROB_HARDWARE_DISABLED) &&
02375 !
IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
02376
02377
IopIsDeviceInstanceEnabled(uniqueIdHandle, &unicodeDeviceInstance,
TRUE);
02378 }
02379
02380
02381
02382
02383
02384
02385
02386 cmResource =
NULL;
02387
if (DeviceNode->BootResources ==
NULL) {
02388 status =
IopQueryDeviceResources( deviceObject,
02389
QUERY_RESOURCE_LIST,
02390 &cmResource,
02391 &cmLength );
02392
if (!
NT_SUCCESS(status)) {
02393 cmResource =
NULL;
02394 }
02395 }
else {
02396
02397
DebugPrint(1,
02398 (
"PNPENUM: %ws already has BOOT config in IopProcessNewDeviceNode!\n",
02399 DeviceNode->InstancePath.Buffer));
02400 }
02401
02402
KeEnterCriticalRegion();
02403
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
02404
02405
02406
02407
02408
if (logConfHandle && DeviceNode->BootResources ==
NULL) {
02409 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG);
02410
if (cmResource) {
02411 ZwSetValueKey(
02412 logConfHandle,
02413 &unicodeName,
02414
TITLE_INDEX_VALUE,
02415 REG_RESOURCE_LIST,
02416 cmResource,
02417 cmLength
02418 );
02419
02420
ExReleaseResource(&
PpRegistryDeviceResource);
02421
02422
02423
02424
02425
02426 status = (*IopReserveResourcesRoutine)(
ArbiterRequestPnpEnumerated,
02427 deviceObject,
02428 cmResource);
02429
02430
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
02431
02432
if (
NT_SUCCESS(status)) {
02433 DeviceNode->Flags |=
DNF_HAS_BOOT_CONFIG;
02434 }
02435
ExFreePool(cmResource);
02436 }
else {
02437 ZwDeleteValueKey(logConfHandle, &unicodeName);
02438 }
02439 }
02440
02441
02442
02443
02444 status =
IopDeviceCapabilitiesToRegistry(DeviceNode,&capabilities);
02445
02446
#if DBG
02447
ASSERT(status == STATUS_SUCCESS);
02448
#endif
02449
02450
02451
02452
02453
02454
if (logConfHandle) {
02455 ZwClose(logConfHandle);
02456 }
02457
02458
ExReleaseResource(&
PpRegistryDeviceResource);
02459
KeLeaveCriticalRegion();
02460
02461
02462
02463
02464
02465
02466 status =
IopNotifySetupDeviceArrival( deviceObject,
02467 uniqueIdHandle,
02468
TRUE);
02469
02470 configuredBySetup =
NT_SUCCESS(status);
02471
02472 status =
PpDeviceRegistration(
02473 &unicodeDeviceInstance,
02474
TRUE,
02475 &DeviceNode->ServiceName
02476 );
02477
02478
if (
NT_SUCCESS(status) && (configuredBySetup || isRemoteBootCard) &&
02479
IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED)) {
02480
02481
IopClearDevNodeProblem(DeviceNode);
02482 }
02483
02484
02485
02486
02487
PpSetPlugPlayEvent( &GUID_DEVICE_ENUMERATED,
02488 deviceObject);
02489
02490 ZwClose(uniqueIdHandle);
02491
02492
if (buffer) {
02493
ExFreePool(buffer);
02494 }
02495
if (description) {
02496
ExFreePool(description);
02497 }
02498
if (location) {
02499
ExFreePool(location);
02500 }
02501
return STATUS_SUCCESS;
02502
02503
exit:
02504
02505
02506
02507
02508
02509
02510
ExReleaseResource(&
PpRegistryDeviceResource);
02511
KeLeaveCriticalRegion();
02512
if (buffer) {
02513
ExFreePool(buffer);
02514 }
02515
if (description) {
02516
ExFreePool(description);
02517 }
02518
if (location) {
02519
ExFreePool(location);
02520 }
02521
return status;
02522 }
02523
02524
NTSTATUS
02525 IopCallDriverAddDevice(
02526 IN
PDEVICE_NODE DeviceNode,
02527 IN BOOLEAN LoadDriver,
02528 IN
PADD_CONTEXT Context
02529 )
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553 {
02554 HANDLE enumKey;
02555 HANDLE instanceKey;
02556 HANDLE classKey =
NULL;
02557 HANDLE classPropsKey =
NULL;
02558 PKEY_VALUE_FULL_INFORMATION keyValueInformation =
NULL;
02559 RTL_QUERY_REGISTRY_TABLE queryTable[3];
02560
QUERY_CONTEXT queryContext;
02561 BOOLEAN deviceRaw =
FALSE;
02562 BOOLEAN usePdoCharacteristics =
TRUE;
02563
NTSTATUS status;
02564
DEVICE_CAPABILITIES capabilities;
02565 ULONG index;
02566
PDEVICE_OBJECT deviceObject;
02567
#ifndef NO_SPECIAL_IRP
02568
PDEVICE_OBJECT fdoDeviceObject, topOfPdoStack, topOfLowerFilterStack;
02569 BOOLEAN deviceObjectHasBeenAttached =
FALSE;
02570
#endif
02571
02572
DebugPrint(1, (
"IopCallDriverAddDevice: Processing devnode %#08lx\n",
02573 DeviceNode));
02574
02575
DebugPrint(1, (
"IopCallDriverAddDevice: DevNode flags going in = %#08lx\n",
02576 DeviceNode->Flags));
02577
02578
02579
02580
02581
02582
02583
02584
if (!
OK_TO_ADD_DEVICE(DeviceNode)) {
02585
return STATUS_SUCCESS;
02586 }
02587
02588
ASSERT_INITED(DeviceNode->PhysicalDeviceObject);
02589
02590
DebugPrint(1, (
"IopCallDriverAddDevice:\t%s load driver\n",
02591 (LoadDriver ?
"Will" :
"Won't")));
02592
02593
DebugPrint(1, (
"IopCallDriverAddDevice:\tOpening registry key %wZ\n",
02594 &DeviceNode->InstancePath));
02595
02596
02597
02598
02599
02600 status =
IopOpenRegistryKeyEx( &enumKey,
02601
NULL,
02602 &
CmRegistryMachineSystemCurrentControlSetEnumName,
02603 KEY_READ
02604 );
02605
02606
if (!
NT_SUCCESS(status)) {
02607
DebugPrint(1, (
"IopCallDriverAddDevice:\tUnable to open "
02608
"HKLM\\SYSTEM\\CCS\\ENUM\n"));
02609
return status;
02610 }
02611
02612
02613
02614
02615
02616 status =
IopOpenRegistryKeyEx( &instanceKey,
02617 enumKey,
02618 &DeviceNode->InstancePath,
02619 KEY_READ
02620 );
02621
02622 ZwClose(enumKey);
02623
02624
if (!
NT_SUCCESS(status)) {
02625
02626
DebugPrint(1, (
"IopCallDriverAddDevice:\t\tError %#08lx opening enum key\n",
02627 status));
02628
return status;
02629 }
02630
02631
02632
02633
02634
02635 status =
IopGetRegistryValue(instanceKey,
02636 REGSTR_VALUE_CLASSGUID,
02637 &keyValueInformation);
02638
02639
if (
NT_SUCCESS(status) && ((keyValueInformation->Type == REG_SZ) &&
02640 (keyValueInformation->DataLength != 0))) {
02641
02642 HANDLE controlKey;
02643 UNICODE_STRING unicodeClassGuid;
02644
02645
IopRegistryDataToUnicodeString(
02646 &unicodeClassGuid,
02647 (PWSTR)
KEY_VALUE_DATA(keyValueInformation),
02648 keyValueInformation->DataLength);
02649
02650
DebugPrint(1, (
"IopCallDriverAddDevice:\t\tClass GUID is %wZ\n",
02651 &unicodeClassGuid));
02652
02653
if (
InitSafeBootMode) {
02654
if (!
IopSafebootDriverLoad(&unicodeClassGuid)) {
02655 PKEY_VALUE_FULL_INFORMATION ClassValueInformation =
NULL;
02656
NTSTATUS s;
02657
02658
02659
02660
02661
DbgPrint(
"SAFEBOOT: skipping device = %wZ\n",&unicodeClassGuid);
02662 s =
IopGetRegistryValue(instanceKey,
02663 REGSTR_VAL_DEVDESC,
02664 &ClassValueInformation);
02665
if (
NT_SUCCESS(s)) {
02666 UNICODE_STRING ClassString;
02667
02668
RtlInitUnicodeString(&ClassString, (PCWSTR)
KEY_VALUE_DATA(ClassValueInformation));
02669
02670
IopBootLog(&ClassString,
FALSE);
02671 }
else {
02672
IopBootLog(&unicodeClassGuid,
FALSE);
02673 }
02674
return STATUS_UNSUCCESSFUL;
02675 }
02676 }
02677
02678
02679
02680
02681
02682 status =
IopOpenRegistryKeyEx( &controlKey,
02683
NULL,
02684 &
CmRegistryMachineSystemCurrentControlSetControlClass,
02685 KEY_READ
02686 );
02687
02688
if (!
NT_SUCCESS(status)) {
02689
02690
DebugPrint(1, (
"IopCallDriverAddDevice:\tUnable to open "
02691
"HKLM\\SYSTEM\\CCS\\CONTROL\\CLASS - %#08lx\n",
02692 status));
02693 classKey =
NULL;
02694 }
else {
02695
02696 status =
IopOpenRegistryKeyEx( &classKey,
02697 controlKey,
02698 &unicodeClassGuid,
02699 KEY_READ
02700 );
02701
02702 ZwClose(controlKey);
02703
02704
if (!
NT_SUCCESS(status)) {
02705
02706
DebugPrint(1, (
"IopCallDriverAddDevice:\tUnable to open GUID key "
02707
"%wZ - %#08lx\n",
02708 &unicodeClassGuid,
02709 status));
02710
02711 classKey =
NULL;
02712 }
02713 }
02714
02715
if (classKey !=
NULL) {
02716
02717 UNICODE_STRING unicodeProperties;
02718
02719
RtlInitUnicodeString(&unicodeProperties, REGSTR_KEY_DEVICE_PROPERTIES );
02720
02721 status =
IopOpenRegistryKeyEx( &classPropsKey,
02722 classKey,
02723 &unicodeProperties,
02724 KEY_READ
02725 );
02726
02727
if (!
NT_SUCCESS(status)) {
02728
02729
DebugPrint(2, (
"IopCallDriverAddDevice:\tUnable to open GUID\\Properties key "
02730
"%wZ - %#08lx\n",
02731 &unicodeClassGuid,
02732 status));
02733
02734 classPropsKey =
NULL;
02735 }
02736 }
02737
02738
ExFreePool(keyValueInformation);
02739 keyValueInformation =
NULL;
02740
02741 }
02742
02743
02744
02745
02746
02747
02748 RtlZeroMemory(&queryContext,
sizeof(queryContext));
02749
02750 queryContext.DeviceNode = DeviceNode;
02751 queryContext.LoadDriver = LoadDriver;
02752
02753 queryContext.AddContext = Context;
02754
02755 RtlZeroMemory(queryTable,
sizeof(queryTable));
02756
02757 queryTable[0].QueryRoutine =
02758 (PRTL_QUERY_REGISTRY_ROUTINE)
IopCallDriverAddDeviceQueryRoutine;
02759 queryTable[0].Name = REGSTR_VAL_LOWERFILTERS;
02760 queryTable[0].EntryContext = (PVOID) UIntToPtr(
LowerDeviceFilters);
02761
02762 status =
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
02763 (PWSTR) instanceKey,
02764 queryTable,
02765 &queryContext,
02766
NULL);
02767
if (
NT_SUCCESS(status)) {
02768
02769
if (classKey !=
NULL) {
02770
02771 queryTable[0].QueryRoutine =
02772 (PRTL_QUERY_REGISTRY_ROUTINE)
IopCallDriverAddDeviceQueryRoutine;
02773 queryTable[0].Name = REGSTR_VAL_LOWERFILTERS;
02774 queryTable[0].EntryContext = (PVOID) UIntToPtr(
LowerClassFilters);
02775 status =
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
02776 (PWSTR) classKey,
02777 queryTable,
02778 &queryContext,
02779
NULL);
02780 }
02781
02782
if (
NT_SUCCESS(status)) {
02783 queryTable[0].QueryRoutine = (PRTL_QUERY_REGISTRY_ROUTINE)
IopCallDriverAddDeviceQueryRoutine;
02784 queryTable[0].Name = REGSTR_VALUE_SERVICE;
02785 queryTable[0].EntryContext = (PVOID) UIntToPtr(
DeviceService);
02786 queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
02787
02788 status =
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
02789 (PWSTR) instanceKey,
02790 queryTable,
02791 &queryContext,
02792
NULL);
02793 }
02794 }
02795
02796
if (DeviceNode->Flags &
DNF_LEGACY_DRIVER) {
02797
02798
02799
02800
02801
02802
02803 status = STATUS_SUCCESS;
02804
goto Cleanup;
02805
02806 }
else if (
NT_SUCCESS(status)) {
02807
02808
02809
02810
02811
02812
02813
ASSERT(queryContext.DriverLists[
DeviceService] !=
NULL);
02814
02815
if (queryContext.DriverLists[
DeviceService]->NextEntry !=
NULL) {
02816
02817
02818
02819
02820
02821
DebugPrint(1, (
"IopCallDriverAddDevice: Configuration Error - more "
02822
"than one service in driver list\n"));
02823
02824
IopSetDevNodeProblem(DeviceNode, CM_PROB_REGISTRY);
02825
02826 status = STATUS_UNSUCCESSFUL;
02827
02828
goto Cleanup;
02829 }
02830
02831
02832
02833 usePdoCharacteristics =
FALSE;
02834
02835 }
else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
02836
02837
DebugPrint(1, (
"IopCallDriverAddDevice\t\tError %#08lx reading service "
02838
"value for devnode %#08lx\n", status, DeviceNode));
02839
02840
if (!
IopDeviceNodeFlagsToCapabilities(DeviceNode)->RawDeviceOK) {
02841
02842
02843
02844
02845
02846 status = STATUS_UNSUCCESSFUL;
02847
goto Cleanup;
02848
02849 }
else {
02850
02851
02852
02853
02854
02855
IopClearDevNodeProblem(DeviceNode);
02856
02857 usePdoCharacteristics =
TRUE;
02858 deviceRaw =
TRUE;
02859 status = STATUS_SUCCESS;
02860
02861 }
02862
02863 }
else {
02864
02865
02866
02867
02868
02869
02870
02871
goto Cleanup;
02872
02873 }
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886 RtlZeroMemory(queryTable,
sizeof(queryTable));
02887
02888 queryTable[0].QueryRoutine =
02889 (PRTL_QUERY_REGISTRY_ROUTINE)
IopCallDriverAddDeviceQueryRoutine;
02890 queryTable[0].Name = REGSTR_VAL_UPPERFILTERS;
02891 queryTable[0].EntryContext = (PVOID) UIntToPtr(
UpperDeviceFilters);
02892 status =
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
02893 (PWSTR) instanceKey,
02894 queryTable,
02895 &queryContext,
02896
NULL);
02897
02898
if (
NT_SUCCESS(status) && classKey) {
02899 queryTable[0].QueryRoutine =
02900 (PRTL_QUERY_REGISTRY_ROUTINE)
IopCallDriverAddDeviceQueryRoutine;
02901 queryTable[0].Name = REGSTR_VAL_UPPERFILTERS;
02902 queryTable[0].EntryContext = (PVOID) UIntToPtr(
UpperClassFilters);
02903
02904 status =
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
02905 (PWSTR) classKey,
02906 queryTable,
02907 &queryContext,
02908
NULL);
02909 }
02910
02911
if (
NT_SUCCESS(status)) {
02912
02913 UCHAR serviceType = 0;
02914
PDRIVER_LIST_ENTRY listEntry = queryContext.DriverLists[serviceType];
02915
02916
02917
02918
02919
02920
02921
ASSERT(!(DeviceNode->Flags &
DNF_LEGACY_DRIVER));
02922
ASSERT(!(DeviceNode->Flags &
DNF_ADDED));
02923
02924
ASSERTMSG(
02925
"Error - Device has no service but cannot be run RAW\n",
02926 ((queryContext.DriverLists[
DeviceService] !=
NULL) || (deviceRaw)));
02927
02928
#ifndef NO_SPECIAL_IRP
02929
02930
02931
02932 topOfPdoStack =
IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject);
02933
#endif
02934
02935
02936
02937
02938
for (serviceType = 0; serviceType <
MaximumAddStage; serviceType++) {
02939
02940
DebugPrint(1, (
"IopCallDriverAddDevice: Adding Services (type %d)\n",
02941 serviceType));
02942
02943
if (serviceType ==
DeviceService) {
02944
02945
if (deviceRaw&&(queryContext.DriverLists[serviceType]==
NULL)) {
02946
02947
02948
02949
02950
02951
ASSERT(queryContext.DriverLists[serviceType] ==
NULL);
02952 DeviceNode->Flags |=
DNF_ADDED;
02953
02954
#ifndef NO_SPECIAL_IRP
02955
02956
02957
02958
02959
02960 DeviceNode->PhysicalDeviceObject->DeviceObjectExtension->ExtensionFlags |=
02961
DOE_DESIGNATED_FDO |
DOE_RAW_FDO;
02962
02963 }
else {
02964
02965
02966
02967
02968
02969
02970
ASSERT(queryContext.DriverLists[serviceType]);
02971
ASSERT(!queryContext.DriverLists[serviceType]->NextEntry);
02972 topOfLowerFilterStack =
IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject);
02973
#endif
02974
}
02975 }
02976
02977
for (listEntry = queryContext.DriverLists[serviceType];
02978 listEntry !=
NULL;
02979 listEntry = listEntry->NextEntry) {
02980
02981
PDRIVER_ADD_DEVICE addDeviceRoutine;
02982
02983
DebugPrint(1, (
"IopCallDriverAddDevice:\tAdding driver %#08lx\n",
02984 listEntry->DriverObject));
02985
02986
ASSERT(listEntry->DriverObject);
02987
ASSERT(listEntry->DriverObject->DriverExtension);
02988
ASSERT(listEntry->DriverObject->DriverExtension->AddDevice);
02989
02990
02991
02992
02993 addDeviceRoutine =
02994 listEntry->DriverObject->DriverExtension->AddDevice;
02995
02996 status = (addDeviceRoutine)(listEntry->DriverObject,
02997 DeviceNode->PhysicalDeviceObject);
02998
02999
DebugPrint(1, (
"IopCallDriverAddDevice:\t\tRoutine returned "
03000
"%#08lx\n", status));
03001
03002
if (
NT_SUCCESS(status)) {
03003
03004
#ifndef NO_SPECIAL_IRP
03005
if (!deviceObjectHasBeenAttached) {
03006
03007
03008
03009
03010
03011
03012
03013 fdoDeviceObject = topOfPdoStack->
AttachedDevice;
03014
if (fdoDeviceObject) {
03015
03016 fdoDeviceObject->
DeviceObjectExtension->
ExtensionFlags |=
DOE_BOTTOM_OF_FDO_STACK;
03017 deviceObjectHasBeenAttached =
TRUE;
03018 }
03019 }
03020
03021
03022
03023
03024
03025
if (serviceType ==
DeviceService) {
03026
03027
03028
03029
03030
03031
03032
03033 fdoDeviceObject = topOfLowerFilterStack->
AttachedDevice;
03034
03035
03036
03037
if (!fdoDeviceObject) {
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047 fdoDeviceObject = DeviceNode->PhysicalDeviceObject;
03048 fdoDeviceObject->
DeviceObjectExtension->
ExtensionFlags |=
DOE_RAW_FDO;
03049 }
03050
03051
03052
03053
03054 fdoDeviceObject->
DeviceObjectExtension->
ExtensionFlags |=
DOE_DESIGNATED_FDO;
03055 }
03056
#endif
03057
03058 DeviceNode->Flags |=
DNF_ADDED;
03059 }
else if (serviceType ==
DeviceService) {
03060
03061
03062
03063
03064
03065 DeviceNode->Flags &= ~
DNF_ADDED;
03066
IopSetDevNodeProblem(DeviceNode, CM_PROB_FAILED_ADD);
03067
IopRequestDeviceRemoval(DeviceNode->PhysicalDeviceObject, CM_PROB_FAILED_ADD);
03068
goto Cleanup;
03069 }
03070
03071
if (
IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject)->
Flags &
DO_DEVICE_INITIALIZING) {
03072
DebugPrint(1, (
"***************** DO_DEVICE_INITIALIZING not cleared on %#08lx\n",
03073
IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject)));
03074 }
03075
03076
ASSERT_INITED(
IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject));
03077 }
03078 }
03079
03080
03081
03082
03083
03084
03085
IopChangeDeviceObjectFromRegistryProperties(DeviceNode->PhysicalDeviceObject, classPropsKey, instanceKey, usePdoCharacteristics);
03086
03087
03088
03089
03090
03091 }
else {
03092
03093
DebugPrint(1, (
"IopCallDriverAddDevice: Error %#08lx while building "
03094
"driver load list\n", status));
03095 }
03096
03097 deviceObject = DeviceNode->PhysicalDeviceObject;
03098
03099 status =
IopQueryLegacyBusInformation(
03100 deviceObject,
03101
NULL,
03102 &DeviceNode->InterfaceType,
03103 &DeviceNode->BusNumber
03104 );
03105
03106
if (!
NT_SUCCESS(status)) {
03107
03108 DeviceNode->InterfaceType = InterfaceTypeUndefined;
03109 DeviceNode->BusNumber = 0xfffffff0;
03110
03111 }
03112
03113 status = STATUS_SUCCESS;
03114
03115 Cleanup:
03116 {
03117
03118 UCHAR i;
03119
03120
DebugPrint(1, (
"IopCallDriverAddDevice: DevNode flags leaving = %#08lx\n",
03121 DeviceNode->Flags));
03122
03123
DebugPrint(1, (
"IopCallDriverAddDevice: Cleaning up\n"));
03124
03125
03126
03127
03128
03129
03130
for (i = 0; i <
MaximumAddStage; i++) {
03131
03132
PDRIVER_LIST_ENTRY listHead = queryContext.DriverLists[i];
03133
03134
while(listHead !=
NULL) {
03135
03136
PDRIVER_LIST_ENTRY tmp = listHead;
03137
03138 listHead = listHead->
NextEntry;
03139
03140
ASSERT(tmp->DriverObject !=
NULL);
03141
03142
ObDereferenceObject(tmp->DriverObject);
03143
03144
ExFreePool(tmp);
03145 }
03146 }
03147 }
03148
03149 ZwClose(instanceKey);
03150
03151
if (classKey !=
NULL) {
03152 ZwClose(classKey);
03153 }
03154
03155
if (classPropsKey !=
NULL) {
03156 ZwClose(classPropsKey);
03157 }
03158
03159
DebugPrint(1, (
"IopCallDriverAddDevice: Returning status %#08lx\n", status));
03160
03161
return status;
03162 }
03163
03164
NTSTATUS
03165 IopCallDriverAddDeviceQueryRoutine(
03166 IN PWSTR ValueName,
03167 IN ULONG ValueType,
03168 IN PWCHAR ValueData,
03169 IN ULONG ValueLength,
03170 IN PQUERY_CONTEXT Context,
03171 IN ULONG ServiceType
03172 )
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214 {
03215 UNICODE_STRING unicodeServiceName;
03216 UNICODE_STRING unicodeDriverName;
03217 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
03218
03219 ULONG i;
03220 ULONG loadType;
03221
03222 PWSTR prefixString =
L"\\Driver\\";
03223 BOOLEAN madeupService;
03224
03225
USHORT groupIndex;
03226
PDRIVER_OBJECT driverObject =
NULL;
03227
03228
NTSTATUS status = STATUS_SUCCESS;
03229 BOOLEAN freeDriverName =
FALSE;
03230
03231
DebugPrint(1, (
"IopCallDriverAddDevice:\t\tValue %ws [Type %d, Len %d] @ "
03232
"%#08lx\n",
03233
ValueName, ValueType, ValueLength, ValueData));
03234
03235
03236
03237
03238
03239
03240
if (ValueType != REG_SZ) {
03241
03242
DebugPrint(1, (
"IopCallDriverAddDevice:\t\tValueType %d invalid for "
03243
"ServiceType %d\n",
03244 ValueType,
03245 ServiceType));
03246
03247
return STATUS_SUCCESS;
03248 }
03249
03250
03251
03252
03253
03254
if (ValueLength <=
sizeof(WCHAR)) {
03255
03256
DebugPrint(1, (
"IopCallDriverAddDevice:\t\tValueLength %d is too short\n",
03257 ValueLength));
03258
03259
return STATUS_SUCCESS;
03260 }
03261
03262
RtlInitUnicodeString(&unicodeServiceName, ValueData);
03263
03264
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tService Name %wZ\n",
03265 &unicodeServiceName));
03266
03267
03268
03269
03270
03271
03272
03273 madeupService =
TRUE;
03274 i = 0;
03275
03276
while(*prefixString !=
L'\0') {
03277
03278
if (unicodeServiceName.Buffer[i] != *prefixString) {
03279
03280 madeupService =
FALSE;
03281
break;
03282 }
03283
03284 i++;
03285 prefixString++;
03286 }
03287
03288
if (madeupService) {
03289
03290
RtlInitUnicodeString(&unicodeDriverName, unicodeServiceName.Buffer);
03291
03292 groupIndex = 0;
03293 loadType = SERVICE_BOOT_START;
03294
03295 }
else {
03296
03297 HANDLE serviceKey;
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
if (Context->DeviceNode->ServiceName.Length == 0) {
03309
03310 Context->DeviceNode->ServiceName = unicodeServiceName;
03311 Context->DeviceNode->ServiceName.Buffer =
ExAllocatePool(
NonPagedPool,
03312 unicodeServiceName.MaximumLength );
03313
03314
if (Context->DeviceNode->ServiceName.Buffer !=
NULL) {
03315 RtlCopyMemory( Context->DeviceNode->ServiceName.Buffer,
03316 unicodeServiceName.Buffer,
03317 unicodeServiceName.MaximumLength );
03318 }
else {
03319
RtlInitUnicodeString( &Context->DeviceNode->ServiceName,
NULL );
03320
03321
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tCannot allocate memory for service name in devnode\n"));
03322
03323 status = STATUS_UNSUCCESSFUL;
03324
03325
goto Cleanup;
03326 }
03327 }
03328
03329
03330
03331
03332
03333
03334 status =
IopOpenServiceEnumKeys(&unicodeServiceName,
03335 KEY_READ,
03336 &serviceKey,
03337
NULL,
03338
FALSE);
03339
03340
if (!
NT_SUCCESS(status)) {
03341
03342
03343
03344
03345
03346
03347
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tStatus %#08lx "
03348
"opening service key\n",
03349 status));
03350
03351
IopSetDevNodeProblem(Context->DeviceNode, CM_PROB_REGISTRY);
03352
03353
goto Cleanup;
03354 }
03355
03356 groupIndex =
IopGetGroupOrderIndex(serviceKey);
03357
03358 status =
IopGetDriverNameFromKeyNode(serviceKey, &unicodeDriverName);
03359
03360
if (!
NT_SUCCESS(status)) {
03361
03362 ZwClose(serviceKey);
03363
03364
03365
03366
03367
03368
03369
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tStatus %#08lx "
03370
"getting driver name\n",
03371 status));
03372
03373
IopSetDevNodeProblem(Context->DeviceNode, CM_PROB_REGISTRY);
03374
goto Cleanup;
03375 }
else {
03376 freeDriverName =
TRUE;
03377 }
03378
03379 loadType = SERVICE_DISABLED;
03380
03381 status =
IopGetRegistryValue(serviceKey,
L"Start", &keyValueInformation);
03382
if (
NT_SUCCESS(status)) {
03383
if (keyValueInformation->Type == REG_DWORD) {
03384
if (keyValueInformation->DataLength ==
sizeof(ULONG)) {
03385 loadType = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
03386 }
03387 }
03388
ExFreePool(keyValueInformation);
03389 }
03390
03391 ZwClose(serviceKey);
03392 }
03393
03394
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tDriverName is %wZ\n",
03395 &unicodeDriverName));
03396
03397 driverObject =
IopReferenceDriverObjectByName(&unicodeDriverName);
03398
03399
if (driverObject ==
NULL) {
03400
03401 PWCHAR buffer;
03402 UNICODE_STRING unicodeServicePath;
03403
03404
03405
03406
03407
03408
03409
03410
if (madeupService) {
03411
03412
03413
03414
03415
03416
03417
03418
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tCannot find driver "
03419
"object for madeup service\n"));
03420
03421 status = STATUS_UNSUCCESSFUL;
03422
03423
goto Cleanup;
03424 }
03425
03426
if (ServiceType !=
DeviceService && !
PnPBootDriversInitialized) {
03427
03428
03429
03430
03431
03432 driverObject =
IopLoadBootFilterDriver(&unicodeDriverName, groupIndex);
03433
if (driverObject ==
NULL) {
03434 status = STATUS_UNSUCCESSFUL;
03435
goto Cleanup;
03436 }
03437 }
else {
03438
if (!Context->LoadDriver) {
03439
03440
03441
03442
03443
03444
03445
03446
03447
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tNot allowed to load "
03448
"drivers yet\n"));
03449
03450 status = STATUS_UNSUCCESSFUL;
03451
goto Cleanup;
03452 }
03453
03454
if (groupIndex > Context->AddContext->GroupsToStart) {
03455
03456
03457
03458
03459
03460
03461
03462
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tLower group drivers "
03463
"have not been initialized yet\n"));
03464
if (groupIndex < Context->AddContext->GroupToStartNext) {
03465 Context->AddContext->GroupToStartNext = groupIndex;
03466 }
03467
03468
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tGroup = %d, To Start = "
03469
"Start Next = %d\n",
03470 groupIndex,
03471 Context->AddContext->GroupsToStart,
03472 Context->AddContext->GroupToStartNext));
03473
03474 status = STATUS_UNSUCCESSFUL;
03475
goto Cleanup;
03476 }
03477
03478
03479
03480
if (loadType > Context->AddContext->DriverStartType) {
03481
03482
if (loadType == SERVICE_DISABLED &&
03483 !
IopDoesDevNodeHaveProblem(Context->DeviceNode)) {
03484
IopSetDevNodeProblem(Context->DeviceNode, CM_PROB_DISABLED_SERVICE);
03485 }
03486
03487
03488
03489
03490
03491
03492
03493
03494
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tService is disabled or not at right time to load it\n"));
03495 status = STATUS_UNSUCCESSFUL;
03496
goto Cleanup;
03497 }
03498
03499 {
03500 HANDLE handle;
03501
03502
03503
03504
03505
03506
03507 status =
IopOpenServiceEnumKeys(&unicodeServiceName,
03508 KEY_READ,
03509 &handle,
03510
NULL,
03511
FALSE);
03512
03513
if (!
NT_SUCCESS(status)) {
03514
03515
03516
03517
03518
03519
03520
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tStatus %#08lx "
03521
"opening service key\n",
03522 status));
03523 }
else {
03524 status =
IopLoadDriver(handle,
FALSE);
03525
03526
if (
PnPInitialized) {
03527
03528 PLIST_ENTRY entry;
03529
PREINIT_PACKET reinitEntry;
03530
03531
03532
03533
03534
03535
03536
03537
while (entry =
ExInterlockedRemoveHeadList( &
IopDriverReinitializeQueueHead, &
IopDatabaseLock )) {
03538 reinitEntry = CONTAINING_RECORD( entry,
REINIT_PACKET, ListEntry );
03539 reinitEntry->
DriverObject->
DriverExtension->
Count++;
03540 reinitEntry->
DriverObject->
Flags &= ~
DRVO_REINIT_REGISTERED;
03541 reinitEntry->
DriverReinitializationRoutine( reinitEntry->
DriverObject,
03542 reinitEntry->
Context,
03543 reinitEntry->
DriverObject->
DriverExtension->
Count );
03544
ExFreePool( reinitEntry );
03545 }
03546 }
03547 }
03548
03549 }
03550
if (!
NT_SUCCESS(status)) {
03551
03552
if (
PnPBootDriversInitialized) {
03553
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tStatus %#08lx "
03554
"from loading driver\n", status));
03555 }
03556 }
03557
03558 }
03559 }
else {
03560
ObDereferenceObject(driverObject);
03561
if (!(driverObject->
Flags &
DRVO_INITIALIZED)) {
03562 status = STATUS_UNSUCCESSFUL;
03563
goto Cleanup;
03564 }
03565 }
03566
03567
03568
03569
03570
03571
03572 driverObject =
IopReferenceDriverObjectByName(&unicodeDriverName);
03573
03574
if (driverObject ==
NULL) {
03575
03576
if (
PnPBootDriversInitialized) {
03577
03578
03579
03580
03581
03582
03583
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tUnable to reference "
03584
"driver %wZ\n", &unicodeDriverName));
03585
03586
if (!
IopDoesDevNodeHaveProblem(Context->DeviceNode)) {
03587
IopSetDevNodeProblem(Context->DeviceNode, CM_PROB_FAILED_ADD);
03588 }
03589 }
03590
03591 status = STATUS_UNSUCCESSFUL;
03592
goto Cleanup;
03593 }
else if (!(driverObject->
Flags &
DRVO_INITIALIZED)) {
03594
ObDereferenceObject(driverObject);
03595 status = STATUS_UNSUCCESSFUL;
03596
goto Cleanup;
03597 }
03598
03599
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tDriver Reference %#08lx\n",
03600 driverObject));
03601
03602
03603
03604
03605
03606
if (
IopIsLegacyDriver(driverObject)) {
03607
03608
03609
03610
03611
03612
03613
03614
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tDriver is a legacy "
03615
"driver\n"));
03616
03617
if (ServiceType ==
DeviceService) {
03618 Context->DeviceNode->Flags |=
DNF_ADDED +
03619
DNF_STARTED +
03620
DNF_LEGACY_DRIVER;
03621
03622 status = STATUS_UNSUCCESSFUL;
03623 }
else {
03624
03625
03626
03627
03628
03629
03630
03631 status = STATUS_SUCCESS;
03632 }
03633
goto Cleanup;
03634 }
03635
03636
03637
03638
03639
03640
03641
if (!
OK_TO_ADD_DEVICE(Context->DeviceNode)) {
03642
03643
DebugPrint(1, (
"IopCallDriverAddDevice\t\t\tDevNode was reported "
03644
"as detected during driver entry\n"));
03645 status = STATUS_UNSUCCESSFUL;
03646
goto Cleanup;
03647 }
03648
03649
03650
03651
03652
03653 {
03654
PDRIVER_LIST_ENTRY listEntry;
03655
PDRIVER_LIST_ENTRY *runner = &(Context->DriverLists[ServiceType]);
03656
03657 status = STATUS_SUCCESS;
03658
03659
03660
03661
03662
03663 listEntry =
ExAllocatePool(
PagedPool,
sizeof(DRIVER_LIST_ENTRY));
03664
03665
if (listEntry ==
NULL) {
03666
03667
DebugPrint(1, (
"IopCallDriverAddDevice:\t\t\tUnable to allocate list "
03668
"entry\n"));
03669
03670 status = STATUS_INSUFFICIENT_RESOURCES;
03671
goto Cleanup;
03672 }
03673
03674 listEntry->DriverObject = driverObject;
03675 listEntry->NextEntry =
NULL;
03676
03677
while(*runner !=
NULL) {
03678 runner = &((*runner)->NextEntry);
03679 }
03680
03681 *runner = listEntry;
03682 }
03683
03684 Cleanup:
03685
03686
if (freeDriverName) {
03687
RtlFreeUnicodeString(&unicodeDriverName);
03688 }
03689
return status;
03690 }
03691
03692
03693
NTSTATUS
03694 IopQueryDeviceCapabilities(
03695 IN
PDEVICE_NODE DeviceNode,
03696 OUT
PDEVICE_CAPABILITIES Capabilities
03697 )
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723 {
03724
IO_STACK_LOCATION irpStack;
03725 PVOID
dummy;
03726
03727
NTSTATUS status;
03728
03729
03730
03731
03732
03733 RtlZeroMemory(Capabilities,
sizeof(
DEVICE_CAPABILITIES));
03734 Capabilities->Size =
sizeof(
DEVICE_CAPABILITIES);
03735 Capabilities->Version = 1;
03736 Capabilities->Address = Capabilities->UINumber = (ULONG)-1;
03737
03738
03739
03740
03741
03742 RtlZeroMemory(&irpStack,
sizeof(
IO_STACK_LOCATION));
03743
03744
03745
03746
03747
03748 irpStack.
MajorFunction =
IRP_MJ_PNP;
03749 irpStack.
MinorFunction =
IRP_MN_QUERY_CAPABILITIES;
03750 irpStack.
Parameters.DeviceCapabilities.Capabilities = Capabilities;
03751
03752 status =
IopSynchronousCall(DeviceNode->PhysicalDeviceObject,
03753 &irpStack,
03754 &
dummy);
03755
03756
ASSERT(status != STATUS_PENDING);
03757
03758
return status;
03759 }
03760
03761 BOOLEAN
03762 IopProcessCriticalDevice(
03763 IN
PDEVICE_NODE DeviceNode
03764 )
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786 {
03787 HANDLE enumKey;
03788 HANDLE instanceKey;
03789
03790 UNICODE_STRING service, classGuid, lowerFilters, upperFilters;
03791 BOOLEAN foundMatch =
FALSE;
03792
03793 RTL_QUERY_REGISTRY_TABLE queryTable[2];
03794
03795
NTSTATUS status;
03796
03797
#if DBG_SCOPE
03798
PWCHAR str;
03799 ULONG length;
03800
#endif
03801
03802
DebugPrint(1, (
"IopIsCriticalPnpDevice called for devnode %#08lx\n", DeviceNode));
03803
03804
03805
03806
03807
03808 status =
IopOpenRegistryKeyEx( &enumKey,
03809
NULL,
03810 &
CmRegistryMachineSystemCurrentControlSetEnumName,
03811 KEY_READ
03812 );
03813
03814
if (!
NT_SUCCESS(status)) {
03815
DebugPrint(1, (
"IICPD: couldn't open enum key %#08lx\n", status));
03816
return FALSE;
03817 }
03818
03819
03820
03821
03822
03823 status =
IopOpenRegistryKeyEx( &instanceKey,
03824 enumKey,
03825 &DeviceNode->InstancePath,
03826 KEY_ALL_ACCESS
03827 );
03828
03829 ZwClose(enumKey);
03830
03831
03832
03833
03834
03835
if (!
NT_SUCCESS(status)) {
03836
DebugPrint(1, (
"IICPD: couldn't open instance path key %wZ [%#08lx]\n",
03837 &(DeviceNode->InstancePath)));
03838 ZwClose(instanceKey);
03839
return FALSE;
03840
03841 }
else {
03842
03843
03844
03845
03846
03847
03848
RtlInitUnicodeString(&service,
NULL);
03849
RtlInitUnicodeString(&classGuid,
NULL);
03850
RtlInitUnicodeString(&lowerFilters,
NULL);
03851
RtlInitUnicodeString(&upperFilters,
NULL);
03852 status =
IopProcessCriticalDeviceRoutine(instanceKey,
03853 &foundMatch,
03854 &service,
03855 &classGuid,
03856 &lowerFilters,
03857 &upperFilters);
03858
if (!
NT_SUCCESS(status)) {
03859
DebugPrint(1, (
"IICPD: IopProcessCriticalDeviceRoutine failed with status %#08lx\n", status));
03860
return FALSE;
03861 }
03862
03863 }
03864
03865
03866
03867
03868
03869
03870
if (!foundMatch) {
03871 ZwClose(instanceKey);
03872
return FALSE;
03873
03874 }
else {
03875 UNICODE_STRING serviceValue, classGuidValue, lowerFiltersValue,
03876 upperFiltersValue;
03877
03878
DebugPrint(1, (
"IopProcessCriticalDevice: Setting up critical service\n"));
03879
03880
RtlInitUnicodeString(&serviceValue, REGSTR_VALUE_SERVICE);
03881
RtlInitUnicodeString(&classGuidValue, REGSTR_VALUE_CLASSGUID);
03882
RtlInitUnicodeString(&lowerFiltersValue, REGSTR_VALUE_LOWERFILTERS);
03883
RtlInitUnicodeString(&upperFiltersValue, REGSTR_VALUE_UPPERFILTERS);
03884
03885
if (classGuid.Buffer) {
03886
DebugPrint(1, (
"IopProcessCriticalDevice: classGuid is %wZ\n",
03887 &classGuid));
03888 status = ZwSetValueKey(instanceKey,
03889 &classGuidValue,
03890 0
L,
03891 REG_SZ,
03892 classGuid.Buffer,
03893 classGuid.Length +
sizeof(UNICODE_NULL));
03894 }
03895
if (lowerFilters.Buffer) {
03896
#if DBG_SCOPE
03897
str = lowerFilters.Buffer;
03898
while ((length = wcslen(str)) != 0) {
03899
DebugPrint(1, (
"IopProcessCriticalDevice: lower filter is %ws\n",
03900 str));
03901 str += (length + 1);
03902 }
03903
#endif
03904
status = ZwSetValueKey(instanceKey,
03905 &lowerFiltersValue,
03906 0
L,
03907 REG_MULTI_SZ,
03908 lowerFilters.Buffer,
03909 lowerFilters.Length);
03910 }
03911
03912
if (upperFilters.Buffer) {
03913
#if DBG_SCOPE
03914
str = upperFilters.Buffer;
03915
while ((length = wcslen(str)) != 0) {
03916
DebugPrint(1, (
"IopProcessCriticalDevice: upper filter is %ws\n",
03917 str));
03918 str += (length + 1);
03919 }
03920
#endif
03921
status = ZwSetValueKey(instanceKey,
03922 &upperFiltersValue,
03923 0
L,
03924 REG_MULTI_SZ,
03925 upperFilters.Buffer,
03926 upperFilters.Length);
03927 }
03928
03929
DebugPrint(1, (
"IopProcessCriticalDevice: service is %wZ\n",
03930 &service));
03931 status = ZwSetValueKey(instanceKey,
03932 &serviceValue,
03933 0
L,
03934 REG_SZ,
03935 service.Buffer,
03936 service.Length +
sizeof(UNICODE_NULL));
03937
03938
03939
03940
03941
03942
03943
03944
if (
NT_SUCCESS(status)) {
03945
03946 UCHAR buffer[
sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
sizeof(ULONG)];
03947 UNICODE_STRING valueName;
03948 PKEY_VALUE_PARTIAL_INFORMATION keyInfo =
03949 (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
03950 ULONG flags = 0;
03951
03952 ULONG length;
03953
03954
NTSTATUS tmpStatus;
03955
03956
RtlInitUnicodeString(&valueName, REGSTR_VALUE_CONFIG_FLAGS);
03957
03958 tmpStatus = ZwQueryValueKey(instanceKey,
03959 &valueName,
03960 KeyValuePartialInformation,
03961 keyInfo,
03962
sizeof(buffer),
03963 &length);
03964
03965
if (
NT_SUCCESS(tmpStatus) && (keyInfo->Type == REG_DWORD)) {
03966
03967 flags = *(PULONG)keyInfo->Data;
03968 }
03969
03970 flags &= ~(CONFIGFLAG_REINSTALL | CONFIGFLAG_FAILEDINSTALL);
03971 flags |= CONFIGFLAG_FINISH_INSTALL;
03972
03973 ZwSetValueKey(instanceKey,
03974 &valueName,
03975 0
L,
03976 REG_DWORD,
03977 &flags,
03978
sizeof(ULONG));
03979
03980
ASSERT(!
IopDoesDevNodeHaveProblem(DeviceNode) ||
03981
IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) ||
03982
IopIsDevNodeProblem(DeviceNode, CM_PROB_FAILED_INSTALL) ||
03983
IopIsDevNodeProblem(DeviceNode, CM_PROB_REINSTALL));
03984
03985
IopClearDevNodeProblem(DeviceNode);
03986 }
03987 ZwClose(instanceKey);
03988 }
03989
03990
IopFreeAllocatedUnicodeString(&service);
03991
IopFreeAllocatedUnicodeString(&classGuid);
03992
IopFreeAllocatedUnicodeString(&lowerFilters);
03993
IopFreeAllocatedUnicodeString(&upperFilters);
03994
03995
return (
NT_SUCCESS(status));
03996 }
03997
03998
03999
NTSTATUS
04000 IopProcessCriticalDeviceRoutine(
04001 IN HANDLE HDevInstance,
04002 IN PBOOLEAN FoundMatch,
04003 IN PUNICODE_STRING ServiceName,
04004 IN PUNICODE_STRING ClassGuid,
04005 IN PUNICODE_STRING LowerFilters,
04006 IN PUNICODE_STRING UpperFilters
04007 )
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038 {
04039
NTSTATUS status;
04040 HANDLE hRegistryMachine, hCriticalDeviceKey,
04041 hCriticalEntry;
04042 PWSTR keyValueInfoTag[2];
04043 PKEY_VALUE_FULL_INFORMATION keyValueInfo[2], matchedKeyValFullInfo;
04044
BUFFER_INFO infoBuffer;
04045 ULONG enumIndex, idIndex, resultSize, stringLength;
04046 UNICODE_STRING tmpUnicodeString, unicodeCriticalEntry,
04047 unicodeCriticalDeviceKeyName;
04048 PWCHAR stringStart, bufferEnd, ptr;
04049 PRTL_QUERY_REGISTRY_TABLE parameters =
NULL;
04050
04051
#define INITIAL_INFOBUFFER_SIZE sizeof(KEY_VALUE_FULL_INFORMATION) + 8*sizeof(WCHAR) + 255*sizeof(WCHAR)
04052
04053 hRegistryMachine =
NULL;
04054 hCriticalDeviceKey =
NULL;
04055 infoBuffer.
Buffer =
NULL;
04056
04057
04058
04059
04060
04061
04062
04063
04064 keyValueInfoTag[0] = REGSTR_VAL_HARDWAREID;
04065 keyValueInfoTag[1] = REGSTR_VAL_COMPATIBLEIDS;
04066
04067
for (idIndex = 0; idIndex < 2; idIndex++) {
04068
04069 keyValueInfo[idIndex] =
NULL;
04070 status =
IopGetRegistryValue(HDevInstance,
04071 keyValueInfoTag[idIndex],
04072 &keyValueInfo[idIndex]);
04073
if (!
NT_SUCCESS( status )) {
04074
04075
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: Unable to get some "
04076
"%ws value info, %#08lx. continuing.\n",
04077 keyValueInfoTag[idIndex], status));
04078
04079 }
else if ((keyValueInfo[idIndex]->Type != REG_MULTI_SZ) ||
04080 (keyValueInfo[idIndex]->DataLength == 0)) {
04081
04082
ExFreePool(keyValueInfo[idIndex]);
04083 keyValueInfo[idIndex] =
NULL;
04084
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: some %ws"
04085
"Key Value Info not in expected format\n",
04086 keyValueInfoTag[idIndex]));
04087 }
else {
04088
04089
04090
04091
04092 tmpUnicodeString.Buffer = (PWCHAR)
KEY_VALUE_DATA(keyValueInfo[idIndex]);
04093 tmpUnicodeString.Length = (
USHORT) keyValueInfo[idIndex]->DataLength;
04094 tmpUnicodeString.MaximumLength = tmpUnicodeString.Length;
04095
04096
IopReplaceSeperatorWithPound(&tmpUnicodeString,
04097 &tmpUnicodeString);
04098 }
04099 }
04100
04101
04102
04103
04104 status =
IopOpenRegistryKeyEx( &hRegistryMachine,
04105
NULL,
04106 &
CmRegistryMachineName,
04107 KEY_READ
04108 );
04109
if (!
NT_SUCCESS(status)) {
04110
goto cleanup;
04111 }
04112
04113
04114
04115
04116
04117
04118
04119
04120
04121
04122 PiWstrToUnicodeString(&unicodeCriticalDeviceKeyName, REGSTR_PATH_CRITICALDEVICEDATABASE);
04123 status =
IopOpenRegistryKeyEx( &hCriticalDeviceKey,
04124 hRegistryMachine,
04125 &unicodeCriticalDeviceKeyName,
04126 KEY_READ
04127 );
04128
04129
04130
04131 ZwClose(hRegistryMachine);
04132
04133
04134
04135
04136
if ( !
NT_SUCCESS(status) ) {
04137
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: Unable to open %wZ key. exiting...\n",
04138 &unicodeCriticalDeviceKeyName));
04139
goto cleanup;
04140 }
04141
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: Successfully opened %wZ key.\n",
04142 &unicodeCriticalDeviceKeyName));
04143
04144
04145
04146
04147
04148 status =
IopAllocateBuffer( &infoBuffer,
04149
INITIAL_INFOBUFFER_SIZE );
04150
if (!
NT_SUCCESS(status)) {
04151
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: Unable to allocate buffer to hold key values. exiting...\n",
04152 &unicodeCriticalDeviceKeyName));
04153
goto cleanup;
04154 }
04155
04156
04157
04158
04159
04160
04161
04162 enumIndex = 0;
04163
while (((status = ZwEnumerateKey( hCriticalDeviceKey,
04164 enumIndex,
04165 KeyBasicInformation,
04166 (PVOID) infoBuffer.
Buffer,
04167 infoBuffer.
MaxSize,
04168 &resultSize)) != STATUS_NO_MORE_ENTRIES)) {
04169
if (status == STATUS_BUFFER_OVERFLOW) {
04170
04171
04172
04173
04174 status =
IopResizeBuffer( &infoBuffer,
04175 resultSize,
04176
FALSE );
04177
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: ZwEnumerateKey returned STATUS_BUFFER_OVERFLOW, %#08lx\n",
04178 status));
04179
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: (resizing buffer...)\n"));
04180
continue;
04181
04182 }
else if (!
NT_SUCCESS(status)) {
04183
04184
04185
04186
04187
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: ZwEnumerateValueKey failed, %#08lx exiting...\n",
04188 status));
04189
goto cleanup;
04190 }
04191
04192
04193
04194
04195
04196
04197 unicodeCriticalEntry.Buffer = ((PKEY_BASIC_INFORMATION)(infoBuffer.
Buffer))->Name;
04198 unicodeCriticalEntry.Length = (
USHORT) ((PKEY_BASIC_INFORMATION)(infoBuffer.
Buffer))->NameLength;
04199 unicodeCriticalEntry.MaximumLength = unicodeCriticalEntry.Length;
04200
04201
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: \t key (%u) enumerated: %wZ\n",
04202 enumIndex,
04203 &unicodeCriticalEntry));
04204
04205
04206
04207
04208
04209
for ( idIndex=0; idIndex < 2; idIndex++) {
04210
04211
if (!keyValueInfo[idIndex]){
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: No %ws value was found, move on to next\n",
04222 keyValueInfoTag[idIndex]));
04223
continue;
04224 }
04225
04226
04227
04228
04229 ptr = (PWCHAR)
KEY_VALUE_DATA(keyValueInfo[idIndex]);
04230 stringStart = ptr;
04231 bufferEnd = (PWCHAR)((PUCHAR)ptr + keyValueInfo[idIndex]->DataLength);
04232
04233
while(ptr != bufferEnd) {
04234
04235
if (!*ptr) {
04236
04237
04238
04239 stringLength = (ULONG)((PUCHAR)ptr - (PUCHAR)stringStart);
04240 tmpUnicodeString.Buffer = stringStart;
04241 tmpUnicodeString.Length = (
USHORT)stringLength;
04242 tmpUnicodeString.MaximumLength = (
USHORT)stringLength +
sizeof(UNICODE_NULL);
04243
04244
DebugPrint(2, (
"IopProcessCriticalDeviceRoutine: comparing %wZ with %wZ\n",
04245 &tmpUnicodeString, &unicodeCriticalEntry));
04246
04247
04248
04249
if (
RtlEqualUnicodeString(&tmpUnicodeString,
04250 &unicodeCriticalEntry,
04251
TRUE)) {
04252
04253
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: ***** Critical Device %wZ: Matched to Device %wZ.\n",
04254 &tmpUnicodeString,
04255 &unicodeCriticalEntry));
04256
04257
#define NUM_QUERIES 4
04258
status =
IopOpenRegistryKeyEx( &hCriticalEntry,
04259 hCriticalDeviceKey,
04260 &unicodeCriticalEntry,
04261 KEY_READ
04262 );
04263
04264
if (!
NT_SUCCESS(status)) {
04265
goto cleanup;
04266 }
04267
04268 parameters = (PRTL_QUERY_REGISTRY_TABLE)
04269
ExAllocatePool(
NonPagedPool,
04270
sizeof(RTL_QUERY_REGISTRY_TABLE)*(
NUM_QUERIES+1));
04271
04272
if (!parameters) {
04273 ZwClose(hCriticalEntry);
04274 status = STATUS_INSUFFICIENT_RESOURCES;
04275
goto cleanup;
04276 }
04277
04278 RtlZeroMemory(parameters,
04279
sizeof(RTL_QUERY_REGISTRY_TABLE) * (
NUM_QUERIES + 1));
04280
04281 parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
04282 parameters[0].Name = REGSTR_VALUE_SERVICE;
04283 parameters[0].EntryContext = ServiceName;
04284 parameters[0].DefaultType = REG_SZ;
04285 parameters[0].DefaultData =
L"";
04286 parameters[0].DefaultLength = 0;
04287
04288 parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
04289 parameters[1].Name = REGSTR_VALUE_CLASSGUID;
04290 parameters[1].EntryContext = ClassGuid;
04291 parameters[1].DefaultType = REG_SZ;
04292 parameters[1].DefaultData =
L"";
04293 parameters[1].DefaultLength = 0;
04294
04295 parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND;
04296 parameters[2].Name = REGSTR_VALUE_LOWERFILTERS;
04297 parameters[2].EntryContext = LowerFilters;
04298 parameters[2].DefaultType = REG_MULTI_SZ;
04299 parameters[2].DefaultData =
L"";
04300 parameters[2].DefaultLength = 0;
04301
04302 parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND;
04303 parameters[3].Name = REGSTR_VALUE_UPPERFILTERS;
04304 parameters[3].EntryContext = UpperFilters;
04305 parameters[3].DefaultType = REG_MULTI_SZ;
04306 parameters[3].DefaultData =
L"";
04307 parameters[3].DefaultLength = 0;
04308
04309 status =
RtlQueryRegistryValues(
04310 RTL_REGISTRY_HANDLE | RTL_REGISTRY_OPTIONAL,
04311 (PWSTR) hCriticalEntry,
04312 parameters,
04313
NULL,
04314
NULL
04315 );
04316
04317
ExFreePool(parameters);
04318 ZwClose(hCriticalEntry);
04319
04320
if (
NT_SUCCESS(status)) {
04321
04322
04323
04324
04325
04326
04327
if (!ServiceName->Buffer || !ServiceName->Length ||
04328 (ClassGuid->Length && (ClassGuid->Length < 38 *
sizeof (WCHAR)))) {
04329
goto FreeStrings;
04330 }
04331
04332
04333
04334
04335
04336
if (UpperFilters->Length <= 2 && UpperFilters->Buffer) {
04337
RtlFreeUnicodeString(UpperFilters);
04338 }
04339
if (LowerFilters->Length <= 2 && LowerFilters->Buffer) {
04340
RtlFreeUnicodeString(LowerFilters);
04341 }
04342
if (ClassGuid->Length == 0 && ClassGuid->Buffer) {
04343
RtlFreeUnicodeString(ClassGuid);
04344 }
04345
04346
#if DBG
04347
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: ***** Using ServiceName %wZ.\n",
04348 ServiceName));
04349
04350
if (ClassGuid->Buffer) {
04351
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: ***** Using ClassGuid %wZ.\n",
04352 ClassGuid));
04353 }
04354
#endif
04355
04356 }
else {
04357 FreeStrings:
04358
04359
04360
04361
04362
RtlFreeUnicodeString(ServiceName);
04363
RtlFreeUnicodeString(ClassGuid);
04364
RtlFreeUnicodeString(LowerFilters);
04365
RtlFreeUnicodeString(UpperFilters);
04366 }
04367
04368
if (ServiceName->Buffer !=
NULL) {
04369 *FoundMatch =
TRUE;
04370
goto exit;
04371 }
04372 }
04373
04374
04375
04376
04377
if (((ptr + 1) == bufferEnd) || !*(ptr + 1)) {
04378
break;
04379 }
else {
04380 stringStart = ptr + 1;
04381 }
04382
04383 }
04384
04385
04386
04387 ptr++;
04388 }
04389 }
04390
04391
04392
04393 enumIndex++;
04394 }
04395
04396
04397
04398
04399
04400
if (status == STATUS_NO_MORE_ENTRIES) {
04401
DebugPrint(1, (
"IopProcessCriticalDeviceRoutine: No match found for this device.\n"));
04402 }
04403
04404
04405
exit:
04406 status = STATUS_SUCCESS;
04407
04408 cleanup:
04409
if (infoBuffer.
Buffer) {
04410
IopFreeBuffer(&infoBuffer);
04411 }
04412
if (hCriticalDeviceKey) {
04413 ZwClose(hCriticalDeviceKey);
04414 }
04415
if (keyValueInfo[0]) {
04416
ExFreePool(keyValueInfo[0]);
04417 }
04418
if (keyValueInfo[1]) {
04419
ExFreePool(keyValueInfo[1]);
04420 }
04421
return status;
04422 }
04423
04424
USHORT
04425 IopGetBusTypeGuidIndex(
04426 IN LPGUID BusTypeGuid
04427 )
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450 {
04451 PCHAR p;
04452
USHORT i, busTypeIndex = 0xffff;
04453 ULONG size;
04454
04455
ASSERT(
IopBusTypeGuidList !=
NULL);
04456
04457 ExAcquireFastMutex(&
IopBusTypeGuidList->
Lock);
04458
04459
04460
04461
04462
for (i = 0; i < (
USHORT)
IopBusTypeGuidList->
Count; i++) {
04463
if (
IopCompareGuid(BusTypeGuid, &
IopBusTypeGuidList->
Guid[i])) {
04464 busTypeIndex = i;
04465
goto Clean0;
04466 }
04467 }
04468
04469
04470
04471
04472
04473
if (
IopBusTypeGuidList->
Count > 0) {
04474
04475
04476
04477
04478
04479 size =
sizeof(
BUS_TYPE_GUID_LIST) +
04480
sizeof(GUID) * (
IopBusTypeGuidList->
Count);
04481
04482 p =
ExAllocatePool(
PagedPool, size);
04483
if (!p) {
04484
goto Clean0;
04485 }
04486
04487 size =
sizeof(
BUS_TYPE_GUID_LIST) +
04488
sizeof(GUID) * (
IopBusTypeGuidList->
Count - 1);
04489
04490 RtlCopyMemory(p,
IopBusTypeGuidList, size);
04491
04492
ExFreePool(
IopBusTypeGuidList);
04493
IopBusTypeGuidList = (
PBUS_TYPE_GUID_LIST)p;
04494 }
04495
04496
04497
04498
04499 RtlCopyMemory(&
IopBusTypeGuidList->
Guid[
IopBusTypeGuidList->
Count],
04500 BusTypeGuid,
04501
sizeof(GUID));
04502
04503 busTypeIndex = (
USHORT)
IopBusTypeGuidList->
Count;
04504
IopBusTypeGuidList->
Count += 1;
04505
04506 Clean0:
04507
04508 ExReleaseFastMutex(&
IopBusTypeGuidList->
Lock);
04509
04510
return busTypeIndex;
04511 }
04512
04513 BOOLEAN
04514 IopFixupDeviceId(
04515 PWCHAR DeviceId
04516 )
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542 {
04543 PWCHAR p;
04544
04545
04546
04547
for (p = DeviceId; *p; p++) {
04548
if (*p ==
L' ') {
04549 *p =
L'_';
04550 }
else if ((*p < L' ') || (*p > (WCHAR)0x7F) || (*p ==
L',')) {
04551
return FALSE;
04552 }
04553 }
04554
04555
return TRUE;
04556 }
04557
04558 BOOLEAN
04559 IopFixupIds(
04560 IN PWCHAR Ids,
04561 IN ULONG Length
04562 )
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589 {
04590 PWCHAR p, end;
04591
04592 p = Ids;
04593 end = p + Length /
sizeof(WCHAR);
04594
04595
while ((p < end) && (*p)) {
04596
if (!
IopFixupDeviceId(p)) {
04597
return FALSE;
04598 }
04599
04600
while (*p) {
04601 p++;
04602 }
04603 p++;
04604 }
04605
return TRUE;
04606 }
04607
04608
04609 BOOLEAN
04610 IopGetRegistryDwordWithFallback(
04611 IN PUNICODE_STRING valueName,
04612 IN HANDLE PrimaryKey,
04613 IN HANDLE SecondaryKey,
04614 IN OUT PULONG Value)
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638 {
04639 PKEY_VALUE_FULL_INFORMATION info;
04640 PUCHAR data;
04641
NTSTATUS status;
04642 HANDLE Keys[3];
04643
int count = 0;
04644
int index;
04645 BOOLEAN set =
FALSE;
04646
04647
if (PrimaryKey !=
NULL) {
04648 Keys[count++] = PrimaryKey;
04649 }
04650
if (SecondaryKey !=
NULL) {
04651 Keys[count++] = SecondaryKey;
04652 }
04653 Keys[count] =
NULL;
04654
04655
for (index = 0; index < count && !set; index ++) {
04656 info =
NULL;
04657
try {
04658 status =
IopGetRegistryValue(Keys[index],
04659 valueName->Buffer,
04660 &info);
04661
if (
NT_SUCCESS(status) && info->Type == REG_DWORD) {
04662 data = ((PUCHAR) info) + info->DataOffset;
04663 *Value = *((PULONG) data);
04664 set =
TRUE;
04665 }
04666 } except(
EXCEPTION_EXECUTE_HANDLER) {
04667
04668
04669
04670 }
04671
if (info) {
04672
ExFreePool(info);
04673 }
04674 }
04675
return set;
04676 }
04677
04678 PSECURITY_DESCRIPTOR
04679 IopGetRegistrySecurityWithFallback(
04680 IN PUNICODE_STRING valueName,
04681 IN HANDLE PrimaryKey,
04682 IN HANDLE SecondaryKey)
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700
04701
04702
04703
04704
04705
04706 {
04707 PKEY_VALUE_FULL_INFORMATION info;
04708 PUCHAR data;
04709
NTSTATUS status;
04710 HANDLE Keys[3];
04711
int count = 0;
04712
int index;
04713 BOOLEAN set =
FALSE;
04714 PSECURITY_DESCRIPTOR secDesc =
NULL;
04715 PSECURITY_DESCRIPTOR allocDesc =
NULL;
04716
04717
if (PrimaryKey !=
NULL) {
04718 Keys[count++] = PrimaryKey;
04719 }
04720
if (SecondaryKey !=
NULL) {
04721 Keys[count++] = SecondaryKey;
04722 }
04723 Keys[count] =
NULL;
04724
04725
for (index = 0; index < count && !set; index ++) {
04726 info =
NULL;
04727
try {
04728 status =
IopGetRegistryValue(Keys[index],
04729 valueName->Buffer,
04730 &info);
04731
if (
NT_SUCCESS(status) && info->Type == REG_BINARY) {
04732 data = ((PUCHAR) info) + info->DataOffset;
04733 secDesc = (PSECURITY_DESCRIPTOR)data;
04734 status =
SeCaptureSecurityDescriptor(secDesc,
04735
KernelMode,
04736
PagedPool,
04737
TRUE,
04738 &allocDesc);
04739
if (
NT_SUCCESS(status)) {
04740 set =
TRUE;
04741 }
04742 }
04743 } except(
EXCEPTION_EXECUTE_HANDLER) {
04744
04745
04746
04747 }
04748
if (info) {
04749
ExFreePool(info);
04750 }
04751 }
04752
if (set) {
04753
return allocDesc;
04754 }
04755
return NULL;
04756 }
04757
04758
NTSTATUS
04759 IopChangeDeviceObjectFromRegistryProperties(
04760 IN
PDEVICE_OBJECT PhysicalDeviceObject,
04761 IN HANDLE DeviceClassPropKey,
04762 IN HANDLE DevicePropKey,
04763 IN BOOLEAN UsePdoCharacteristics
04764 )
04765
04766
04767
04768
04769
04770
04771
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
04799 {
04800 UNICODE_STRING valueName;
04801 PKEY_VALUE_FULL_INFORMATION info;
04802 PUCHAR data;
04803
NTSTATUS status;
04804
04805 BOOLEAN deviceTypeSpec =
FALSE;
04806 BOOLEAN characteristicsSpec =
FALSE;
04807 BOOLEAN exclusiveSpec =
FALSE;
04808 BOOLEAN securityForce =
FALSE;
04809
CHAR buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
04810 SECURITY_INFORMATION securityInformation = 0;
04811
04812 PSECURITY_DESCRIPTOR securityDescriptor =
NULL;
04813 PACL allocatedAcl =
NULL;
04814 ULONG deviceType = 0;
04815 ULONG characteristics = 0;
04816 ULONG exclusive = 0;
04817 ULONG prevCharacteristics = 0;
04818 ULONG prevExclusive = 0;
04819
PDEVICE_OBJECT StackIterator =
NULL;
04820
PDEVICE_NODE deviceNode =
NULL;
04821
04822
ASSERT(PhysicalDeviceObject);
04823 deviceNode = PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
04824
ASSERT(deviceNode);
04825
04826
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Modifying device stack for PDO: %08x\n",PhysicalDeviceObject));
04827
04828
04829
04830
04831
04832
04833
04834 StackIterator = PhysicalDeviceObject;
04835
if (UsePdoCharacteristics || StackIterator->
AttachedDevice ==
NULL) {
04836
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Assuming PDO is being used RAW\n"));
04837 }
else {
04838 StackIterator = StackIterator->
AttachedDevice;
04839
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Ignoring PDO's settings\n"));
04840 }
04841
for ( ; StackIterator !=
NULL; StackIterator = StackIterator->
AttachedDevice) {
04842
#if 0 // BUGBUG (jamiehun) we were breaking serial, I'd like to put this back in though...
04843
prevExclusive |= StackIterator->
Flags &
DO_EXCLUSIVE;
04844
#endif
04845
prevCharacteristics |= StackIterator->
Characteristics;
04846 }
04847
04848
04849
04850
04851
RtlInitUnicodeString(&valueName, REGSTR_VAL_DEVICE_TYPE);
04852 deviceTypeSpec =
IopGetRegistryDwordWithFallback(&valueName,DevicePropKey,DeviceClassPropKey,&deviceType);
04853
RtlInitUnicodeString(&valueName, REGSTR_VAL_DEVICE_CHARACTERISTICS);
04854 characteristicsSpec =
IopGetRegistryDwordWithFallback(&valueName,DevicePropKey,DeviceClassPropKey,&characteristics);
04855
RtlInitUnicodeString(&valueName, REGSTR_VAL_DEVICE_EXCLUSIVE);
04856 exclusiveSpec =
IopGetRegistryDwordWithFallback(&valueName,DevicePropKey,DeviceClassPropKey,&exclusive);
04857
04858
if (exclusive) {
04859
04860
04861
04862 exclusive =
DO_EXCLUSIVE;
04863 }
04864
04865
if (exclusiveSpec) {
04866 exclusive |= prevExclusive;
04867 }
else {
04868 exclusive = prevExclusive;
04869 }
04870
if (!characteristicsSpec) {
04871 characteristics = 0;
04872 }
04873 characteristics = (characteristics | prevCharacteristics) & FILE_CHARACTERISTICS_PROPAGATED;
04874
04875
RtlInitUnicodeString(&valueName, REGSTR_VAL_DEVICE_SECURITY_DESCRIPTOR);
04876 securityDescriptor =
IopGetRegistrySecurityWithFallback(&valueName,DevicePropKey,DeviceClassPropKey);
04877
04878
if (securityDescriptor ==
NULL) {
04879
04880
04881
04882
if (deviceTypeSpec) {
04883 BOOLEAN hasName = (PhysicalDeviceObject->Flags &
DO_DEVICE_HAS_NAME) ?
TRUE :
FALSE;
04884
04885 securityDescriptor =
IopCreateDefaultDeviceSecurityDescriptor(
04886 (DEVICE_TYPE)deviceType,
04887 characteristics,
04888 hasName,
04889 buffer,
04890 &allocatedAcl,
04891 &securityInformation
04892 );
04893
if (securityDescriptor) {
04894 securityForce =
TRUE;
04895 }
else {
04896
DebugPrint(1, (
"IopChangeDeviceObjectFromRegistryProperties: Was not able to get default security descriptor\n"));
04897 }
04898 }
04899 }
else {
04900
04901
04902
04903 PSID sid;
04904 PACL acl;
04905 BOOLEAN present, tmp;
04906
04907 securityInformation = 0;
04908
04909
04910
04911
04912
04913
04914 status =
RtlGetOwnerSecurityDescriptor(securityDescriptor, &sid, &tmp);
04915
04916
if (
NT_SUCCESS(status) && (sid !=
NULL)) {
04917 securityInformation |= OWNER_SECURITY_INFORMATION;
04918 }
04919
04920 status =
RtlGetGroupSecurityDescriptor(securityDescriptor, &sid, &tmp);
04921
04922
if (
NT_SUCCESS(status) && (sid !=
NULL)) {
04923 securityInformation |= GROUP_SECURITY_INFORMATION;
04924 }
04925
04926 status =
RtlGetSaclSecurityDescriptor(securityDescriptor,
04927 &present,
04928 &acl,
04929 &tmp);
04930
04931
if (
NT_SUCCESS(status) && (present)) {
04932 securityInformation |= SACL_SECURITY_INFORMATION;
04933 }
04934
04935 status =
RtlGetDaclSecurityDescriptor(securityDescriptor,
04936 &present,
04937 &acl,
04938 &tmp);
04939
04940
if (
NT_SUCCESS(status) && (present)) {
04941 securityInformation |= DACL_SECURITY_INFORMATION;
04942 }
04943
04944 }
04945
04946
#if DBG
04947
if (deviceTypeSpec ==
FALSE && characteristicsSpec ==
FALSE && exclusiveSpec ==
FALSE && securityDescriptor ==
NULL) {
04948
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: No property changes\n"));
04949 }
else {
04950
if (deviceTypeSpec) {
04951
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Overide DeviceType=%08x\n",
04952 deviceType));
04953 }
04954
if (characteristicsSpec) {
04955
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Overide DeviceCharacteristics=%08x\n",
04956 characteristics));
04957 }
04958
if (exclusiveSpec) {
04959
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Overide Exclusive=%d\n",(exclusive?1:0)));
04960 }
04961
if (securityForce) {
04962
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Overide Security based on DeviceType & DeviceCharacteristics\n"));
04963 }
04964
if (securityDescriptor ==
NULL) {
04965
DebugPrint(2, (
"IopChangeDeviceObjectFromRegistryProperties: Overide Security\n"));
04966 }
04967 }
04968
#endif
04969
04970
04971
04972
04973 PhysicalDeviceObject->Characteristics = (PhysicalDeviceObject->Characteristics & ~FILE_CHARACTERISTICS_PROPAGATED) | characteristics;
04974
ASSERT((PhysicalDeviceObject->Characteristics & FILE_CHARACTERISTICS_PROPAGATED) == characteristics);
04975
04976
04977
04978
04979
#if 0 // BUGBUG (jamiehun) we were breaking serial, I'd like to put this back in though...
04980
PhysicalDeviceObject->Flags = (PhysicalDeviceObject->Flags & ~
DO_EXCLUSIVE) | exclusive;
04981
ASSERT((PhysicalDeviceObject->Flags &
DO_EXCLUSIVE) == exclusive);
04982
#endif
04983
04984
04985
04986
04987
04988
04989
for ( StackIterator = PhysicalDeviceObject->
AttachedDevice ; StackIterator !=
NULL ; StackIterator = StackIterator->
AttachedDevice) {
04990
04991
04992
04993 StackIterator->
Characteristics |= characteristics;
04994
ASSERT((StackIterator->
Characteristics & FILE_CHARACTERISTICS_PROPAGATED) == characteristics);
04995
04996
04997
04998 StackIterator->
Flags |= exclusive;
04999
#if 0 // BUGBUG (jamiehun) we were breaking serial, I'd like to put this back in though...
05000
ASSERT((StackIterator->
Flags &
DO_EXCLUSIVE) == exclusive);
05001
#endif
05002
}
05003
if (deviceTypeSpec) {
05004
05005
05006
05007 PhysicalDeviceObject->DeviceType = deviceType;
05008 }
05009
if (securityDescriptor !=
NULL) {
05010
05011
05012
05013 status =
ObSetSecurityObjectByPointer(PhysicalDeviceObject,
05014 securityInformation,
05015 securityDescriptor);
05016
if (
NT_SUCCESS(status) ==
FALSE) {
05017
DebugPrint(1, (
"IopChangeDeviceObjectFromRegistryProperties: Set security failed (%08x)\n",status));
05018 }
05019 }
05020
05021
05022
05023
if ((securityDescriptor !=
NULL) && !securityForce) {
05024
ExFreePool(securityDescriptor);
05025 }
05026
if (allocatedAcl) {
05027
ExFreePool(allocatedAcl);
05028 }
05029
05030
return STATUS_SUCCESS;
05031 }
05032
05033
NTSTATUS
05034 IopProcessNewProfile(
05035 VOID
05036 )
05037
05038
05039
05040
05041
05042
05043
05044
05045
05046
05047
05048
05049
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061
05062
05063
05064
05065
05066
05067
05068
05069
05070
05071
05072
05073
05074 {
05075
PWORK_QUEUE_ITEM workQueueItem;
05076
05077
PAGED_CODE();
05078
05079 workQueueItem = (
PWORK_QUEUE_ITEM)
ExAllocatePool(
05080
NonPagedPool,
05081
sizeof(
WORK_QUEUE_ITEM)
05082 );
05083
05084
if (workQueueItem) {
05085
05086
05087
05088
05089
ExInitializeWorkItem(
05090 workQueueItem,
05091
IopProcessNewProfileWorker,
05092 workQueueItem
05093 );
05094
05095
ExQueueWorkItem(
05096 workQueueItem,
05097
CriticalWorkQueue
05098 );
05099
05100
return STATUS_SUCCESS;
05101
05102 }
else {
05103
05104
return STATUS_INSUFFICIENT_RESOURCES;
05105 }
05106 }
05107
05108
VOID
05109 IopProcessNewProfileWorker(
05110 IN PVOID Context
05111 )
05112
05113
05114
05115
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126
05127
05128
05129 {
05130
PAGED_CODE();
05131
05132
IopForAllDeviceNodes(
IopProcessNewProfileStateCallback,
NULL);
05133
05134
ExFreePool(Context);
05135 }
05136
05137
NTSTATUS
05138 IopProcessNewProfileStateCallback(
05139 IN
PDEVICE_NODE DeviceNode,
05140 IN PVOID Context
05141 )
05142
05143
05144
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159 {
05160
PDEVICE_NODE parentDevNode;
05161
05162
PAGED_CODE();
05163
05164
if (DeviceNode->Flags &
DNF_STARTED) {
05165
05166
05167
05168
05169
05170
if (!
IopIsDeviceInstanceEnabled(
NULL, &DeviceNode->InstancePath,
FALSE)) {
05171
05172
IopRequestDeviceRemoval(
05173 DeviceNode->PhysicalDeviceObject,
05174 CM_PROB_DISABLED
05175 );
05176 }
05177
05178 }
else if (
IopIsDevNodeProblem(DeviceNode, CM_PROB_DISABLED)) {
05179
05180
05181
05182
05183
05184
IopClearDevNodeProblem(DeviceNode);
05185
05186
05187
05188
05189
if (
IopIsDeviceInstanceEnabled(
NULL, &DeviceNode->InstancePath,
FALSE)) {
05190
05191
05192
05193
05194
05195 parentDevNode = DeviceNode->
Parent;
05196
05197
IoInvalidateDeviceRelations(
05198 parentDevNode->
PhysicalDeviceObject,
05199
BusRelations
05200 );
05201 }
05202 }
05203
05204
return STATUS_SUCCESS;
05205 }