Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

pnpsubs.c File Reference

#include "iop.h"

Go to the source code of this file.

Functions

VOID IopDisableDevice (IN PDEVICE_NODE DeviceNode, IN HANDLE Handle)
NTSTATUS IopCreateMadeupNode (IN PUNICODE_STRING ServiceKeyName, OUT PHANDLE ReturnedHandle, OUT PUNICODE_STRING KeyName, OUT PULONG InstanceNumber, IN BOOLEAN ResourceOwned)
NTSTATUS IopRemoveStringFromValueKey (IN HANDLE Handle, IN PWSTR ValueName, IN PUNICODE_STRING String)
NTSTATUS IopAppendStringToValueKey (IN HANDLE Handle, IN PWSTR ValueName, IN PUNICODE_STRING String, IN BOOLEAN Create)
BOOLEAN IopConcatenateUnicodeStrings (OUT PUNICODE_STRING Destination, IN PUNICODE_STRING String1, IN PUNICODE_STRING String2 OPTIONAL)
NTSTATUS IopPrepareDriverLoading (IN PUNICODE_STRING KeyName, IN HANDLE KeyHandle, IN PIMAGE_NT_HEADERS Header)
NTSTATUS IopServiceInstanceToDeviceInstance (IN HANDLE ServiceKeyHandle OPTIONAL, IN PUNICODE_STRING ServiceKeyName OPTIONAL, IN ULONG ServiceInstanceOrdinal, OUT PUNICODE_STRING DeviceInstanceRegistryPath OPTIONAL, OUT PHANDLE DeviceInstanceHandle OPTIONAL, IN ACCESS_MASK DesiredAccess)
NTSTATUS IopOpenRegistryKeyEx (OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess)
NTSTATUS IopCreateRegistryKeyEx (OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
NTSTATUS IopOpenServiceEnumKeys (IN PUNICODE_STRING ServiceKeyName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE ServiceHandle OPTIONAL, OUT PHANDLE ServiceEnumHandle OPTIONAL, IN BOOLEAN CreateEnum)
NTSTATUS IopGetDeviceInstanceCsConfigFlags (IN PUNICODE_STRING DeviceInstance, OUT PULONG CsConfigFlags)
NTSTATUS IopGetServiceInstanceCsConfigFlags (IN PUNICODE_STRING ServiceKeyName, IN ULONG Instance, OUT PULONG CsConfigFlags)
NTSTATUS IopSetServiceInstanceCsConfigFlags (IN PUNICODE_STRING ServiceKeyName, IN ULONG Instance, IN ULONG CsConfigFlags)
NTSTATUS IopOpenCurrentHwProfileDeviceInstanceKey (OUT PHANDLE Handle, IN PUNICODE_STRING ServiceKeyName, IN ULONG Instance, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Create)
NTSTATUS IopApplyFunctionToSubKeys (IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG Flags, IN PIOP_SUBKEY_CALLBACK_ROUTINE SubKeyCallbackRoutine, IN OUT PVOID Context)
NTSTATUS IopRegMultiSzToUnicodeStrings (IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation, OUT PUNICODE_STRING *UnicodeStringList, OUT PULONG UnicodeStringCount)
NTSTATUS IopApplyFunctionToServiceInstances (IN HANDLE ServiceKeyHandle OPTIONAL, IN PUNICODE_STRING ServiceKeyName OPTIONAL, IN ACCESS_MASK DesiredAccess, IN BOOLEAN IgnoreNonCriticalErrors, IN PIOP_SUBKEY_CALLBACK_ROUTINE DevInstCallbackRoutine, IN OUT PVOID Context, OUT PULONG ServiceInstanceOrdinal OPTIONAL)
NTSTATUS IopMarkDuplicateDevice (IN PUNICODE_STRING TargetKeyName, IN ULONG TargetInstance, IN PUNICODE_STRING SourceKeyName, IN ULONG SourceInstance)
BOOLEAN IopIsDuplicatedDevices (IN PCM_RESOURCE_LIST Configuration1, IN PCM_RESOURCE_LIST Configuration2, IN PHAL_BUS_INFORMATION BusInfo1 OPTIONAL, IN PHAL_BUS_INFORMATION BusInfo2 OPTIONAL)
VOID IopFreeUnicodeStringList (IN PUNICODE_STRING UnicodeStringList, IN ULONG StringCount)
NTSTATUS IopDriverLoadingFailed (IN HANDLE ServiceHandle OPTIONAL, IN PUNICODE_STRING ServiceName OPTIONAL)
BOOLEAN IopIsAnyDeviceInstanceEnabled (IN PUNICODE_STRING ServiceKeyName, IN HANDLE ServiceHandle OPTIONAL, IN BOOLEAN LegacyIncluded)
BOOLEAN IopIsDeviceInstanceEnabled (IN HANDLE DeviceInstanceHandle OPTIONAL, IN PUNICODE_STRING DeviceInstance, IN BOOLEAN DisableIfEnabled)
ULONG IopDetermineResourceListSize (IN PCM_RESOURCE_LIST ResourceList)
PDRIVER_OBJECT IopReferenceDriverObjectByName (IN PUNICODE_STRING DriverName)
PDEVICE_OBJECT IopDeviceObjectFromDeviceInstance (IN HANDLE DeviceInstanceHandle OPTIONAL, IN PUNICODE_STRING DeviceInstance OPTIONAL)
NTSTATUS IopDeviceObjectToDeviceInstance (IN PDEVICE_OBJECT DeviceObject, IN PHANDLE DeviceInstanceHandle, IN ACCESS_MASK DesiredAccess)
NTSTATUS IopCleanupDeviceRegistryValues (IN PUNICODE_STRING InstancePath, IN BOOLEAN KeepReference)
NTSTATUS IopGetDeviceResourcesFromRegistry (IN PDEVICE_OBJECT DeviceObject, IN ULONG ResourceType, IN ULONG Preference, OUT PVOID *Resource, OUT PULONG Length)
NTSTATUS IopReadDeviceConfiguration (IN HANDLE Handle, IN ULONG Flags, OUT PCM_RESOURCE_LIST *CmResource, OUT PULONG Length)
PIO_RESOURCE_REQUIREMENTS_LIST IopCmResourcesToIoResources (IN ULONG SlotNumber, IN PCM_RESOURCE_LIST CmResourceList, IN ULONG Priority)
NTSTATUS IopFilterResourceRequirementsList (IN PIO_RESOURCE_REQUIREMENTS_LIST IoList, IN PCM_RESOURCE_LIST CmList, IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *FilteredList, OUT PBOOLEAN ExactMatch)
NTSTATUS IopMergeFilteredResourceRequirementsList (IN PIO_RESOURCE_REQUIREMENTS_LIST IoList1, IN PIO_RESOURCE_REQUIREMENTS_LIST IoList2, IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *MergedList)
NTSTATUS IopMergeCmResourceLists (IN PCM_RESOURCE_LIST List1, IN PCM_RESOURCE_LIST List2, IN OUT PCM_RESOURCE_LIST *MergedList)
BOOLEAN IopIsLegacyDriver (IN PDRIVER_OBJECT DriverObject)
USHORT IopGetGroupOrderIndex (IN HANDLE ServiceHandle)
VOID IopDeleteLegacyKey (IN PDRIVER_OBJECT DriverObject)
NTSTATUS IopDeviceNodeCapabilitiesToRegistry (IN PDEVICE_NODE DeviceNode)
NTSTATUS IopDeviceCapabilitiesToRegistry (IN PDEVICE_NODE DeviceNode, IN PDEVICE_CAPABILITIES Capabilities)
NTSTATUS IopRestartDeviceNode (IN PDEVICE_NODE DeviceNode)
BOOLEAN IopDeleteKeyRecursiveCallback (IN HANDLE KeyHandle, IN PUNICODE_STRING KeyName, IN OUT PVOID Context)
NTSTATUS IopDeleteKeyRecursive (IN HANDLE ParentKey OPTIONAL, IN PWCHAR KeyName)


Function Documentation

NTSTATUS IopAppendStringToValueKey IN HANDLE  Handle,
IN PWSTR  ValueName,
IN PUNICODE_STRING  String,
IN BOOLEAN  Create
 

Definition at line 546 of file pnpsubs.c.

References Create(), ExAllocatePool, ExFreePool(), Handle, IopGetRegistryValue(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, RtlInitUnicodeString(), String, TITLE_INDEX_VALUE, and ValueName.

00555 : 00556 00557 This routine appends a string to a value entry specified by ValueName 00558 under an already opened registry handle. If the ValueName is not present 00559 and Create is TRUE, a new value entry will be created using the name 00560 ValueName. 00561 00562 Parameters: 00563 00564 Handle - Supplies the handle to a registry key whose value entry will 00565 be modified. 00566 00567 ValueName - Supplies a pointer to a string to specify the value entry. 00568 00569 String - Supplies a unicode string to append to the value entry. 00570 00571 Create - Supplies a BOOLEAN variable to indicate if the ValueName 00572 value entry should be created if it is not present. 00573 00574 Return Value: 00575 00576 Status code that indicates whether or not the function was successful. 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 // Read registry value entry data 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 // if no valid entry exists and user said ok to create one 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) { // empty or one NULL WCHAR 00620 00621 ExFreePool(keyValueInformation); 00622 keyValueInformation = NULL; 00623 } 00624 00625 // 00626 // Allocate a buffer to hold new data for the specified key value entry 00627 // Make sure the buffer is at least an empty MULTI_SZ big. 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 // Copy the existing data to our newly allocated buffer, if any 00646 // 00647 00648 if (keyValueInformation) { 00649 00650 // 00651 // Note we need to remove a UNICODE_NULL because the 00652 // MULTI_SZ has two terminating UNICODE_NULL. 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 // Append the user specified unicode string to our buffer 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 // Finally write the data to the specified registy value entry 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 }

NTSTATUS IopApplyFunctionToServiceInstances IN HANDLE ServiceKeyHandle  OPTIONAL,
IN PUNICODE_STRING ServiceKeyName  OPTIONAL,
IN ACCESS_MASK  DesiredAccess,
IN BOOLEAN  IgnoreNonCriticalErrors,
IN PIOP_SUBKEY_CALLBACK_ROUTINE  DevInstCallbackRoutine,
IN OUT PVOID  Context,
OUT PULONG ServiceInstanceOrdinal  OPTIONAL
 

Definition at line 2209 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, ExAllocatePool, ExFreePool(), FALSE, IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopOpenServiceEnumKeys(), IopRegistryDataToUnicodeString, KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PNP_SCRATCH_BUFFER_SIZE, Status, and TRUE.

02221 : 02222 02223 This routine enumerates all device instances referenced by the instance 02224 ordinal entries under a service's volatile Enum key, and calls 02225 the specified callback routine for each instance's corresponding subkey 02226 under HKLM\System\Enum. 02227 02228 Arguments: 02229 02230 ServiceKeyHandle - Optional handle to the service entry. If this parameter 02231 is not specified, then the service key name must be given in 02232 ServiceKeyName (if both parameters are specified, then ServiceKeyHandle 02233 is used, and ServiceKeyName is ignored). 02234 02235 ServiceKeyName - Optional name of the service entry key (under 02236 HKLM\CurrentControlSet\Services). If this parameter is not specified, 02237 then ServiceKeyHandle must contain a handle to the desired service key. 02238 02239 DesiredAccess - Specifies the desired access that the callback routine 02240 needs to the enumerated device instance keys. If no desired access is 02241 specified (i.e., DesiredAccess is zero), then no handle will be opened 02242 for the device instance keys, and the callback will be passed a NULL for 02243 its DeviceInstanceHandle parameter. 02244 02245 IgnoreNonCriticalErrors - Specifies whether this function should 02246 immediately terminate on all errors, or only on critical ones. 02247 An example of a non-critical error is when an enumerated device instance 02248 key cannot be opened for the desired access. 02249 02250 DevInstCallbackRoutine - Supplies a pointer to a function that will 02251 be called for each device instance key referenced by a service instance 02252 entry under the service's volatile Enum subkey. The prototype of the 02253 function is as follows: 02254 02255 typedef BOOLEAN (*PIOP_SUBKEY_CALLBACK_ROUTINE) ( 02256 IN HANDLE DeviceInstanceHandle, 02257 IN PUNICODE_STRING DeviceInstancePath, 02258 IN OUT PVOID Context 02259 ); 02260 02261 where DeviceInstanceHandle is the handle to an enumerated device instance 02262 key, DeviceInstancePath is the registry path (relative to 02263 HKLM\System\Enum) to this device instance, and Context is a pointer to 02264 user-defined data. 02265 02266 This function should return TRUE to continue enumeration, or 02267 FALSE to terminate it. 02268 02269 Context - Supplies a pointer to user-defined data that will be passed 02270 in to the callback routine at each device instance key invocation. 02271 02272 ServiceInstanceOrdinal - Optionally, receives the service instance ordinal (1 based) 02273 that terminated the enumeration, or the total number of instances enumerated 02274 if the enumeration completed without being aborted. 02275 02276 Return Value: 02277 02278 NT status code indicating whether the device instance keys were successfully 02279 enumerated. Note that this does not provide information on the success or 02280 failure of the callback routine--if desired, this information should be 02281 stored in the Context structure. 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 // First, open up the volatile Enum subkey under the specified service entry. 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 // Find out how many instances are referenced in the service's Enum key. 02319 // 02320 02321 ServiceInstanceCount = 0; // assume none. 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 // If 'Count' value entry not found, consider this to mean there are simply 02342 // no device instance controlled by this service. 02343 // 02344 Status = STATUS_SUCCESS; 02345 } 02346 02347 // 02348 // Now, enumerate each service instance, and call the specified callback function 02349 // for the corresponding device instance. 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 // Set DeviceInstanceHandle to NULL, since we won't be opening up the 02366 // device instance keys. 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 ( // i was initialized to zero above. 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 // We have retrieved a (non-empty) string for this service instance. 02413 // If the user specified a non-zero value for the DesiredAccess 02414 // parameter, we will attempt to open up the corresponding device 02415 // instance key under HKLM\System\Enum. 02416 // 02417 if (DesiredAccess) { 02418 Status = IopOpenRegistryKeyEx( &DeviceInstanceHandle, 02419 SystemEnumHandle, 02420 &TempUnicodeString, 02421 DesiredAccess 02422 ); 02423 } 02424 02425 if (NT_SUCCESS(Status)) { 02426 // 02427 // Invoke the specified callback routine for this device instance. 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 }

NTSTATUS IopApplyFunctionToSubKeys IN HANDLE BaseHandle  OPTIONAL,
IN PUNICODE_STRING KeyName  OPTIONAL,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  Flags,
IN PIOP_SUBKEY_CALLBACK_ROUTINE  SubKeyCallbackRoutine,
IN OUT PVOID  Context
 

Definition at line 1844 of file pnpsubs.c.

References ExAllocatePool, ExFreePool(), FALSE, FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS, FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS, Handle, IopOpenRegistryKeyEx(), KeyName, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, Status, TRUE, and USHORT.

01855 : 01856 01857 This routine enumerates all subkeys under the specified key, and calls 01858 the specified callback routine for each subkey. 01859 01860 Arguments: 01861 01862 BaseHandle - Optional handle to the base registry path. If KeyName is also 01863 specified, then KeyName represents a subkey under this path. If KeyName 01864 is not specified, the subkeys are enumerated under this handle. If this 01865 parameter is not specified, then the full path to the base key must be 01866 given in KeyName. 01867 01868 KeyName - Optional name of the key whose subkeys are to be enumerated. 01869 01870 DesiredAccess - Specifies the desired access that the callback routine 01871 needs to the subkeys. If no desired access is specified (i.e., 01872 DesiredAccess is zero), then no handle will be opened for the 01873 subkeys, and the callback will be passed a NULL for its SubKeyHandle 01874 parameter. 01875 01876 Flags - Controls the behavior of subkey enumeration. Currently, the 01877 following flags are defined: 01878 01879 FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS - Specifies whether this 01880 function should immediately terminate on all errors, or only on 01881 critical ones. An example of a non-critical error is when an 01882 enumerated subkey cannot be opened for the desired access. 01883 01884 FUNCTION_SUBKEY_DELETE_SUBKEYS - Specifies that each subkey should be 01885 deleted after the specified SubKeyCallBackRoutine has been performed 01886 on it. Note that this is NOT a recursive delete on each of the 01887 subkeys, just an attempt to delete the subkey itself. It the subkey 01888 contains children, this will fail. 01889 01890 SubKeyCallbackRoutine - Supplies a pointer to a function that will 01891 be called for each subkey found under the 01892 specified key. The prototype of the function 01893 is as follows: 01894 01895 typedef BOOLEAN (*PIOP_SUBKEY_CALLBACK_ROUTINE) ( 01896 IN HANDLE SubKeyHandle, 01897 IN PUNICODE_STRING SubKeyName, 01898 IN OUT PVOID Context 01899 ); 01900 01901 where SubKeyHandle is the handle to an enumerated subkey under the 01902 specified key, SubKeyName is its name, and Context is a pointer to 01903 user-defined data. 01904 01905 This function should return TRUE to continue enumeration, or 01906 FALSE to terminate it. 01907 01908 Context - Supplies a pointer to user-defined data that will be passed 01909 in to the callback routine at each subkey invocation. 01910 01911 Return Value: 01912 01913 NT status code indicating whether the subkeys were successfully 01914 enumerated. Note that this does not provide information on the 01915 success or failure of the callback routine--if desired, this 01916 information should be stored in the Context structure. 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 // Use an initial key name buffer size large enough for a 20-character key 01927 // (+ terminating NULL) 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 // Enumerate the subkeys until we run out of them. 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 // Try again with larger buffer. 01980 // 01981 ExFreePool(KeyInformation); 01982 KeyInformation = NULL; 01983 KeyInformationLength = RequiredBufferLength; 01984 continue; 01985 01986 } else if(Status == STATUS_NO_MORE_ENTRIES) { 01987 // 01988 // break out of loop 01989 // 01990 Status = STATUS_SUCCESS; 01991 break; 01992 01993 } else { 01994 // 01995 // This is a non-critical error. 01996 // 01997 if(Flags & FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS) { 01998 goto ContinueWithNextSubKey; 01999 } else { 02000 break; 02001 } 02002 } 02003 } 02004 02005 // 02006 // Initialize a unicode string with this key name. Note that this string 02007 // WILL NOT be NULL-terminated. 02008 // 02009 SubKeyName.Length = SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength; 02010 SubKeyName.Buffer = KeyInformation->Name; 02011 02012 // 02013 // If DesiredAccess is non-zero, open a handle to this subkey. 02014 // 02015 if(DesiredAccess) { 02016 Status = IopOpenRegistryKeyEx( &SubKeyHandle, 02017 Handle, 02018 &SubKeyName, 02019 DesiredAccess 02020 ); 02021 if(!NT_SUCCESS(Status)) { 02022 // 02023 // This is a non-critical error. 02024 // 02025 if(Flags & FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS) { 02026 goto ContinueWithNextSubKey; 02027 } else { 02028 break; 02029 } 02030 } 02031 } 02032 02033 // 02034 // Invoke the supplied callback function for this subkey. 02035 // 02036 ContinueEnumeration = SubKeyCallbackRoutine(SubKeyHandle, &SubKeyName, Context); 02037 02038 if (DesiredAccess) { 02039 if (ContinueEnumeration && 02040 (Flags & FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS)) { 02041 // 02042 // Delete the key when asked to, only if the callback routine 02043 // was successful, otherwise we may not be able to. 02044 // 02045 Status = ZwDeleteKey(SubKeyHandle); 02046 } 02047 ZwClose(SubKeyHandle); 02048 } 02049 02050 if(!ContinueEnumeration) { 02051 // 02052 // Enumeration has been aborted. 02053 // 02054 Status = STATUS_SUCCESS; 02055 break; 02056 02057 } 02058 02059 ContinueWithNextSubKey: 02060 if (!(Flags & FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS)) { 02061 // 02062 // Only increment the enumeration index for non-deleted subkeys 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 }

NTSTATUS IopCleanupDeviceRegistryValues IN PUNICODE_STRING  InstancePath,
IN BOOLEAN  KeepReference
 

Definition at line 3960 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, FALSE, IopOpenRegistryKeyEx(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and TITLE_INDEX_VALUE.

03967 : 03968 03969 This routine cleans up a device instance key when the device is no 03970 longer present/enumerated. If the device is registered to a Service 03971 the Service's enum key will also been cleaned up. 03972 03973 Note the caller must lock the RegistryDeciceResource 03974 03975 Arguments: 03976 03977 InstancePath - supplies a pointer to the name of the device instance key. 03978 03979 KeepReference - supplies a boolean value to indicate if we should remove the 03980 device instance path to device object mapping. 03981 03982 Return Value: 03983 03984 status 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 // Open System\CurrentControlSet\Enum 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 // Open the device instance key 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 // There is no registry key for the ServiceKeyName information. 04026 // 04027 04028 return status; 04029 } 04030 04031 // 04032 // Delete the DeviceReference value name under Control key 04033 // 04034 04035 if (!KeepReference) { 04036 04037 // 04038 // BUGBUG (lonnym)--verify that removal of the following code fragment is valid. 04039 // 04040 #if 0 04041 // 04042 // Set the 'FoundAtEnum' value to false. 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 // Deregister the device from its controlling service's service enum key 04070 // 04071 04072 status = PiDeviceRegistration( InstancePath, FALSE, NULL ); 04073 } 04074 04075 ZwClose(instanceHandle); 04076 04077 return status; 04078 }

PIO_RESOURCE_REQUIREMENTS_LIST IopCmResourcesToIoResources IN ULONG  SlotNumber,
IN PCM_RESOURCE_LIST  CmResourceList,
IN ULONG  Priority
 

Definition at line 4392 of file pnpsubs.c.

References CmResourceTypeReserved, ExAllocatePool, NULL, PagedPool, and PnpDefaultInterfaceType.

04400 : 04401 04402 This routines converts the input CmResourceList to IO_RESOURCE_REQUIREMENTS_LIST. 04403 04404 Arguments: 04405 04406 SlotNumber - supplies the SlotNumber the resources refer to. 04407 04408 CmResourceList - the cm resource list to convert. 04409 04410 Priority - specifies the priority of the logconfig 04411 04412 Return Value: 04413 04414 returns a IO_RESOURCE_REQUIREMENTS_LISTST if succeeds. Otherwise a NULL value is 04415 returned. 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 // First determine number of descriptors required. 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 // Count the extra descriptors for InterfaceType and BusNumber information. 04453 // 04454 04455 count += CmResourceList->Count - 1; 04456 04457 // 04458 // Allocate heap space for IO RESOURCE REQUIREMENTS LIST 04459 // 04460 04461 count++; // add one for CmResourceTypeConfigData 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 // Parse the cm resource descriptor and build its corresponding IO resource descriptor 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 // Generate a CmResourceTypeConfigData descriptor 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 // Set up descriptor to remember the InterfaceType and BusNumber. 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 }

BOOLEAN IopConcatenateUnicodeStrings OUT PUNICODE_STRING  Destination,
IN PUNICODE_STRING  String1,
IN PUNICODE_STRING String2  OPTIONAL
 

Definition at line 695 of file pnpsubs.c.

References ExAllocatePool, FALSE, PagedPool, String1, String2, TRUE, and USHORT.

00703 : 00704 00705 This routine returns a buffer containing the concatenation of the 00706 two specified strings. Since String2 is optional, this function may 00707 also be used to make a copy of a unicode string. Paged pool space 00708 is allocated for the destination string. Caller must release the 00709 space once done with it. 00710 00711 Parameters: 00712 00713 Destination - Supplies a variable to receive the handle of the 00714 newly created key. 00715 00716 String1 - Supplies a pointer to the frist UNICODE_STRING. 00717 00718 String2 - Supplies an optional pointer to the second UNICODE_STRING. 00719 00720 Return Value: 00721 00722 Status code that indicates whether or not the function was successful. 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 }

NTSTATUS IopCreateMadeupNode IN PUNICODE_STRING  ServiceKeyName,
OUT PHANDLE  ReturnedHandle,
OUT PUNICODE_STRING  KeyName,
OUT PULONG  InstanceNumber,
IN BOOLEAN  ResourceOwned
 

Definition at line 91 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumRootName, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), ExReleaseResource, FALSE, IopConcatenateUnicodeStrings(), IopCreateRegistryKeyEx(), IopFixupDeviceId(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopOpenServiceEnumKeys(), IopRegistryDataToUnicodeString, KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, KeyName, L, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PpDeviceRegistration(), PpRegistryDeviceResource, ReturnedHandle, RtlFreeUnicodeString(), RtlInitUnicodeString(), RtlUpcaseUnicodeString(), TITLE_INDEX_VALUE, and TRUE.

00101 : 00102 00103 This routine creates a new instance node under System\Enum\Root\*Madeup<Name> 00104 key and all the required default value entries. Also a value entry under 00105 Service\ServiceKeyName\Enum is created to point to the newly created madeup 00106 entry. A handle and the keyname of the new key are returned to caller. 00107 Caller must free the unicode string when he is done with it. 00108 00109 Parameters: 00110 00111 ServiceKeyName - Supplies a pointer to the name of the subkey in the 00112 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 00113 that caused the driver to load. This is the RegistryPath parameter 00114 to the DriverEntry routine. 00115 00116 ReturnedHandle - Supplies a variable to receive the handle of the 00117 newly created key. 00118 00119 KeyName - Supplies a variable to receive the name of the newly created 00120 key. 00121 00122 InstanceNumber - supplies a variable to receive the InstanceNumber value 00123 entry created under service\name\enum subkey. 00124 00125 ResourceOwned - supplies a BOOLEAN variable to indicate if caller owns 00126 the registry resource exclusively. 00127 00128 Return Value: 00129 00130 Status code that indicates whether or not the function was successful. 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 // Open LocalMachine\System\CurrentControlSet\Enum\Root 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 // Open, and create if not already exist, System\Enum\Root\LEGACY_<ServiceName> 00169 // First, try to find the ServiceName by extracting it from user supplied 00170 // ServiceKeyName. 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), // reserve first WCHAR space 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 // Prepare newly created registry key name for returning to caller 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 // Create all the default value entry for the newly created key. 00256 // Service = ServiceKeyName 00257 // FoundAtEnum = 1 00258 // Class = "LegacyDriver" 00259 // ClassGUID = GUID for legacy driver class 00260 // ConfigFlags = 0 00261 // 00262 // Create "Control" subkey with "NewlyCreated" value key 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 // We'll keep the null-terminated service name buffer around for a while, 00304 // because we may need it later on for the DeviceDesc in case the service 00305 // has no DisplayName. 00306 // 00307 // ExFreePool(p); 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 // Initialize DeviceDesc= value entry. If the service key has a "DisplayName" 00355 // value entry, it is used as the DeviceDesc value. Otherwise, the service key 00356 // name is used. 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 // No DisplayName--use the service key name. 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 // Create new value entry under ServiceKeyName\Enum to reflect the newly 00417 // added made-up device instance node. 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 // There is no registry key for the ServiceKeyName information. 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 }

NTSTATUS IopCreateRegistryKeyEx OUT PHANDLE  Handle,
IN HANDLE BaseHandle  OPTIONAL,
IN PUNICODE_STRING  KeyName,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  CreateOptions,
OUT PULONG Disposition  OPTIONAL
 

Definition at line 1156 of file pnpsubs.c.

References FALSE, Handle, KeyName, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, TRUE, and USHORT.

Referenced by ComPortDBAdd(), EisaBuildEisaDeviceNode(), IoOpenDeviceInterfaceRegistryKey(), IoOpenDeviceRegistryKey(), IopBuildCmResourceList(), IopCreateMadeupNode(), IopGetDeviceInterfaces(), IopGetRootDevices(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopIsAnyDeviceInstanceEnabled(), IopIsFirmwareDisabled(), IopOpenCurrentHwProfileDeviceInstanceKey(), IopOpenDeviceParametersSubkey(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopOpenServiceEnumKeys(), IopPrepareDriverLoading(), IopProcessNewDeviceNode(), IopProcessSetInterfaceState(), IopRegisterDeviceInterface(), IopReleaseDeviceResources(), IopStoreSystemPartitionInformation(), IopWriteAllocatedResourcesToRegistry(), IoReportDetectedDevice(), PnPBiosCopyIoDecode(), and PnPBiosWriteInfo().

01167 : 01168 01169 Opens or creates a registry key using the name 01170 passed in based at the BaseHandle node. This name may specify a key 01171 that is actually a registry path, in which case each intermediate subkey 01172 will be created (if Create is TRUE). 01173 01174 NOTE: Creating a registry path (i.e., more than one of the keys in the path 01175 do not presently exist) requires that a BaseHandle be specified. 01176 01177 Arguments: 01178 01179 Handle - Pointer to the handle which will contain the registry key that 01180 was opened. 01181 01182 BaseHandle - Optional handle to the base path from which the key must be opened. 01183 If KeyName specifies a registry path that must be created, then this parameter 01184 must be specified, and KeyName must be a relative path. 01185 01186 KeyName - Name of the Key that must be opened/created (possibly a registry path) 01187 01188 DesiredAccess - Specifies the desired access that the caller needs to 01189 the key. 01190 01191 CreateOptions - Options passed to ZwCreateKey. 01192 01193 Disposition - If Create is TRUE, this optional pointer receives a ULONG indicating 01194 whether the key was newly created: 01195 01196 REG_CREATED_NEW_KEY - A new Registry Key was created 01197 REG_OPENED_EXISTING_KEY - An existing Registry Key was opened 01198 01199 Return Value: 01200 01201 The function value is the final status of the operation. 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 // Attempt to create the path as specified. We have to try it this 01225 // way first, because it allows us to create a key without a BaseHandle 01226 // (if only the last component of the registry path is not present). 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 // If we get to here, then there must be more than one element of the 01240 // registry path that does not currently exist. We will now parse the 01241 // specified path, extracting each component and doing a ZwCreateKey on it. 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 // There's more to do, so close the previous base handle (if necessary), 01254 // and replace it with the current key handle. 01255 // 01256 if(closeBaseHandle > 1) { 01257 ZwClose(handles[baseHandleIndex]); 01258 } 01259 baseHandleIndex = keyHandleIndex; 01260 keyHandleIndex = (keyHandleIndex + 1) & 1; // toggle between 0 and 1. 01261 handles[keyHandleIndex] = NULL; 01262 01263 // 01264 // Extract next component out of the specified registry path. 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 // Then we have a non-empty path component (key name). Attempt 01273 // to create this key. 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 // Increment the closeBaseHandle value, which basically tells us whether 01295 // the BaseHandle passed in has been 'shifted out' of our way, so that 01296 // we should start closing our base handles when we're finished with them. 01297 // 01298 closeBaseHandle++; 01299 } else { 01300 continueParsing = FALSE; 01301 continue; 01302 } 01303 } else { 01304 // 01305 // Either a path separator ('\') was included at the beginning of 01306 // the path, or we hit 2 consecutive separators. 01307 // 01308 status = STATUS_INVALID_PARAMETER; 01309 continueParsing = FALSE; 01310 continue; 01311 } 01312 01313 if((pathCurPtr == pathEndPtr) || 01314 ((pathBeginPtr = pathCurPtr + 1) == pathEndPtr)) { 01315 // 01316 // Then we've reached the end of the path 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 }

NTSTATUS IopDeleteKeyRecursive IN HANDLE ParentKey  OPTIONAL,
IN PWCHAR  KeyName
 

Definition at line 5902 of file pnpsubs.c.

References IopDeleteKeyRecursiveCallback(), IopOpenRegistryKeyEx(), KeyName, NT_SUCCESS, NTSTATUS(), PAGED_CODE, and RtlInitUnicodeString().

Referenced by IopRemoveDeviceInterfaces(), IopUnregisterDeviceInterface(), and PnPBiosWriteInfo().

05908 : 05909 05910 Recursively deletes all subkeys of KeyName, then deletes KeyName. 05911 05912 Arguments: 05913 05914 ParentKey - Handle to the parent key of KeyName. If NULL then KeyName is 05915 expected to start with \Registry. 05916 05917 KeyName - Name of subkey to delete, as a NULL terminated UNICODE string. 05918 05919 Return Value: 05920 05921 STATUS_SUCCESS if no errors, otherwise the appropriate error. 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 // Attempt to open the key name we were given 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 // Recusively delete all subkeys 05944 // 05945 result = IopDeleteKeyRecursiveCallback(hKey, 05946 &unicodeKeyName, 05947 (PVOID)&status); 05948 if (result) { 05949 // 05950 // It is safe to delete this key 05951 // 05952 status = ZwDeleteKey(hKey); 05953 } 05954 ZwClose(hKey); 05955 } 05956 05957 return status; 05958 }

BOOLEAN IopDeleteKeyRecursiveCallback IN HANDLE  KeyHandle,
IN PUNICODE_STRING  KeyName,
IN OUT PVOID  Context
 

Definition at line 5846 of file pnpsubs.c.

References FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS, FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS, IopApplyFunctionToSubKeys(), IopDeleteKeyRecursiveCallback(), KeyName, NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopDeleteKeyRecursive(), and IopDeleteKeyRecursiveCallback().

05853 : 05854 05855 This is a callback routine to IopApplyFunctionToSubkeys, that gets called 05856 through IopDeleteKeyRecursive. This routine prepares a given key for 05857 deletion by deleting all of its subkeys. This is done, using 05858 IopApplyFunctionToSubkeys, with instructions to delete all enumerated 05859 subkeys, and calling this routine as a callback routine, if necessary, until 05860 no subkeys remain. KeyHandle can then be successfully deleted by the 05861 caller. 05862 05863 Arguments: 05864 05865 KeyHandle - Handle to a subkey that has been enumerated by 05866 IopApplyFunctionToSubkeys. 05867 05868 KeyName - Name of the subkey whose handle is specified by KeyHandle. 05869 05870 Context - Supplies a pointer to user-defined data that will be passed 05871 in to the callback routine at each subkey invocation. 05872 05873 Return Value: 05874 05875 BOOLEAN that returns whether or not the given key can be safely deleted. 05876 05877 --*/ 05878 { 05879 NTSTATUS status = STATUS_SUCCESS; 05880 05881 PAGED_CODE(); 05882 05883 UNREFERENCED_PARAMETER(KeyName); 05884 05885 // 05886 // delete any subkeys, recursively if necessary 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 }

VOID IopDeleteLegacyKey IN PDRIVER_OBJECT  DriverObject  ) 
 

Definition at line 5453 of file pnpsubs.c.

References ASSERT, CmRegistryMachineSystemCurrentControlSetEnumName, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_MADEUP, DNF_STARTED, ExAcquireResourceShared, ExFreePool(), exit, ExReleaseResource, FALSE, _DEVICE_NODE::Flags, IoDeleteDevice(), IopCleanupDeviceRegistryValues(), IopDeviceObjectFromDeviceInstance(), IopDoesDevNodeHaveProblem, IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopReleaseDeviceResources(), IopSetDevNodeProblem, KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, L, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, _DEVICE_NODE::OverUsed1, _DEVICE_NODE::OverUsed2, PpRegistryDeviceResource, TRUE, and USHORT.

05459 : 05460 05461 This routine checks if the Legacy= value of the driver's legacy_xxx key 05462 is one. If yes, it deletes the Legacy key. 05463 05464 Parameters: 05465 05466 DriverObject - supplies a pointer to the driver object. 05467 05468 Return Value: 05469 05470 None. If anything fails in this routine, the legacy key stays. 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 // We also want to delete the madeup device node 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 // Now mark this one deleted. 05559 // 05560 if (!IopDoesDevNodeHaveProblem(deviceNode)) { 05561 deviceNode->Flags &= ~DNF_STARTED; 05562 IopSetDevNodeProblem(deviceNode, CM_PROB_DEVICE_NOT_THERE); 05563 } 05564 05565 // 05566 // This is actually doing nothing because DeviceNode->ResourceList is NULL. 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; // remove its boot config if any 05579 IoDeleteDevice(deviceObject); 05580 } 05581 ObDereferenceObject(deviceObject); // added via IopDeviceObjectFromDeviceInstance 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 // We need to call IopCleanupDeviceRegistryValue even we are going to 05607 // delete it. Because, it also cleans up related value names in other 05608 // keys. 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 }

ULONG IopDetermineResourceListSize IN PCM_RESOURCE_LIST  ResourceList  ) 
 

Definition at line 3631 of file pnpsubs.c.

References List.

03637 : 03638 03639 This routine determines size of the passed in ResourceList 03640 structure. 03641 03642 Arguments: 03643 03644 Configuration1 - Supplies a pointer to the resource list. 03645 03646 Return Value: 03647 03648 size of the resource list structure. 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 }

NTSTATUS IopDeviceCapabilitiesToRegistry IN PDEVICE_NODE  DeviceNode,
IN PDEVICE_CAPABILITIES  Capabilities
 

Definition at line 5675 of file pnpsubs.c.

References ASSERT, DEVICE_CAPABILITIES, DNF_HAS_BOOT_CONFIG, FIELD_SIZE, IopDeviceObjectToDeviceInstance(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, TITLE_INDEX_VALUE, and Version.

05682 : 05683 05684 This routine updates device capabilities, must be called after a valid device instance key has been created 05685 Called directly from IopProcessNewDeviceNode, and indirecly via IopDeviceNodeCapabilitiesToRegistry 05686 after device is started. 05687 05688 Arguments: 05689 05690 DeviceObject - supplies a pointer to a device object whose registry 05691 values are to be updated. 05692 05693 Return Value: 05694 05695 status 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 // Open the device instance key 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 // Assert the bit fields are completely contained in a ULONG. This is a 05724 // public structure, so it shouldn't ever change, but paranoia is a good 05725 // thing... 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 }

NTSTATUS IopDeviceNodeCapabilitiesToRegistry IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 5633 of file pnpsubs.c.

References ASSERT, IopDeviceCapabilitiesToRegistry(), IopQueryDeviceCapabilities(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopInitializeDeviceInstanceKey(), and IopStartAndEnumerateDevice().

05639 : 05640 05641 Called after start to refresh Capability flags 05642 05643 Arguments: 05644 05645 DeviceObject - supplies a pointer to a device object whose registry 05646 values are to be updated. 05647 05648 Return Value: 05649 05650 status 05651 05652 --*/ 05653 05654 { 05655 NTSTATUS status; 05656 DEVICE_CAPABILITIES capabilities; 05657 05658 PAGED_CODE(); 05659 05660 ASSERT(DeviceNode != NULL); 05661 05662 // 05663 // Open the device instance key 05664 // 05665 05666 status = IopQueryDeviceCapabilities(DeviceNode, &capabilities); 05667 if (!NT_SUCCESS(status)) { 05668 return status; 05669 } 05670 05671 return IopDeviceCapabilitiesToRegistry(DeviceNode,&capabilities); 05672 }

PDEVICE_OBJECT IopDeviceObjectFromDeviceInstance IN HANDLE DeviceInstanceHandle  OPTIONAL,
IN PUNICODE_STRING DeviceInstance  OPTIONAL
 

Definition at line 3759 of file pnpsubs.c.

References ASSERT, CmRegistryMachineSystemCurrentControlSetEnumName, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), exit, IO_TYPE_DEVICE, IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopRootDeviceNode, KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, ObReferenceObject, PAGED_CODE, _DEVICE_NODE::PhysicalDeviceObject, RtlEqualUnicodeString(), TRUE, and _DEVICE_OBJECT::Type.

03766 : 03767 03768 This routine receives a DeviceInstance path (or DeviceInstance handle) and 03769 returns a reference to a bus device object for the DeviceInstance. 03770 03771 Note, caller must owner the PpRegistryDeviceResource before calling the function, 03772 03773 Arguments: 03774 03775 DeviceInstanceHandle - Supplies a handle to the registry Device Instance key. 03776 If this parameter is NULL, DeviceInstance must specify the registry path. 03777 03778 DeviceInstance - supplies a UNICODE_STRING to specify the device instance path. 03779 if this parameter is NULL, DeviceInstanceHandle must specify the handle 03780 to its registry key. 03781 03782 Returns: 03783 03784 A reference to the desired bus device object. 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 // Treat HTREE\ROOT\0 specially 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 // first open System\CCS\Enum key and then the device instance key. 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 // Read the address of device object 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 // Make sure the address of the device object is not clobbered, 03873 // unfortunately if the address is truly bogus we will bugcheck since 03874 // try/except doesn't work for kernel addresses. 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 }

NTSTATUS IopDeviceObjectToDeviceInstance IN PDEVICE_OBJECT  DeviceObject,
IN PHANDLE  DeviceInstanceHandle,
IN ACCESS_MASK  DesiredAccess
 

Definition at line 3897 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, _DEVICE_NODE::InstancePath, IopOpenRegistryKeyEx(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

03905 : 03906 03907 This routine receives a DeviceObject pointer and returns a handle to the device 03908 instance path under registry System\ENUM key. 03909 03910 Note, caller must owner the PpRegistryDeviceResource before calling the function, 03911 03912 Arguments: 03913 03914 DeviceObject - supplies a pointer to a physical device object. 03915 03916 DeviceInstanceHandle - Supplies a variable to receive the handle to the registry 03917 device instance key. 03918 03919 DesiredAccess - specifies the access that is needed to this key. 03920 03921 Returns: 03922 03923 NTSTATUS code to indicate success or failure. 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 }

VOID IopDisableDevice IN PDEVICE_NODE  DeviceNode,
IN HANDLE  Handle
 

Definition at line 3125 of file pnpsubs.c.

References ASSERT, IopClearDevNodeProblem, IopDoesDevNodeHaveProblem, IopIsDevNodeProblem, IopReleaseDeviceResources(), IopRemoveDevice(), IopSetDevNodeProblem, IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE, NT_SUCCESS, NTSTATUS(), and TRUE.

03132 : 03133 03134 This routine tries to ask a bus driver stopping decoding resources 03135 03136 Arguments: 03137 03138 DeviceNode - Specifies the device to be disabled. 03139 03140 Handle - specifies the device instance handle. 03141 03142 Returns: 03143 03144 None. 03145 03146 --*/ 03147 03148 { 03149 NTSTATUS status; 03150 03151 // 03152 // If the device has boot config, we will query-remove and remove the device to free 03153 // the boot config if possible. 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 }

NTSTATUS IopDriverLoadingFailed IN HANDLE ServiceHandle  OPTIONAL,
IN PUNICODE_STRING ServiceName  OPTIONAL
 

Definition at line 2779 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_MADEUP, DNF_STARTED, ExAcquireResourceShared, ExFreePool(), ExReleaseResource, FALSE, _DEVICE_NODE::Flags, IoDeleteDevice(), IopDeviceObjectFromDeviceInstance(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopOpenServiceEnumKeys(), IopReleaseDeviceResources(), IopServiceInstanceToDeviceInstance(), IopSetDevNodeProblem, KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, L, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, PpRegistryDeviceResource, RtlInitUnicodeString(), TITLE_INDEX_VALUE, and TRUE.

02786 : 02787 02788 This routine is invoked when driver failed to start. All the device 02789 instances controlled by this driver/service are marked as failing to 02790 start. 02791 02792 Arguments: 02793 02794 ServiceKeyHandle - Optionally, supplies a handle to the driver service node in the 02795 registry that controls this device instance. If this argument is not specified, 02796 then ServiceKeyName is used to specify the service entry. 02797 02798 ServiceKeyName - Optionally supplies the name of the service entry that controls 02799 the device instance. This must be specified if ServiceKeyHandle isn't given. 02800 02801 Returns: 02802 02803 None. 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 // Open registry ServiceKeyName\Enum branch 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 // No Service Enum key? no device instance. Return FALSE. 02841 // 02842 02843 return status; 02844 } 02845 02846 // 02847 // Set "STARTFAILED" flags. So, we won't load it again. 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 // Find out how many device instances listed in the ServiceName's 02863 // Enum key. 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 // Open HTREE\ROOT\0 key so later we can remove device instance key 02889 // from its AttachedComponents value name. 02890 // 02891 02892 status = IopOpenRegistryKeyEx( &sysEnumHandle, 02893 NULL, 02894 &CmRegistryMachineSystemCurrentControlSetEnumName, 02895 KEY_ALL_ACCESS 02896 ); 02897 02898 // 02899 // Walk through each registered device instance to mark its Problem and 02900 // StatusFlags as fail to start and reset its ActiveService 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 // If the device instance is a detected device reported during driver's 02922 // DriverEntry we need to clean it up. 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 // Now mark this one deleted. 02936 // 02937 deviceNode->Flags &= ~DNF_STARTED; 02938 02939 IopSetDevNodeProblem(deviceNode, CM_PROB_DEVICE_NOT_THERE); 02940 deletePdo = TRUE; 02941 } 02942 } 02943 ObDereferenceObject(deviceObject); // added via IopDeviceObjectFromDeviceInstance 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 // Remove the instance value name from service enum key 02969 // 02970 02971 PiUlongToUnicodeString(&unicodeValueName, unicodeBuffer, 20, i); 02972 status = ZwDeleteValueKey (serviceEnumHandle, &unicodeValueName); 02973 if (NT_SUCCESS(status)) { 02974 02975 // 02976 // If we can successfaully remove the instance value entry 02977 // from service enum key, we then remove the device instance key 02978 // Otherwise, we go thru normal path to mark driver loading failed 02979 // in the device instance key. 02980 // 02981 02982 newCount--; 02983 02984 ZwDeleteKey(controlHandle); 02985 ZwDeleteKey(handle); 02986 02987 02988 // 02989 // We also want to delete the ROOT\LEGACY_<driver> key 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 // If there is a PDO for this device, remove it 03010 // 03011 03012 if (deletePdo) { 03013 IoDeleteDevice(deviceObject); 03014 } 03015 03016 ExReleaseResource(&PpRegistryDeviceResource); 03017 KeLeaveCriticalRegion(); 03018 03019 continue; 03020 } 03021 } 03022 } 03023 03024 // 03025 // Reset Control\ActiveService value name. 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 // If some instance value entry is deleted, we need to update the count of instance 03045 // value entries and rearrange the instance value entries under service enum key. 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 // Need to change the instance i to instance j 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 // Don't forget to update the "Count=" and "NextInstance=" value entries 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 }

NTSTATUS IopFilterResourceRequirementsList IN PIO_RESOURCE_REQUIREMENTS_LIST  IoList,
IN PCM_RESOURCE_LIST  CmList,
IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *  FilteredList,
OUT PBOOLEAN  ExactMatch
 

Definition at line 4592 of file pnpsubs.c.

References ASSERT, ExAllocatePool, ExFreePool(), FALSE, IopCmResourcesToIoResources(), NTSTATUS(), NULL, PAGED_CODE, PagedPool, TRUE, and USHORT.

04601 : 04602 04603 This routines adjusts the input IoList based on input BootConfig. 04604 04605 04606 Arguments: 04607 04608 IoList - supplies the pointer to an IoResourceRequirementsList 04609 04610 CmList - supplies the pointer to a BootConfig. 04611 04612 FilteredList - Supplies a variable to receive the filtered resource 04613 requirements list. 04614 04615 Return Value: 04616 04617 A NTSTATUS code to indicate the result of the function. 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 // Make sure there is some resource requirements to be filtered. 04642 // If no, we will convert CmList/BootConfig to an IoResourceRequirementsList 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 // Make a copy of the Io Resource Requirements List 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 // If there is no BootConfig, simply return the copy of the input Io list. 04665 // 04666 04667 if (CmList == NULL || CmList->Count == 0) { 04668 *FilteredList = ioList; 04669 return STATUS_SUCCESS; 04670 } 04671 04672 // 04673 // First determine minimum number of descriptors required. 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 // Invalid cmresource list. Ignore it and use io resources 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 // cmDescriptorCount is the number of BootConfig Descriptors needs. 04715 // 04716 // For each IO list Alternative ... 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) { // Convert bogus version to valid number 04736 version = 1; 04737 } 04738 04739 // 04740 // We use Version field to store number of BootConfig found. 04741 // Count field to store new number of descriptor in the alternative list. 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 // An alternative list with zero descriptor count 04754 // 04755 04756 ioResourceList->Version = 0xffff; // Mark it as invalid 04757 ioList->AlternativeLists--; 04758 continue; 04759 } 04760 04761 exactMatch = TRUE; 04762 04763 // 04764 // For each Cm Resource descriptor ... except DevicePrivate and 04765 // DeviceSpecific... 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 // Check CmDescriptor against current Io Alternative list 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 // For phase 0 match, we want near exact match... 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; // skip 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 // Io range covers Cm range ... Change the Io range to what is specified 04903 // in BootConfig. 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 } // Don't add any instruction after this ... 04961 } // phase 04962 } // switch 04963 04964 // 04965 // Move to next Cm Descriptor 04966 // 04967 04968 cmDescriptor++; 04969 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor + size); 04970 } 04971 04972 // 04973 // Move to next Cm List 04974 // 04975 04976 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor; 04977 } 04978 04979 if (ioResourceList->Version != (USHORT)cmDescriptorCount) { 04980 04981 // 04982 // If the current alternative list does not cover all the boot config 04983 // descriptors, make it as invalid. 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 // Move to next Io alternative list. 05012 // 05013 05014 ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd; 05015 } 05016 05017 // 05018 // If there is not any valid alternative, convert CmList to Io list. 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 // we have finished filtering the resource requirements list. Now allocate memory 05029 // and rebuild a new list. 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 // Walk through the io resource requirements list and pick up any valid descriptor. 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 //if (newIoResourceList->Count == (cmDescriptorCount + 1)) { 05091 configDataDescriptor->u.ConfigData.Priority = LCPRI_BOOTCONFIG; 05092 //} 05093 05094 // 05095 // Move to next Io alternative list. 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 }

VOID IopFreeUnicodeStringList IN PUNICODE_STRING  UnicodeStringList,
IN ULONG  StringCount
 

Definition at line 2740 of file pnpsubs.c.

References Buffer, and ExFreePool().

02747 : 02748 02749 This routine frees the buffer for each UNICODE_STRING in the specified list 02750 (there are StringCount of them), and then frees the memory used for the 02751 string list itself. 02752 02753 Arguments: 02754 02755 UnicodeStringList - Supplies a pointer to an array of UNICODE_STRINGs. 02756 02757 StringCount - Supplies the number of strings in the UnicodeStringList array. 02758 02759 Returns: 02760 02761 None. 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 }

NTSTATUS IopGetDeviceInstanceCsConfigFlags IN PUNICODE_STRING  DeviceInstance,
OUT PULONG  CsConfigFlags
 

Definition at line 1477 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, ExFreePool(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

01484 : 01485 01486 This routine retrieves the csconfig flags for the specified device. 01487 01488 Arguments: 01489 01490 DeviceInstance - Supplies a pointer to the devnode's instance path 01491 01492 CsConfigFlags - Supplies a variable to receive the device's CsConfigFlags 01493 01494 Return Value: 01495 01496 status 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 // Now, we must open the System\CCS\Enum key under this. 01523 // 01524 // 01525 // Open system\CurrentControlSet under current hardware profile key 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 }

NTSTATUS IopGetDeviceResourcesFromRegistry IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  ResourceType,
IN ULONG  Preference,
OUT PVOID *  Resource,
OUT PULONG  Length
 

Definition at line 4081 of file pnpsubs.c.

References ExAllocatePool, ExFreePool(), IopDeviceObjectToDeviceInstance(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopReadDeviceConfiguration(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PnpDefaultInterfaceType, QUERY_RESOURCE_LIST, REGISTRY_ALLOC_CONFIG, REGISTRY_BASIC_CONFIGVECTOR, REGISTRY_BOOT_CONFIG, REGISTRY_FORCED_CONFIG, REGISTRY_OVERRIDE_CONFIGVECTOR, and Resource.

04091 : 04092 04093 This routine determines the resources decoded by the device specified. 04094 If the device object is a madeup device, we will try to read the resources 04095 from registry. Otherwise, we need to traverse the internal assigned resource 04096 list to compose the resource list. 04097 04098 Arguments: 04099 04100 DeviceObject - supplies a pointer to a device object whose registry 04101 values are to be cleaned up. 04102 04103 ResourceType - 0 for CM_RESOURCE_LIST and 1 for IO_RESOURCE_REQUIREMENTS_LIS 04104 04105 Flags - specify the preference. 04106 04107 Resource - Specified a variable to receive the required resources. 04108 04109 Length - Specified a variable to receive the length of the resource structure. 04110 04111 Return Value: 04112 04113 status 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 // Open the LogConfig key of the device instance. 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 // Caller is asking for CM_RESOURCE_LIST 04144 // 04145 04146 if (Preference & REGISTRY_ALLOC_CONFIG) { 04147 04148 // 04149 // Try alloc config first 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 // Try alloc config first 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 // Try to read device's configuration vector 04234 // 04235 04236 status = IopGetRegistryValue (handle, 04237 valueName, 04238 &keyValueInformation); 04239 if (NT_SUCCESS(status)) { 04240 04241 // 04242 // Try to read what caller wants. 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 // Process the io resource requirements list to change undefined 04260 // interface type to our default type. 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 }

USHORT IopGetGroupOrderIndex IN HANDLE  ServiceHandle  ) 
 

Definition at line 5334 of file pnpsubs.c.

References ExFreePool(), IopFreeUnicodeStringList(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopRegistryDataToUnicodeString, IopRegMultiSzToUnicodeStrings(), KEY_VALUE_DATA, L, NO_MORE_GROUP, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlEqualUnicodeString(), TRUE, and USHORT.

05340 : 05341 05342 This routine reads the Group value of the service key, finds its position in the 05343 ServiceOrderList. If ServiceHandle is NULL or unrecognized group value, it returns 05344 a value with max group order + 1. 05345 if any. 05346 05347 Parameters: 05348 05349 ServiceHandle - supplies a handle to the service key. 05350 05351 Return Value: 05352 05353 group order index. 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 // Open System\CurrentControlSet\Control\ServiceOrderList 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 // Read and build a unicode string array containing all the group names. 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 // Read service key's Group value 05413 // 05414 05415 status = IopGetRegistryValue (ServiceHandle, 05416 L"Group", 05417 &keyValueInformation); 05418 if (NT_SUCCESS(status)) { 05419 05420 // 05421 // Try to read what caller wants. 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 // If we failed to read the Group value, or no Group value... 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 }

NTSTATUS IopGetServiceInstanceCsConfigFlags IN PUNICODE_STRING  ServiceKeyName,
IN ULONG  Instance,
OUT PULONG  CsConfigFlags
 

Definition at line 1591 of file pnpsubs.c.

References ExFreePool(), FALSE, IopGetRegistryValue(), IopOpenCurrentHwProfileDeviceInstanceKey(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), and PAGED_CODE.

Referenced by IopIsAnyDeviceInstanceEnabled().

01599 : 01600 01601 This routine retrieves the csconfig flags for the specified device 01602 which is specified by the instance number under ServiceKeyName\Enum. 01603 01604 Arguments: 01605 01606 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01607 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01608 that caused the driver to load. 01609 01610 Instance - Supplies the instance value under ServiceKeyName\Enum key 01611 01612 CsConfigFlags - Supplies a variable to receive the device's CsConfigFlags 01613 01614 Return Value: 01615 01616 status 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 }

BOOLEAN IopIsAnyDeviceInstanceEnabled IN PUNICODE_STRING  ServiceKeyName,
IN HANDLE ServiceHandle  OPTIONAL,
IN BOOLEAN  LegacyIncluded
 

Definition at line 3181 of file pnpsubs.c.

References _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), FALSE, IopCreateRegistryKeyEx(), IopDeviceObjectFromDeviceInstance(), IopDisableDevice(), IopGetRegistryValue(), IopGetServiceInstanceCsConfigFlags(), IopIsDevNodeProblem, IopOpenRegistryKeyEx(), IopOpenServiceEnumKeys(), IopServiceInstanceToDeviceInstance(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, TITLE_INDEX_VALUE, and TRUE.

03189 : 03190 03191 This routine checks if any of the devices instances is turned on for the specified 03192 service. This routine is used for Pnp Driver only and is temporary function to support 03193 SUR. 03194 03195 Arguments: 03196 03197 ServiceKeyName - Specifies the service key unicode name 03198 03199 ServiceHandle - Optionally supplies a handle to the service key to be checked. 03200 03201 LegacyIncluded - TRUE, a legacy device instance key is counted as a device instance. 03202 FALSE, a legacy device instance key is not counted. 03203 03204 Returns: 03205 03206 A BOOLEAN value. 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 // Open registry ServiceKeyName\Enum branch 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 // No Service Enum key? no device instance. Return FALSE. 03244 // 03245 03246 return FALSE; 03247 } 03248 03249 // 03250 // Find out how many device instances listed in the ServiceName's 03251 // Enum key. 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 // Walk through each registered device instance to check it is enabled. 03277 // 03278 03279 enabled = FALSE; 03280 for (i = 0; i < count; i++) { 03281 03282 // 03283 // Get device instance handle. If it fails, we will skip this device 03284 // instance. 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 // Check if the device instance has been disabled. 03313 // First check global flag: CONFIGFLAG and then CSCONFIGFLAG. 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 // Convert this flag into the hardware profile-specific version, so it'll 03333 // look the same as the CsConfigFlags we retrieve below. 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 // If the device is disabled (either globally, or specifically for this 03352 // hardware profile), then mark the devnode as DNF_DISABLED. 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 // Finally, we need to set the STATUSFLAGS of the device instance to 03368 // indicate if the driver is successfully started. 03369 // 03370 03371 if (!(deviceFlags & (CSCONFIGFLAG_DISABLED | CSCONFIGFLAG_DO_NOT_CREATE | CSCONFIGFLAG_DO_NOT_START))) { 03372 03373 ULONG legacy; 03374 03375 // 03376 // Check should legacy instance key be counted as an enabled device 03377 // 03378 03379 if (LegacyIncluded == FALSE) { 03380 03381 // 03382 // The legacy variable must be initialized to zero. Because the device 03383 // instance key may be an enumerated device. In this case, there is no 03384 // legacy value name. 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 // Mark that the driver has at least a device instance to work with. 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 }

BOOLEAN IopIsDeviceInstanceEnabled IN HANDLE DeviceInstanceHandle  OPTIONAL,
IN PUNICODE_STRING  DeviceInstance,
IN BOOLEAN  DisableIfEnabled
 

Definition at line 3443 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), exit, FALSE, IopDeviceObjectFromDeviceInstance(), IopDisableDevice(), IopGetRegistryValue(), IopIsDevNodeProblem, IopOpenRegistryKeyEx(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, and TRUE.

03451 : 03452 03453 This routine checks if the specified devices instances is enabled. 03454 03455 Arguments: 03456 03457 DeviceInstanceHandle - Optionally supplies a handle to the device instance 03458 key to be checked. 03459 03460 DeviceInstance - Specifies the device instance key unicode name. Caller 03461 must at least specified DeviceInstanceHandle or DeviceInstance. 03462 03463 DisableIfEnabled - If this flag is set, and the device should be disabled 03464 but is currently disabled, then the device is disabled. 03465 03466 Returns: 03467 03468 A BOOLEAN value. 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 // Open registry ServiceKeyName\Enum branch 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 // First check the device node 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 // Check if the device instance has been disabled. 03526 // First check global flag: CONFIGFLAG and then CSCONFIGFLAG. 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 // See if we can open current hardware profile 03545 // 03546 status = IopOpenRegistryKeyEx( &handle1, 03547 NULL, 03548 &CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, 03549 KEY_READ 03550 ); 03551 03552 if (NT_SUCCESS(status) && DeviceInstance != NULL) { 03553 03554 // 03555 // Now, we must open the System\CCS\Enum key under this. 03556 // 03557 // 03558 // Open system\CurrentControlSet under current hardware profile key 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 // If the device is disabled and has device node associated with it. 03614 // disable the device. 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 }

BOOLEAN IopIsDuplicatedDevices IN PCM_RESOURCE_LIST  Configuration1,
IN PCM_RESOURCE_LIST  Configuration2,
IN PHAL_BUS_INFORMATION BusInfo1  OPTIONAL,
IN PHAL_BUS_INFORMATION BusInfo2  OPTIONAL
 

Definition at line 2554 of file pnpsubs.c.

References FALSE, HalTranslateBusAddress(), NULL, and TRUE.

02563 : 02564 02565 This routine compares two set of configurations and bus information to 02566 determine if the resources indicate the same device. If BusInfo1 and 02567 BusInfo2 both are absent, it means caller wants to compare the raw 02568 resources. 02569 02570 Arguments: 02571 02572 Configuration1 - Supplies a pointer to the first set of resource. 02573 02574 Configuration2 - Supplies a pointer to the second set of resource. 02575 02576 BusInfo1 - Supplies a pointer to the first set of bus information. 02577 02578 BusInfo2 - Supplies a pointer to the second set of bus information. 02579 02580 Return Value: 02581 02582 returns TRUE if the two set of resources indicate the same device; 02583 otherwise a value of FALSE is returned. 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 // The BusInfo for both resources must be both present or not present. 02596 // 02597 02598 if ((ARGUMENT_PRESENT(BusInfo1) && !ARGUMENT_PRESENT(BusInfo2)) || 02599 (!ARGUMENT_PRESENT(BusInfo1) && ARGUMENT_PRESENT(BusInfo2))) { 02600 02601 // 02602 // Unable to determine. 02603 // 02604 02605 return FALSE; 02606 } 02607 02608 // 02609 // Next check resources used by the two devices. 02610 // Currently, we *only* check the Io ports. 02611 // 02612 02613 if (Configuration1->Count == 0 || Configuration2->Count == 0) { 02614 02615 // 02616 // If any one of the configuration data is empty, we assume 02617 // the devices are not duplicates. 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 // If this is an i/o port or a memory range then look for a match 02634 // in the other list. 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 // If the types match then check to see if both addresses 02646 // match as well. If bus info was provided then go ahead 02647 // and translate the ranges first. 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 // If the ranges are in the same space and start at the 02691 // same location then break out and go on to the next 02692 // range 02693 // 02694 02695 if((range1Translated.QuadPart == range2Translated.QuadPart) && 02696 (range1IoSpace == range2IoSpace)) { 02697 02698 break; 02699 } 02700 } 02701 } 02702 02703 // 02704 // If we made it all the way through the resource list without 02705 // finding a match then these are not duplicates. 02706 // 02707 02708 if(j == list2->Count) { 02709 return FALSE; 02710 } 02711 } 02712 } 02713 02714 // 02715 // If every resource in list 1 exists in list 2 then we also need to make 02716 // sure that every resource in list 2 exists in list 1. 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 }

BOOLEAN IopIsLegacyDriver IN PDRIVER_OBJECT  DriverObject  ) 
 

Definition at line 5290 of file pnpsubs.c.

References DRVO_LEGACY_DRIVER, FALSE, PAGED_CODE, and TRUE.

05296 : 05297 05298 This routine checks if the driver object specifies a legacy driver. 05299 05300 Arguments: 05301 05302 DriverObject - supplies a pointer to the driver object to be checked. 05303 05304 Return Value: 05305 05306 BOOLEAN 05307 05308 --*/ 05309 05310 { 05311 05312 PAGED_CODE(); 05313 05314 // 05315 // If AddDevice entry is not empty it is a wdm driver 05316 // 05317 05318 if (DriverObject->DriverExtension->AddDevice) { 05319 return FALSE; 05320 } 05321 05322 // 05323 // Else if LEGACY flag is set in the driver object, it's a legacy driver. 05324 // 05325 05326 if (DriverObject->Flags & DRVO_LEGACY_DRIVER) { 05327 return TRUE; 05328 } else { 05329 return FALSE; 05330 } 05331 }

NTSTATUS IopMarkDuplicateDevice IN PUNICODE_STRING  TargetKeyName,
IN ULONG  TargetInstance,
IN PUNICODE_STRING  SourceKeyName,
IN ULONG  SourceInstance
 

Definition at line 2467 of file pnpsubs.c.

References IopServiceInstanceToDeviceInstance(), NT_SUCCESS, NTSTATUS(), NULL, and TITLE_INDEX_VALUE.

02476 : 02477 02478 This routine marks the device instance specified by TargetKeyName and TargetInstance 02479 as DuplicateOf the device specified by SourceKeyName and SourceInstance. 02480 02481 Arguments: 02482 02483 TargetKeyName - supplies a pointer to the name of service key which will be marked 02484 as duplicate. 02485 02486 TargetInstance - the instance number of the target device. 02487 02488 SourceKeyName - supplies a pointer to the name of service key. 02489 02490 SourceInstance - the instance number of the source device. 02491 02492 02493 Returns: 02494 02495 NTSTATUS code. 02496 02497 --*/ 02498 02499 { 02500 HANDLE handle; 02501 NTSTATUS status; 02502 UNICODE_STRING sourceDeviceString, unicodeValueName; 02503 02504 // 02505 // Open the handle of the target device instance. 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 // Get the name of the source device instance 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 // Write the name of the source device to the DuplicateOf value entry of 02538 // target device key. 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 }

NTSTATUS IopMergeCmResourceLists IN PCM_RESOURCE_LIST  List1,
IN PCM_RESOURCE_LIST  List2,
IN OUT PCM_RESOURCE_LIST *  MergedList
 

Definition at line 5198 of file pnpsubs.c.

References ExAllocatePool, IopDetermineResourceListSize(), List, NTSTATUS(), NULL, PAGED_CODE, and PagedPool.

05206 : 05207 05208 This routines merges two IoLists into one. 05209 05210 05211 Arguments: 05212 05213 IoList1 - supplies the pointer to the first CmResourceList 05214 05215 IoList2 - supplies the pointer to the second CmResourceList 05216 05217 MergedList - Supplies a variable to receive the merged resource 05218 list. 05219 05220 Return Value: 05221 05222 A NTSTATUS code to indicate the result of the function. 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 // First handle the easy cases that both IO Lists are empty or any one of 05237 // them is empty. 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 // Do real work... 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 }

NTSTATUS IopMergeFilteredResourceRequirementsList IN PIO_RESOURCE_REQUIREMENTS_LIST  IoList1,
IN PIO_RESOURCE_REQUIREMENTS_LIST  IoList2,
IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *  MergedList
 

Definition at line 5109 of file pnpsubs.c.

References ExAllocatePool, List, NTSTATUS(), NULL, PAGED_CODE, and PagedPool.

05117 : 05118 05119 This routines merges two IoLists into one. 05120 05121 05122 Arguments: 05123 05124 IoList1 - supplies the pointer to the first IoResourceRequirementsList 05125 05126 IoList2 - supplies the pointer to the second IoResourceRequirementsList 05127 05128 MergedList - Supplies a variable to receive the merged resource 05129 requirements list. 05130 05131 Return Value: 05132 05133 A NTSTATUS code to indicate the result of the function. 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 // First handle the easy cases that both IO Lists are empty or any one of 05148 // them is empty. 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 // Do real work... 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 }

NTSTATUS IopOpenCurrentHwProfileDeviceInstanceKey OUT PHANDLE  Handle,
IN PUNICODE_STRING  ServiceKeyName,
IN ULONG  Instance,
IN ACCESS_MASK  DesiredAccess,
IN BOOLEAN  Create
 

Definition at line 1712 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, Create(), Handle, IopCreateRegistryKeyEx(), IopOpenRegistryKeyEx(), IopServiceInstanceToDeviceInstance(), NT_SUCCESS, NTSTATUS(), NULL, and RtlFreeUnicodeString().

01722 : 01723 01724 This routine sets the csconfig flags for the specified device 01725 which is specified by the instance number under ServiceKeyName\Enum. 01726 01727 Arguments: 01728 01729 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01730 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01731 that caused the driver to load. This is the RegistryPath parameter 01732 to the DriverEntry routine. 01733 01734 Instance - Supplies the instance value under ServiceKeyName\Enum key 01735 01736 DesiredAccess - Specifies the desired access that the caller needs to 01737 the key. 01738 01739 Create - Determines if the key is to be created if it does not exist. 01740 01741 Return Value: 01742 01743 status 01744 01745 --*/ 01746 01747 { 01748 NTSTATUS status; 01749 UNICODE_STRING tempUnicodeString; 01750 HANDLE profileHandle, profileEnumHandle, tmpHandle; 01751 01752 // 01753 // See if we can open current hardware profile 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 // Now, we must open the System\CCS\Enum key under this. 01775 // 01776 // 01777 // Open system\CurrentControlSet under current hardware profile key 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 }

NTSTATUS IopOpenRegistryKeyEx OUT PHANDLE  Handle,
IN HANDLE BaseHandle  OPTIONAL,
IN PUNICODE_STRING  KeyName,
IN ACCESS_MASK  DesiredAccess
 

Definition at line 1104 of file pnpsubs.c.

References Handle, KeyName, NULL, and PAGED_CODE.

Referenced by EisaBuildEisaDeviceNode(), EisaGetEisaDevicesResources(), IoGetDeviceProperty(), IoOpenDeviceRegistryKey(), IopApplyFunctionToServiceInstances(), IopApplyFunctionToSubKeys(), IopCallDriverAddDevice(), IopCleanupDeviceRegistryValues(), IopCreateMadeupNode(), IopDeleteKeyRecursive(), IopDeleteLegacyKey(), IopDeviceInterfaceKeysFromSymbolicLink(), IopDeviceObjectFromDeviceInstance(), IopDeviceObjectToDeviceInstance(), IopDriverLoadingFailed(), IopGetDeviceInstanceCsConfigFlags(), IopGetDeviceInterfaces(), IopGetDeviceResourcesFromRegistry(), IopGetDriverTagPriority(), IopGetGroupOrderIndex(), IopInitializeBootDrivers(), IopInitializeBuiltinDriver(), IopInitializePlugPlayServices(), IopInitializeSystemDrivers(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopIsFirmwareMapperDevicePresent(), IopIsReportedAlready(), IopMakeGloballyUniqueId(), IopOpenCurrentHwProfileDeviceInstanceKey(), IopOpenDeviceParametersSubkey(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopOpenServiceEnumKeys(), IopProcessCriticalDevice(), IopProcessCriticalDeviceRoutine(), IopProcessNewDeviceNode(), IopQueryDeviceResources(), IopRemoveDeviceInterfaces(), IopServiceInstanceToDeviceInstance(), IopStoreSystemPartitionInformation(), IopUnregisterDeviceInterface(), IoReportDetectedDevice(), PnPBiosCopyDeviceParamKey(), PnPBiosEliminateDupes(), PnPBiosGetBiosInfo(), PnPBiosWriteInfo(), PnPCheckFixedIoOverrideDecodes(), and PnPGetDevnodeExcludeList().

01113 : 01114 01115 Opens a registry key using the name passed in based at the BaseHandle node. 01116 This name may specify a key that is actually a registry path. 01117 01118 Arguments: 01119 01120 Handle - Pointer to the handle which will contain the registry key that 01121 was opened. 01122 01123 BaseHandle - Optional handle to the base path from which the key must be opened. 01124 If KeyName specifies a registry path that must be created, then this parameter 01125 must be specified, and KeyName must be a relative path. 01126 01127 KeyName - Name of the Key that must be opened/created (possibly a registry path) 01128 01129 DesiredAccess - Specifies the desired access that the caller needs to 01130 the key. 01131 01132 Return Value: 01133 01134 The function value is the final status of the operation. 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 // Simply attempt to open the path, as specified. 01151 // 01152 return ZwOpenKey( Handle, DesiredAccess, &objectAttributes ); 01153 }

NTSTATUS IopOpenServiceEnumKeys IN PUNICODE_STRING  ServiceKeyName,
IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE ServiceHandle  OPTIONAL,
OUT PHANDLE ServiceEnumHandle  OPTIONAL,
IN BOOLEAN  CreateEnum
 

Definition at line 1339 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetServices, IopCreateRegistryKeyEx(), IopOpenRegistryKeyEx(), NT_SUCCESS, NTSTATUS(), and NULL.

01349 : 01350 01351 This routine opens the HKEY_LOCAL_MACHINE\CurrentControlSet\Services\ 01352 ServiceKeyName and its Enum subkey and returns handles for both key. 01353 It is caller's responsibility to close the returned handles. 01354 01355 Arguments: 01356 01357 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01358 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01359 that caused the driver to load. This is the RegistryPath parameter 01360 to the DriverEntry routine. 01361 01362 DesiredAccess - Specifies the desired access to the keys. 01363 01364 ServiceHandle - Supplies a variable to receive a handle to ServiceKeyName. 01365 A NULL ServiceHandle indicates caller does not want need the handle to 01366 the ServiceKeyName. 01367 01368 ServiceEnumHandle - Supplies a variable to receive a handle to ServiceKeyName\Enum. 01369 A NULL ServiceEnumHandle indicates caller does not need the handle to 01370 the ServiceKeyName\Enum. 01371 01372 CreateEnum - Supplies a BOOLEAN variable to indicate should the Enum subkey be 01373 created if not present. 01374 01375 Return Value: 01376 01377 status 01378 01379 --*/ 01380 01381 { 01382 HANDLE handle, serviceHandle, enumHandle; 01383 UNICODE_STRING enumName; 01384 NTSTATUS status; 01385 01386 // 01387 // Open System\CurrentControlSet\Services 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 // Open the registry ServiceKeyName key. 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 // There is no registry key for the ServiceKeyName information. 01415 // 01416 01417 return status; 01418 } 01419 01420 if (ARGUMENT_PRESENT(ServiceEnumHandle) || CreateEnum) { 01421 01422 // 01423 // Open registry ServiceKeyName\Enum branch if caller wants 01424 // the handle or wants to create it. 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 // There is no registry key for the ServiceKeyName\Enum information. 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 // if caller wants to have the ServiceKey handle, we return it. Otherwise 01464 // we close it. 01465 // 01466 01467 if (ARGUMENT_PRESENT(ServiceHandle)) { 01468 *ServiceHandle = serviceHandle; 01469 } else { 01470 ZwClose(serviceHandle); 01471 } 01472 01473 return STATUS_SUCCESS; 01474 }

NTSTATUS IopPrepareDriverLoading IN PUNICODE_STRING  KeyName,
IN HANDLE  KeyHandle,
IN PIMAGE_NT_HEADERS  Header
 

Definition at line 753 of file pnpsubs.c.

References ExAcquireResourceShared, ExFreePool(), ExReleaseResource, FALSE, Header, IopCreateMadeupNode(), IopCreateRegistryKeyEx(), IopGetRegistryValue(), IopIsAnyDeviceInstanceEnabled(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, KeyName, NT_SUCCESS, NTSTATUS(), NULL, PnPDetectionEnabled, PpRegistryDeviceResource, RtlFreeUnicodeString(), TITLE_INDEX_VALUE, and TRUE.

00761 : 00762 00763 This routine first checks if the driver is loadable. If its a 00764 PnP driver, it will always be loaded (we trust it to do the right 00765 things.) If it is a legacy driver, we need to check if its device 00766 has been disabled. Once we decide to load the driver, the Enum 00767 subkey of the service node will be checked for duplicates, if any. 00768 00769 Parameters: 00770 00771 KeyName - Supplies a pointer to the driver's service key unicode string 00772 00773 KeyHandle - Supplies a handle to the driver service node in the registry 00774 that describes the driver to be loaded. 00775 00776 Return Value: 00777 00778 The function value is the final status of the load operation. 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 // First open registry ServiceKeyName\Enum branch 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 // Find out how many device instances listed in the ServiceName's 00825 // Enum key. 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 // If there is no Enum key or instance under Enum for the 00856 // legacy driver we will create a madeup node for it. 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 // Create and set Control\ActiveService value 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 // Don't forget to update the "Count=" and "NextInstance=" value entries 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 }

NTSTATUS IopReadDeviceConfiguration IN HANDLE  Handle,
IN ULONG  Flags,
OUT PCM_RESOURCE_LIST *  CmResource,
OUT PULONG  Length
 

Definition at line 4283 of file pnpsubs.c.

References ExAllocatePool, ExFreePool(), Handle, IopGetRegistryValue(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PnpDefaultInterfaceType, REGISTRY_ALLOC_CONFIG, REGISTRY_BOOT_CONFIG, and REGISTRY_FORCED_CONFIG.

04292 : 04293 04294 This routine read the specified ALLOC config or ForcedConfig or Boot config. 04295 04296 Arguments: 04297 04298 Hanle - supplies a handle to the registry key to read resources. 04299 04300 Return Value: 04301 04302 status 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 // Read the registry value of the desired value name 04326 // 04327 04328 status = IopGetRegistryValue (Handle, 04329 valueName, 04330 &keyValueInformation); 04331 if (NT_SUCCESS(status)) { 04332 04333 // 04334 // Try to read what caller wants. 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 // Process the resource list read from Registry to change undefined 04360 // interface type to our default interface type. 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 }

PDRIVER_OBJECT IopReferenceDriverObjectByName IN PUNICODE_STRING  DriverName  ) 
 

Definition at line 3686 of file pnpsubs.c.

References IoDriverObjectType, KernelMode, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, ObOpenObjectByName(), and ObReferenceObjectByHandle().

03692 : 03693 03694 This routine references a driver object by a given driver name. 03695 03696 Arguments: 03697 03698 DriverName - supplies a pointer to the name of the driver whose driver object is 03699 to be referenced. 03700 03701 Returns: 03702 03703 A pointer to a DRIVER_OBJECT if succeeds. Otherwise, a NULL value. 03704 03705 --*/ 03706 03707 { 03708 OBJECT_ATTRIBUTES objectAttributes; 03709 HANDLE driverHandle; 03710 NTSTATUS status; 03711 PDRIVER_OBJECT driverObject; 03712 03713 // 03714 // Make sure the driver name is valid. 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 // Now reference the driver object. 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 }

NTSTATUS IopRegMultiSzToUnicodeStrings IN PKEY_VALUE_FULL_INFORMATION  KeyValueInformation,
OUT PUNICODE_STRING *  UnicodeStringList,
OUT PULONG  UnicodeStringCount
 

Definition at line 2080 of file pnpsubs.c.

References Buffer, ExAllocatePool, IopFreeUnicodeStringList(), KEY_VALUE_DATA, PagedPool, StringLength(), and USHORT.

02088 : 02089 02090 This routine takes a KEY_VALUE_FULL_INFORMATION structure containing 02091 a REG_MULTI_SZ value, and allocates an array of UNICODE_STRINGs, 02092 initializing each one to a copy of one of the strings in the value entry. 02093 All the resulting UNICODE_STRINGs will be NULL terminated 02094 (MaximumLength = Length + sizeof(UNICODE_NULL)). 02095 02096 It is the responsibility of the caller to free the buffers for each 02097 unicode string, as well as the buffer containing the UNICODE_STRING 02098 array. This may be done by calling IopFreeUnicodeStringList. 02099 02100 Arguments: 02101 02102 KeyValueInformation - Supplies the buffer containing the REG_MULTI_SZ 02103 value entry data. 02104 02105 UnicodeStringList - Receives a pointer to an array of UNICODE_STRINGs, each 02106 initialized with a copy of one of the strings in the REG_MULTI_SZ. 02107 02108 UnicodeStringCount - Receives the number of strings in the 02109 UnicodeStringList. 02110 02111 Returns: 02112 02113 NT status code indicating whether the function was successful. 02114 02115 --*/ 02116 02117 { 02118 PWCHAR p, BufferEnd, StringStart; 02119 ULONG StringCount, i, StringLength; 02120 02121 // 02122 // First, make sure this is really a REG_MULTI_SZ value. 02123 // 02124 if(KeyValueInformation->Type != REG_MULTI_SZ) { 02125 return STATUS_INVALID_PARAMETER; 02126 } 02127 02128 // 02129 // Make a preliminary pass through the buffer to count the number of strings 02130 // There will always be at least one string returned (possibly empty). 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 // Now, make a second pass through the buffer making copies of each string. 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 }

NTSTATUS IopRemoveStringFromValueKey IN HANDLE  Handle,
IN PWSTR  ValueName,
IN PUNICODE_STRING  String
 

Definition at line 449 of file pnpsubs.c.

References ExFreePool(), FALSE, Handle, IopGetRegistryValue(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, RtlEqualUnicodeString(), RtlInitUnicodeString(), String, TITLE_INDEX_VALUE, TRUE, USHORT, and ValueName.

00457 : 00458 00459 This routine remove a string from a value entry specified by ValueName 00460 under an already opened registry handle. Note, this routine will not 00461 delete the ValueName entry even it becomes empty after the removal. 00462 00463 Parameters: 00464 00465 Handle - Supplies the handle to a registry key whose value entry will 00466 be modified. 00467 00468 ValueName - Supplies a unicode string to specify the value entry. 00469 00470 String - Supplies a unicode string to remove from value entry. 00471 00472 Return Value: 00473 00474 Status code that indicates whether or not the function was successful. 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 // Read registry value entry data 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 // Scan through the multi_sz string to find the matching string 00509 // and remove it. 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 }

NTSTATUS IopRestartDeviceNode IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 5777 of file pnpsubs.c.

References ASSERT, DNF_ADDED, DNF_BOOT_CONFIG_RESERVED, DNF_ENUMERATED, DNF_ENUMERATION_REQUEST_QUEUED, DNF_HAS_BOOT_CONFIG, DNF_MADEUP, DNF_NO_RESOURCE_REQUIRED, DNF_PROCESSED, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, DNF_RESOURCE_REQUIREMENTS_CHANGED, DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED, DNF_STARTED, DNUF_NEED_RESTART, DNUF_WILL_BE_REMOVED, ExFreePool(), IopDoesDevNodeHaveProblem, NULL, PAGED_CODE, and RtlInitUnicodeString().

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 // Free any existing devnode strings so we can recreate them 05812 // during enumeration. 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 }

NTSTATUS IopServiceInstanceToDeviceInstance IN HANDLE ServiceKeyHandle  OPTIONAL,
IN PUNICODE_STRING ServiceKeyName  OPTIONAL,
IN ULONG  ServiceInstanceOrdinal,
OUT PUNICODE_STRING DeviceInstanceRegistryPath  OPTIONAL,
OUT PHANDLE DeviceInstanceHandle  OPTIONAL,
IN ACCESS_MASK  DesiredAccess
 

Definition at line 931 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, ExFreePool(), FALSE, IopConcatenateUnicodeStrings(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopOpenServiceEnumKeys(), IopRegistryDataToUnicodeString, KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), and NULL.

00942 : 00943 00944 This routine reads the service node enum entry to find the desired device instance 00945 under the System\Enum tree. It then optionally returns the registry path of the 00946 specified device instance (relative to HKLM\System\Enum) and an open handle 00947 to that registry key. 00948 00949 It is the caller's responsibility to close the handle returned if 00950 DeviceInstanceHandle is supplied, and also to free the (PagedPool) memory 00951 allocated for the unicode string buffer of DeviceInstanceRegistryPath, if 00952 supplied. 00953 00954 Parameters: 00955 00956 ServiceKeyHandle - Optionally, supplies a handle to the driver service node in the 00957 registry that controls this device instance. If this argument is not specified, 00958 then ServiceKeyName is used to specify the service entry. 00959 00960 ServiceKeyName - Optionally supplies the name of the service entry that controls 00961 the device instance. This must be specified if ServiceKeyHandle isn't given. 00962 00963 ServiceInstanceOrdinal - Supplies the instance value under the service entry's 00964 volatile Enum subkey that references the desired device instance. 00965 00966 DeviceInstanceRegistryPath - Optionally, supplies a pointer to a unicode string 00967 that will be initialized with the registry path (relative to HKLM\System\Enum) 00968 to the device instance key. 00969 00970 DeviceInstanceHandle - Optionally, supplies a pointer to a variable that will 00971 receive a handle to the opened device instance registry key. 00972 00973 DesiredAccess - If DeviceInstanceHandle is specified (i.e., the device instance 00974 key is to be opened), then this variable specifies the access that is needed 00975 to this key. 00976 00977 Return Value: 00978 00979 NT status code indicating whether the function was successful. 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 // Open registry ServiceKeyName\Enum branch 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 // There is no registry key for the ServiceKeyName\Enum information. 01015 // 01016 01017 return status; 01018 } 01019 01020 // 01021 // Read a path to System\Enum hardware tree branch specified by the service 01022 // instance ordinal 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 // If the DeviceInstanceHandle argument was specified, open the device instance 01054 // key under HKLM\System\CurrentControlSet\Enum 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 // If the DeviceInstanceRegistryPath argument was specified, then store a 01082 // copy of the device instance path in the supplied unicode string variable. 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 }

NTSTATUS IopSetServiceInstanceCsConfigFlags IN PUNICODE_STRING  ServiceKeyName,
IN ULONG  Instance,
IN ULONG  CsConfigFlags
 

Definition at line 1653 of file pnpsubs.c.

References IopOpenCurrentHwProfileDeviceInstanceKey(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, TITLE_INDEX_VALUE, and TRUE.

01661 : 01662 01663 This routine sets the csconfig flags for the specified device 01664 which is specified by the instance number under ServiceKeyName\Enum. 01665 01666 Arguments: 01667 01668 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01669 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01670 that caused the driver to load. This is the RegistryPath parameter 01671 to the DriverEntry routine. 01672 01673 Instance - Supplies the instance value under ServiceKeyName\Enum key 01674 01675 CsConfigFlags - Supplies the device instance's new CsConfigFlags 01676 01677 Return Value: 01678 01679 status 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 }


Generated on Sat May 15 19:45:16 2004 for test by doxygen 1.3.7