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