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
#include "iop.h"
00029
#pragma hdrstop
00030
00031
#ifdef POOL_TAGGING
00032
#undef ExAllocatePool
00033
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'uspP')
00034
#endif
00035
00036
00037
00038
00039
00040
VOID
00041
IopDisableDevice(
00042 IN
PDEVICE_NODE DeviceNode,
00043 IN HANDLE Handle
00044 );
00045
00046
#ifdef ALLOC_PRAGMA
00047
#pragma alloc_text(PAGE, IopCreateMadeupNode)
00048
#pragma alloc_text(PAGE, IopRemoveStringFromValueKey)
00049
#pragma alloc_text(PAGE, IopAppendStringToValueKey)
00050
#pragma alloc_text(PAGE, IopConcatenateUnicodeStrings)
00051
#pragma alloc_text(PAGE, IopPrepareDriverLoading)
00052
#pragma alloc_text(PAGE, IopServiceInstanceToDeviceInstance)
00053
#pragma alloc_text(PAGE, IopOpenRegistryKeyPersist)
00054
#pragma alloc_text(PAGE, IopOpenServiceEnumKeys)
00055
#pragma alloc_text(PAGE, IopOpenCurrentHwProfileDeviceInstanceKey)
00056
#pragma alloc_text(PAGE, IopGetDeviceInstanceCsConfigFlags)
00057
#pragma alloc_text(PAGE, IopSetDeviceInstanceCsConfigFlags)
00058
#pragma alloc_text(PAGE, IopApplyFunctionToSubKeys)
00059
#pragma alloc_text(PAGE, IopRegMultiSzToUnicodeStrings)
00060
#pragma alloc_text(PAGE, IopApplyFunctionToServiceInstances)
00061
#pragma alloc_text(PAGE, IopIsDuplicatedDevices)
00062
#pragma alloc_text(PAGE, IopMarkDuplicateDevice)
00063
#pragma alloc_text(PAGE, IopFreeUnicodeStringList)
00064
#pragma alloc_text(PAGE, IopDriverLoadingFailed)
00065
#pragma alloc_text(PAGE, IopIsAnyDeviceInstanceEnabled)
00066
#pragma alloc_text(PAGE, IopIsDeviceInstanceEnabled)
00067
#pragma alloc_text(PAGE, IopDetermineResourceListSize)
00068
#pragma alloc_text(PAGE, IopReferenceDriverObjectByName)
00069
#pragma alloc_text(PAGE, IopDeviceObjectFromDeviceInstance)
00070
#pragma alloc_text(PAGE, IopDeviceObjectToDeviceInstance)
00071
#pragma alloc_text(PAGE, IopCleanupDeviceRegistryValues)
00072
#pragma alloc_text(PAGE, IopGetDeviceResourcesFromRegistry)
00073
#pragma alloc_text(PAGE, IopCmResourcesToIoResources)
00074
#pragma alloc_text(PAGE, IopReadDeviceConfiguration)
00075
#pragma alloc_text(PAGE, IopGetGroupOrderIndex)
00076
#pragma alloc_text(PAGE, IopDeleteLegacyKey)
00077
#pragma alloc_text(PAGE, IopIsLegacyDriver)
00078
#pragma alloc_text(PAGE, IopFilterResourceRequirementsList)
00079
#pragma alloc_text(PAGE, IopMergeFilteredResourceRequirementsList)
00080
#pragma alloc_text(PAGE, IopDisableDevice)
00081
#pragma alloc_text(PAGE, IopMergeCmResourceLists)
00082
#pragma alloc_text(PAGE, IopDeviceCapabilitiesToRegistry)
00083
#pragma alloc_text(PAGE, IopRestartDeviceNode)
00084
#endif
00085
00086
NTSTATUS
00087 IopCreateMadeupNode(
00088 IN PUNICODE_STRING ServiceKeyName,
00089 OUT PHANDLE ReturnedHandle,
00090 OUT PUNICODE_STRING KeyName,
00091 OUT PULONG InstanceNumber,
00092 IN BOOLEAN ResourceOwned
00093 )
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 {
00131 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
00132 UNICODE_STRING tmpKeyName, unicodeInstanceName, unicodeString;
00133 UNICODE_STRING rootKeyName, unicodeValueName, unicodeKeyName;
00134 HANDLE handle, enumRootHandle, hTreeHandle;
00135 ULONG instance;
00136 UCHAR unicodeBuffer[20];
00137 ULONG tmpValue, disposition = 0;
00138
NTSTATUS status;
00139 PWSTR p;
00140 BOOLEAN releaseResource =
FALSE;
00141
00142
if (!ResourceOwned) {
00143
KeEnterCriticalRegion();
00144
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
00145 releaseResource =
TRUE;
00146 }
00147
00148
00149
00150
00151
00152 status =
IopOpenRegistryKey(&enumRootHandle,
00153
NULL,
00154 &
CmRegistryMachineSystemCurrentControlSetEnumRootName,
00155 KEY_ALL_ACCESS,
00156
FALSE
00157 );
00158
if (!
NT_SUCCESS(status)) {
00159
goto local_exit0;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 PiWstrToUnicodeString(&tmpKeyName, REGSTR_KEY_MADEUP);
00169
IopConcatenateUnicodeStrings(&unicodeKeyName, &tmpKeyName, ServiceKeyName);
00170
RtlUpcaseUnicodeString(&unicodeKeyName, &unicodeKeyName,
FALSE);
00171 status =
IopOpenRegistryKeyPersist(&handle,
00172 enumRootHandle,
00173 &unicodeKeyName,
00174 KEY_ALL_ACCESS,
00175
TRUE,
00176
NULL
00177 );
00178 ZwClose(enumRootHandle);
00179
if (!
NT_SUCCESS(status)) {
00180
RtlFreeUnicodeString(&unicodeKeyName);
00181
goto local_exit0;
00182 }
00183
00184 instance = 1;
00185
00186 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE);
00187 status = ZwSetValueKey(
00188 handle,
00189 &unicodeValueName,
00190
TITLE_INDEX_VALUE,
00191 REG_DWORD,
00192 &instance,
00193
sizeof(instance)
00194 );
00195
00196 instance--;
00197 *InstanceNumber = instance;
00198 PiUlongToInstanceKeyUnicodeString(&unicodeInstanceName,
00199 unicodeBuffer +
sizeof(WCHAR),
00200 20 -
sizeof(WCHAR),
00201 instance
00202 );
00203 status =
IopOpenRegistryKeyPersist(
ReturnedHandle,
00204 handle,
00205 &unicodeInstanceName,
00206 KEY_ALL_ACCESS,
00207
TRUE,
00208 &disposition
00209 );
00210 ZwClose(handle);
00211
if (!
NT_SUCCESS(status)) {
00212
RtlFreeUnicodeString(&unicodeKeyName);
00213
goto local_exit0;
00214 }
00215
00216
00217
00218
00219
00220 *(PWSTR)unicodeBuffer = OBJ_NAME_PATH_SEPARATOR;
00221 unicodeInstanceName.Buffer = (PWSTR)unicodeBuffer;
00222 unicodeInstanceName.Length +=
sizeof(WCHAR);
00223 unicodeInstanceName.MaximumLength +=
sizeof(WCHAR);
00224 PiWstrToUnicodeString(&rootKeyName, REGSTR_KEY_ROOTENUM);
00225
RtlInitUnicodeString(&tmpKeyName,
L"\\");
00226
IopConcatenateUnicodeStrings(&unicodeString, &tmpKeyName, &unicodeKeyName);
00227
RtlFreeUnicodeString(&unicodeKeyName);
00228
IopConcatenateUnicodeStrings(&tmpKeyName, &rootKeyName, &unicodeString);
00229
RtlFreeUnicodeString(&unicodeString);
00230
IopConcatenateUnicodeStrings(
KeyName, &tmpKeyName, &unicodeInstanceName);
00231
00232
if (disposition == REG_CREATED_NEW_KEY) {
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL);
00246 status =
IopOpenRegistryKey(&handle,
00247 *
ReturnedHandle,
00248 &unicodeValueName,
00249 KEY_ALL_ACCESS,
00250
TRUE
00251 );
00252
if (
NT_SUCCESS(status)) {
00253 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEWLY_CREATED);
00254 tmpValue = 0;
00255 ZwSetValueKey(handle,
00256 &unicodeValueName,
00257
TITLE_INDEX_VALUE,
00258 REG_DWORD,
00259 &tmpValue,
00260
sizeof(tmpValue)
00261 );
00262 ZwClose(handle);
00263 }
00264
00265 handle = *
ReturnedHandle;
00266
00267 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_SERVICE);
00268 p = (PWSTR)
ExAllocatePool(
PagedPool,
00269 ServiceKeyName->Length +
sizeof(UNICODE_NULL));
00270
if(p) {
00271 RtlMoveMemory(p, ServiceKeyName->Buffer, ServiceKeyName->Length);
00272 p[ServiceKeyName->Length /
sizeof (WCHAR)] = UNICODE_NULL;
00273 ZwSetValueKey(
00274 handle,
00275 &unicodeValueName,
00276
TITLE_INDEX_VALUE,
00277 REG_SZ,
00278 p,
00279 ServiceKeyName->Length +
sizeof(UNICODE_NULL)
00280 );
00281
00282
00283
00284
00285
00286
00287 }
00288
00289 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_LEGACY);
00290 tmpValue = 1;
00291 ZwSetValueKey(
00292 handle,
00293 &unicodeValueName,
00294
TITLE_INDEX_VALUE,
00295 REG_DWORD,
00296 &tmpValue,
00297
sizeof(tmpValue)
00298 );
00299
00300 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CONFIG_FLAGS);
00301 tmpValue = 0;
00302 ZwSetValueKey(
00303 handle,
00304 &unicodeValueName,
00305
TITLE_INDEX_VALUE,
00306 REG_DWORD,
00307 &tmpValue,
00308
sizeof(tmpValue)
00309 );
00310
00311
00312
00313
00314
#if 0
00315
PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_FOUNDATENUM);
00316 tmpValue = 1;
00317 ZwSetValueKey(
00318 handle,
00319 &unicodeValueName,
00320
TITLE_INDEX_VALUE,
00321 REG_DWORD,
00322 &tmpValue,
00323
sizeof(tmpValue)
00324 );
00325
#endif // (lonnym, verify removal to here)
00326
00327 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CLASS);
00328 ZwSetValueKey(
00329 handle,
00330 &unicodeValueName,
00331
TITLE_INDEX_VALUE,
00332 REG_SZ,
00333 REGSTR_VALUE_LEGACY_DRIVER,
00334
sizeof(REGSTR_VALUE_LEGACY_DRIVER)
00335 );
00336
00337 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CLASSGUID);
00338 ZwSetValueKey(
00339 handle,
00340 &unicodeValueName,
00341
TITLE_INDEX_VALUE,
00342 REG_SZ,
00343 REGSTR_VALUE_LEGACY_DRIVER_CLASS_GUID,
00344
sizeof(REGSTR_VALUE_LEGACY_DRIVER_CLASS_GUID)
00345 );
00346
00347
00348
00349
00350
00351
00352
00353
00354 status =
IopOpenServiceEnumKeys(ServiceKeyName,
00355 KEY_READ,
00356 &handle,
00357
NULL,
00358
FALSE
00359 );
00360
if (
NT_SUCCESS(status)) {
00361
00362 keyValueInformation =
NULL;
00363 unicodeString.Length = 0;
00364 status =
IopGetRegistryValue(handle,
00365 REGSTR_VALUE_DISPLAY_NAME,
00366 &keyValueInformation
00367 );
00368
if (
NT_SUCCESS(status)) {
00369
if (keyValueInformation->Type == REG_SZ) {
00370
if (keyValueInformation->DataLength >
sizeof(UNICODE_NULL)) {
00371
IopRegistryDataToUnicodeString(&unicodeString,
00372 (PWSTR)
KEY_VALUE_DATA(keyValueInformation),
00373 keyValueInformation->DataLength
00374 );
00375 }
00376 }
00377 }
00378
if ((unicodeString.Length == 0) && p) {
00379
00380
00381
00382
00383
00384 unicodeString.Length = ServiceKeyName->Length;
00385 unicodeString.MaximumLength = ServiceKeyName->Length +
sizeof(UNICODE_NULL);
00386 unicodeString.Buffer = p;
00387 }
00388
00389
if(unicodeString.Length) {
00390 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DEVICE_DESC);
00391 ZwSetValueKey(*
ReturnedHandle,
00392 &unicodeValueName,
00393
TITLE_INDEX_VALUE,
00394 REG_SZ,
00395 unicodeString.Buffer,
00396 unicodeString.Length +
sizeof(UNICODE_NULL)
00397 );
00398 }
00399
if (keyValueInformation) {
00400
ExFreePool(keyValueInformation);
00401 }
00402 ZwClose(handle);
00403 }
00404
00405
if(p) {
00406
ExFreePool(p);
00407 }
00408 }
00409
00410
00411
00412
00413
00414
00415
ExReleaseResource(&
PpRegistryDeviceResource);
00416
KeLeaveCriticalRegion();
00417 releaseResource =
FALSE;
00418
00419 status =
PpDeviceRegistration(
00420
KeyName,
00421
TRUE,
00422
NULL,
00423
NULL
00424 );
00425
00426
if (ResourceOwned) {
00427
KeEnterCriticalRegion();
00428
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
00429 }
00430
RtlFreeUnicodeString(&tmpKeyName);
00431
if (!
NT_SUCCESS( status )) {
00432
00433
00434
00435
00436
00437 ZwClose(*
ReturnedHandle);
00438
RtlFreeUnicodeString(
KeyName);
00439 }
00440 local_exit0:
00441
if (releaseResource) {
00442
ExReleaseResource(&
PpRegistryDeviceResource);
00443
KeLeaveCriticalRegion();
00444 }
00445
return status;
00446 }
00447
00448
NTSTATUS
00449 IopRemoveStringFromValueKey (
00450 IN HANDLE Handle,
00451 IN PWSTR ValueName,
00452 IN PUNICODE_STRING String
00453 )
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 {
00479 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
00480 UNICODE_STRING unicodeString;
00481 PWSTR nextString, currentString;
00482 ULONG length, leftLength;
00483
NTSTATUS status;
00484 BOOLEAN found =
FALSE;
00485
00486
if (
String ==
NULL ||
String->Length /
sizeof(WCHAR) == 0) {
00487
return STATUS_SUCCESS;
00488 }
00489
00490
00491
00492
00493
00494 status =
IopGetRegistryValue(
Handle,
ValueName, &keyValueInformation);
00495
00496
if (!
NT_SUCCESS( status )) {
00497
return status;
00498 }
else if ((keyValueInformation->Type != REG_MULTI_SZ) ||
00499 (keyValueInformation->DataLength == 0)) {
00500
00501 status = (keyValueInformation->Type == REG_MULTI_SZ) ? STATUS_SUCCESS
00502 : STATUS_INVALID_PARAMETER;
00503
ExFreePool(keyValueInformation);
00504
return status;
00505 }
00506
00507
00508
00509
00510
00511
00512 status = STATUS_SUCCESS;
00513 currentString = (PWSTR)
KEY_VALUE_DATA(keyValueInformation);
00514 leftLength = keyValueInformation->DataLength;
00515
while (!found && leftLength >=
String->Length +
sizeof(WCHAR)) {
00516 unicodeString.Buffer = currentString;
00517 length = wcslen( currentString ) *
sizeof( WCHAR );
00518 unicodeString.Length = (
USHORT)length;
00519 length +=
sizeof(UNICODE_NULL);
00520 unicodeString.MaximumLength = (
USHORT)length;
00521 nextString = currentString + length /
sizeof(WCHAR);
00522 leftLength -= length;
00523
00524
if (
RtlEqualUnicodeString(&unicodeString,
String,
TRUE)) {
00525 found =
TRUE;
00526 RtlMoveMemory(currentString, nextString, leftLength);
00527
RtlInitUnicodeString(&unicodeString,
ValueName);
00528 status = ZwSetValueKey(
00529
Handle,
00530 &unicodeString,
00531
TITLE_INDEX_VALUE,
00532 REG_MULTI_SZ,
00533
KEY_VALUE_DATA(keyValueInformation),
00534 keyValueInformation->DataLength - length
00535 );
00536
break;
00537 }
else {
00538 currentString = nextString;
00539 }
00540 }
00541
ExFreePool(keyValueInformation);
00542
return status;
00543 }
00544
00545
NTSTATUS
00546 IopAppendStringToValueKey (
00547 IN HANDLE Handle,
00548 IN PWSTR ValueName,
00549 IN PUNICODE_STRING String,
00550 IN BOOLEAN Create
00551 )
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 {
00581 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
00582 PWSTR destinationString, p;
00583 UNICODE_STRING unicodeValueName;
00584 ULONG size;
00585
NTSTATUS status;
00586
00587
if ( !
String || (
String->Length <
sizeof(WCHAR)) ) {
00588
return STATUS_SUCCESS;
00589 }
00590
00591
00592
00593
00594
00595 status =
IopGetRegistryValue(
Handle,
ValueName, &keyValueInformation);
00596
00597
if(!
NT_SUCCESS( status )) {
00598
if (status == STATUS_OBJECT_NAME_NOT_FOUND &&
Create) {
00599
00600
00601
00602
00603
00604 keyValueInformation =
NULL;
00605 }
else {
00606
return status;
00607 }
00608 }
else if(keyValueInformation->Type != REG_MULTI_SZ) {
00609
00610
ExFreePool(keyValueInformation);
00611
00612
if(
Create) {
00613 keyValueInformation =
NULL;
00614 }
else {
00615
return STATUS_INVALID_PARAMETER_2;
00616 }
00617
00618 }
else if(keyValueInformation->DataLength <
sizeof(WCHAR) ||
00619 *(PWCHAR)
KEY_VALUE_DATA(keyValueInformation) == UNICODE_NULL) {
00620
00621
ExFreePool(keyValueInformation);
00622 keyValueInformation =
NULL;
00623 }
00624
00625
00626
00627
00628
00629
00630
if (keyValueInformation) {
00631 size = keyValueInformation->DataLength +
String->Length +
sizeof (UNICODE_NULL);
00632 }
else {
00633 size =
String->Length + 2 *
sizeof(UNICODE_NULL);
00634 }
00635
00636 destinationString = p = (PWSTR)
ExAllocatePool(
PagedPool, size);
00637
if (destinationString ==
NULL) {
00638
if (keyValueInformation) {
00639
ExFreePool(keyValueInformation);
00640 }
00641
return STATUS_INSUFFICIENT_RESOURCES;
00642 }
00643
00644
00645
00646
00647
00648
if (keyValueInformation) {
00649
00650
00651
00652
00653
00654
00655 RtlMoveMemory(p,
00656
KEY_VALUE_DATA(keyValueInformation),
00657 keyValueInformation->DataLength -
sizeof(WCHAR)
00658 );
00659 p += keyValueInformation->DataLength /
sizeof(WCHAR) - 1;
00660
00661
ExFreePool(keyValueInformation);
00662 }
00663
00664
00665
00666
00667 RtlMoveMemory(p,
00668
String->Buffer,
00669
String->Length
00670 );
00671 p +=
String->Length /
sizeof(WCHAR);
00672 *p = UNICODE_NULL;
00673 p++;
00674 *p = UNICODE_NULL;
00675
00676
00677
00678
00679
00680
RtlInitUnicodeString(&unicodeValueName,
ValueName);
00681 status = ZwSetValueKey(
00682
Handle,
00683 &unicodeValueName,
00684
TITLE_INDEX_VALUE,
00685 REG_MULTI_SZ,
00686 destinationString,
00687 size
00688 );
00689
00690
ExFreePool(destinationString);
00691
return status;
00692 }
00693
00694 BOOLEAN
00695 IopConcatenateUnicodeStrings (
00696 OUT PUNICODE_STRING Destination,
00697 IN PUNICODE_STRING String1,
00698 IN PUNICODE_STRING String2 OPTIONAL
00699 )
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 {
00727 ULONG length;
00728 PWSTR buffer;
00729
00730 length =
String1->Length +
sizeof(UNICODE_NULL);
00731
if (ARGUMENT_PRESENT(
String2)) {
00732 length +=
String2->Length;
00733 }
00734 buffer = (PWSTR)
ExAllocatePool(
PagedPool, length);
00735
if (!buffer) {
00736
return FALSE;
00737 }
00738 Destination->Buffer = buffer;
00739 Destination->Length = (
USHORT)length -
sizeof(UNICODE_NULL);
00740 Destination->MaximumLength = (
USHORT)length;
00741 RtlMoveMemory (Destination->Buffer,
String1->Buffer,
String1->Length);
00742
if(ARGUMENT_PRESENT(
String2)) {
00743 RtlMoveMemory((PUCHAR)Destination->Buffer +
String1->Length,
00744
String2->Buffer,
00745
String2->Length
00746 );
00747 }
00748 buffer[length /
sizeof(WCHAR) - 1] = UNICODE_NULL;
00749
return TRUE;
00750 }
00751
00752
NTSTATUS
00753 IopPrepareDriverLoading (
00754 IN PUNICODE_STRING KeyName,
00755 IN HANDLE KeyHandle,
00756 IN PIMAGE_NT_HEADERS Header
00757 )
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 {
00783
NTSTATUS status;
00784 PKEY_VALUE_FULL_INFORMATION keyValueInformation =
NULL;
00785 ULONG tmp, count = 0;
00786 HANDLE serviceEnumHandle =
NULL, sysEnumXxxHandle, controlHandle;
00787 UNICODE_STRING unicodeKeyName, unicodeValueName;
00788 BOOLEAN IsPlugPlayDriver =
FALSE;
00789
00790
KeEnterCriticalRegion();
00791
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
00792
00793
00794
00795
00796
00797
00798
00799
if ((
Header) &&
00800 (
Header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)) {
00801 IsPlugPlayDriver =
TRUE;
00802 }
00803
if (IsPlugPlayDriver) {
00804
00805
00806
00807
00808
00809
00810
if (!
IopIsAnyDeviceInstanceEnabled(
KeyName, KeyHandle,
FALSE)) {
00811
if (
PnPDetectionEnabled) {
00812
00813
00814
00815
00816
00817 status = STATUS_SUCCESS;
00818 }
else {
00819 status = STATUS_PLUGPLAY_NO_DEVICE;
00820 }
00821
goto exit;
00822
00823 }
00824 }
else {
00825
00826
00827
00828
00829
00830
00831
00832
if (!
IopIsAnyDeviceInstanceEnabled(
KeyName, KeyHandle,
TRUE)) {
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 PiWstrToUnicodeString(&unicodeKeyName, REGSTR_KEY_ENUM);
00845 status =
IopOpenRegistryKey(&serviceEnumHandle,
00846 KeyHandle,
00847 &unicodeKeyName,
00848 KEY_ALL_ACCESS,
00849
TRUE
00850 );
00851
00852
if (!
NT_SUCCESS( status )) {
00853
goto exit;
00854 }
00855
00856
00857
00858
00859
00860
00861 status =
IopGetRegistryValue ( serviceEnumHandle,
00862 REGSTR_VALUE_COUNT,
00863 &keyValueInformation
00864 );
00865
if (
NT_SUCCESS(status)) {
00866
if ((keyValueInformation->Type == REG_DWORD) &&
00867 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
00868
00869 count = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
00870 }
00871
ExFreePool(keyValueInformation);
00872 }
else if (status != STATUS_OBJECT_PATH_NOT_FOUND &&
00873 status != STATUS_OBJECT_NAME_NOT_FOUND) {
00874
00875 ZwClose(serviceEnumHandle);
00876
goto exit;
00877 }
00878
00879
if (count == 0) {
00880
00881
00882
00883
00884
00885
00886 status =
IopCreateMadeupNode(
KeyName,
00887 &sysEnumXxxHandle,
00888 &unicodeKeyName,
00889 &tmp,
00890
TRUE);
00891
00892
if (!
NT_SUCCESS(status)) {
00893 ZwClose(serviceEnumHandle);
00894
goto exit;
00895 }
00896
RtlFreeUnicodeString(&unicodeKeyName);
00897
00898
00899
00900
00901
00902 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL);
00903 status =
IopOpenRegistryKey(&controlHandle,
00904 sysEnumXxxHandle,
00905 &unicodeValueName,
00906 KEY_ALL_ACCESS,
00907
TRUE
00908 );
00909
if (
NT_SUCCESS(status)) {
00910 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VAL_ACTIVESERVICE);
00911 ZwSetValueKey(
00912 controlHandle,
00913 &unicodeValueName,
00914
TITLE_INDEX_VALUE,
00915 REG_SZ,
00916
KeyName->Buffer,
00917
KeyName->Length +
sizeof(UNICODE_NULL)
00918 );
00919
00920 ZwClose(controlHandle);
00921 }
00922 count++;
00923
00924
00925
00926
00927
00928 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_COUNT);
00929
00930 ZwSetValueKey(serviceEnumHandle,
00931 &unicodeValueName,
00932
TITLE_INDEX_VALUE,
00933 REG_DWORD,
00934 &count,
00935
sizeof (count)
00936 );
00937 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE);
00938
00939 ZwSetValueKey(serviceEnumHandle,
00940 &unicodeValueName,
00941
TITLE_INDEX_VALUE,
00942 REG_DWORD,
00943 &count,
00944
sizeof (count)
00945 );
00946 ZwClose(sysEnumXxxHandle);
00947 ZwClose(serviceEnumHandle);
00948 }
else {
00949 ZwClose(serviceEnumHandle);
00950 status = STATUS_PLUGPLAY_NO_DEVICE;
00951
goto exit;
00952 }
00953 }
00954 }
00955
00956 status = STATUS_SUCCESS;
00957
exit:
00958
ExReleaseResource(&
PpRegistryDeviceResource);
00959
KeLeaveCriticalRegion();
00960
return status;
00961 }
00962
00963
NTSTATUS
00964 IopServiceInstanceToDeviceInstance (
00965 IN HANDLE ServiceKeyHandle OPTIONAL,
00966 IN PUNICODE_STRING ServiceKeyName OPTIONAL,
00967 IN ULONG ServiceInstanceOrdinal,
00968 OUT PUNICODE_STRING DeviceInstanceRegistryPath OPTIONAL,
00969 OUT PHANDLE DeviceInstanceHandle OPTIONAL,
00970 IN ACCESS_MASK DesiredAccess
00971 )
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 {
01017 WCHAR unicodeBuffer[20];
01018 UNICODE_STRING unicodeKeyName;
01019
NTSTATUS status;
01020 HANDLE handle;
01021 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
01022
01023
01024
01025
01026
if(ARGUMENT_PRESENT(ServiceKeyHandle)) {
01027
01028 PiWstrToUnicodeString(&unicodeKeyName, REGSTR_KEY_ENUM);
01029 status =
IopOpenRegistryKey(&handle,
01030 ServiceKeyHandle,
01031 &unicodeKeyName,
01032 KEY_READ,
01033
FALSE
01034 );
01035 }
else {
01036
01037 status =
IopOpenServiceEnumKeys(ServiceKeyName,
01038 KEY_READ,
01039
NULL,
01040 &handle,
01041
FALSE
01042 );
01043 }
01044
01045
if (!
NT_SUCCESS( status )) {
01046
01047
01048
01049
01050
01051
return status;
01052 }
01053
01054
01055
01056
01057
01058
01059 swprintf(unicodeBuffer, REGSTR_VALUE_STANDARD_ULONG_FORMAT, ServiceInstanceOrdinal);
01060 status =
IopGetRegistryValue ( handle,
01061 unicodeBuffer,
01062 &keyValueInformation
01063 );
01064
01065 ZwClose(handle);
01066
if (!
NT_SUCCESS( status )) {
01067
return status;
01068 }
else {
01069
if(keyValueInformation->Type == REG_SZ) {
01070
IopRegistryDataToUnicodeString(&unicodeKeyName,
01071 (PWSTR)
KEY_VALUE_DATA(keyValueInformation),
01072 keyValueInformation->DataLength
01073 );
01074
if(!unicodeKeyName.Length) {
01075 status = STATUS_OBJECT_PATH_NOT_FOUND;
01076 }
01077 }
else {
01078 status = STATUS_INVALID_PLUGPLAY_DEVICE_PATH;
01079 }
01080
01081
if(!
NT_SUCCESS(status)) {
01082
goto PrepareForReturn;
01083 }
01084 }
01085
01086
01087
01088
01089
01090
01091
if (ARGUMENT_PRESENT(DeviceInstanceHandle)) {
01092
01093 status =
IopOpenRegistryKey(&handle,
01094
NULL,
01095 &
CmRegistryMachineSystemCurrentControlSetEnumName,
01096 KEY_READ,
01097
FALSE
01098 );
01099
01100
if (
NT_SUCCESS( status )) {
01101
01102 status =
IopOpenRegistryKey (DeviceInstanceHandle,
01103 handle,
01104 &unicodeKeyName,
01105 DesiredAccess,
01106
FALSE
01107 );
01108 ZwClose(handle);
01109 }
01110
01111
if (!
NT_SUCCESS( status )) {
01112
goto PrepareForReturn;
01113 }
01114 }
01115
01116
01117
01118
01119
01120
if (ARGUMENT_PRESENT(DeviceInstanceRegistryPath)) {
01121
01122
if (!
IopConcatenateUnicodeStrings(DeviceInstanceRegistryPath,
01123 &unicodeKeyName,
01124
NULL)) {
01125
01126
if(ARGUMENT_PRESENT(DeviceInstanceHandle)) {
01127 ZwClose(*DeviceInstanceHandle);
01128 }
01129 status = STATUS_INSUFFICIENT_RESOURCES;
01130 }
01131 }
01132
01133 PrepareForReturn:
01134
01135
ExFreePool(keyValueInformation);
01136
return status;
01137 }
01138
01139
NTSTATUS
01140 IopOpenRegistryKeyPersist(
01141 OUT PHANDLE Handle,
01142 IN HANDLE BaseHandle OPTIONAL,
01143 IN PUNICODE_STRING KeyName,
01144 IN ACCESS_MASK DesiredAccess,
01145 IN BOOLEAN Create,
01146 OUT PULONG Disposition OPTIONAL
01147 )
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 {
01190 OBJECT_ATTRIBUTES objectAttributes;
01191 ULONG disposition, baseHandleIndex = 0, keyHandleIndex = 1, closeBaseHandle;
01192 HANDLE handles[2];
01193 BOOLEAN continueParsing;
01194 PWCHAR pathEndPtr, pathCurPtr, pathBeginPtr;
01195 ULONG pathComponentLength;
01196 UNICODE_STRING unicodeString;
01197
NTSTATUS status;
01198
01199
PAGED_CODE();
01200
01201 InitializeObjectAttributes(&objectAttributes,
01202
KeyName,
01203 OBJ_CASE_INSENSITIVE,
01204 BaseHandle,
01205 (PSECURITY_DESCRIPTOR)
NULL
01206 );
01207
if(
Create) {
01208
01209
01210
01211
01212
01213 status = ZwCreateKey(&(handles[keyHandleIndex]),
01214 DesiredAccess,
01215 &objectAttributes,
01216 0,
01217 (PUNICODE_STRING)
NULL,
01218 REG_OPTION_NON_VOLATILE,
01219 &disposition
01220 );
01221
01222
if(!((status == STATUS_OBJECT_NAME_NOT_FOUND) && ARGUMENT_PRESENT(BaseHandle))) {
01223
01224
01225
01226
01227
goto PrepareForReturn;
01228 }
01229
01230 }
else {
01231
01232
01233
01234
return ZwOpenKey(
Handle,
01235 DesiredAccess,
01236 &objectAttributes
01237 );
01238 }
01239
01240
01241
01242
01243
01244
01245 handles[baseHandleIndex] =
NULL;
01246 handles[keyHandleIndex] = BaseHandle;
01247 closeBaseHandle = 0;
01248 continueParsing =
TRUE;
01249 pathBeginPtr =
KeyName->Buffer;
01250 pathEndPtr = (PWCHAR)((PCHAR)pathBeginPtr +
KeyName->Length);
01251 status = STATUS_SUCCESS;
01252
01253
while(continueParsing) {
01254
01255
01256
01257
01258
if(closeBaseHandle > 1) {
01259 ZwClose(handles[baseHandleIndex]);
01260 }
01261 baseHandleIndex = keyHandleIndex;
01262 keyHandleIndex = (keyHandleIndex + 1) & 1;
01263 handles[keyHandleIndex] =
NULL;
01264
01265
01266
01267
01268
for(pathCurPtr = pathBeginPtr;
01269 ((pathCurPtr < pathEndPtr) && (*pathCurPtr != OBJ_NAME_PATH_SEPARATOR));
01270 pathCurPtr++);
01271
01272
if((pathComponentLength = (ULONG)((PCHAR)pathCurPtr - (PCHAR)pathBeginPtr))) {
01273
01274
01275
01276
01277 unicodeString.Buffer = pathBeginPtr;
01278 unicodeString.Length = unicodeString.MaximumLength = (
USHORT)pathComponentLength;
01279
01280 InitializeObjectAttributes(&objectAttributes,
01281 &unicodeString,
01282 OBJ_CASE_INSENSITIVE,
01283 handles[baseHandleIndex],
01284 (PSECURITY_DESCRIPTOR)
NULL
01285 );
01286 status = ZwCreateKey(&(handles[keyHandleIndex]),
01287 DesiredAccess,
01288 &objectAttributes,
01289 0,
01290 (PUNICODE_STRING)
NULL,
01291 REG_OPTION_NON_VOLATILE,
01292 &disposition
01293 );
01294
if(
NT_SUCCESS(status)) {
01295
01296
01297
01298
01299
01300 closeBaseHandle++;
01301 }
else {
01302 continueParsing =
FALSE;
01303
continue;
01304 }
01305 }
else {
01306
01307
01308
01309
01310 status = STATUS_INVALID_PARAMETER;
01311 continueParsing =
FALSE;
01312
continue;
01313 }
01314
01315
if((pathCurPtr == pathEndPtr) ||
01316 ((pathBeginPtr = pathCurPtr + 1) == pathEndPtr)) {
01317
01318
01319
01320 continueParsing =
FALSE;
01321 }
01322 }
01323
01324
if(closeBaseHandle > 1) {
01325 ZwClose(handles[baseHandleIndex]);
01326 }
01327
01328 PrepareForReturn:
01329
01330
if(
NT_SUCCESS(status)) {
01331 *
Handle = handles[keyHandleIndex];
01332
01333
if(ARGUMENT_PRESENT(Disposition)) {
01334 *Disposition = disposition;
01335 }
01336 }
01337
01338
return status;
01339 }
01340
01341
NTSTATUS
01342 IopOpenServiceEnumKeys (
01343 IN PUNICODE_STRING ServiceKeyName,
01344 IN ACCESS_MASK DesiredAccess,
01345 OUT PHANDLE ServiceHandle OPTIONAL,
01346 OUT PHANDLE ServiceEnumHandle OPTIONAL,
01347 IN BOOLEAN CreateEnum
01348 )
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384 {
01385 HANDLE handle, serviceHandle, enumHandle;
01386 UNICODE_STRING enumName;
01387
NTSTATUS status;
01388
01389
01390
01391
01392
01393 status =
IopOpenRegistryKey(&handle,
01394
NULL,
01395 &
CmRegistryMachineSystemCurrentControlSetServices,
01396 DesiredAccess,
01397
FALSE
01398 );
01399
01400
if (!
NT_SUCCESS( status )) {
01401
return status;
01402 }
01403
01404
01405
01406
01407
01408 status =
IopOpenRegistryKey(&serviceHandle,
01409 handle,
01410 ServiceKeyName,
01411 DesiredAccess,
01412
FALSE
01413 );
01414
01415 ZwClose(handle);
01416
if (!
NT_SUCCESS( status )) {
01417
01418
01419
01420
01421
01422
return status;
01423 }
01424
01425
if (ARGUMENT_PRESENT(ServiceEnumHandle) || CreateEnum) {
01426
01427
01428
01429
01430
01431
01432 PiWstrToUnicodeString(&enumName, REGSTR_KEY_ENUM);
01433 status =
IopOpenRegistryKey(&enumHandle,
01434 serviceHandle,
01435 &enumName,
01436 DesiredAccess,
01437 CreateEnum
01438 );
01439
01440
if (!
NT_SUCCESS( status )) {
01441
01442
01443
01444
01445
01446 ZwClose(serviceHandle);
01447
return status;
01448 }
01449
if (ARGUMENT_PRESENT(ServiceEnumHandle)) {
01450 *ServiceEnumHandle = enumHandle;
01451 }
else {
01452 ZwClose(enumHandle);
01453 }
01454 }
01455
01456
01457
01458
01459
01460
01461
if (ARGUMENT_PRESENT(ServiceHandle)) {
01462 *ServiceHandle = serviceHandle;
01463 }
else {
01464 ZwClose(serviceHandle);
01465 }
01466
01467
return STATUS_SUCCESS;
01468 }
01469
01470
NTSTATUS
01471 IopGetDeviceInstanceCsConfigFlags(
01472 IN PUNICODE_STRING ServiceKeyName,
01473 IN ULONG Instance,
01474 OUT PULONG CsConfigFlags
01475 )
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500 {
01501
NTSTATUS status;
01502 HANDLE handle;
01503 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
01504
01505 *CsConfigFlags = 0;
01506
01507 status =
IopOpenCurrentHwProfileDeviceInstanceKey(&handle,
01508 ServiceKeyName,
01509 Instance,
01510 KEY_READ,
01511
FALSE
01512 );
01513
if(
NT_SUCCESS(status)) {
01514 status =
IopGetRegistryValue(handle,
01515 REGSTR_VALUE_CSCONFIG_FLAGS,
01516 &keyValueInformation
01517 );
01518
if(
NT_SUCCESS(status)) {
01519
if((keyValueInformation->Type == REG_DWORD) &&
01520 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
01521 *CsConfigFlags = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
01522 }
01523
ExFreePool(keyValueInformation);
01524 }
01525 ZwClose(handle);
01526 }
01527
return status;
01528 }
01529
01530
NTSTATUS
01531 IopSetDeviceInstanceCsConfigFlags(
01532 IN PUNICODE_STRING ServiceKeyName,
01533 IN ULONG Instance,
01534 IN ULONG CsConfigFlags
01535 )
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561 {
01562 HANDLE handle;
01563
NTSTATUS status;
01564 UNICODE_STRING tempUnicodeString;
01565
01566 status =
IopOpenCurrentHwProfileDeviceInstanceKey(&handle,
01567 ServiceKeyName,
01568 Instance,
01569 KEY_READ | KEY_WRITE,
01570
TRUE
01571 );
01572
if(
NT_SUCCESS(status)) {
01573
01574 PiWstrToUnicodeString(&tempUnicodeString, REGSTR_VALUE_CSCONFIG_FLAGS);
01575 status = ZwSetValueKey(handle,
01576 &tempUnicodeString,
01577
TITLE_INDEX_VALUE,
01578 REG_DWORD,
01579 &CsConfigFlags,
01580
sizeof(CsConfigFlags)
01581 );
01582 ZwClose(handle);
01583 }
01584
return status;
01585 }
01586
01587
NTSTATUS
01588 IopOpenCurrentHwProfileDeviceInstanceKey(
01589 OUT PHANDLE Handle,
01590 IN PUNICODE_STRING ServiceKeyName,
01591 IN ULONG Instance,
01592 IN ACCESS_MASK DesiredAccess,
01593 IN BOOLEAN Create
01594 )
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623 {
01624
NTSTATUS status;
01625 UNICODE_STRING tempUnicodeString;
01626 HANDLE profileHandle, profileEnumHandle, tmpHandle;
01627
01628
01629
01630
01631 status =
IopOpenRegistryKey(&profileHandle,
01632
NULL,
01633 &
CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent,
01634 KEY_READ,
01635
Create
01636 );
01637
if(
NT_SUCCESS(status)) {
01638
01639
01640
01641
01642
01643
01644
01645 PiWstrToUnicodeString(&tempUnicodeString, REGSTR_PATH_CURRENTCONTROLSET);
01646 status =
IopOpenRegistryKey(&tmpHandle,
01647 profileHandle,
01648 &tempUnicodeString,
01649 DesiredAccess,
01650
FALSE
01651 );
01652 ZwClose(profileHandle);
01653
if (!
NT_SUCCESS(status)) {
01654
return status;
01655 }
01656
01657 PiWstrToUnicodeString(&tempUnicodeString, REGSTR_KEY_ENUM);
01658 status =
IopOpenRegistryKey(&profileEnumHandle,
01659 tmpHandle,
01660 &tempUnicodeString,
01661 KEY_READ,
01662
Create
01663 );
01664 ZwClose(tmpHandle);
01665
if(
NT_SUCCESS(status)) {
01666
01667 status =
IopServiceInstanceToDeviceInstance(
NULL,
01668 ServiceKeyName,
01669 Instance,
01670 &tempUnicodeString,
01671
NULL,
01672 0
01673 );
01674
if(
NT_SUCCESS(status)) {
01675 status =
IopOpenRegistryKey(
Handle,
01676 profileEnumHandle,
01677 &tempUnicodeString,
01678 DesiredAccess,
01679
Create
01680 );
01681
RtlFreeUnicodeString(&tempUnicodeString);
01682 }
01683 ZwClose(profileEnumHandle);
01684 }
01685 }
01686
return status;
01687 }
01688
01689
NTSTATUS
01690 IopApplyFunctionToSubKeys(
01691 IN HANDLE BaseHandle OPTIONAL,
01692 IN PUNICODE_STRING KeyName OPTIONAL,
01693 IN ACCESS_MASK DesiredAccess,
01694 IN BOOLEAN IgnoreNonCriticalErrors,
01695 IN PIOP_SUBKEY_CALLBACK_ROUTINE SubKeyCallbackRoutine,
01696 IN OUT PVOID Context
01697 )
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757 {
01758
NTSTATUS Status;
01759 BOOLEAN CloseHandle =
FALSE, ContinueEnumeration;
01760 HANDLE
Handle, SubKeyHandle;
01761 ULONG i, RequiredBufferLength;
01762 PKEY_BASIC_INFORMATION KeyInformation =
NULL;
01763
01764
01765 ULONG KeyInformationLength =
sizeof(KEY_BASIC_INFORMATION) + (20 *
sizeof(WCHAR));
01766 UNICODE_STRING SubKeyName;
01767
01768
if(ARGUMENT_PRESENT(
KeyName)) {
01769
01770
Status =
IopOpenRegistryKey(&
Handle,
01771 BaseHandle,
01772
KeyName,
01773 KEY_READ,
01774
FALSE
01775 );
01776
if(!
NT_SUCCESS(
Status)) {
01777
return Status;
01778 }
else {
01779 CloseHandle =
TRUE;
01780 }
01781
01782 }
else {
01783
01784
Handle = BaseHandle;
01785 }
01786
01787
01788
01789
01790 i = 0;
01791 SubKeyHandle =
NULL;
01792
01793
while(
TRUE) {
01794
01795
if(!KeyInformation) {
01796
01797 KeyInformation = (PKEY_BASIC_INFORMATION)
ExAllocatePool(
PagedPool,
01798 KeyInformationLength
01799 );
01800
if(!KeyInformation) {
01801
Status = STATUS_INSUFFICIENT_RESOURCES;
01802
break;
01803 }
01804 }
01805
01806
Status = ZwEnumerateKey(
Handle,
01807 i,
01808 KeyBasicInformation,
01809 KeyInformation,
01810 KeyInformationLength,
01811 &RequiredBufferLength
01812 );
01813
01814
if(!
NT_SUCCESS(
Status)) {
01815
if(
Status == STATUS_BUFFER_OVERFLOW) {
01816
01817
01818
01819
ExFreePool(KeyInformation);
01820 KeyInformation =
NULL;
01821 KeyInformationLength = RequiredBufferLength;
01822
continue;
01823
01824 }
else if(
Status == STATUS_NO_MORE_ENTRIES) {
01825
01826
01827
01828
Status = STATUS_SUCCESS;
01829
break;
01830
01831 }
else {
01832
01833
01834
01835
if(IgnoreNonCriticalErrors) {
01836
goto ContinueWithNextSubKey;
01837 }
else {
01838
break;
01839 }
01840 }
01841 }
01842
01843
01844
01845
01846
01847 SubKeyName.Length = SubKeyName.MaximumLength = (
USHORT)KeyInformation->NameLength;
01848 SubKeyName.Buffer = KeyInformation->Name;
01849
01850
01851
01852
01853
if(DesiredAccess) {
01854
Status =
IopOpenRegistryKey(&SubKeyHandle,
01855
Handle,
01856 &SubKeyName,
01857 DesiredAccess,
01858
FALSE
01859 );
01860
if(!
NT_SUCCESS(
Status)) {
01861
01862
01863
01864
if(IgnoreNonCriticalErrors) {
01865
goto ContinueWithNextSubKey;
01866 }
else {
01867
break;
01868 }
01869 }
01870 }
01871
01872
01873
01874
01875 ContinueEnumeration = SubKeyCallbackRoutine(SubKeyHandle, &SubKeyName, Context);
01876
01877
if(DesiredAccess) {
01878 ZwClose(SubKeyHandle);
01879 }
01880
01881
if(!ContinueEnumeration) {
01882
01883
01884
01885
Status = STATUS_SUCCESS;
01886
break;
01887
01888 }
01889
01890 ContinueWithNextSubKey:
01891
01892 i++;
01893 }
01894
01895
if(KeyInformation) {
01896
ExFreePool(KeyInformation);
01897 }
01898
01899
if(CloseHandle) {
01900 ZwClose(
Handle);
01901 }
01902
01903
return Status;
01904 }
01905
01906
NTSTATUS
01907 IopRegMultiSzToUnicodeStrings(
01908 IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
01909 OUT PUNICODE_STRING *UnicodeStringList,
01910 OUT PULONG UnicodeStringCount
01911 )
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 {
01945 PWCHAR p, BufferEnd, StringStart;
01946 ULONG StringCount, i,
StringLength;
01947
01948
01949
01950
01951
if(KeyValueInformation->Type != REG_MULTI_SZ) {
01952
return STATUS_INVALID_PARAMETER;
01953 }
01954
01955
01956
01957
01958
01959 StringCount = 0;
01960 p = (PWCHAR)
KEY_VALUE_DATA(KeyValueInformation);
01961 BufferEnd = (PWCHAR)((PUCHAR)p + KeyValueInformation->DataLength);
01962
while(p != BufferEnd) {
01963
if(!*p) {
01964 StringCount++;
01965
if(((p + 1) == BufferEnd) || !*(p + 1)) {
01966
break;
01967 }
01968 }
01969 p++;
01970 }
01971
if(p == BufferEnd) {
01972 StringCount++;
01973 }
01974
01975 *UnicodeStringList =
ExAllocatePool(
PagedPool,
sizeof(UNICODE_STRING) * StringCount);
01976
if(!(*UnicodeStringList)) {
01977
return STATUS_INSUFFICIENT_RESOURCES;
01978 }
01979
01980
01981
01982
01983 i = 0;
01984 StringStart = p = (PWCHAR)
KEY_VALUE_DATA(KeyValueInformation);
01985
while(p != BufferEnd) {
01986
if(!*p) {
01987
StringLength = (ULONG)((PUCHAR)p - (PUCHAR)StringStart) +
sizeof(UNICODE_NULL);
01988 (*UnicodeStringList)[i].Buffer =
ExAllocatePool(
PagedPool,
StringLength);
01989
01990
if(!((*UnicodeStringList)[i].Buffer)) {
01991
IopFreeUnicodeStringList(*UnicodeStringList, i);
01992
return STATUS_INSUFFICIENT_RESOURCES;
01993 }
01994
01995 RtlMoveMemory((*UnicodeStringList)[i].
Buffer, StringStart,
StringLength);
01996
01997 (*UnicodeStringList)[i].Length =
01998 ((*UnicodeStringList)[i].MaximumLength = (
USHORT)
StringLength)
01999 -
sizeof(UNICODE_NULL);
02000
02001 i++;
02002
02003
if(((p + 1) == BufferEnd) || !*(p + 1)) {
02004
break;
02005 }
else {
02006 StringStart = p + 1;
02007 }
02008 }
02009 p++;
02010 }
02011
if(p == BufferEnd) {
02012
StringLength = (ULONG)((PUCHAR)p - (PUCHAR)StringStart);
02013 (*UnicodeStringList)[i].Buffer =
ExAllocatePool(
PagedPool,
02014
StringLength +
sizeof(UNICODE_NULL)
02015 );
02016
if(!((*UnicodeStringList)[i].Buffer)) {
02017
IopFreeUnicodeStringList(*UnicodeStringList, i);
02018
return STATUS_INSUFFICIENT_RESOURCES;
02019 }
02020
if(
StringLength) {
02021 RtlMoveMemory((*UnicodeStringList)[i].
Buffer, StringStart,
StringLength);
02022 }
02023 (*UnicodeStringList)[i].Buffer[CB_TO_CWC(
StringLength)] = UNICODE_NULL;
02024
02025 (*UnicodeStringList)[i].MaximumLength =
02026 ((*UnicodeStringList)[i].Length = (
USHORT)
StringLength)
02027 +
sizeof(UNICODE_NULL);
02028 }
02029
02030 *UnicodeStringCount = StringCount;
02031
02032
return STATUS_SUCCESS;
02033 }
02034
02035
NTSTATUS
02036 IopApplyFunctionToServiceInstances(
02037 IN HANDLE ServiceKeyHandle OPTIONAL,
02038 IN PUNICODE_STRING ServiceKeyName OPTIONAL,
02039 IN ACCESS_MASK DesiredAccess,
02040 IN BOOLEAN IgnoreNonCriticalErrors,
02041 IN PIOP_SUBKEY_CALLBACK_ROUTINE DevInstCallbackRoutine,
02042 IN OUT PVOID Context,
02043 OUT PULONG ServiceInstanceOrdinal OPTIONAL
02044 )
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112 {
02113
NTSTATUS Status;
02114 HANDLE ServiceEnumHandle, SystemEnumHandle, DeviceInstanceHandle;
02115 UNICODE_STRING TempUnicodeString;
02116 ULONG ServiceInstanceCount, i, junk;
02117 PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
02118 WCHAR ValueNameString[20];
02119 BOOLEAN ContinueEnumeration;
02120
02121
02122
02123
02124
02125
if(ARGUMENT_PRESENT(ServiceKeyHandle)) {
02126 PiWstrToUnicodeString(&TempUnicodeString, REGSTR_KEY_ENUM);
02127
Status =
IopOpenRegistryKey(&ServiceEnumHandle,
02128 ServiceKeyHandle,
02129 &TempUnicodeString,
02130 KEY_READ,
02131
FALSE
02132 );
02133 }
else {
02134
Status =
IopOpenServiceEnumKeys(ServiceKeyName,
02135 KEY_READ,
02136
NULL,
02137 &ServiceEnumHandle,
02138
FALSE
02139 );
02140 }
02141
if(!
NT_SUCCESS(
Status)) {
02142
return Status;
02143 }
02144
02145
02146
02147
02148
02149 ServiceInstanceCount = 0;
02150
02151
Status =
IopGetRegistryValue(ServiceEnumHandle,
02152 REGSTR_VALUE_COUNT,
02153 &KeyValueInformation
02154 );
02155
if(
NT_SUCCESS(
Status)) {
02156
02157
if((KeyValueInformation->Type == REG_DWORD) &&
02158 (KeyValueInformation->DataLength >=
sizeof(ULONG))) {
02159
02160 ServiceInstanceCount = *(PULONG)
KEY_VALUE_DATA(KeyValueInformation);
02161
02162 }
02163
ExFreePool(KeyValueInformation);
02164
02165 }
else if(
Status != STATUS_OBJECT_NAME_NOT_FOUND) {
02166
goto PrepareForReturn;
02167 }
else {
02168
02169
02170
02171
02172
Status = STATUS_SUCCESS;
02173 }
02174
02175
02176
02177
02178
02179
02180
if (ServiceInstanceCount) {
02181
02182
if (DesiredAccess) {
02183
Status =
IopOpenRegistryKey(&SystemEnumHandle,
02184
NULL,
02185 &
CmRegistryMachineSystemCurrentControlSetEnumName,
02186 KEY_READ,
02187
FALSE
02188 );
02189
if(!
NT_SUCCESS(
Status)) {
02190
goto PrepareForReturn;
02191 }
02192 }
else {
02193
02194
02195
02196
02197 DeviceInstanceHandle =
NULL;
02198 }
02199 KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)
ExAllocatePool(
02200
PagedPool,
02201
PNP_SCRATCH_BUFFER_SIZE);
02202
if (!KeyValueInformation) {
02203
Status = STATUS_INSUFFICIENT_RESOURCES;
02204
goto PrepareForReturn;
02205 }
02206 i = 0;
02207
while (
TRUE) {
02208
Status = ZwEnumerateValueKey (
02209 ServiceEnumHandle,
02210 i++,
02211 KeyValueFullInformation,
02212 KeyValueInformation,
02213
PNP_SCRATCH_BUFFER_SIZE,
02214 &junk
02215 );
02216
02217
if (!
NT_SUCCESS (
Status)) {
02218
if (
Status == STATUS_NO_MORE_ENTRIES) {
02219
Status = STATUS_SUCCESS;
02220
break;
02221 }
else if(IgnoreNonCriticalErrors) {
02222
continue;
02223 }
else {
02224
break;
02225 }
02226 }
02227
02228
if (KeyValueInformation->Type != REG_SZ) {
02229
continue;
02230 }
02231
02232 ContinueEnumeration =
TRUE;
02233 TempUnicodeString.Length = 0;
02234
IopRegistryDataToUnicodeString(&TempUnicodeString,
02235 (PWSTR)
KEY_VALUE_DATA(KeyValueInformation),
02236 KeyValueInformation->DataLength
02237 );
02238
if (TempUnicodeString.Length) {
02239
02240
02241
02242
02243
02244
02245
02246
if (DesiredAccess) {
02247
Status =
IopOpenRegistryKey(&DeviceInstanceHandle,
02248 SystemEnumHandle,
02249 &TempUnicodeString,
02250 DesiredAccess,
02251
FALSE
02252 );
02253 }
02254
02255
if (
NT_SUCCESS(
Status)) {
02256
02257
02258
02259 ContinueEnumeration = DevInstCallbackRoutine(DeviceInstanceHandle,
02260 &TempUnicodeString,
02261 Context
02262 );
02263
if (DesiredAccess) {
02264 ZwClose(DeviceInstanceHandle);
02265 }
02266 }
else if (IgnoreNonCriticalErrors) {
02267
continue;
02268 }
else {
02269
break;
02270 }
02271 }
else {
02272
continue;
02273 }
02274
if (!ContinueEnumeration) {
02275
break;
02276 }
02277 }
02278
02279
if(DesiredAccess) {
02280 ZwClose(SystemEnumHandle);
02281 }
02282
ExFreePool(KeyValueInformation);
02283 }
02284
02285
if(ARGUMENT_PRESENT(ServiceInstanceOrdinal)) {
02286 *ServiceInstanceOrdinal = i;
02287 }
02288
02289 PrepareForReturn:
02290
02291 ZwClose(ServiceEnumHandle);
02292
02293
return Status;
02294 }
02295
02296
NTSTATUS
02297 IopMarkDuplicateDevice (
02298 IN PUNICODE_STRING TargetKeyName,
02299 IN ULONG TargetInstance,
02300 IN PUNICODE_STRING SourceKeyName,
02301 IN ULONG SourceInstance
02302 )
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329 {
02330 HANDLE handle;
02331
NTSTATUS status;
02332 UNICODE_STRING sourceDeviceString, unicodeValueName;
02333
02334
02335
02336
02337
02338 status =
IopServiceInstanceToDeviceInstance(
02339
NULL,
02340 TargetKeyName,
02341 TargetInstance,
02342
NULL,
02343 &handle,
02344 0
02345 );
02346
if (!
NT_SUCCESS(status)) {
02347
return status;
02348 }
02349
02350
02351
02352
02353
02354 status =
IopServiceInstanceToDeviceInstance(
02355
NULL,
02356 SourceKeyName,
02357 SourceInstance,
02358 &sourceDeviceString,
02359
NULL,
02360 0
02361 );
02362
if (!
NT_SUCCESS(status)) {
02363
return status;
02364 }
02365
02366
02367
02368
02369
02370
02371 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DUPLICATEOF);
02372 status = ZwSetValueKey(
02373 handle,
02374 &unicodeValueName,
02375
TITLE_INDEX_VALUE,
02376 REG_SZ,
02377 &sourceDeviceString,
02378 sourceDeviceString.Length +
sizeof(WCHAR)
02379 );
02380
return status;
02381 }
02382
02383 BOOLEAN
02384 IopIsDuplicatedDevices(
02385 IN PCM_RESOURCE_LIST Configuration1,
02386 IN PCM_RESOURCE_LIST Configuration2,
02387 IN
PHAL_BUS_INFORMATION BusInfo1 OPTIONAL,
02388 IN
PHAL_BUS_INFORMATION BusInfo2 OPTIONAL
02389 )
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417 {
02418 PCM_PARTIAL_RESOURCE_LIST list1, list2;
02419 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor1, descriptor2;
02420
02421 ULONG i, j;
02422 ULONG pass = 0;
02423
02424
02425
02426
02427
02428
if ((ARGUMENT_PRESENT(BusInfo1) && !ARGUMENT_PRESENT(BusInfo2)) ||
02429 (!ARGUMENT_PRESENT(BusInfo1) && ARGUMENT_PRESENT(BusInfo2))) {
02430
02431
02432
02433
02434
02435
return FALSE;
02436 }
02437
02438
02439
02440
02441
02442
02443
if (Configuration1->Count == 0 || Configuration2->Count == 0) {
02444
02445
02446
02447
02448
02449
02450
return FALSE;
02451 }
02452
02453 RedoScan:
02454
02455 list1 = &(Configuration1->List[0].PartialResourceList);
02456 list2 = &(Configuration2->List[0].PartialResourceList);
02457
02458
for(i = 0, descriptor1 = list1->PartialDescriptors;
02459 i < list1->Count;
02460 i++, descriptor1++) {
02461
02462
02463
02464
02465
02466
02467
if((descriptor1->Type == CmResourceTypePort) ||
02468 (descriptor1->Type == CmResourceTypeMemory)) {
02469
02470
for(j = 0, descriptor2 = list2->PartialDescriptors;
02471 j < list2->Count;
02472 j++, descriptor2++) {
02473
02474
02475
02476
02477
02478
02479
02480
if(descriptor1->Type == descriptor2->Type) {
02481
02482 PHYSICAL_ADDRESS range1, range1Translated;
02483 PHYSICAL_ADDRESS range2, range2Translated;
02484 ULONG range1IoSpace, range2IoSpace;
02485
02486 range1 = descriptor1->u.Generic.Start;
02487 range2 = descriptor2->u.Generic.Start;
02488
02489
if((range1.QuadPart == 0) ||
02490 (BusInfo1 ==
NULL) ||
02491 (
HalTranslateBusAddress(
02492 BusInfo1->BusType,
02493 BusInfo1->BusNumber,
02494 range1,
02495 &range1IoSpace,
02496 &range1Translated) ==
FALSE)) {
02497
02498 range1Translated = range1;
02499 range1IoSpace =
02500 (descriptor1->Type == CmResourceTypePort) ?
TRUE :
02501
FALSE;
02502 }
02503
02504
if((range2.QuadPart == 0) ||
02505 (BusInfo2 ==
NULL) ||
02506 (
HalTranslateBusAddress(
02507 BusInfo2->BusType,
02508 BusInfo2->BusNumber,
02509 range2,
02510 &range2IoSpace,
02511 &range2Translated) ==
FALSE)) {
02512
02513 range2Translated = range2;
02514 range2IoSpace =
02515 (descriptor2->Type == CmResourceTypePort) ?
TRUE :
02516
FALSE;
02517 }
02518
02519
02520
02521
02522
02523
02524
02525
if((range1Translated.QuadPart == range2Translated.QuadPart) &&
02526 (range1IoSpace == range2IoSpace)) {
02527
02528
break;
02529 }
02530 }
02531 }
02532
02533
02534
02535
02536
02537
02538
if(j == list2->Count) {
02539
return FALSE;
02540 }
02541 }
02542 }
02543
02544
02545
02546
02547
02548
02549
if(pass == 0) {
02550
02551 PVOID tmp ;
02552
02553 tmp = Configuration2;
02554 Configuration2 = Configuration1;
02555 Configuration1 = tmp;
02556
02557 tmp = BusInfo2;
02558 BusInfo2 = BusInfo1;
02559 BusInfo1 = tmp;
02560
02561 pass = 1;
02562
02563
goto RedoScan;
02564 }
02565
02566
return TRUE;
02567 }
02568
02569
VOID
02570 IopFreeUnicodeStringList(
02571 IN PUNICODE_STRING UnicodeStringList,
02572 IN ULONG StringCount
02573 )
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595 {
02596 ULONG i;
02597
02598
if(UnicodeStringList) {
02599
for(i = 0; i < StringCount; i++) {
02600
if(UnicodeStringList[i].Buffer) {
02601
ExFreePool(UnicodeStringList[i].
Buffer);
02602 }
02603 }
02604
ExFreePool(UnicodeStringList);
02605 }
02606 }
02607
02608
NTSTATUS
02609 IopDriverLoadingFailed(
02610 IN HANDLE ServiceHandle OPTIONAL,
02611 IN PUNICODE_STRING ServiceName OPTIONAL
02612 )
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637 {
02638
NTSTATUS status;
02639 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
02640 BOOLEAN closeHandle =
FALSE, deletePdo;
02641 HANDLE handle, serviceEnumHandle, controlHandle;
02642 HANDLE sysEnumHandle =
NULL;
02643 ULONG deviceFlags, count, newCount, i, j;
02644 UNICODE_STRING unicodeValueName, deviceInstanceName;
02645 WCHAR unicodeBuffer[20];
02646
02647
02648
02649
02650
02651
if (!ARGUMENT_PRESENT(ServiceHandle)) {
02652 status =
IopOpenServiceEnumKeys(ServiceName,
02653 KEY_READ,
02654 &ServiceHandle,
02655 &serviceEnumHandle,
02656
FALSE
02657 );
02658 closeHandle =
TRUE;
02659 }
else {
02660 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_ENUM);
02661 status =
IopOpenRegistryKey(&serviceEnumHandle,
02662 ServiceHandle,
02663 &unicodeValueName,
02664 KEY_READ,
02665
FALSE
02666 );
02667 }
02668
if (!
NT_SUCCESS( status )) {
02669
02670
02671
02672
02673
02674
return status;
02675 }
02676
02677
02678
02679
02680
02681
RtlInitUnicodeString(&unicodeValueName,
L"INITSTARTFAILED");
02682 deviceFlags = 1;
02683 ZwSetValueKey(
02684 serviceEnumHandle,
02685 &unicodeValueName,
02686
TITLE_INDEX_VALUE,
02687 REG_DWORD,
02688 &deviceFlags,
02689
sizeof(deviceFlags)
02690 );
02691
02692
02693
02694
02695
02696
02697 status =
IopGetRegistryValue ( serviceEnumHandle,
02698 REGSTR_VALUE_COUNT,
02699 &keyValueInformation
02700 );
02701 count = 0;
02702
if (
NT_SUCCESS(status)) {
02703
if ((keyValueInformation->Type == REG_DWORD) &&
02704 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
02705
02706 count = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
02707 }
02708
ExFreePool(keyValueInformation);
02709 }
02710
if (count == 0) {
02711 ZwClose(serviceEnumHandle);
02712
if (closeHandle) {
02713 ZwClose(ServiceHandle);
02714 }
02715
return status;
02716 }
02717
02718
02719
02720
02721
02722
02723 status =
IopOpenRegistryKey(&sysEnumHandle,
02724
NULL,
02725 &
CmRegistryMachineSystemCurrentControlSetEnumName,
02726 KEY_ALL_ACCESS,
02727
FALSE
02728 );
02729
02730
02731
02732
02733
02734
02735
KeEnterCriticalRegion();
02736
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
02737
02738 newCount = count;
02739
for (i = 0; i < count; i++) {
02740 deletePdo =
FALSE;
02741 status =
IopServiceInstanceToDeviceInstance (
02742 ServiceHandle,
02743 ServiceName,
02744 i,
02745 &deviceInstanceName,
02746 &handle,
02747 KEY_ALL_ACCESS
02748 );
02749
02750
if (
NT_SUCCESS(status)) {
02751
02752
PDEVICE_OBJECT deviceObject;
02753
PDEVICE_NODE deviceNode;
02754
02755
02756
02757
02758
02759
02760 deviceObject =
IopDeviceObjectFromDeviceInstance(handle,
NULL);
02761
if (deviceObject) {
02762 deviceNode = (
PDEVICE_NODE)deviceObject->
DeviceObjectExtension->
DeviceNode;
02763
if (deviceNode) {
02764
02765
IopReleaseDeviceResources(deviceNode);
02766
02767
if ((deviceNode->
Flags &
DNF_MADEUP) && (deviceNode->
Flags &
DNF_STARTED)) {
02768
02769
02770
02771
02772 deviceNode->
Flags &= ~
DNF_STARTED;
02773
02774
IopSetDevNodeProblem(deviceNode, CM_PROB_DEVICE_NOT_THERE);
02775 deletePdo =
TRUE;
02776 }
02777 }
02778
ObDereferenceObject(deviceObject);
02779 }
02780
02781 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL);
02782 controlHandle =
NULL;
02783 status =
IopOpenRegistryKey(&controlHandle,
02784 handle,
02785 &unicodeValueName,
02786 KEY_ALL_ACCESS,
02787
FALSE
02788 );
02789
if (
NT_SUCCESS(status)) {
02790
02791 status =
IopGetRegistryValue(controlHandle,
02792 REGSTR_VALUE_NEWLY_CREATED,
02793 &keyValueInformation);
02794
if (
NT_SUCCESS(status)) {
02795
ExFreePool(keyValueInformation);
02796 }
02797
if ((status != STATUS_OBJECT_NAME_NOT_FOUND) &&
02798 (status != STATUS_OBJECT_PATH_NOT_FOUND)) {
02799
02800
02801
02802
02803
02804 PiUlongToUnicodeString(&unicodeValueName, unicodeBuffer, 20, i);
02805 status = ZwDeleteValueKey (serviceEnumHandle, &unicodeValueName);
02806
if (
NT_SUCCESS(status)) {
02807
02808
02809
02810
02811
02812
02813
02814
02815 newCount--;
02816
02817 ZwDeleteKey(controlHandle);
02818 ZwDeleteKey(handle);
02819
02820
02821
02822
02823
02824
02825
if (sysEnumHandle) {
02826 deviceInstanceName.Length -= 5 *
sizeof(WCHAR);
02827 deviceInstanceName.Buffer[deviceInstanceName.Length /
sizeof(WCHAR)] =
02828 UNICODE_NULL;
02829 status =
IopOpenRegistryKey(&handle,
02830 sysEnumHandle,
02831 &deviceInstanceName,
02832 KEY_ALL_ACCESS,
02833
FALSE
02834 );
02835
if (
NT_SUCCESS(status)) {
02836 ZwDeleteKey(handle);
02837 }
02838 }
02839
02840
ExFreePool(deviceInstanceName.Buffer);
02841
02842
02843
02844
02845
02846
if (deletePdo) {
02847
IoDeleteDevice(deviceObject);
02848 }
02849
02850
continue;
02851 }
02852 }
02853 }
02854
02855
02856
02857
02858
02859
if (controlHandle) {
02860 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VAL_ACTIVESERVICE);
02861 ZwDeleteValueKey(controlHandle, &unicodeValueName);
02862 ZwClose(controlHandle);
02863 }
02864
02865 ZwClose(handle);
02866
ExFreePool(deviceInstanceName.Buffer);
02867 }
02868 }
02869
02870
02871
02872
02873
02874
02875
if (newCount != count) {
02876
if (newCount != 0) {
02877 j = 0;
02878 i = 0;
02879
while (i < count) {
02880 PiUlongToUnicodeString(&unicodeValueName, unicodeBuffer, 20, i);
02881 status =
IopGetRegistryValue(serviceEnumHandle,
02882 unicodeValueName.Buffer,
02883 &keyValueInformation
02884 );
02885
if (
NT_SUCCESS(status)) {
02886
if (i != j) {
02887
02888
02889
02890
02891
02892 ZwDeleteValueKey(serviceEnumHandle, &unicodeValueName);
02893
02894 PiUlongToUnicodeString(&unicodeValueName, unicodeBuffer, 20, j);
02895 ZwSetValueKey (serviceEnumHandle,
02896 &unicodeValueName,
02897
TITLE_INDEX_VALUE,
02898 REG_SZ,
02899 (PVOID)
KEY_VALUE_DATA(keyValueInformation),
02900 keyValueInformation->DataLength
02901 );
02902 }
02903
ExFreePool(keyValueInformation);
02904 j++;
02905 }
02906 i++;
02907 }
02908 }
02909
02910
02911
02912
02913
02914 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_COUNT);
02915
02916 ZwSetValueKey(serviceEnumHandle,
02917 &unicodeValueName,
02918
TITLE_INDEX_VALUE,
02919 REG_DWORD,
02920 &newCount,
02921
sizeof (newCount)
02922 );
02923 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE);
02924
02925 ZwSetValueKey(serviceEnumHandle,
02926 &unicodeValueName,
02927
TITLE_INDEX_VALUE,
02928 REG_DWORD,
02929 &newCount,
02930
sizeof (newCount)
02931 );
02932 }
02933 ZwClose(serviceEnumHandle);
02934
if (closeHandle) {
02935 ZwClose(ServiceHandle);
02936 }
02937
if (sysEnumHandle) {
02938 ZwClose(sysEnumHandle);
02939 }
02940
02941
ExReleaseResource(&
PpRegistryDeviceResource);
02942
KeLeaveCriticalRegion();
02943
02944
return STATUS_SUCCESS;
02945 }
02946
02947
VOID
02948
IopDisableDevice(
02949 IN
PDEVICE_NODE DeviceNode,
02950 IN HANDLE Handle
02951 )
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971 {
02972 UNICODE_STRING unicodeName;
02973
NTSTATUS status;
02974 PCM_RESOURCE_LIST cmResource;
02975 ULONG cmLength, tmpValue;
02976 HANDLE logConfHandle;
02977
02978
02979
02980
02981
02982
02983
if (DeviceNode->Flags &
DNF_HAS_BOOT_CONFIG) {
02984 status =
IopRemoveDevice (DeviceNode->PhysicalDeviceObject, IRP_MN_QUERY_REMOVE_DEVICE);
02985
if (
NT_SUCCESS(status)) {
02986 status =
IopRemoveDevice (DeviceNode->PhysicalDeviceObject, IRP_MN_REMOVE_DEVICE);
02987
ASSERT(
NT_SUCCESS(status));
02988
IopReleaseDeviceResources(DeviceNode);
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
if (DeviceNode->BootResources ==
NULL) {
02999 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
03000 status =
IopOpenRegistryKeyPersist(&logConfHandle,
03001 Handle,
03002 &unicodeName,
03003 KEY_ALL_ACCESS,
03004 TRUE,
03005 &tmpValue
03006 );
03007
if (!
NT_SUCCESS(status)) {
03008 logConfHandle =
NULL;
03009 }
03010 status =
IopQueryDeviceResources (
03011 DeviceNode->PhysicalDeviceObject,
03012 QUERY_RESOURCE_LIST,
03013 &cmResource,
03014 &cmLength
03015 );
03016
03017
if (!
NT_SUCCESS(status)) {
03018 cmResource =
NULL;
03019 cmLength = 0;
03020 }
03021
03022
if (logConfHandle) {
03023
KeEnterCriticalRegion();
03024
ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
03025
if (cmResource) {
03026 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG);
03027 ZwSetValueKey(
03028 logConfHandle,
03029 &unicodeName,
03030 TITLE_INDEX_VALUE,
03031 REG_RESOURCE_LIST,
03032 cmResource,
03033 cmLength
03034 );
03035 }
else {
03036 ZwDeleteValueKey(logConfHandle, &unicodeName);
03037 }
03038
ExReleaseResource(&PpRegistryDeviceResource);
03039
KeLeaveCriticalRegion();
03040 ZwClose(logConfHandle);
03041 }
03042
if (cmResource) {
03043 DeviceNode->Flags |=
DNF_HAS_BOOT_CONFIG;
03044 DeviceNode->BootResources = cmResource;
03045
03046
03047
03048
03049
03050 (*IopReserveResourcesRoutine)(
ArbiterRequestPnpEnumerated,
03051 DeviceNode->PhysicalDeviceObject,
03052 cmResource);
03053 }
03054 }
03055 }
else {
03056
IopRemoveDevice (DeviceNode->PhysicalDeviceObject, IRP_MN_CANCEL_REMOVE_DEVICE);
03057 }
03058 }
03059
03060
if (
IopDoesDevNodeHaveProblem(DeviceNode)) {
03061
ASSERT(
IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) ||
03062
IopIsDevNodeProblem(DeviceNode, CM_PROB_REINSTALL));
03063
03064
IopClearDevNodeProblem(DeviceNode);
03065 }
03066
03067
IopSetDevNodeProblem(DeviceNode, CM_PROB_DISABLED);
03068 }
03069
03070 BOOLEAN
03071 IopIsAnyDeviceInstanceEnabled(
03072 IN PUNICODE_STRING ServiceKeyName,
03073 IN HANDLE ServiceHandle OPTIONAL,
03074 IN BOOLEAN LegacyIncluded
03075 )
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100 {
03101
NTSTATUS status;
03102 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
03103 HANDLE serviceEnumHandle, handle, controlHandle;
03104 ULONG i, count, deviceFlags;
03105 UNICODE_STRING unicodeName;
03106 BOOLEAN enabled, setProblem, closeHandle =
FALSE;
03107
PDEVICE_OBJECT physicalDeviceObject;
03108
PDEVICE_NODE deviceNode;
03109
03110
03111
03112
03113
03114
if (!ARGUMENT_PRESENT(ServiceHandle)) {
03115 status =
IopOpenServiceEnumKeys(ServiceKeyName,
03116 KEY_READ,
03117 &ServiceHandle,
03118 &serviceEnumHandle,
03119
FALSE
03120 );
03121 closeHandle =
TRUE;
03122 }
else {
03123 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ENUM);
03124 status =
IopOpenRegistryKey(&serviceEnumHandle,
03125 ServiceHandle,
03126 &unicodeName,
03127 KEY_READ,
03128
FALSE
03129 );
03130 }
03131
if (!
NT_SUCCESS( status )) {
03132
03133
03134
03135
03136
03137
return FALSE;
03138 }
03139
03140
03141
03142
03143
03144
03145 status =
IopGetRegistryValue ( serviceEnumHandle,
03146 REGSTR_VALUE_COUNT,
03147 &keyValueInformation
03148 );
03149 ZwClose(serviceEnumHandle);
03150 count = 0;
03151
if (
NT_SUCCESS(status)) {
03152
if ((keyValueInformation->Type == REG_DWORD) &&
03153 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
03154
03155 count = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
03156 }
03157
ExFreePool(keyValueInformation);
03158 }
03159
if (count == 0) {
03160
if (closeHandle) {
03161 ZwClose(ServiceHandle);
03162 }
03163
return FALSE;
03164 }
03165
03166
03167
03168
03169
03170 enabled =
FALSE;
03171
for (i = 0; i < count; i++) {
03172
03173
03174
03175
03176
03177
03178 status =
IopServiceInstanceToDeviceInstance (
03179 ServiceHandle,
03180
NULL,
03181 i,
03182
NULL,
03183 &handle,
03184 KEY_ALL_ACCESS
03185 );
03186
if (!
NT_SUCCESS(status)) {
03187
continue;
03188 }
03189
03190 physicalDeviceObject =
IopDeviceObjectFromDeviceInstance(handle,
NULL);
03191
if (physicalDeviceObject) {
03192 deviceNode = (
PDEVICE_NODE)physicalDeviceObject->
DeviceObjectExtension->
DeviceNode;
03193
if (deviceNode &&
IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED)) {
03194 ZwClose(handle);
03195
ObDereferenceObject(physicalDeviceObject);
03196
continue;
03197 }
03198 }
03199
03200
03201
03202
03203
03204
03205 deviceFlags = 0;
03206 status =
IopGetRegistryValue(handle,
03207 REGSTR_VALUE_CONFIG_FLAGS,
03208 &keyValueInformation);
03209
if (
NT_SUCCESS(status)) {
03210
if ((keyValueInformation->Type == REG_DWORD) &&
03211 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
03212
03213 deviceFlags = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
03214 }
03215
ExFreePool(keyValueInformation);
03216 }
03217
03218
if (deviceFlags & CONFIGFLAG_DISABLED) {
03219
03220
03221
03222
03223
03224
03225 deviceFlags = CSCONFIGFLAG_DISABLED;
03226
03227 }
else {
03228
03229 status =
IopGetDeviceInstanceCsConfigFlags(
03230 ServiceKeyName,
03231 i,
03232 &deviceFlags
03233 );
03234
03235
if (!
NT_SUCCESS(status)) {
03236 deviceFlags = 0;
03237 }
03238 }
03239
03240
03241
03242
03243
03244
03245
if ((deviceFlags & CSCONFIGFLAG_DISABLED) || (deviceFlags & CSCONFIGFLAG_DO_NOT_START)) {
03246
03247
if (deviceNode) {
03248
IopDisableDevice(deviceNode, handle);
03249 }
03250 }
03251
03252
if (physicalDeviceObject) {
03253
ObDereferenceObject(physicalDeviceObject);
03254 }
03255
03256
03257
03258
03259
03260
03261
if (!(deviceFlags & (CSCONFIGFLAG_DISABLED | CSCONFIGFLAG_DO_NOT_CREATE | CSCONFIGFLAG_DO_NOT_START))) {
03262
03263 ULONG legacy;
03264
03265
03266
03267
03268
03269
if (LegacyIncluded ==
FALSE) {
03270
03271
03272
03273
03274
03275
03276
03277 legacy = 0;
03278 status =
IopGetRegistryValue(handle,
03279 REGSTR_VALUE_LEGACY,
03280 &keyValueInformation
03281 );
03282
if (
NT_SUCCESS(status)) {
03283
if ((keyValueInformation->Type == REG_DWORD) &&
03284 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
03285 legacy = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
03286 }
03287
ExFreePool(keyValueInformation);
03288 }
03289 }
else {
03290 legacy = 0;
03291 }
03292
03293
if (legacy == 0) {
03294
03295
03296
03297
03298
03299 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
03300 status =
IopOpenRegistryKey(&controlHandle,
03301 handle,
03302 &unicodeName,
03303 KEY_ALL_ACCESS,
03304
TRUE
03305 );
03306
if (
NT_SUCCESS(status)) {
03307 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_ACTIVESERVICE);
03308 ZwSetValueKey(
03309 controlHandle,
03310 &unicodeName,
03311
TITLE_INDEX_VALUE,
03312 REG_SZ,
03313 ServiceKeyName->Buffer,
03314 ServiceKeyName->Length +
sizeof(UNICODE_NULL)
03315 );
03316
03317 ZwClose(controlHandle);
03318 }
03319 enabled =
TRUE;
03320 }
03321 }
03322 ZwClose(handle);
03323 }
03324
03325
if (closeHandle) {
03326 ZwClose(ServiceHandle);
03327 }
03328
return enabled;
03329 }
03330
03331 BOOLEAN
03332 IopIsDeviceInstanceEnabled(
03333 IN HANDLE DeviceInstanceHandle,
03334 IN PUNICODE_STRING DeviceInstance,
03335 IN BOOLEAN DisableIfEnabled
03336 )
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358 {
03359
NTSTATUS status;
03360 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
03361 HANDLE handle, handle1;
03362 ULONG deviceFlags;
03363 BOOLEAN enabled, closeHandle =
FALSE;
03364 UNICODE_STRING unicodeString;
03365
PDEVICE_OBJECT deviceObject =
NULL;
03366
PDEVICE_NODE deviceNode =
NULL;;
03367
03368
03369
03370
03371
03372
if (!ARGUMENT_PRESENT(DeviceInstanceHandle)) {
03373 status =
IopOpenRegistryKey(&handle,
03374
NULL,
03375 &
CmRegistryMachineSystemCurrentControlSetEnumName,
03376 KEY_READ,
03377
FALSE
03378 );
03379
03380
if (
NT_SUCCESS( status )) {
03381
03382 status =
IopOpenRegistryKey (
03383 DeviceInstanceHandle,
03384 handle,
03385 DeviceInstance,
03386 KEY_READ,
03387
FALSE
03388 );
03389 ZwClose(handle);
03390 }
03391
03392
if (!
NT_SUCCESS( status )) {
03393
return FALSE;
03394 }
03395 closeHandle =
TRUE;
03396 }
03397
03398 enabled =
TRUE;
03399
03400
03401
03402
03403
03404 deviceObject =
IopDeviceObjectFromDeviceInstance(DeviceInstanceHandle,
NULL);
03405
if (deviceObject) {
03406 deviceNode = (
PDEVICE_NODE)deviceObject->
DeviceObjectExtension->
DeviceNode;
03407
if (deviceNode &&
IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED)) {
03408 enabled =
FALSE;
03409
goto exit;
03410 }
03411 }
03412
03413
03414
03415
03416
03417
03418 deviceFlags = 0;
03419 status =
IopGetRegistryValue(DeviceInstanceHandle,
03420 REGSTR_VALUE_CONFIG_FLAGS,
03421 &keyValueInformation);
03422
if (
NT_SUCCESS(status)) {
03423
if ((keyValueInformation->Type == REG_DWORD) &&
03424 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
03425 deviceFlags = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
03426 }
03427
ExFreePool(keyValueInformation);
03428 }
03429
if (!(deviceFlags & CONFIGFLAG_DISABLED)) {
03430 enabled =
TRUE;
03431
03432
03433
03434
03435 status =
IopOpenRegistryKey(&handle1,
03436
NULL,
03437 &
CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent,
03438 KEY_READ,
03439
FALSE
03440 );
03441
if (
NT_SUCCESS(status) && DeviceInstance !=
NULL) {
03442
03443
03444
03445
03446
03447
03448
03449
03450 PiWstrToUnicodeString(&unicodeString, REGSTR_PATH_CURRENTCONTROLSET);
03451 status =
IopOpenRegistryKey(&handle,
03452 handle1,
03453 &unicodeString,
03454 KEY_READ,
03455
FALSE
03456 );
03457 ZwClose(handle1);
03458
if (
NT_SUCCESS(status)) {
03459 PiWstrToUnicodeString(&unicodeString, REGSTR_KEY_ENUM);
03460 status =
IopOpenRegistryKey(&handle1,
03461 handle,
03462 &unicodeString,
03463 KEY_READ,
03464
FALSE
03465 );
03466 ZwClose(handle);
03467
if (
NT_SUCCESS(status)) {
03468 status =
IopOpenRegistryKey(&handle,
03469 handle1,
03470 DeviceInstance,
03471 KEY_READ,
03472
FALSE
03473 );
03474 ZwClose(handle1);
03475
if (
NT_SUCCESS(status)) {
03476 status =
IopGetRegistryValue(
03477 handle,
03478 REGSTR_VALUE_CSCONFIG_FLAGS,
03479 &keyValueInformation
03480 );
03481
if (
NT_SUCCESS(status)) {
03482
if((keyValueInformation->Type == REG_DWORD) &&
03483 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
03484 deviceFlags = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
03485 }
03486
ExFreePool(keyValueInformation);
03487 }
03488 ZwClose(handle);
03489
if (
NT_SUCCESS(status)) {
03490
if ((deviceFlags & CSCONFIGFLAG_DISABLED) ||
03491 (deviceFlags & CSCONFIGFLAG_DO_NOT_CREATE) ||
03492 (deviceFlags & CSCONFIGFLAG_DO_NOT_START)) {
03493 enabled =
FALSE;
03494 }
03495 }
03496 }
03497 }
03498 }
03499 }
03500 }
else {
03501 enabled =
FALSE;
03502 }
03503
03504
03505
03506
03507
03508
03509
if (enabled ==
FALSE && deviceNode && DisableIfEnabled) {
03510
IopDisableDevice(deviceNode, DeviceInstanceHandle);
03511 }
03512
exit:
03513
if (deviceObject) {
03514
ObDereferenceObject(deviceObject);
03515 }
03516
if (closeHandle) {
03517 ZwClose(DeviceInstanceHandle);
03518 }
03519
return enabled;
03520 }
03521
03522 ULONG
03523 IopDetermineResourceListSize(
03524 IN PCM_RESOURCE_LIST ResourceList
03525 )
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544 {
03545 ULONG totalSize, listSize, descriptorSize, i, j;
03546 PCM_FULL_RESOURCE_DESCRIPTOR fullResourceDesc;
03547 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor;
03548
03549
if (!ResourceList) {
03550 totalSize = 0;
03551 }
else {
03552 totalSize = FIELD_OFFSET(CM_RESOURCE_LIST,
List);
03553 fullResourceDesc = &ResourceList->List[0];
03554
for (i = 0; i < ResourceList->Count; i++) {
03555 listSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
03556 PartialResourceList) +
03557 FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
03558 PartialDescriptors);
03559 partialDescriptor = &fullResourceDesc->PartialResourceList.PartialDescriptors[0];
03560
for (j = 0; j < fullResourceDesc->PartialResourceList.Count; j++) {
03561 descriptorSize =
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
03562
if (partialDescriptor->Type == CmResourceTypeDeviceSpecific) {
03563 descriptorSize += partialDescriptor->u.DeviceSpecificData.DataSize;
03564 }
03565 listSize += descriptorSize;
03566 partialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
03567 ((PUCHAR)partialDescriptor + descriptorSize);
03568 }
03569 totalSize += listSize;
03570 fullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)
03571 ((PUCHAR)fullResourceDesc + listSize);
03572 }
03573 }
03574
return totalSize;
03575 }
03576
03577
PDRIVER_OBJECT
03578 IopReferenceDriverObjectByName (
03579 IN PUNICODE_STRING DriverName
03580 )
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599 {
03600 OBJECT_ATTRIBUTES objectAttributes;
03601 HANDLE driverHandle;
03602
NTSTATUS status;
03603
PDRIVER_OBJECT driverObject;
03604
03605
03606
03607
03608
03609
if (DriverName->Length == 0) {
03610
return NULL;
03611 }
03612
03613 InitializeObjectAttributes(&objectAttributes,
03614 DriverName,
03615 OBJ_CASE_INSENSITIVE,
03616
NULL,
03617
NULL
03618 );
03619 status =
ObOpenObjectByName(&objectAttributes,
03620
IoDriverObjectType,
03621
KernelMode,
03622
NULL,
03623 FILE_READ_ATTRIBUTES,
03624
NULL,
03625 &driverHandle
03626 );
03627
if (
NT_SUCCESS(status)) {
03628
03629
03630
03631
03632
03633 status =
ObReferenceObjectByHandle(driverHandle,
03634 0,
03635
IoDriverObjectType,
03636
KernelMode,
03637 &driverObject,
03638
NULL
03639 );
03640
NtClose(driverHandle);
03641 }
03642
03643
if (
NT_SUCCESS(status)) {
03644
return driverObject;
03645 }
else {
03646
return NULL;
03647 }
03648 }
03649
03650
PDEVICE_OBJECT
03651 IopDeviceObjectFromDeviceInstance (
03652 IN HANDLE DeviceInstanceHandle OPTIONAL,
03653 IN PUNICODE_STRING DeviceInstance OPTIONAL
03654 )
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678 {
03679
NTSTATUS status;
03680 HANDLE handle, deviceHandle =
NULL;
03681
PDEVICE_OBJECT deviceReference =
NULL;
03682 UNICODE_STRING unicodeName;
03683 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
03684
PDEVICE_NODE deviceNode;
03685
03686
PAGED_CODE();
03687
03688
if (!ARGUMENT_PRESENT(DeviceInstanceHandle)) {
03689
03690
03691
03692
03693
03694 status =
IopOpenRegistryKey(&handle,
03695
NULL,
03696 &
CmRegistryMachineSystemCurrentControlSetEnumName,
03697 KEY_READ,
03698
FALSE
03699 );
03700
03701
if (!
NT_SUCCESS( status )) {
03702
return deviceReference;
03703 }
03704
03705
ASSERT(DeviceInstance);
03706 status =
IopOpenRegistryKey (&deviceHandle,
03707 handle,
03708 DeviceInstance,
03709 KEY_READ,
03710
FALSE
03711 );
03712 ZwClose(handle);
03713
if (!
NT_SUCCESS(status)) {
03714
return deviceReference;
03715 }
03716 DeviceInstanceHandle = deviceHandle;
03717 }
03718
03719
03720
03721
03722
03723 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
03724 status =
IopOpenRegistryKey(&handle,
03725 DeviceInstanceHandle,
03726 &unicodeName,
03727 KEY_READ,
03728
FALSE
03729 );
03730
if (!
NT_SUCCESS(status)) {
03731
goto exit;
03732 }
03733
03734 status =
IopGetRegistryValue (handle,
03735 REGSTR_VALUE_DEVICE_REFERENCE,
03736 &keyValueInformation);
03737 ZwClose(handle);
03738
if (
NT_SUCCESS(status)) {
03739
if ((keyValueInformation->Type == REG_DWORD) &&
03740 (keyValueInformation->DataLength ==
sizeof(ULONG_PTR))) {
03741
03742 deviceReference = *(
PDEVICE_OBJECT *)
KEY_VALUE_DATA(keyValueInformation);
03743 }
03744
ExFreePool(keyValueInformation);
03745 }
03746
if (!deviceReference) {
03747
goto exit;
03748 }
03749
03750
03751
03752
03753
03754
03755
03756
if (deviceReference->
Type !=
IO_TYPE_DEVICE) {
03757 deviceReference =
NULL;
03758 }
else {
03759 deviceNode = (
PDEVICE_NODE)deviceReference->
DeviceObjectExtension->
DeviceNode;
03760
if (deviceNode && (deviceNode->
PhysicalDeviceObject == deviceReference)) {
03761
ObReferenceObject(deviceReference);
03762 }
else {
03763 deviceReference =
NULL;
03764 }
03765 }
03766
03767
exit:
03768
if (deviceHandle) {
03769 ZwClose(deviceHandle);
03770 }
03771
return deviceReference;
03772
03773 }
03774
03775
NTSTATUS
03776 IopDeviceObjectToDeviceInstance (
03777 IN
PDEVICE_OBJECT DeviceObject,
03778 IN PHANDLE DeviceInstanceHandle,
03779 IN ACCESS_MASK DesiredAccess
03780 )
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806 {
03807
NTSTATUS status;
03808 HANDLE handle;
03809
PDEVICE_NODE deviceNode;
03810
03811
PAGED_CODE();
03812
03813 status =
IopOpenRegistryKey(&handle,
03814
NULL,
03815 &
CmRegistryMachineSystemCurrentControlSetEnumName,
03816 KEY_READ,
03817
FALSE
03818 );
03819
03820
if (!
NT_SUCCESS( status )) {
03821
return status;
03822 }
03823
03824 deviceNode = (
PDEVICE_NODE) DeviceObject->DeviceObjectExtension->DeviceNode;
03825
if (deviceNode && (deviceNode->
InstancePath.Length != 0)) {
03826 status =
IopOpenRegistryKey (DeviceInstanceHandle,
03827 handle,
03828 &deviceNode->
InstancePath,
03829 DesiredAccess,
03830
FALSE
03831 );
03832 }
else {
03833 status = STATUS_INVALID_DEVICE_REQUEST;
03834 }
03835 ZwClose(handle);
03836
03837
return status;
03838 }
03839
03840
NTSTATUS
03841 IopCleanupDeviceRegistryValues (
03842 IN PUNICODE_STRING InstancePath,
03843 IN BOOLEAN KeepReference
03844 )
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869 {
03870 HANDLE handle, instanceHandle;
03871 UNICODE_STRING unicodeValueName;
03872
NTSTATUS status;
03873 ULONG count = 0;
03874 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
03875
03876
PAGED_CODE();
03877
03878
03879
03880
03881
03882 status =
IopOpenRegistryKey(&handle,
03883
NULL,
03884 &
CmRegistryMachineSystemCurrentControlSetEnumName,
03885 KEY_ALL_ACCESS,
03886
FALSE
03887 );
03888
03889
if (!
NT_SUCCESS( status )) {
03890
return status;
03891 }
03892
03893
03894
03895
03896
03897 status =
IopOpenRegistryKey(&instanceHandle,
03898 handle,
03899 InstancePath,
03900 KEY_ALL_ACCESS,
03901
FALSE
03902 );
03903
03904 ZwClose(handle);
03905
if (!
NT_SUCCESS( status )) {
03906
03907
03908
03909
03910
03911
return status;
03912 }
03913
03914
03915
03916
03917
03918
if (!KeepReference) {
03919
03920
03921
03922
03923
#if 0
03924
03925
03926
03927
03928 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_FOUNDATENUM);
03929 tmpValue = 0;
03930 ZwSetValueKey(instanceHandle,
03931 &unicodeValueName,
03932
TITLE_INDEX_VALUE,
03933 REG_DWORD,
03934 &tmpValue,
03935
sizeof(tmpValue)
03936 );
03937
#endif // (lonnym, verify removal to here)
03938
03939 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL);
03940 status =
IopOpenRegistryKey(&handle,
03941 instanceHandle,
03942 &unicodeValueName,
03943 KEY_ALL_ACCESS,
03944
FALSE
03945 );
03946
if (
NT_SUCCESS( status )) {
03947 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DEVICE_REFERENCE);
03948 ZwDeleteValueKey(handle, &unicodeValueName);
03949 ZwClose(handle);
03950 }
03951
03952
03953
03954
03955
03956 status = PiDeviceRegistration(InstancePath,
03957
FALSE,
03958
NULL
03959 );
03960 }
03961 ZwClose(instanceHandle);
03962
03963
return status;
03964 }
03965
03966
NTSTATUS
03967 IopGetDeviceResourcesFromRegistry (
03968 IN
PDEVICE_OBJECT DeviceObject,
03969 IN ULONG ResourceType,
03970 IN ULONG Preference,
03971 OUT PVOID *Resource,
03972 OUT PULONG Length
03973 )
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003 {
04004
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
04005 HANDLE handle, handlex;
04006
NTSTATUS status;
04007 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
04008 PCM_RESOURCE_LIST cmResource;
04009 PIO_RESOURCE_REQUIREMENTS_LIST ioResource;
04010 ULONG length;
04011 UNICODE_STRING unicodeName;
04012 PWCHAR valueName =
NULL;
04013
04014 *
Resource =
NULL;
04015 *Length = 0;
04016
04017
04018
04019
04020
04021 status =
IopDeviceObjectToDeviceInstance(DeviceObject, &handlex, KEY_READ);
04022
if (!
NT_SUCCESS(status)) {
04023
return status;
04024 }
04025
04026
if (ResourceType ==
QUERY_RESOURCE_LIST) {
04027
04028
04029
04030
04031
04032
if (Preference &
REGISTRY_ALLOC_CONFIG) {
04033
04034
04035
04036
04037
04038 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
04039 status =
IopOpenRegistryKey(&handle,
04040 handlex,
04041 &unicodeName,
04042 KEY_READ,
04043
FALSE
04044 );
04045
if (
NT_SUCCESS(status)) {
04046 status =
IopReadDeviceConfiguration (handle,
REGISTRY_ALLOC_CONFIG, (PCM_RESOURCE_LIST *)
Resource, Length);
04047 ZwClose(handle);
04048
if (
NT_SUCCESS(status)) {
04049 ZwClose(handlex);
04050
return status;
04051 }
04052 }
04053 }
04054
04055 handle =
NULL;
04056
if (Preference &
REGISTRY_FORCED_CONFIG) {
04057
04058 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
04059 status =
IopOpenRegistryKey(&handle,
04060 handlex,
04061 &unicodeName,
04062 KEY_READ,
04063
FALSE
04064 );
04065
if (
NT_SUCCESS(status)) {
04066 status =
IopReadDeviceConfiguration (handle,
REGISTRY_FORCED_CONFIG, (PCM_RESOURCE_LIST *)
Resource, Length);
04067
if (
NT_SUCCESS(status)) {
04068 ZwClose(handle);
04069 ZwClose(handlex);
04070
return status;
04071 }
04072 }
else {
04073 ZwClose(handlex);
04074
return status;
04075 }
04076 }
04077
if (Preference &
REGISTRY_BOOT_CONFIG) {
04078
04079
04080
04081
04082
04083
if (handle ==
NULL) {
04084 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
04085 status =
IopOpenRegistryKey(&handle,
04086 handlex,
04087 &unicodeName,
04088 KEY_READ,
04089
FALSE
04090 );
04091
if (!
NT_SUCCESS(status)) {
04092 ZwClose(handlex);
04093
return status;
04094 }
04095 }
04096 status =
IopReadDeviceConfiguration (handle,
REGISTRY_BOOT_CONFIG, (PCM_RESOURCE_LIST *)
Resource, Length);
04097 }
04098
if (handle) {
04099 ZwClose(handle);
04100 }
04101 }
else {
04102
04103 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
04104 status =
IopOpenRegistryKey(&handle,
04105 handlex,
04106 &unicodeName,
04107 KEY_READ,
04108
FALSE
04109 );
04110
if (
NT_SUCCESS(status)) {
04111
04112
if (Preference &
REGISTRY_OVERRIDE_CONFIGVECTOR) {
04113 valueName = REGSTR_VALUE_OVERRIDE_CONFIG_VECTOR;
04114 }
else if (Preference &
REGISTRY_BASIC_CONFIGVECTOR) {
04115 valueName = REGSTR_VALUE_BASIC_CONFIG_VECTOR;
04116 }
04117
if (valueName) {
04118
04119
04120
04121
04122
04123 status =
IopGetRegistryValue (handle,
04124 valueName,
04125 &keyValueInformation);
04126
if (
NT_SUCCESS(status)) {
04127
04128
04129
04130
04131
04132
if ((keyValueInformation->Type == REG_RESOURCE_REQUIREMENTS_LIST) &&
04133 (keyValueInformation->DataLength != 0)) {
04134
04135 *
Resource =
ExAllocatePool(
PagedPool,
04136 keyValueInformation->DataLength);
04137
if (*Resource) {
04138 PIO_RESOURCE_REQUIREMENTS_LIST ioResource;
04139
04140 *Length = keyValueInformation->DataLength;
04141 RtlMoveMemory(*
Resource,
04142
KEY_VALUE_DATA(keyValueInformation),
04143 keyValueInformation->DataLength);
04144
04145
04146
04147
04148
04149
04150 ioResource = *
Resource;
04151
if (ioResource->InterfaceType == InterfaceTypeUndefined) {
04152 ioResource->BusNumber = 0;
04153 ioResource->InterfaceType =
PnpDefaultInterfaceType;
04154 }
04155 }
else {
04156 status = STATUS_INVALID_PARAMETER_2;
04157 }
04158 }
04159
ExFreePool(keyValueInformation);
04160 }
04161 }
04162 ZwClose(handle);
04163 }
04164 }
04165 ZwClose(handlex);
04166
return status;
04167 }
04168
04169
NTSTATUS
04170 IopReadDeviceConfiguration (
04171 IN HANDLE Handle,
04172 IN ULONG Flags,
04173 OUT PCM_RESOURCE_LIST *CmResource,
04174 OUT PULONG Length
04175 )
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193 {
04194
NTSTATUS status;
04195 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
04196 PWCHAR valueName;
04197
04198 *CmResource =
NULL;
04199 *Length = 0;
04200
04201
if (Flags ==
REGISTRY_ALLOC_CONFIG) {
04202 valueName = REGSTR_VALUE_ALLOC_CONFIG;
04203 }
else if (Flags ==
REGISTRY_FORCED_CONFIG) {
04204 valueName = REGSTR_VALUE_FORCED_CONFIG;
04205 }
else if (Flags ==
REGISTRY_BOOT_CONFIG) {
04206 valueName = REGSTR_VALUE_BOOT_CONFIG;
04207 }
else {
04208
return STATUS_INVALID_PARAMETER_2;
04209 }
04210
04211
04212
04213
04214
04215 status =
IopGetRegistryValue (
Handle,
04216 valueName,
04217 &keyValueInformation);
04218
if (
NT_SUCCESS(status)) {
04219
04220
04221
04222
04223
04224
if ((keyValueInformation->Type == REG_RESOURCE_LIST) &&
04225 (keyValueInformation->DataLength != 0)) {
04226 *CmResource =
ExAllocatePool(
PagedPool,
04227 keyValueInformation->DataLength);
04228
if (*CmResource) {
04229
if (*CmResource) {
04230 *Length = keyValueInformation->DataLength;
04231 RtlMoveMemory(*CmResource,
04232
KEY_VALUE_DATA(keyValueInformation),
04233 keyValueInformation->DataLength);
04234 }
else {
04235 status = STATUS_INSUFFICIENT_RESOURCES;
04236 }
04237 }
04238
ExFreePool(keyValueInformation);
04239
if (*CmResource) {
04240 PCM_RESOURCE_LIST resourceList;
04241 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
04242 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
04243 ULONG j, k, size, count;
04244
04245
04246
04247
04248
04249
04250 resourceList = *CmResource;
04251 cmFullDesc = &resourceList->List[0];
04252
for (j = 0; j < resourceList->Count; j++) {
04253
if (cmFullDesc->InterfaceType == InterfaceTypeUndefined) {
04254 cmFullDesc->BusNumber = 0;
04255 cmFullDesc->InterfaceType =
PnpDefaultInterfaceType;
04256 }
04257 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
04258
for (k = 0; k < cmFullDesc->PartialResourceList.Count; k++) {
04259 size = 0;
04260
switch (cmPartDesc->Type) {
04261
case CmResourceTypeDeviceSpecific:
04262 size = cmPartDesc->u.DeviceSpecificData.DataSize;
04263
break;
04264 }
04265 cmPartDesc++;
04266 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
04267 }
04268 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
04269 }
04270 }
04271 }
else if (keyValueInformation->Type != REG_RESOURCE_LIST) {
04272 status = STATUS_UNSUCCESSFUL;
04273 }
04274 }
04275
return status;
04276 }
04277
04278 PIO_RESOURCE_REQUIREMENTS_LIST
04279 IopCmResourcesToIoResources (
04280 IN ULONG SlotNumber,
04281 IN PCM_RESOURCE_LIST CmResourceList,
04282 IN ULONG Priority
04283 )
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305 {
04306 PIO_RESOURCE_REQUIREMENTS_LIST ioResReqList;
04307 ULONG count = 0, size, i, j;
04308 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
04309 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
04310 PIO_RESOURCE_DESCRIPTOR ioDesc;
04311
04312
04313
04314
04315
04316 cmFullDesc = &CmResourceList->List[0];
04317
for (i = 0; i < CmResourceList->Count; i++) {
04318 count += cmFullDesc->PartialResourceList.Count;
04319 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
04320
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
04321 size = 0;
04322
switch (cmPartDesc->Type) {
04323
case CmResourceTypeDeviceSpecific:
04324 size = cmPartDesc->u.DeviceSpecificData.DataSize;
04325 count--;
04326
break;
04327 }
04328 cmPartDesc++;
04329 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
04330 }
04331 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
04332 }
04333
04334
if (count == 0) {
04335
return NULL;
04336 }
04337
04338
04339
04340
04341
04342 count += CmResourceList->Count - 1;
04343
04344
04345
04346
04347
04348 count++;
04349 ioResReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool(
04350
PagedPool,
04351
sizeof(IO_RESOURCE_REQUIREMENTS_LIST) +
04352 count *
sizeof(IO_RESOURCE_DESCRIPTOR)
04353 );
04354
if (!ioResReqList) {
04355
return NULL;
04356 }
04357
04358
04359
04360
04361
04362 ioResReqList->InterfaceType = CmResourceList->List[0].InterfaceType;
04363 ioResReqList->BusNumber = CmResourceList->List[0].BusNumber;
04364 ioResReqList->SlotNumber = SlotNumber;
04365 ioResReqList->Reserved[0] = 0;
04366 ioResReqList->Reserved[1] = 0;
04367 ioResReqList->Reserved[2] = 0;
04368 ioResReqList->AlternativeLists = 1;
04369 ioResReqList->List[0].Version = 1;
04370 ioResReqList->List[0].Revision = 1;
04371 ioResReqList->List[0].Count = count;
04372
04373
04374
04375
04376
04377 ioDesc = &ioResReqList->List[0].Descriptors[0];
04378 ioDesc->Option = IO_RESOURCE_PREFERRED;
04379 ioDesc->Type = CmResourceTypeConfigData;
04380 ioDesc->ShareDisposition = CmResourceShareShared;
04381 ioDesc->Flags = 0;
04382 ioDesc->Spare1 = 0;
04383 ioDesc->Spare2 = 0;
04384 ioDesc->u.ConfigData.Priority = Priority;
04385 ioDesc++;
04386
04387 cmFullDesc = &CmResourceList->List[0];
04388
for (i = 0; i < CmResourceList->Count; i++) {
04389
if (i != 0) {
04390
04391
04392
04393
04394
04395 ioDesc->Option = IO_RESOURCE_PREFERRED;
04396 ioDesc->Type =
CmResourceTypeReserved;
04397 ioDesc->ShareDisposition = CmResourceShareUndetermined;
04398 ioDesc->Flags = 0;
04399 ioDesc->Spare1 = 0;
04400 ioDesc->Spare2 = 0;
04401
if (cmFullDesc->InterfaceType == InterfaceTypeUndefined) {
04402 ioDesc->u.DevicePrivate.Data[0] =
PnpDefaultInterfaceType;
04403 }
else {
04404 ioDesc->u.DevicePrivate.Data[0] = cmFullDesc->InterfaceType;
04405 }
04406 ioDesc->u.DevicePrivate.Data[1] = cmFullDesc->BusNumber;
04407 ioDesc->u.DevicePrivate.Data[2] = 0;
04408 ioDesc++;
04409 }
04410 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
04411
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
04412 ioDesc->Option = IO_RESOURCE_PREFERRED;
04413 ioDesc->Type = cmPartDesc->Type;
04414 ioDesc->ShareDisposition = cmPartDesc->ShareDisposition;
04415 ioDesc->Flags = cmPartDesc->Flags;
04416 ioDesc->Spare1 = 0;
04417 ioDesc->Spare2 = 0;
04418
04419 size = 0;
04420
switch (cmPartDesc->Type) {
04421
case CmResourceTypePort:
04422 ioDesc->u.Port.MinimumAddress = cmPartDesc->u.Port.Start;
04423 ioDesc->u.Port.MaximumAddress.QuadPart = cmPartDesc->u.Port.Start.QuadPart +
04424 cmPartDesc->u.Port.Length - 1;
04425 ioDesc->u.Port.Alignment = 1;
04426 ioDesc->u.Port.Length = cmPartDesc->u.Port.Length;
04427 ioDesc++;
04428
break;
04429
case CmResourceTypeInterrupt:
04430
#if defined(_X86_)
04431
ioDesc->u.Interrupt.MinimumVector = ioDesc->u.Interrupt.MaximumVector =
04432 cmPartDesc->u.Interrupt.Level;
04433
#else
04434
ioDesc->u.Interrupt.MinimumVector = ioDesc->u.Interrupt.MaximumVector =
04435 cmPartDesc->u.Interrupt.Vector;
04436
#endif
04437
ioDesc++;
04438
break;
04439
case CmResourceTypeMemory:
04440 ioDesc->u.Memory.MinimumAddress = cmPartDesc->u.Memory.Start;
04441 ioDesc->u.Memory.MaximumAddress.QuadPart = cmPartDesc->u.Memory.Start.QuadPart +
04442 cmPartDesc->u.Memory.Length - 1;
04443 ioDesc->u.Memory.Alignment = 1;
04444 ioDesc->u.Memory.Length = cmPartDesc->u.Memory.Length;
04445 ioDesc++;
04446
break;
04447
case CmResourceTypeDma:
04448 ioDesc->u.Dma.MinimumChannel = cmPartDesc->u.Dma.Channel;
04449 ioDesc->u.Dma.MaximumChannel = cmPartDesc->u.Dma.Channel;
04450 ioDesc++;
04451
break;
04452
case CmResourceTypeDeviceSpecific:
04453 size = cmPartDesc->u.DeviceSpecificData.DataSize;
04454
break;
04455
case CmResourceTypeBusNumber:
04456 ioDesc->u.BusNumber.MinBusNumber = cmPartDesc->u.BusNumber.Start;
04457 ioDesc->u.BusNumber.MaxBusNumber = cmPartDesc->u.BusNumber.Start +
04458 cmPartDesc->u.BusNumber.Length - 1;
04459 ioDesc->u.BusNumber.Length = cmPartDesc->u.BusNumber.Length;
04460 ioDesc++;
04461
break;
04462
default:
04463 ioDesc->u.DevicePrivate.Data[0] = cmPartDesc->u.DevicePrivate.Data[0];
04464 ioDesc->u.DevicePrivate.Data[1] = cmPartDesc->u.DevicePrivate.Data[1];
04465 ioDesc->u.DevicePrivate.Data[2] = cmPartDesc->u.DevicePrivate.Data[2];
04466 ioDesc++;
04467
break;
04468 }
04469 cmPartDesc++;
04470 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
04471 }
04472 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
04473 }
04474 ioResReqList->ListSize = (ULONG)((ULONG_PTR)ioDesc - (ULONG_PTR)ioResReqList);
04475
return ioResReqList;
04476 }
04477
04478
NTSTATUS
04479 IopFilterResourceRequirementsList (
04480 IN PIO_RESOURCE_REQUIREMENTS_LIST IoList,
04481 IN PCM_RESOURCE_LIST CmList,
04482 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *FilteredList,
04483 OUT PBOOLEAN ExactMatch
04484 )
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501
04502
04503
04504
04505
04506
04507 {
04508
NTSTATUS status;
04509 PIO_RESOURCE_REQUIREMENTS_LIST ioList, newList;
04510 PIO_RESOURCE_LIST ioResourceList, newIoResourceList, selectedResourceList =
NULL;
04511 PIO_RESOURCE_DESCRIPTOR ioResourceDescriptor, ioResourceDescriptorEnd;
04512 PIO_RESOURCE_DESCRIPTOR newIoResourceDescriptor, configDataDescriptor;
04513 LONG ioResourceDescriptorCount = 0;
04514
USHORT version;
04515 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
04516 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor;
04517 ULONG cmDescriptorCount = 0;
04518 ULONG size, i, j, oldCount, phase;
04519 LONG k, alternativeLists;
04520 BOOLEAN exactMatch;
04521
04522
PAGED_CODE();
04523
04524 *FilteredList =
NULL;
04525 *ExactMatch =
FALSE;
04526
04527
04528
04529
04530
04531
04532
if (IoList ==
NULL || IoList->AlternativeLists == 0) {
04533
if (CmList && CmList->Count != 0) {
04534 *FilteredList =
IopCmResourcesToIoResources (0, CmList, LCPRI_BOOTCONFIG);
04535 }
04536
return STATUS_SUCCESS;
04537 }
04538
04539
04540
04541
04542
04543 ioList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool(
PagedPool, IoList->ListSize);
04544
if (ioList ==
NULL) {
04545
return STATUS_INSUFFICIENT_RESOURCES;
04546 }
04547
04548 RtlMoveMemory(ioList, IoList, IoList->ListSize);
04549
04550
04551
04552
04553
04554
if (CmList ==
NULL || CmList->Count == 0) {
04555 *FilteredList = ioList;
04556
return STATUS_SUCCESS;
04557 }
04558
04559
04560
04561
04562
04563 cmFullDesc = &CmList->List[0];
04564
for (i = 0; i < CmList->Count; i++) {
04565 cmDescriptorCount += cmFullDesc->PartialResourceList.Count;
04566 cmDescriptor = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
04567
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
04568 size = 0;
04569
switch (cmDescriptor->Type) {
04570
case CmResourceTypeConfigData:
04571
case CmResourceTypeDevicePrivate:
04572 cmDescriptorCount--;
04573
break;
04574
case CmResourceTypeDeviceSpecific:
04575 size = cmDescriptor->u.DeviceSpecificData.DataSize;
04576 cmDescriptorCount--;
04577
break;
04578
default:
04579
04580
04581
04582
04583
04584
if (cmDescriptor->Type == CmResourceTypeNull ||
04585 cmDescriptor->Type >= CmResourceTypeMaximum) {
04586 cmDescriptorCount--;
04587 }
04588 }
04589 cmDescriptor++;
04590 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor + size);
04591 }
04592 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor;
04593 }
04594
04595
if (cmDescriptorCount == 0) {
04596 *FilteredList = ioList;
04597
return STATUS_SUCCESS;
04598 }
04599
04600
04601
04602
04603
04604
04605
04606 ioResourceList = ioList->List;
04607 k = ioList->AlternativeLists;
04608
while (--k >= 0) {
04609 ioResourceDescriptor = ioResourceList->Descriptors;
04610 ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count;
04611
while (ioResourceDescriptor < ioResourceDescriptorEnd) {
04612 ioResourceDescriptor->Spare1 = 0;
04613 ioResourceDescriptor++;
04614 }
04615 ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd;
04616 }
04617
04618 ioResourceList = ioList->List;
04619 k = alternativeLists = ioList->AlternativeLists;
04620
while (--k >= 0) {
04621 version = ioResourceList->Version;
04622
if (version == 0xffff) {
04623 version = 1;
04624 }
04625
04626
04627
04628
04629
04630
04631 ioResourceList->Version = 0;
04632 oldCount = ioResourceList->Count;
04633
04634 ioResourceDescriptor = ioResourceList->Descriptors;
04635 ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count;
04636
04637
if (ioResourceDescriptor == ioResourceDescriptorEnd) {
04638
04639
04640
04641
04642
04643 ioResourceList->Version = 0xffff;
04644 ioList->AlternativeLists--;
04645
continue;
04646 }
04647
04648 exactMatch =
TRUE;
04649
04650
04651
04652
04653
04654
04655 cmFullDesc = &CmList->List[0];
04656
for (i = 0; i < CmList->Count; i++) {
04657 cmDescriptor = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
04658
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
04659 size = 0;
04660
switch (cmDescriptor->Type) {
04661
case CmResourceTypeDevicePrivate:
04662
break;
04663
case CmResourceTypeDeviceSpecific:
04664 size = cmDescriptor->u.DeviceSpecificData.DataSize;
04665
break;
04666
default:
04667
if (cmDescriptor->Type == CmResourceTypeNull ||
04668 cmDescriptor->Type >= CmResourceTypeMaximum) {
04669
break;
04670 }
04671
04672
04673
04674
04675
04676
for (phase = 0; phase < 2; phase++) {
04677 ioResourceDescriptor = ioResourceList->Descriptors;
04678
while (ioResourceDescriptor < ioResourceDescriptorEnd) {
04679
if ((ioResourceDescriptor->Type == cmDescriptor->Type) &&
04680 (ioResourceDescriptor->Spare1 == 0)) {
04681 ULONGLONG min1, max1, min2, max2;
04682 ULONG len1 = 1, len2 = 1, align1, align2;
04683 UCHAR share1, share2;
04684
04685 share2 = ioResourceDescriptor->ShareDisposition;
04686 share1 = cmDescriptor->ShareDisposition;
04687
if ((share1 == CmResourceShareUndetermined) ||
04688 (share1 > CmResourceShareShared)) {
04689 share1 = share2;
04690 }
04691
if ((share2 == CmResourceShareUndetermined) ||
04692 (share2 > CmResourceShareShared)) {
04693 share2 = share1;
04694 }
04695 align1 = align2 = 1;
04696
04697
switch (cmDescriptor->Type) {
04698
case CmResourceTypePort:
04699
case CmResourceTypeMemory:
04700 min1 = cmDescriptor->u.Port.Start.QuadPart;
04701 max1 = cmDescriptor->u.Port.Start.QuadPart + cmDescriptor->u.Port.Length - 1;
04702 len1 = cmDescriptor->u.Port.Length;
04703 min2 = ioResourceDescriptor->u.Port.MinimumAddress.QuadPart;
04704 max2 = ioResourceDescriptor->u.Port.MaximumAddress.QuadPart;
04705 len2 = ioResourceDescriptor->u.Port.Length;
04706 align2 = ioResourceDescriptor->u.Port.Alignment;
04707
break;
04708
case CmResourceTypeInterrupt:
04709 max1 = min1 = cmDescriptor->u.Interrupt.Vector;
04710 min2 = ioResourceDescriptor->u.Interrupt.MinimumVector;
04711 max2 = ioResourceDescriptor->u.Interrupt.MaximumVector;
04712
break;
04713
case CmResourceTypeDma:
04714 min1 = max1 =cmDescriptor->u.Dma.Channel;
04715 min2 = ioResourceDescriptor->u.Dma.MinimumChannel;
04716 max2 = ioResourceDescriptor->u.Dma.MaximumChannel;
04717
break;
04718
case CmResourceTypeBusNumber:
04719 min1 = cmDescriptor->u.BusNumber.Start;
04720 max1 = cmDescriptor->u.BusNumber.Start + cmDescriptor->u.BusNumber.Length - 1;
04721 len1 = cmDescriptor->u.BusNumber.Length;
04722 min2 = ioResourceDescriptor->u.BusNumber.MinBusNumber;
04723 max2 = ioResourceDescriptor->u.BusNumber.MaxBusNumber;
04724 len2 = ioResourceDescriptor->u.BusNumber.Length;
04725
break;
04726
default:
04727
ASSERT(0);
04728
break;
04729 }
04730
if (phase == 0) {
04731
if (share1 == share2 && min2 == min1 && max2 >= max1 && len2 >= len1) {
04732
04733
04734
04735
04736
04737
if (max2 != max1) {
04738 exactMatch =
FALSE;
04739 }
04740 ioResourceList->Version++;
04741 ioResourceDescriptor->Spare1 = 0x80;
04742
if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
04743 PIO_RESOURCE_DESCRIPTOR ioDesc;
04744
04745 ioDesc = ioResourceDescriptor;
04746 ioDesc--;
04747
while (ioDesc >= ioResourceList->Descriptors) {
04748 ioDesc->Type = CmResourceTypeNull;
04749 ioResourceList->Count--;
04750
if (ioDesc->Option == IO_RESOURCE_ALTERNATIVE) {
04751 ioDesc--;
04752 }
else {
04753
break;
04754 }
04755 }
04756 }
04757 ioResourceDescriptor->Option = IO_RESOURCE_PREFERRED;
04758 ioResourceDescriptor->Flags = cmDescriptor->Flags;
04759
if (ioResourceDescriptor->Type == CmResourceTypePort ||
04760 ioResourceDescriptor->Type == CmResourceTypeMemory) {
04761 ioResourceDescriptor->u.Port.MinimumAddress.QuadPart = min1;
04762 ioResourceDescriptor->u.Port.MaximumAddress.QuadPart = min1 + len2 - 1;
04763 ioResourceDescriptor->u.Port.Alignment = 1;
04764 }
else if (ioResourceDescriptor->Type == CmResourceTypeBusNumber) {
04765 ioResourceDescriptor->u.BusNumber.MinBusNumber = (ULONG)min1;
04766 ioResourceDescriptor->u.BusNumber.MaxBusNumber = (ULONG)(min1 + len2 - 1);
04767 }
04768 ioResourceDescriptor++;
04769
while (ioResourceDescriptor < ioResourceDescriptorEnd) {
04770
if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
04771 ioResourceDescriptor->Type = CmResourceTypeNull;
04772 ioResourceDescriptor++;
04773 ioResourceList->Count--;
04774 }
else {
04775
break;
04776 }
04777 }
04778 phase = 1;
04779
break;
04780 }
else {
04781 ioResourceDescriptor++;
04782 }
04783 }
else {
04784 exactMatch =
FALSE;
04785
if (share1 == share2 && min2 <= min1 && max2 >= max1 && len2 >= len1 &&
04786 (min1 & (align2 - 1)) == 0) {
04787
04788
04789
04790
04791
04792
04793
04794
switch (cmDescriptor->Type) {
04795
case CmResourceTypePort:
04796
case CmResourceTypeMemory:
04797 ioResourceDescriptor->u.Port.MinimumAddress.QuadPart = min1;
04798 ioResourceDescriptor->u.Port.MaximumAddress.QuadPart = min1 + len2 - 1;
04799
break;
04800
case CmResourceTypeInterrupt:
04801
case CmResourceTypeDma:
04802 ioResourceDescriptor->u.Interrupt.MinimumVector = (ULONG)min1;
04803 ioResourceDescriptor->u.Interrupt.MaximumVector = (ULONG)max1;
04804
break;
04805
case CmResourceTypeBusNumber:
04806 ioResourceDescriptor->u.BusNumber.MinBusNumber = (ULONG)min1;
04807 ioResourceDescriptor->u.BusNumber.MaxBusNumber = (ULONG)(min1 + len2 - 1);
04808
break;
04809 }
04810 ioResourceList->Version++;
04811 ioResourceDescriptor->Spare1 = 0x80;
04812 ioResourceDescriptor->Flags = cmDescriptor->Flags;
04813
if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
04814 PIO_RESOURCE_DESCRIPTOR ioDesc;
04815
04816 ioDesc = ioResourceDescriptor;
04817 ioDesc--;
04818
while (ioDesc >= ioResourceList->Descriptors) {
04819 ioDesc->Type = CmResourceTypeNull;
04820 ioResourceList->Count--;
04821
if (ioDesc->Option == IO_RESOURCE_ALTERNATIVE) {
04822 ioDesc--;
04823 }
else {
04824
break;
04825 }
04826 }
04827 }
04828 ioResourceDescriptor->Option = IO_RESOURCE_PREFERRED;
04829 ioResourceDescriptor++;
04830
while (ioResourceDescriptor < ioResourceDescriptorEnd) {
04831
if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
04832 ioResourceDescriptor->Type = CmResourceTypeNull;
04833 ioResourceList->Count--;
04834 ioResourceDescriptor++;
04835 }
else {
04836
break;
04837 }
04838 }
04839
break;
04840 }
else {
04841 ioResourceDescriptor++;
04842 }
04843 }
04844 }
else {
04845 ioResourceDescriptor++;
04846 }
04847 }
04848 }
04849 }
04850
04851
04852
04853
04854
04855 cmDescriptor++;
04856 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor + size);
04857 }
04858
04859
04860
04861
04862
04863 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor;
04864 }
04865
04866
if (ioResourceList->Version != (
USHORT)cmDescriptorCount) {
04867
04868
04869
04870
04871
04872
04873 ioResourceList->Version = 0xffff;
04874 ioList->AlternativeLists--;
04875 }
else {
04876
if ((ioResourceList->Count == cmDescriptorCount) ||
04877 (ioResourceList->Count == (cmDescriptorCount + 1) &&
04878 ioResourceList->Descriptors[0].Type == CmResourceTypeConfigData)) {
04879
if (selectedResourceList) {
04880 ioResourceList->Version = 0xffff;
04881 ioList->AlternativeLists--;
04882 }
else {
04883 selectedResourceList = ioResourceList;
04884 ioResourceDescriptorCount += ioResourceList->Count;
04885 ioResourceList->Version = version;
04886
if (exactMatch) {
04887 *ExactMatch =
TRUE;
04888 }
04889 }
04890 }
else {
04891 ioResourceDescriptorCount += ioResourceList->Count;
04892 ioResourceList->Version = version;
04893 }
04894 }
04895 ioResourceList->Count = oldCount;
04896
04897
04898
04899
04900
04901 ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd;
04902 }
04903
04904
04905
04906
04907
04908
if (ioList->AlternativeLists == 0) {
04909 *FilteredList =
IopCmResourcesToIoResources (0, CmList, LCPRI_BOOTCONFIG);
04910
ExFreePool(ioList);
04911
return STATUS_SUCCESS;
04912 }
04913
04914
04915
04916
04917
04918
04919 size =
sizeof(IO_RESOURCE_REQUIREMENTS_LIST) +
04920
sizeof(IO_RESOURCE_LIST) * (ioList->AlternativeLists - 1) +
04921
sizeof(IO_RESOURCE_DESCRIPTOR) * (ioResourceDescriptorCount);
04922 newList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool(
PagedPool, size);
04923
if (newList ==
NULL) {
04924
ExFreePool(ioList);
04925
return STATUS_INSUFFICIENT_RESOURCES;
04926 }
04927
04928
04929
04930
04931
04932 newList->ListSize = size;
04933 newList->InterfaceType = CmList->List->InterfaceType;
04934 newList->BusNumber = CmList->List->BusNumber;
04935 newList->SlotNumber = ioList->SlotNumber;
04936
if (ioList->AlternativeLists > 1) {
04937 *ExactMatch =
FALSE;
04938 }
04939 newList->AlternativeLists = ioList->AlternativeLists;
04940 ioResourceList = ioList->List;
04941 newIoResourceList = newList->List;
04942
while (--alternativeLists >= 0) {
04943 ioResourceDescriptor = ioResourceList->Descriptors;
04944 ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count;
04945
if (ioResourceList->Version == 0xffff) {
04946 ioResourceList = (PIO_RESOURCE_LIST)ioResourceDescriptorEnd;
04947
continue;
04948 }
04949 newIoResourceList->Version = ioResourceList->Version;
04950 newIoResourceList->Revision = ioResourceList->Revision;
04951
04952 newIoResourceDescriptor = newIoResourceList->Descriptors;
04953
if (ioResourceDescriptor->Type != CmResourceTypeConfigData) {
04954 newIoResourceDescriptor->Option = IO_RESOURCE_PREFERRED;
04955 newIoResourceDescriptor->Type = CmResourceTypeConfigData;
04956 newIoResourceDescriptor->ShareDisposition = CmResourceShareShared;
04957 newIoResourceDescriptor->Flags = 0;
04958 newIoResourceDescriptor->Spare1 = 0;
04959 newIoResourceDescriptor->Spare2 = 0;
04960 newIoResourceDescriptor->u.ConfigData.Priority = LCPRI_BOOTCONFIG;
04961 configDataDescriptor = newIoResourceDescriptor;
04962 newIoResourceDescriptor++;
04963 }
else {
04964 newList->ListSize -=
sizeof(IO_RESOURCE_DESCRIPTOR);
04965 configDataDescriptor = newIoResourceDescriptor;
04966 }
04967
04968
while (ioResourceDescriptor < ioResourceDescriptorEnd) {
04969
if (ioResourceDescriptor->Type != CmResourceTypeNull) {
04970 *newIoResourceDescriptor = *ioResourceDescriptor;
04971 newIoResourceDescriptor++;
04972 }
04973 ioResourceDescriptor++;
04974 }
04975 newIoResourceList->Count = (ULONG)(newIoResourceDescriptor - newIoResourceList->Descriptors);
04976
04977
04978 configDataDescriptor->u.ConfigData.Priority = LCPRI_BOOTCONFIG;
04979
04980
04981
04982
04983
04984
04985 newIoResourceList = (PIO_RESOURCE_LIST) newIoResourceDescriptor;
04986 ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd;
04987 }
04988
ASSERT((PUCHAR)newIoResourceList == ((PUCHAR)newList + newList->ListSize));
04989
04990 *FilteredList = newList;
04991
ExFreePool(ioList);
04992
return STATUS_SUCCESS;
04993 }
04994
04995
NTSTATUS
04996 IopMergeFilteredResourceRequirementsList (
04997 IN PIO_RESOURCE_REQUIREMENTS_LIST IoList1,
04998 IN PIO_RESOURCE_REQUIREMENTS_LIST IoList2,
04999 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *MergedList
05000 )
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023 {
05024
NTSTATUS status = STATUS_SUCCESS;
05025 PIO_RESOURCE_REQUIREMENTS_LIST ioList, newList;
05026 ULONG size;
05027 PUCHAR p;
05028
05029
PAGED_CODE();
05030
05031 *MergedList =
NULL;
05032
05033
05034
05035
05036
05037
05038
if ((IoList1 ==
NULL || IoList1->AlternativeLists == 0) &&
05039 (IoList2 ==
NULL || IoList2->AlternativeLists == 0)) {
05040
return status;
05041 }
05042 ioList =
NULL;
05043
if (IoList1 ==
NULL || IoList1->AlternativeLists == 0) {
05044 ioList = IoList2;
05045 }
else if (IoList2 ==
NULL || IoList2->AlternativeLists == 0) {
05046 ioList = IoList1;
05047 }
05048
if (ioList) {
05049 newList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool(
PagedPool, ioList->ListSize);
05050
if (newList ==
NULL) {
05051
return STATUS_INSUFFICIENT_RESOURCES;
05052 }
05053 RtlMoveMemory(newList, ioList, ioList->ListSize);
05054 *MergedList = newList;
05055
return status;
05056 }
05057
05058
05059
05060
05061
05062 size = IoList1->ListSize + IoList2->ListSize - FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST,
List);
05063 newList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool(
05064
PagedPool,
05065 size
05066 );
05067
if (newList ==
NULL) {
05068
return STATUS_INSUFFICIENT_RESOURCES;
05069 }
05070 p = (PUCHAR)newList;
05071 RtlMoveMemory(p, IoList1, IoList1->ListSize);
05072 p += IoList1->ListSize;
05073 RtlMoveMemory(p,
05074 &IoList2->List[0],
05075 size - IoList1->ListSize
05076 );
05077 newList->ListSize = size;
05078 newList->AlternativeLists += IoList2->AlternativeLists;
05079 *MergedList = newList;
05080
return status;
05081
05082 }
05083
05084
NTSTATUS
05085 IopMergeCmResourceLists (
05086 IN PCM_RESOURCE_LIST List1,
05087 IN PCM_RESOURCE_LIST List2,
05088 IN OUT PCM_RESOURCE_LIST *MergedList
05089 )
05090
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104
05105
05106
05107
05108
05109
05110
05111
05112 {
05113
NTSTATUS status = STATUS_SUCCESS;
05114 PCM_RESOURCE_LIST cmList, newList;
05115 ULONG size, size1, size2;
05116 PUCHAR p;
05117
05118
PAGED_CODE();
05119
05120 *MergedList =
NULL;
05121
05122
05123
05124
05125
05126
05127
if ((List1 ==
NULL || List1->Count == 0) &&
05128 (List2 ==
NULL || List2->Count == 0)) {
05129
return status;
05130 }
05131
05132 cmList =
NULL;
05133
if (List1 ==
NULL || List1->Count == 0) {
05134 cmList = List2;
05135 }
else if (List2 ==
NULL || List2->Count == 0) {
05136 cmList = List1;
05137 }
05138
if (cmList) {
05139 size =
IopDetermineResourceListSize(cmList);
05140 newList = (PCM_RESOURCE_LIST)
ExAllocatePool(
PagedPool, size);
05141
if (newList ==
NULL) {
05142
return STATUS_INSUFFICIENT_RESOURCES;
05143 }
05144 RtlMoveMemory(newList, cmList, size);
05145 *MergedList = newList;
05146
return status;
05147 }
05148
05149
05150
05151
05152
05153 size1 =
IopDetermineResourceListSize(List1);
05154 size2 =
IopDetermineResourceListSize(List2);
05155 size = size1 + size2;
05156 newList = (PCM_RESOURCE_LIST)
ExAllocatePool(
05157
PagedPool,
05158 size
05159 );
05160
if (newList ==
NULL) {
05161
return STATUS_INSUFFICIENT_RESOURCES;
05162 }
05163 p = (PUCHAR)newList;
05164 RtlMoveMemory(p, List1, size1);
05165 p += size1;
05166 RtlMoveMemory(p,
05167 &List2->List[0],
05168 size2 - FIELD_OFFSET(CM_RESOURCE_LIST,
List)
05169 );
05170 newList->Count = List1->Count + List2->Count;
05171 *MergedList = newList;
05172
return status;
05173
05174 }
05175
05176 BOOLEAN
05177 IopIsLegacyDriver (
05178 IN
PDRIVER_OBJECT DriverObject
05179 )
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197 {
05198
05199
PAGED_CODE();
05200
05201
05202
05203
05204
05205
if (DriverObject->DriverExtension->AddDevice) {
05206
return FALSE;
05207 }
05208
05209
05210
05211
05212
05213
if (DriverObject->Flags &
DRVO_LEGACY_DRIVER) {
05214
return TRUE;
05215 }
else {
05216
return FALSE;
05217 }
05218 }
05219
05220
USHORT
05221 IopGetGroupOrderIndex (
05222 IN HANDLE ServiceHandle
05223 )
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244 {
05245
NTSTATUS status;
05246 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
05247 UNICODE_STRING *groupTable, group;
05248 HANDLE handle;
05249 ULONG count, index;
05250
05251
PAGED_CODE();
05252
05253
05254
05255
05256
05257 PiWstrToUnicodeString(&group,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ServiceGroupOrder");
05258 status =
IopOpenRegistryKey(&handle,
05259
NULL,
05260 &group,
05261 KEY_READ,
05262
FALSE
05263 );
05264
05265
if (!
NT_SUCCESS( status )) {
05266
return NO_MORE_GROUP;
05267 }
05268
05269
05270
05271
05272
05273 status =
IopGetRegistryValue (handle,
05274
L"List",
05275 &keyValueInformation);
05276 ZwClose(handle);
05277
if (
NT_SUCCESS(status)) {
05278
05279
if ((keyValueInformation->Type == REG_MULTI_SZ) &&
05280 (keyValueInformation->DataLength != 0)) {
05281 status =
IopRegMultiSzToUnicodeStrings(keyValueInformation, &groupTable, &count);
05282
if (!
NT_SUCCESS(status)) {
05283
ExFreePool(keyValueInformation);
05284
return NO_MORE_GROUP;
05285 }
05286 }
05287
ExFreePool(keyValueInformation);
05288 }
05289
05290
if (ServiceHandle ==
NULL) {
05291
IopFreeUnicodeStringList(groupTable, count);
05292
return (
USHORT)(count + 1);
05293 }
05294
05295
05296
05297
05298
05299
05300 status =
IopGetRegistryValue (ServiceHandle,
05301
L"Group",
05302 &keyValueInformation);
05303
if (
NT_SUCCESS(status)) {
05304
05305
05306
05307
05308
05309
if ((keyValueInformation->Type == REG_SZ) &&
05310 (keyValueInformation->DataLength != 0)) {
05311
IopRegistryDataToUnicodeString(&group,
05312 (PWSTR)
KEY_VALUE_DATA(keyValueInformation),
05313 keyValueInformation->DataLength
05314 );
05315 }
05316 }
else {
05317
05318
05319
05320
05321
05322
IopFreeUnicodeStringList(groupTable, count);
05323
return (
USHORT)count;
05324 }
05325
05326 index = 0;
05327
for (index = 0; index < count; index++) {
05328
if (
RtlEqualUnicodeString(&group, &groupTable[index],
TRUE)) {
05329
break;
05330 }
05331 }
05332
ExFreePool(keyValueInformation);
05333
IopFreeUnicodeStringList(groupTable, count);
05334
return (
USHORT)index;
05335 }
05336
05337
VOID
05338 IopDeleteLegacyKey(
05339 IN
PDRIVER_OBJECT DriverObject
05340 )
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359 {
05360 WCHAR buffer[100];
05361
NTSTATUS status;
05362 UNICODE_STRING deviceName, instanceName, unicodeName, *serviceName;
05363 ULONG length;
05364 HANDLE handle, handle1, handlex, enumHandle;
05365 ULONG legacy;
05366 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
05367
PDEVICE_OBJECT deviceObject;
05368
PDEVICE_NODE deviceNode;
05369
05370 serviceName = &DriverObject->DriverExtension->ServiceKeyName;
05371
05372
KeEnterCriticalRegion();
05373
ExAcquireResourceShared(&
PpRegistryDeviceResource,
TRUE);
05374
05375 status =
IopOpenRegistryKey(&enumHandle,
05376
NULL,
05377 &
CmRegistryMachineSystemCurrentControlSetEnumName,
05378 KEY_ALL_ACCESS,
05379
FALSE
05380 );
05381
05382
if (!
NT_SUCCESS(status)) {
05383
goto exit;
05384 }
05385
05386 length = _snwprintf(buffer,
sizeof(buffer) /
sizeof(WCHAR),
L"ROOT\\LEGACY_%s", serviceName->Buffer);
05387 deviceName.MaximumLength =
sizeof(buffer);
05388
ASSERT(length <=
sizeof(buffer) - 10);
05389 deviceName.Length = (
USHORT)(length *
sizeof(WCHAR));
05390 deviceName.Buffer = buffer;
05391
05392 status =
IopOpenRegistryKey(&handle1,
05393 enumHandle,
05394 &deviceName,
05395 KEY_ALL_ACCESS,
05396
FALSE
05397 );
05398
05399
if (
NT_SUCCESS(status)) {
05400
05401 deviceName.Buffer[deviceName.Length /
sizeof(WCHAR)] =
05402 OBJ_NAME_PATH_SEPARATOR;
05403 deviceName.Length +=
sizeof(WCHAR);
05404 PiUlongToInstanceKeyUnicodeString(
05405 &instanceName,
05406 buffer + deviceName.Length /
sizeof(WCHAR),
05407
sizeof(buffer) - deviceName.Length,
05408 0
05409 );
05410 deviceName.Length += instanceName.Length;
05411
05412
05413 status =
IopOpenRegistryKey(
05414 &handle,
05415 handle1,
05416 &instanceName,
05417 KEY_ALL_ACCESS,
05418
FALSE
05419 );
05420
if (
NT_SUCCESS(status)) {
05421 legacy = 1;
05422 status =
IopGetRegistryValue (handle,
05423 REGSTR_VALUE_LEGACY,
05424 &keyValueInformation);
05425
if (
NT_SUCCESS(status)) {
05426
if ((keyValueInformation->Type == REG_DWORD) &&
05427 (keyValueInformation->DataLength >=
sizeof(ULONG))) {
05428 legacy = *(PULONG)
KEY_VALUE_DATA(keyValueInformation);
05429 }
05430
ExFreePool(keyValueInformation);
05431 }
05432
if (legacy != 0) {
05433
05434
05435
05436
05437
05438 deviceObject =
IopDeviceObjectFromDeviceInstance(handle,
NULL);
05439
if (deviceObject) {
05440
05441
PDEVICE_NODE devNodex, devNodey;
05442
05443 deviceNode = (
PDEVICE_NODE)deviceObject->
DeviceObjectExtension->
DeviceNode;
05444
if (deviceNode) {
05445
if (deviceNode->
Flags &
DNF_MADEUP) {
05446
05447
05448
05449
05450 deviceNode->
Flags &= ~
DNF_STARTED;
05451
IopSetDevNodeProblem(deviceNode, CM_PROB_DEVICE_NOT_THERE);
05452
05453
05454
05455
05456
05457
IopReleaseDeviceResources(deviceNode);
05458 devNodex = deviceNode;
05459
while (devNodex) {
05460 devNodey = devNodex;
05461 devNodex = (
PDEVICE_NODE)devNodey->
OverUsed2.NextResourceDeviceNode;
05462 devNodey->
OverUsed2.NextResourceDeviceNode =
NULL;
05463 devNodey->
OverUsed1.LegacyDeviceNode =
NULL;
05464 }
05465
05466 deviceNode->Flags &= ~
DNF_MADEUP;
05467
IoDeleteDevice(deviceObject);
05468 }
05469 }
05470
ObDereferenceObject(deviceObject);
05471 }
05472
05473 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
05474 status =
IopOpenRegistryKey(&handlex,
05475 handle,
05476 &unicodeName,
05477 KEY_ALL_ACCESS,
05478
FALSE
05479 );
05480
if (
NT_SUCCESS(status)) {
05481 ZwDeleteKey(handlex);
05482 }
05483 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
05484 status =
IopOpenRegistryKey(&handlex,
05485 handle,
05486 &unicodeName,
05487 KEY_ALL_ACCESS,
05488
FALSE
05489 );
05490
if (
NT_SUCCESS(status)) {
05491 ZwDeleteKey(handlex);
05492 }
05493
05494 ZwClose(enumHandle);
05495
05496
05497
05498
05499
05500
05501
05502
IopCleanupDeviceRegistryValues(&deviceName,
FALSE);
05503 ZwDeleteKey(handle);
05504 ZwDeleteKey(handle1);
05505 }
else {
05506 ZwClose(handle);
05507 ZwClose(handle1);
05508 ZwClose(enumHandle);
05509 }
05510 }
else {
05511 ZwClose(handle1);
05512 ZwClose(enumHandle);
05513 }
05514 }
else {
05515 ZwClose(enumHandle);
05516 }
05517
exit:
05518
ExReleaseResource(&
PpRegistryDeviceResource);
05519
KeLeaveCriticalRegion();
05520
return;
05521 }
05522
05523
NTSTATUS
05524 IopDeviceCapabilitiesToRegistry (
05525 IN
PDEVICE_OBJECT DeviceObject
05526 )
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545 {
05546
PDEVICE_NODE deviceNode = (
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
05547 HANDLE handle;
05548
NTSTATUS status;
05549 UNICODE_STRING unicodeName;
05550 ULONG tmpValue;
05551
DEVICE_CAPABILITIES capabilities;
05552
05553
PAGED_CODE();
05554
05555
05556
05557
05558
05559 status =
IopDeviceObjectToDeviceInstance(DeviceObject, &handle, KEY_ALL_ACCESS);
05560
if (!
NT_SUCCESS(status)) {
05561
return status;
05562 }
05563
05564 status =
IopQueryDeviceCapabilities(deviceNode, &capabilities);
05565
if (!
NT_SUCCESS(status)) {
05566
return status;
05567 }
05568
05569
if (deviceNode->
Flags &
DNF_HAS_BOOT_CONFIG) {
05570 capabilities.
SurpriseRemovalOK = 0;
05571 }
05572
05573 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_CAPABILITIES);
05574 tmpValue = (capabilities.
LockSupported) |
05575 (capabilities.
EjectSupported << 1) |
05576 (capabilities.
Removable << 2) |
05577 (capabilities.
DockDevice << 3) |
05578 (capabilities.
UniqueID << 4) |
05579 (capabilities.
SilentInstall << 5) |
05580 (capabilities.
RawDeviceOK << 6) |
05581 (capabilities.
SurpriseRemovalOK << 7);
05582
05583 status = ZwSetValueKey(
05584 handle,
05585 &unicodeName,
05586
TITLE_INDEX_VALUE,
05587 REG_DWORD,
05588 &tmpValue,
05589
sizeof(tmpValue)
05590 );
05591
05592 ZwClose(handle);
05593
return status;
05594 }
05595
05596
NTSTATUS
05597 IopRestartDeviceNode(
05598 IN
PDEVICE_NODE DeviceNode
05599 )
05600 {
05601
PAGED_CODE();
05602
05603
ASSERT(!(
IopDoesDevNodeHaveProblem(DeviceNode) ||
05604 (DeviceNode->Flags & (
DNF_STARTED |
05605
DNF_ADDED |
05606
DNF_RESOURCE_ASSIGNED |
05607
DNF_RESOURCE_REPORTED)) ||
05608 (DeviceNode->UserFlags &
DNUF_WILL_BE_REMOVED)));
05609
05610
ASSERT(DeviceNode->Flags &
DNF_ENUMERATED);
05611
05612
if (!(DeviceNode->Flags &
DNF_ENUMERATED)) {
05613
return STATUS_UNSUCCESSFUL;
05614 }
05615
05616 DeviceNode->UserFlags &= ~
DNUF_NEED_RESTART;
05617
05618
#if DBG_SCOPE
05619
DeviceNode->FailureStatus = 0;
05620
if (DeviceNode->PreviousResourceList) {
05621
ExFreePool(DeviceNode->PreviousResourceList);
05622 DeviceNode->PreviousResourceList =
NULL;
05623 }
05624
if (DeviceNode->PreviousResourceRequirements) {
05625
ExFreePool(DeviceNode->PreviousResourceRequirements);
05626 DeviceNode->PreviousResourceRequirements =
NULL;
05627 }
05628
#endif
05629
05630
05631
05632
05633
05634
05635
if (DeviceNode->Flags &
DNF_PROCESSED) {
05636
05637 DeviceNode->Flags &= ~(
DNF_PROCESSED |
DNF_ENUMERATION_REQUEST_QUEUED |
DNF_RESOURCE_REQUIREMENTS_CHANGED);
05638
05639
if (DeviceNode->ServiceName.Length != 0) {
05640
ExFreePool(DeviceNode->ServiceName.Buffer);
05641
RtlInitUnicodeString(&DeviceNode->ServiceName,
NULL);
05642 }
05643
05644
if (DeviceNode->InstanceOrdinal.Length != 0) {
05645
ExFreePool(DeviceNode->InstanceOrdinal.Buffer);
05646
RtlInitUnicodeString(&DeviceNode->InstanceOrdinal,
NULL);
05647 }
05648
05649
if (DeviceNode->ResourceRequirements !=
NULL) {
05650
ExFreePool(DeviceNode->ResourceRequirements);
05651 DeviceNode->ResourceRequirements =
NULL;
05652 DeviceNode->Flags &= ~
DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED;
05653 }
05654 }
05655
05656
ASSERT(DeviceNode->ServiceName.Length == 0 &&
05657 DeviceNode->ServiceName.MaximumLength == 0 &&
05658 DeviceNode->ServiceName.Buffer ==
NULL);
05659
05660
ASSERT(DeviceNode->InstanceOrdinal.Length == 0 &&
05661 DeviceNode->InstanceOrdinal.MaximumLength == 0 &&
05662 DeviceNode->InstanceOrdinal.Buffer ==
NULL);
05663
05664
ASSERT(!(DeviceNode->Flags &
05665 ~(
DNF_MADEUP |
DNF_ENUMERATED |
DNF_HAS_BOOT_CONFIG |
05666
DNF_BOOT_CONFIG_RESERVED |
DNF_NO_RESOURCE_REQUIRED)));
05667
05668
return STATUS_SUCCESS;
05669 }