00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
#include "iop.h"
00030
#pragma hdrstop
00031
00032
#ifdef POOL_TAGGING
00033
#undef ExAllocatePool
00034
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'nipP')
00035
#endif
00036
00037
00038
00039
00040 #define ALLOW_WORLD_READ_OF_ENUM 1
00041
00042 typedef struct _ROOT_ENUMERATOR_CONTEXT {
00043 NTSTATUS Status;
00044 PUNICODE_STRING
KeyName;
00045 ULONG
MaxDeviceCount;
00046 ULONG
DeviceCount;
00047 PDEVICE_OBJECT *
DeviceList;
00048 }
ROOT_ENUMERATOR_CONTEXT, *
PROOT_ENUMERATOR_CONTEXT;
00049
00050
NTSTATUS
00051
IopPnPDriverEntry(
00052 IN
PDRIVER_OBJECT DriverObject,
00053 IN PUNICODE_STRING RegistryPath
00054 );
00055
00056 BOOLEAN
00057
IopInitializeDeviceKey(
00058 IN HANDLE KeyHandle,
00059 IN PUNICODE_STRING KeyName,
00060 IN OUT PVOID Context
00061 );
00062
00063 BOOLEAN
00064
IopInitializeDeviceInstanceKey(
00065 IN HANDLE KeyHandle,
00066 IN PUNICODE_STRING KeyName,
00067 IN OUT PVOID Context
00068 );
00069
00070
NTSTATUS
00071
IopGetServiceType(
00072 IN PUNICODE_STRING KeyName,
00073 IN PULONG ServiceType
00074 );
00075
00076 INTERFACE_TYPE
00077
IopDetermineDefaultInterfaceType (
00078 VOID
00079 );
00080
00081
#ifdef ALLOC_PRAGMA
00082
#pragma alloc_text(INIT, IopPnPDriverEntry)
00083
#pragma alloc_text(INIT, IopInitializePlugPlayServices)
00084
#pragma alloc_text(INIT, IopDetermineDefaultInterfaceType)
00085
#pragma alloc_text(PAGE, IopIsFirmwareMapperDevicePresent)
00086
#pragma alloc_text(PAGE, IopGetRootDevices)
00087
#pragma alloc_text(PAGE, IopInitializeDeviceKey)
00088
#pragma alloc_text(PAGE, IopInitializeDeviceInstanceKey)
00089
#pragma alloc_text(PAGE, IopGetServiceType)
00090
#endif
00091
00092
NTSTATUS
00093 IopInitializePlugPlayServices(
00094 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
00095 IN ULONG Phase
00096 )
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 {
00115
NTSTATUS status;
00116 HANDLE hTreeHandle, parentHandle, handle, hCurrentControlSet =
NULL;
00117 UNICODE_STRING unicodeName;
00118 PKEY_VALUE_FULL_INFORMATION detectionInfo;
00119
PDEVICE_OBJECT deviceObject;
00120 ULONG disposition;
00121
00122
if (Phase == 0) {
00123
PnPInitialized =
FALSE;
00124
00125
00126
00127
00128
00129
00130
IopPnpScratchBuffer1 =
ExAllocatePool(
PagedPool,
PNP_LARGE_SCRATCH_BUFFER_SIZE);
00131
if (!
IopPnpScratchBuffer1) {
00132
return STATUS_INSUFFICIENT_RESOURCES;
00133 }
00134
IopPnpScratchBuffer2 =
ExAllocatePool(
PagedPool,
PNP_LARGE_SCRATCH_BUFFER_SIZE);
00135
if (!
IopPnpScratchBuffer2) {
00136
ExFreePool(
IopPnpScratchBuffer1);
00137
return STATUS_INSUFFICIENT_RESOURCES;
00138 }
00139
00140
IopInitReservedResourceList =
NULL;
00141
00142
IopReserveResourcesRoutine =
IopReserveBootResources;
00143
00144
00145
00146
00147
00148
00149
00150
PnpDefaultInterfaceType =
IopDetermineDefaultInterfaceType();
00151
00152
00153
00154
00155
00156 status =
IopPortInitialize();
00157
if (!
NT_SUCCESS(status)) {
00158
goto init_Exit0;
00159 }
00160
00161 status =
IopMemInitialize();
00162
if (!
NT_SUCCESS(status)) {
00163
goto init_Exit0;
00164 }
00165
00166 status =
IopDmaInitialize();
00167
if (!
NT_SUCCESS(status)) {
00168
goto init_Exit0;
00169 }
00170
00171 status =
IopIrqInitialize();
00172
if (!
NT_SUCCESS(status)) {
00173
goto init_Exit0;
00174 }
00175
00176 status =
IopBusNumberInitialize();
00177
if (!
NT_SUCCESS(status)) {
00178
goto init_Exit0;
00179 }
00180
00181
00182
00183
00184
00185 status =
IopOpenRegistryKeyEx( &hCurrentControlSet,
00186
NULL,
00187 &
CmRegistryMachineSystemCurrentControlSet,
00188 KEY_ALL_ACCESS
00189 );
00190
if (!
NT_SUCCESS(status)) {
00191 hCurrentControlSet =
NULL;
00192
goto init_Exit0;
00193 }
00194
00195 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ENUM);
00196 status =
IopCreateRegistryKeyEx( &handle,
00197 hCurrentControlSet,
00198 &unicodeName,
00199 KEY_ALL_ACCESS,
00200 REG_OPTION_NON_VOLATILE,
00201 &disposition
00202 );
00203
if (!
NT_SUCCESS(status)) {
00204
goto init_Exit0;
00205 }
00206
00207
if (disposition == REG_CREATED_NEW_KEY) {
00208 SECURITY_DESCRIPTOR newSD;
00209 PACL newDacl;
00210 ULONG sizeDacl;
00211
00212 status =
RtlCreateSecurityDescriptor( &newSD,
00213 SECURITY_DESCRIPTOR_REVISION );
00214
ASSERT(
NT_SUCCESS( status ) );
00215
00216
00217
00218
00219 sizeDacl =
sizeof(ACL);
00220 sizeDacl +=
sizeof(ACCESS_ALLOWED_ACE) +
RtlLengthSid(
SeLocalSystemSid) -
sizeof(ULONG);
00221
00222
#if ALLOW_WORLD_READ_OF_ENUM
00223
sizeDacl +=
sizeof(ACCESS_ALLOWED_ACE) +
RtlLengthSid(
SeWorldSid) -
sizeof(ULONG);
00224
#endif
00225
00226
00227
00228
00229 newDacl =
ExAllocatePool(
PagedPool, sizeDacl);
00230
00231
if (newDacl !=
NULL) {
00232
00233 status =
RtlCreateAcl(newDacl, sizeDacl, ACL_REVISION);
00234
00235
ASSERT(
NT_SUCCESS( status ) );
00236
00237
00238
00239
00240 status =
RtlAddAccessAllowedAceEx( newDacl,
00241 ACL_REVISION,
00242 CONTAINER_INHERIT_ACE,
00243 KEY_ALL_ACCESS,
00244
SeLocalSystemSid
00245 );
00246
ASSERT(
NT_SUCCESS( status ) );
00247
00248
#if ALLOW_WORLD_READ_OF_ENUM
00249
00250
00251
00252 status =
RtlAddAccessAllowedAceEx( newDacl,
00253 ACL_REVISION,
00254 CONTAINER_INHERIT_ACE,
00255 KEY_READ,
00256
SeWorldSid
00257 );
00258
ASSERT(
NT_SUCCESS( status ) );
00259
00260
#endif
00261
00262
00263
00264 status =
RtlSetDaclSecurityDescriptor( (PSECURITY_DESCRIPTOR) &newSD,
00265
TRUE,
00266 newDacl,
00267
FALSE
00268 );
00269
00270
ASSERT(
NT_SUCCESS( status ) );
00271
00272
00273
00274
00275 status =
RtlValidSecurityDescriptor(&newSD);
00276
00277
ASSERT(
NT_SUCCESS( status ) );
00278
00279 status = ZwSetSecurityObject( handle,
00280 DACL_SECURITY_INFORMATION,
00281 &newSD
00282 );
00283
if (!
NT_SUCCESS(status)) {
00284
00285 KdPrint((
"IopInitializePlugPlayServices: ZwSetSecurityObject on Enum key failed, status = %8.8X\n", status));
00286 }
00287
00288
ExFreePool(newDacl);
00289 }
else {
00290
00291 KdPrint((
"IopInitializePlugPlayServices: ExAllocatePool failed allocating DACL for Enum key\n"));
00292 }
00293 }
00294
00295 parentHandle = handle;
00296 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ROOTENUM);
00297 status =
IopCreateRegistryKeyEx( &handle,
00298 parentHandle,
00299 &unicodeName,
00300 KEY_ALL_ACCESS,
00301 REG_OPTION_NON_VOLATILE,
00302
NULL
00303 );
00304
NtClose(parentHandle);
00305
if (!
NT_SUCCESS(status)) {
00306
goto init_Exit0;
00307 }
00308
NtClose(handle);
00309
00310
00311
00312
00313
00314 status =
IopOpenRegistryKeyEx( &handle,
00315
NULL,
00316 &
CmRegistryMachineSystemCurrentControlSetEnumName,
00317 KEY_ALL_ACCESS
00318 );
00319
if (
NT_SUCCESS(status)) {
00320 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_ROOT_DEVNODE);
00321 status =
IopCreateRegistryKeyEx( &hTreeHandle,
00322 handle,
00323 &unicodeName,
00324 KEY_ALL_ACCESS,
00325 REG_OPTION_NON_VOLATILE,
00326
NULL
00327 );
00328
NtClose(handle);
00329
if (
NT_SUCCESS(status)) {
00330
NtClose(hTreeHandle);
00331 }
00332 }
00333
00334
00335
00336
00337
00338
00339 InitializeListHead(&
IopPendingEjects);
00340 InitializeListHead(&
IopPendingSurpriseRemovals);
00341 InitializeListHead(&
IopPnpEnumerationRequestList);
00342
ExInitializeResource(&
IopDeviceTreeLock);
00343
KeInitializeEvent(&
PiEventQueueEmpty, NotificationEvent,
TRUE );
00344
KeInitializeEvent(&
PiEnumerationLock, NotificationEvent,
TRUE );
00345
KeInitializeSpinLock(&
IopPnPSpinLock);
00346
00347
00348
00349
00350 InitializeListHead(&
IopDockDeviceListHead);
00351
ExInitializeFastMutex(&
IopDockDeviceListLock);
00352
IopDockDeviceCount = 0;
00353
00354
00355
00356
00357
IopWarmEjectPdo =
NULL;
00358
KeInitializeEvent(&
IopWarmEjectLock, SynchronizationEvent,
TRUE );
00359
00360
00361
00362
00363
00364
RtlInitUnicodeString(&unicodeName, PNPMGR_STR_PNP_DRIVER);
00365 status =
IoCreateDriver (&unicodeName,
IopPnPDriverEntry);
00366
if (
NT_SUCCESS(status)) {
00367
00368
00369
00370
00371
00372 status =
IoCreateDevice(
IoPnpDriverObject,
00373
sizeof(
IOPNP_DEVICE_EXTENSION),
00374
NULL,
00375 FILE_DEVICE_CONTROLLER,
00376 0,
00377
FALSE,
00378 &deviceObject );
00379
00380
if (
NT_SUCCESS(status)) {
00381 deviceObject->
Flags |=
DO_BUS_ENUMERATED_DEVICE;
00382
IopRootDeviceNode =
IopAllocateDeviceNode(deviceObject);
00383
00384
if (!
IopRootDeviceNode) {
00385
IoDeleteDevice(deviceObject);
00386
IoDeleteDriver(
IoPnpDriverObject);
00387 status = STATUS_INSUFFICIENT_RESOURCES;
00388 }
else {
00389
IopRootDeviceNode->
Flags |=
DNF_STARTED +
DNF_PROCESSED +
DNF_ENUMERATED +
00390
DNF_MADEUP +
DNF_NO_RESOURCE_REQUIRED +
00391
DNF_ADDED;
00392
00393
IopRootDeviceNode->
InstancePath.Buffer =
ExAllocatePool(
PagedPool,
00394
sizeof(REGSTR_VAL_ROOT_DEVNODE));
00395
00396
if (
IopRootDeviceNode->
InstancePath.Buffer !=
NULL) {
00397
IopRootDeviceNode->
InstancePath.MaximumLength =
sizeof(REGSTR_VAL_ROOT_DEVNODE);
00398
IopRootDeviceNode->
InstancePath.Length =
sizeof(REGSTR_VAL_ROOT_DEVNODE) -
sizeof(WCHAR);
00399
00400 RtlMoveMemory(
IopRootDeviceNode->
InstancePath.Buffer,
00401 REGSTR_VAL_ROOT_DEVNODE,
00402
sizeof(REGSTR_VAL_ROOT_DEVNODE));
00403 }
else {
00404
00405
00406
00407
00408
ASSERT(
FALSE);
00409 }
00410 }
00411 }
00412 }
00413
00414
if (!
NT_SUCCESS(status)) {
00415
goto init_Exit0;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 PiWstrToUnicodeString(&unicodeName, REGSTR_PATH_CONTROL_PNP);
00430 status =
IopCreateRegistryKeyEx( &handle,
00431 hCurrentControlSet,
00432 &unicodeName,
00433 KEY_ALL_ACCESS,
00434 REG_OPTION_NON_VOLATILE,
00435
NULL
00436 );
00437
if (!
NT_SUCCESS(status)) {
00438
goto init_Exit0;
00439 }
00440
00441
00442
00443
00444
00445
PnPDetectionEnabled =
PNP_DETECTION_ENABLED_DEFAULT;
00446
00447 status =
IopGetRegistryValue(handle,
00448 REGSTR_VALUE_DETECTION_ENABLED,
00449 &detectionInfo
00450 );
00451
00452
if (
NT_SUCCESS(status)) {
00453
00454
if (detectionInfo->Type == REG_DWORD && detectionInfo->DataLength ==
sizeof(ULONG)) {
00455
PnPDetectionEnabled = (BOOLEAN) *(
KEY_VALUE_DATA(detectionInfo));
00456 }
00457
00458
ExFreePool(detectionInfo);
00459 }
00460
00461
NtClose(handle);
00462
00463
00464
00465
00466
00467 status =
PpInitializeNotification();
00468
if (!
NT_SUCCESS(status)) {
00469
goto init_Exit0;
00470 }
00471
00472
IopInitializePlugPlayNotification();
00473
00474
00475
00476
00477
00478
IopBusTypeGuidList =
ExAllocatePool(
PagedPool,
sizeof(
BUS_TYPE_GUID_LIST));
00479
if (
IopBusTypeGuidList ==
NULL) {
00480 status = STATUS_INSUFFICIENT_RESOURCES;
00481
goto init_Exit0;
00482 }
00483
00484 RtlZeroMemory(
IopBusTypeGuidList,
sizeof(
BUS_TYPE_GUID_LIST));
00485
00486
ExInitializeFastMutex(&
IopBusTypeGuidList->
Lock);
00487
00488
00489
00490
00491
00492
IopRequestDeviceAction(
IopRootDeviceNode->
PhysicalDeviceObject,
ReenumerateRootDevices,
NULL,
NULL);
00493
00494 init_Exit0:
00495
00496
00497
00498
00499
00500
if(hCurrentControlSet) {
00501
NtClose(hCurrentControlSet);
00502 }
00503
00504
if (!
NT_SUCCESS(status)) {
00505
ExFreePool(
IopPnpScratchBuffer1);
00506
ExFreePool(
IopPnpScratchBuffer2);
00507 }
00508
00509 }
else if (Phase == 1) {
00510
00511 BOOLEAN legacySerialPortMappingOnly =
FALSE;
00512
00513
00514
00515
00516
00517 status =
IopOpenRegistryKeyEx( &hCurrentControlSet,
00518
NULL,
00519 &
CmRegistryMachineSystemCurrentControlSet,
00520 KEY_ALL_ACCESS
00521 );
00522
if (!
NT_SUCCESS(status)) {
00523 hCurrentControlSet =
NULL;
00524
goto init_Exit1;
00525 }
00526
00527
00528
00529
00530
00531 PiWstrToUnicodeString(&unicodeName, REGSTR_PATH_CONTROL_PNP);
00532 status =
IopCreateRegistryKeyEx( &handle,
00533 hCurrentControlSet,
00534 &unicodeName,
00535 KEY_ALL_ACCESS,
00536 REG_OPTION_NON_VOLATILE,
00537
NULL
00538 );
00539
if (!
NT_SUCCESS(status)) {
00540
goto init_Exit1;
00541 }
00542
00543
00544
00545
00546
00547
00548
00549 status =
IopGetRegistryValue(handle,
00550 REGSTR_VALUE_DISABLE_FIRMWARE_MAPPER,
00551 &detectionInfo
00552 );
00553
00554
if (
NT_SUCCESS(status)) {
00555
00556
if (detectionInfo->Type == REG_DWORD && detectionInfo->DataLength ==
sizeof(ULONG)) {
00557 legacySerialPortMappingOnly = (BOOLEAN) *(
KEY_VALUE_DATA(detectionInfo));
00558 }
00559
00560
ExFreePool(detectionInfo);
00561
00562 }
00563
NtClose(handle);
00564
00565
00566
00567
00568
00569
MapperProcessFirmwareTree(legacySerialPortMappingOnly);
00570
00571
00572
00573
00574
00575
MapperConstructRootEnumTree(legacySerialPortMappingOnly);
00576
00577
#if i386
00578
if (!legacySerialPortMappingOnly) {
00579
00580
00581
00582
00583
extern NTSTATUS PnPBiosMapper(
VOID);
00584
00585 status =
PnPBiosMapper();
00586
00587
00588
00589
00590
00591
if (
NT_SUCCESS (status)) {
00592
MapperPhantomizeDetectedComPorts();
00593 }
00594 }
00595
EisaBuildEisaDeviceNode();
00596
#endif
00597
00598
00599
00600
00601
00602
MapperFreeList();
00603
00604
00605
00606
00607
00608
00609
IopRequestDeviceAction(
IopRootDeviceNode->
PhysicalDeviceObject,
ReenumerateRootDevices,
NULL,
NULL);
00610
00611 init_Exit1:
00612
00613
00614
00615
00616
00617
if(hCurrentControlSet) {
00618
NtClose(hCurrentControlSet);
00619 }
00620
00621
00622
00623
00624
00625
ExFreePool(
IopPnpScratchBuffer1);
00626
ExFreePool(
IopPnpScratchBuffer2);
00627 status = STATUS_SUCCESS;
00628 }
else {
00629 status = STATUS_INVALID_PARAMETER_1;
00630 }
00631
00632
return status;
00633 }
00634
00635
NTSTATUS
00636 IopPnPDriverEntry(
00637 IN
PDRIVER_OBJECT DriverObject,
00638 IN PUNICODE_STRING RegistryPath
00639 )
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 {
00661
00662
00663
00664
00665
IoPnpDriverObject = DriverObject;
00666
00667
00668
00669
00670
00671 DriverObject->
DriverExtension->
AddDevice = (
PDRIVER_ADD_DEVICE)
IopPnPAddDevice;
00672 DriverObject->MajorFunction[
IRP_MJ_PNP ] =
IopPnPDispatch;
00673 DriverObject->MajorFunction[
IRP_MJ_POWER ] =
IopPowerDispatch;
00674
00675
return STATUS_SUCCESS;
00676
00677 }
00678
00679
NTSTATUS
00680 IopGetRootDevices (
00681
PDEVICE_RELATIONS *DeviceRelations
00682 )
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 {
00702
NTSTATUS status;
00703 HANDLE baseHandle;
00704 UNICODE_STRING workName, tmpName;
00705 PVOID buffer;
00706
ROOT_ENUMERATOR_CONTEXT context;
00707 ULONG i;
00708
PDEVICE_RELATIONS deviceRelations;
00709
00710
PAGED_CODE();
00711
00712 *DeviceRelations =
NULL;
00713 buffer =
ExAllocatePool(
PagedPool,
PNP_LARGE_SCRATCH_BUFFER_SIZE);
00714
if (!buffer) {
00715
return STATUS_INSUFFICIENT_RESOURCES;
00716 }
00717
00718
00719
00720
00721
00722
00723 context.
DeviceList = (
PDEVICE_OBJECT *)
ExAllocatePool(
PagedPool,
PNP_SCRATCH_BUFFER_SIZE * 2);
00724
if (context.
DeviceList) {
00725 context.
MaxDeviceCount = (
PNP_SCRATCH_BUFFER_SIZE * 2) /
sizeof(
PDEVICE_OBJECT);
00726 context.
DeviceCount = 0;
00727 }
else {
00728
ExFreePool(buffer);
00729
return STATUS_INSUFFICIENT_RESOURCES;
00730 }
00731
00732
KeEnterCriticalRegion();
00733
ExAcquireResourceExclusive(&
PpRegistryDeviceResource,
TRUE);
00734
00735
00736
00737
00738
00739
00740 status =
IopCreateRegistryKeyEx( &baseHandle,
00741
NULL,
00742 &
CmRegistryMachineSystemCurrentControlSetEnumRootName,
00743 KEY_READ,
00744 REG_OPTION_NON_VOLATILE,
00745
NULL
00746 );
00747
00748
if (
NT_SUCCESS(status)) {
00749
00750 workName.Buffer = (PWSTR)buffer;
00751 RtlFillMemory(buffer,
PNP_LARGE_SCRATCH_BUFFER_SIZE, 0);
00752 workName.MaximumLength =
PNP_LARGE_SCRATCH_BUFFER_SIZE;
00753 workName.Length = 0;
00754
00755
00756
00757
00758
00759 PiWstrToUnicodeString(&tmpName, REGSTR_KEY_ROOTENUM);
00760
RtlAppendStringToString((PSTRING)&workName, (PSTRING)&tmpName);
00761
00762
00763
00764
00765
00766 context.
Status = STATUS_SUCCESS;
00767 context.
KeyName = &workName;
00768
00769 status =
IopApplyFunctionToSubKeys(baseHandle,
00770
NULL,
00771 KEY_ALL_ACCESS,
00772
FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS,
00773
IopInitializeDeviceKey,
00774 &context
00775 );
00776 ZwClose(baseHandle);
00777
00778
00779
00780
00781
00782
00783 status = context.
Status;
00784
if (
NT_SUCCESS(status) && context.
DeviceCount != 0) {
00785 deviceRelations = (
PDEVICE_RELATIONS)
ExAllocatePool(
00786
PagedPool,
00787
sizeof (
DEVICE_RELATIONS) +
sizeof(
PDEVICE_OBJECT) * context.
DeviceCount
00788 );
00789
if (deviceRelations ==
NULL) {
00790 status = STATUS_INSUFFICIENT_RESOURCES;
00791 }
else {
00792 deviceRelations->
Count = context.
DeviceCount;
00793 RtlMoveMemory(deviceRelations->
Objects,
00794 context.
DeviceList,
00795 sizeof (
PDEVICE_OBJECT) * context.
DeviceCount);
00796 *DeviceRelations = deviceRelations;
00797 }
00798 }
00799
if (!
NT_SUCCESS(status)) {
00800
00801
00802
00803
00804
00805
00806
for (i = 0; i < context.
DeviceCount; i++) {
00807
ObDereferenceObject(context.
DeviceList[i]);
00808 }
00809 }
00810 }
00811
ExReleaseResource(&
PpRegistryDeviceResource);
00812
KeLeaveCriticalRegion();
00813
ExFreePool(buffer);
00814
ExFreePool(context.
DeviceList);
00815
return status;
00816 }
00817
00818 BOOLEAN
00819 IopInitializeDeviceKey(
00820 IN HANDLE KeyHandle,
00821 IN PUNICODE_STRING KeyName,
00822 IN OUT PVOID Context
00823 )
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 {
00847
USHORT length;
00848 PWSTR p;
00849 PUNICODE_STRING unicodeName = ((
PROOT_ENUMERATOR_CONTEXT)Context)->KeyName;
00850
00851 length = unicodeName->Length;
00852
00853 p = unicodeName->Buffer;
00854
if ( unicodeName->Length /
sizeof(WCHAR) != 0) {
00855 p += unicodeName->Length /
sizeof(WCHAR);
00856 *p = OBJ_NAME_PATH_SEPARATOR;
00857 unicodeName->Length +=
sizeof (WCHAR);
00858 }
00859
00860
RtlAppendStringToString((PSTRING)unicodeName, (PSTRING)
KeyName);
00861
00862
00863
00864
00865
00866
IopApplyFunctionToSubKeys(KeyHandle,
00867
NULL,
00868 KEY_ALL_ACCESS,
00869
FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS,
00870
IopInitializeDeviceInstanceKey,
00871 Context
00872 );
00873 unicodeName->Length = length;
00874
00875
return NT_SUCCESS(((
PROOT_ENUMERATOR_CONTEXT)Context)->
Status);
00876 }
00877
00878 BOOLEAN
00879 IopInitializeDeviceInstanceKey(
00880 IN HANDLE KeyHandle,
00881 IN PUNICODE_STRING KeyName,
00882 IN OUT PVOID Context
00883 )
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 {
00907 UNICODE_STRING unicodeName, serviceName;
00908 PKEY_VALUE_FULL_INFORMATION serviceKeyValueInfo;
00909 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
00910
NTSTATUS status;
00911 BOOLEAN isDuplicate =
FALSE;
00912 BOOLEAN configuredBySetup;
00913 ULONG deviceFlags, instance, tmpValue1;
00914 ULONG legacy;
00915
USHORT savedLength;
00916 PUNICODE_STRING pUnicode;
00917 HANDLE handle;
00918
PDEVICE_OBJECT deviceObject;
00919
PDEVICE_NODE deviceNode =
NULL;
00920
PROOT_ENUMERATOR_CONTEXT enumContext = (
PROOT_ENUMERATOR_CONTEXT)Context;
00921 WCHAR buffer[30];
00922 UNICODE_STRING deviceName;
00923
USHORT length;
00924 LARGE_INTEGER tickCount;
00925
00926
00927
00928
00929
00930
00931
00932 status =
IopGetRegistryValue(KeyHandle,
00933 REGSTR_VAL_PHANTOM,
00934 &keyValueInformation);
00935
00936
if (
NT_SUCCESS(status)) {
00937
if ((keyValueInformation->Type == REG_DWORD) &&
00938 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
00939 tmpValue1 = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
00940 }
else {
00941 tmpValue1 = 0;
00942 }
00943
00944
ExFreePool(keyValueInformation);
00945
00946
if (tmpValue1) {
00947
return TRUE;
00948 }
00949 }
00950
00951
00952
00953
00954
00955
00956
if (enumContext->
DeviceCount == enumContext->
MaxDeviceCount) {
00957
00958
PDEVICE_OBJECT *tmpDeviceObjectList;
00959 ULONG tmpDeviceObjectListSize;
00960
00961
00962
00963
00964
00965 tmpDeviceObjectListSize = (enumContext->
MaxDeviceCount *
sizeof(
PDEVICE_OBJECT))
00966 + (
PNP_SCRATCH_BUFFER_SIZE * 2);
00967
00968 tmpDeviceObjectList =
ExAllocatePool(
PagedPool, tmpDeviceObjectListSize);
00969
00970
if (tmpDeviceObjectList) {
00971
00972 RtlCopyMemory( tmpDeviceObjectList,
00973 enumContext->
DeviceList,
00974 enumContext->
DeviceCount *
sizeof(
PDEVICE_OBJECT)
00975 );
00976
ExFreePool(enumContext->
DeviceList);
00977 enumContext->
DeviceList = tmpDeviceObjectList;
00978 enumContext->
MaxDeviceCount = tmpDeviceObjectListSize /
sizeof(
PDEVICE_OBJECT);
00979
00980 }
else {
00981
00982
00983
00984
00985
00986
00987 enumContext->
Status = STATUS_INSUFFICIENT_RESOURCES;
00988
00989
return FALSE;
00990 }
00991 }
00992
00993
00994
00995
00996
00997
00998 deviceObject =
IopDeviceObjectFromDeviceInstance(KeyHandle,
NULL);
00999
01000
if (deviceObject !=
NULL) {
01001
01002 enumContext->
DeviceList[enumContext->
DeviceCount] = deviceObject;
01003 enumContext->
DeviceCount++;
01004
return TRUE;
01005 }
01006
01007
01008
01009
01010
01011
01012
01013
if (!
IopIsFirmwareMapperDevicePresent(KeyHandle)) {
01014
return TRUE;
01015 }
01016
01017
01018
01019
01020
01021
01022
01023 status =
IopGetRegistryValue( KeyHandle,
01024 REGSTR_VALUE_DUPLICATEOF,
01025 &keyValueInformation
01026 );
01027
if (
NT_SUCCESS(status)) {
01028
if (keyValueInformation->Type == REG_SZ &&
01029 keyValueInformation->DataLength > 0) {
01030 isDuplicate =
TRUE;
01031 }
01032
01033
ExFreePool(keyValueInformation);
01034 }
01035
01036
01037
01038
01039
01040 serviceKeyValueInfo =
NULL;
01041
01042
RtlInitUnicodeString(&serviceName,
NULL);
01043
01044 status =
IopGetRegistryValue ( KeyHandle,
01045 REGSTR_VALUE_SERVICE,
01046 &serviceKeyValueInfo
01047 );
01048
if (
NT_SUCCESS(status)) {
01049
01050
01051
01052
01053
01054
01055
if (serviceKeyValueInfo->Type == REG_SZ &&
01056 serviceKeyValueInfo->DataLength != 0) {
01057
01058
01059
01060
01061
01062
IopRegistryDataToUnicodeString(
01063 &serviceName,
01064 (PWSTR)
KEY_VALUE_DATA(serviceKeyValueInfo),
01065 serviceKeyValueInfo->DataLength
01066 );
01067 }
01068
01069
01070
01071
01072
01073 }
01074
01075
01076
01077
01078
01079
01080
01081
01082 pUnicode = ((
PROOT_ENUMERATOR_CONTEXT)Context)->KeyName;
01083 savedLength = pUnicode->Length;
01084
if (pUnicode->Buffer[pUnicode->Length /
sizeof(WCHAR) - 1] != OBJ_NAME_PATH_SEPARATOR) {
01085 pUnicode->Buffer[pUnicode->Length /
sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
01086 pUnicode->Length += 2;
01087 }
01088
01089
RtlAppendStringToString((PSTRING)pUnicode, (PSTRING)
KeyName);
01090
01091
01092
01093
01094
01095
01096 status =
IopGetDeviceInstanceCsConfigFlags( pUnicode, &deviceFlags );
01097
01098
if (
NT_SUCCESS(status) && (deviceFlags & CSCONFIGFLAG_DO_NOT_CREATE)) {
01099
ExFreePool(serviceKeyValueInfo);
01100
return TRUE;
01101 }
01102
01103
01104
01105
01106
01107
01108 legacy = 0;
01109 status =
IopGetRegistryValue( KeyHandle,
01110 REGSTR_VALUE_LEGACY,
01111 &keyValueInformation
01112 );
01113
if (
NT_SUCCESS(status)) {
01114
01115
01116
01117
01118
01119
if (keyValueInformation->Type == REG_DWORD) {
01120
if (keyValueInformation->DataLength >=
sizeof(ULONG)) {
01121 legacy = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01122 }
01123 }
01124
ExFreePool(keyValueInformation);
01125 }
01126
01127
if (legacy) {
01128 BOOLEAN doCreate =
FALSE;
01129
01130
01131
01132
01133
01134
01135
01136
if (serviceName.Length) {
01137 status =
IopGetServiceType(&serviceName, &tmpValue1);
01138
if (
NT_SUCCESS(status) && tmpValue1 == SERVICE_KERNEL_DRIVER) {
01139 doCreate =
TRUE;
01140 }
01141 }
01142
01143
if (!doCreate) {
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
PpDeviceRegistration( pUnicode,
TRUE,
NULL );
01156
01157
01158
01159
01160
01161
if (serviceKeyValueInfo) {
01162
ExFreePool(serviceKeyValueInfo);
01163 }
01164
01165 pUnicode->Length = savedLength;
01166
01167
return TRUE;
01168 }
01169 }
01170
01171
if (serviceKeyValueInfo) {
01172
ExFreePool(serviceKeyValueInfo);
01173 }
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
KeQueryTickCount(&tickCount);
01184
01185 length = (
USHORT) _snwprintf(buffer,
sizeof(buffer) /
sizeof(WCHAR),
L"\\Device\\%04u%x",
01186
IopNumberDeviceNodes, tickCount.LowPart);
01187 deviceName.MaximumLength =
sizeof(buffer);
01188 deviceName.Length = length *
sizeof(WCHAR);
01189 deviceName.Buffer = buffer;
01190
01191
01192
01193
01194
01195 status =
IoCreateDevice(
IoPnpDriverObject,
01196
sizeof(
IOPNP_DEVICE_EXTENSION),
01197 &deviceName,
01198 FILE_DEVICE_CONTROLLER,
01199 0,
01200
FALSE,
01201 &deviceObject );
01202
01203
if (
NT_SUCCESS(status)) {
01204
01205 deviceObject->
Flags |=
DO_BUS_ENUMERATED_DEVICE;
01206 deviceObject->
DeviceObjectExtension->
ExtensionFlags |=
DOE_START_PENDING;
01207
01208 deviceNode =
IopAllocateDeviceNode(deviceObject);
01209
if (deviceNode) {
01210 PCM_RESOURCE_LIST cmResource;
01211
01212 deviceNode->
Flags =
DNF_MADEUP +
DNF_PROCESSED +
DNF_ENUMERATED;
01213
01214
IopInsertTreeDeviceNode(
IopRootDeviceNode, deviceNode);
01215
01216
01217
01218
01219
01220
01221 status =
IopConcatenateUnicodeStrings(
01222 &deviceNode->
InstancePath,
01223 pUnicode,
01224
NULL
01225 );
01226
if (legacy) {
01227 deviceNode->
Flags |=
DNF_LEGACY_DRIVER +
DNF_ADDED +
DNF_STARTED +
01228
DNF_NO_RESOURCE_REQUIRED;
01229 }
else {
01230
01231
01232
01233
01234
01235 deviceFlags = 0;
01236 status =
IopGetRegistryValue(KeyHandle,
01237 REGSTR_VALUE_CONFIG_FLAGS,
01238 &keyValueInformation);
01239
if (
NT_SUCCESS(status)) {
01240
if ((keyValueInformation->Type == REG_DWORD) &&
01241 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
01242 deviceFlags = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01243 }
01244
ExFreePool(keyValueInformation);
01245
if (deviceFlags & CONFIGFLAG_REINSTALL) {
01246
IopSetDevNodeProblem(deviceNode, CM_PROB_REINSTALL);
01247 }
else if (deviceFlags & CONFIGFLAG_PARTIAL_LOG_CONF) {
01248
IopSetDevNodeProblem(deviceNode, CM_PROB_PARTIAL_LOG_CONF);
01249 }
else if (deviceFlags & CONFIGFLAG_FAILEDINSTALL) {
01250
IopSetDevNodeProblem(deviceNode, CM_PROB_FAILED_INSTALL);
01251 }
01252
01253 }
else if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND) {
01254
IopSetDevNodeProblem(deviceNode, CM_PROB_NOT_CONFIGURED);
01255 }
01256 }
01257
01258
if (isDuplicate) {
01259 deviceNode->
Flags |=
DNF_DUPLICATE;
01260 }
01261
01262
01263
01264
01265
01266 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_NO_RESOURCE_AT_INIT);
01267 status =
IopGetRegistryValue( KeyHandle,
01268 unicodeName.Buffer,
01269 &keyValueInformation
01270 );
01271
01272
if (
NT_SUCCESS(status)) {
01273
if (keyValueInformation->Type == REG_DWORD) {
01274
if (keyValueInformation->DataLength >=
sizeof(ULONG)) {
01275 tmpValue1 = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01276
01277
if (tmpValue1 != 0) {
01278 deviceNode->
Flags |=
DNF_NO_RESOURCE_REQUIRED;
01279 }
01280 }
01281 }
01282
ExFreePool(keyValueInformation);
01283 }
01284
01285
01286
01287
01288
01289
IopDeviceNodeCapabilitiesToRegistry(deviceNode);
01290
01291
if (
IopDeviceNodeFlagsToCapabilities(deviceNode)->HardwareDisabled &&
01292 !
IopIsDevNodeProblem(deviceNode,CM_PROB_NOT_CONFIGURED)) {
01293
01294
01295
01296
01297
IopClearDevNodeProblem(deviceNode);
01298
IopSetDevNodeProblem(deviceNode, CM_PROB_HARDWARE_DISABLED);
01299
01300
01301
01302
01303
01304
01305 }
01306
01307
01308
01309
01310
01311
if (
IopDoesDevNodeHaveProblem(deviceNode) &&
01312 !
IopDeviceNodeFlagsToCapabilities(deviceNode)->HardwareDisabled) {
01313
IopProcessCriticalDevice(deviceNode);
01314 }
01315
01316
01317
01318
01319
01320
ASSERT(!
IopDoesDevNodeHaveProblem(deviceNode) ||
01321
IopIsDevNodeProblem(deviceNode, CM_PROB_NOT_CONFIGURED) ||
01322
IopIsDevNodeProblem(deviceNode, CM_PROB_REINSTALL) ||
01323
IopIsDevNodeProblem(deviceNode, CM_PROB_FAILED_INSTALL) ||
01324
IopIsDevNodeProblem(deviceNode, CM_PROB_HARDWARE_DISABLED) ||
01325
IopIsDevNodeProblem(deviceNode, CM_PROB_PARTIAL_LOG_CONF));
01326
01327
if (!
IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED) &&
01328 !
IopIsDevNodeProblem(deviceNode, CM_PROB_HARDWARE_DISABLED) &&
01329 !
IopIsDeviceInstanceEnabled(KeyHandle, &deviceNode->InstancePath,
TRUE)) {
01330
01331
01332
01333
01334
01335
01336
01337
01338
IopSetDevNodeProblem( deviceNode, CM_PROB_DISABLED );
01339 }
01340
01341 status =
IopNotifySetupDeviceArrival( deviceNode->PhysicalDeviceObject,
01342 KeyHandle,
01343
TRUE);
01344
01345 configuredBySetup =
NT_SUCCESS(status);
01346
01347 status =
PpDeviceRegistration( &deviceNode->InstancePath,
01348
TRUE,
01349 &deviceNode->ServiceName
01350 );
01351
01352
if (
NT_SUCCESS(status) && configuredBySetup &&
01353
IopIsDevNodeProblem(deviceNode, CM_PROB_NOT_CONFIGURED)) {
01354
01355
IopClearDevNodeProblem(deviceNode);
01356 }
01357
01358
01359
01360
01361
01362 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
01363 status =
IopCreateRegistryKeyEx( &handle,
01364 KeyHandle,
01365 &unicodeName,
01366 KEY_ALL_ACCESS,
01367 REG_OPTION_VOLATILE,
01368
NULL
01369 );
01370
if (
NT_SUCCESS(status)) {
01371
01372 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DEVICE_REFERENCE);
01373 ZwSetValueKey( handle,
01374 &unicodeName,
01375
TITLE_INDEX_VALUE,
01376 REG_DWORD,
01377 (PULONG_PTR)&deviceObject,
01378
sizeof(ULONG_PTR)
01379 );
01380 ZwClose(handle);
01381 }
01382
01383
01384
01385
01386
01387
ObReferenceObject(deviceObject);
01388
01389
01390
01391
01392
01393 cmResource =
NULL;
01394 status =
IopGetDeviceResourcesFromRegistry (
01395 deviceObject,
01396
QUERY_RESOURCE_LIST,
01397
REGISTRY_BOOT_CONFIG,
01398 &cmResource,
01399 &tmpValue1
01400 );
01401
01402
if (
NT_SUCCESS(status) && cmResource) {
01403
01404
01405
01406
01407
01408
01409 status = (*IopReserveResourcesRoutine)(
01410
ArbiterRequestPnpEnumerated,
01411 deviceNode->PhysicalDeviceObject,
01412 cmResource);
01413
if (
NT_SUCCESS(status)) {
01414 deviceNode->Flags |=
DNF_HAS_BOOT_CONFIG;
01415 }
01416
ExFreePool(cmResource);
01417 }
01418
01419 status = STATUS_SUCCESS;
01420
01421
01422
01423
01424
01425
ObReferenceObject(deviceObject);
01426
01427 }
else {
01428
IoDeleteDevice(deviceObject);
01429 deviceObject =
NULL;
01430 status = STATUS_INSUFFICIENT_RESOURCES;
01431 }
01432 }
01433
01434 pUnicode->Length = savedLength;
01435
01436
01437
01438
01439
01440
if (
NT_SUCCESS(status)) {
01441
ASSERT(deviceObject !=
NULL);
01442
01443 enumContext->
DeviceList[enumContext->
DeviceCount] = deviceObject;
01444 enumContext->
DeviceCount++;
01445
01446
return TRUE;
01447 }
else {
01448 enumContext->
Status = status;
01449
return FALSE;
01450 }
01451 }
01452
01453
NTSTATUS
01454 IopGetServiceType(
01455 IN PUNICODE_STRING KeyName,
01456 IN PULONG ServiceType
01457 )
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478 {
01479
NTSTATUS status;
01480 HANDLE handle;
01481 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
01482
01483
01484
PAGED_CODE();
01485
01486 *ServiceType = -1;
01487 status =
IopOpenServiceEnumKeys (
01488
KeyName,
01489 KEY_READ,
01490 &handle,
01491
NULL,
01492
FALSE
01493 );
01494
if (
NT_SUCCESS(status)) {
01495 status =
IopGetRegistryValue(handle,
L"Type", &keyValueInformation);
01496
if (
NT_SUCCESS(status)) {
01497
if (keyValueInformation->Type == REG_DWORD) {
01498
if (keyValueInformation->DataLength >=
sizeof(ULONG)) {
01499 *ServiceType = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01500 }
01501 }
01502
ExFreePool(keyValueInformation);
01503 }
01504 ZwClose(handle);
01505 }
01506
return status;
01507 }
01508
01509 INTERFACE_TYPE
01510 IopDetermineDefaultInterfaceType (
01511 VOID
01512 )
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532 {
01533
NTSTATUS status;
01534 PVOID p;
01535
PHAL_BUS_INFORMATION pBusInfo;
01536 ULONG length, i;
01537 INTERFACE_TYPE interfaceType = Isa;
01538
01539 pBusInfo =
IopPnpScratchBuffer1;
01540 length =
PNP_LARGE_SCRATCH_BUFFER_SIZE;
01541 status =
HalQuerySystemInformation (
01542
HalInstalledBusInformation,
01543 length,
01544 pBusInfo,
01545 &length
01546 );
01547
01548
if (!
NT_SUCCESS(status)) {
01549
01550
return interfaceType;
01551 }
01552
01553
01554
01555
01556
01557
01558 p = pBusInfo;
01559
for (i = 0; i < length /
sizeof(
HAL_BUS_INFORMATION); i++, pBusInfo++) {
01560
if (pBusInfo->BusType == Isa || pBusInfo->BusType == Eisa) {
01561 interfaceType = Isa;
01562
break;
01563 }
else if (pBusInfo->BusType == MicroChannel) {
01564 interfaceType = MicroChannel;
01565 }
01566 }
01567
01568
return interfaceType;
01569 }
01570
01571 BOOLEAN
01572 IopIsFirmwareMapperDevicePresent (
01573 IN HANDLE KeyHandle
01574 )
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 {
01594
NTSTATUS status;
01595 HANDLE handle;
01596 UNICODE_STRING unicodeName;
01597 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
01598 ULONG tmp = 0;
01599
01600
PAGED_CODE();
01601
01602
01603
01604
01605
01606 status =
IopGetRegistryValue (KeyHandle,
01607 REGSTR_VAL_FIRMWAREIDENTIFIED,
01608 &keyValueInformation);
01609
if (
NT_SUCCESS(status)) {
01610
if ((keyValueInformation->Type == REG_DWORD) &&
01611 (keyValueInformation->DataLength ==
sizeof(ULONG))) {
01612
01613 tmp = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01614 }
01615
ExFreePool(keyValueInformation);
01616 }
01617
if (tmp == 0) {
01618
return TRUE;
01619 }
01620
01621
01622
01623
01624
01625 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
01626 status =
IopOpenRegistryKeyEx( &handle,
01627 KeyHandle,
01628 &unicodeName,
01629 KEY_READ
01630 );
01631
if (!
NT_SUCCESS(status)) {
01632
return FALSE;
01633 }
01634
01635 status =
IopGetRegistryValue (handle,
01636 REGSTR_VAL_FIRMWAREMEMBER,
01637 &keyValueInformation);
01638 ZwClose(handle);
01639 tmp = 0;
01640
01641
if (
NT_SUCCESS(status)) {
01642
if ((keyValueInformation->Type == REG_DWORD) &&
01643 (keyValueInformation->DataLength ==
sizeof(ULONG))) {
01644
01645 tmp = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01646 }
01647
ExFreePool(keyValueInformation);
01648 }
01649
if (!tmp) {
01650
return FALSE;
01651 }
else {
01652
return TRUE;
01653 }
01654 }
01655