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 IopOpenRegistryKeyPersist (OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Create, 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 ServiceKeyName, IN ULONG Instance, OUT PULONG CsConfigFlags)
NTSTATUS IopSetDeviceInstanceCsConfigFlags (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 BOOLEAN IgnoreNonCriticalErrors, 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, 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 IopDeviceCapabilitiesToRegistry (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IopRestartDeviceNode (IN PDEVICE_NODE DeviceNode)


Function Documentation

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

Definition at line 546 of file pri_bld/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 2036 of file pri_bld/pnpsubs.c.

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

Referenced by IopAddDevicesToBootDriver(), and IopGetDriverDeviceList().

02048 : 02049 02050 This routine enumerates all device instances referenced by the instance 02051 ordinal entries under a service's volatile Enum key, and calls 02052 the specified callback routine for each instance's corresponding subkey 02053 under HKLM\System\Enum. 02054 02055 Arguments: 02056 02057 ServiceKeyHandle - Optional handle to the service entry. If this parameter 02058 is not specified, then the service key name must be given in 02059 ServiceKeyName (if both parameters are specified, then ServiceKeyHandle 02060 is used, and ServiceKeyName is ignored). 02061 02062 ServiceKeyName - Optional name of the service entry key (under 02063 HKLM\CurrentControlSet\Services). If this parameter is not specified, 02064 then ServiceKeyHandle must contain a handle to the desired service key. 02065 02066 DesiredAccess - Specifies the desired access that the callback routine 02067 needs to the enumerated device instance keys. If no desired access is 02068 specified (i.e., DesiredAccess is zero), then no handle will be opened 02069 for the device instance keys, and the callback will be passed a NULL for 02070 its DeviceInstanceHandle parameter. 02071 02072 IgnoreNonCriticalErrors - Specifies whether this function should 02073 immediately terminate on all errors, or only on critical ones. 02074 An example of a non-critical error is when an enumerated device instance 02075 key cannot be opened for the desired access. 02076 02077 DevInstCallbackRoutine - Supplies a pointer to a function that will 02078 be called for each device instance key referenced by a service instance 02079 entry under the service's volatile Enum subkey. The prototype of the 02080 function is as follows: 02081 02082 typedef BOOLEAN (*PIOP_SUBKEY_CALLBACK_ROUTINE) ( 02083 IN HANDLE DeviceInstanceHandle, 02084 IN PUNICODE_STRING DeviceInstancePath, 02085 IN OUT PVOID Context 02086 ); 02087 02088 where DeviceInstanceHandle is the handle to an enumerated device instance 02089 key, DeviceInstancePath is the registry path (relative to 02090 HKLM\System\Enum) to this device instance, and Context is a pointer to 02091 user-defined data. 02092 02093 This function should return TRUE to continue enumeration, or 02094 FALSE to terminate it. 02095 02096 Context - Supplies a pointer to user-defined data that will be passed 02097 in to the callback routine at each device instance key invocation. 02098 02099 ServiceInstanceOrdinal - Optionally, receives the service instance ordinal (1 based) 02100 that terminated the enumeration, or the total number of instances enumerated 02101 if the enumeration completed without being aborted. 02102 02103 Return Value: 02104 02105 NT status code indicating whether the device instance keys were successfully 02106 enumerated. Note that this does not provide information on the success or 02107 failure of the callback routine--if desired, this information should be 02108 stored in the Context structure. 02109 02110 --*/ 02111 02112 { 02113 NTSTATUS Status; 02114 HANDLE ServiceEnumHandle, SystemEnumHandle, DeviceInstanceHandle; 02115 UNICODE_STRING TempUnicodeString; 02116 ULONG ServiceInstanceCount, i, junk; 02117 PKEY_VALUE_FULL_INFORMATION KeyValueInformation; 02118 WCHAR ValueNameString[20]; 02119 BOOLEAN ContinueEnumeration; 02120 02121 // 02122 // First, open up the volatile Enum subkey under the specified service entry. 02123 // 02124 02125 if(ARGUMENT_PRESENT(ServiceKeyHandle)) { 02126 PiWstrToUnicodeString(&TempUnicodeString, REGSTR_KEY_ENUM); 02127 Status = IopOpenRegistryKey(&ServiceEnumHandle, 02128 ServiceKeyHandle, 02129 &TempUnicodeString, 02130 KEY_READ, 02131 FALSE 02132 ); 02133 } else { 02134 Status = IopOpenServiceEnumKeys(ServiceKeyName, 02135 KEY_READ, 02136 NULL, 02137 &ServiceEnumHandle, 02138 FALSE 02139 ); 02140 } 02141 if(!NT_SUCCESS(Status)) { 02142 return Status; 02143 } 02144 02145 // 02146 // Find out how many instances are referenced in the service's Enum key. 02147 // 02148 02149 ServiceInstanceCount = 0; // assume none. 02150 02151 Status = IopGetRegistryValue(ServiceEnumHandle, 02152 REGSTR_VALUE_COUNT, 02153 &KeyValueInformation 02154 ); 02155 if(NT_SUCCESS(Status)) { 02156 02157 if((KeyValueInformation->Type == REG_DWORD) && 02158 (KeyValueInformation->DataLength >= sizeof(ULONG))) { 02159 02160 ServiceInstanceCount = *(PULONG)KEY_VALUE_DATA(KeyValueInformation); 02161 02162 } 02163 ExFreePool(KeyValueInformation); 02164 02165 } else if(Status != STATUS_OBJECT_NAME_NOT_FOUND) { 02166 goto PrepareForReturn; 02167 } else { 02168 // 02169 // If 'Count' value entry not found, consider this to mean there are simply 02170 // no device instance controlled by this service. 02171 // 02172 Status = STATUS_SUCCESS; 02173 } 02174 02175 // 02176 // Now, enumerate each service instance, and call the specified callback function 02177 // for the corresponding device instance. 02178 // 02179 02180 if (ServiceInstanceCount) { 02181 02182 if (DesiredAccess) { 02183 Status = IopOpenRegistryKey(&SystemEnumHandle, 02184 NULL, 02185 &CmRegistryMachineSystemCurrentControlSetEnumName, 02186 KEY_READ, 02187 FALSE 02188 ); 02189 if(!NT_SUCCESS(Status)) { 02190 goto PrepareForReturn; 02191 } 02192 } else { 02193 // 02194 // Set DeviceInstanceHandle to NULL, since we won't be opening up the 02195 // device instance keys. 02196 // 02197 DeviceInstanceHandle = NULL; 02198 } 02199 KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool( 02200 PagedPool, 02201 PNP_SCRATCH_BUFFER_SIZE); 02202 if (!KeyValueInformation) { 02203 Status = STATUS_INSUFFICIENT_RESOURCES; 02204 goto PrepareForReturn; 02205 } 02206 i = 0; 02207 while (TRUE) { 02208 Status = ZwEnumerateValueKey ( // i was initialized to zero above. 02209 ServiceEnumHandle, 02210 i++, 02211 KeyValueFullInformation, 02212 KeyValueInformation, 02213 PNP_SCRATCH_BUFFER_SIZE, 02214 &junk 02215 ); 02216 02217 if (!NT_SUCCESS (Status)) { 02218 if (Status == STATUS_NO_MORE_ENTRIES) { 02219 Status = STATUS_SUCCESS; 02220 break; 02221 } else if(IgnoreNonCriticalErrors) { 02222 continue; 02223 } else { 02224 break; 02225 } 02226 } 02227 02228 if (KeyValueInformation->Type != REG_SZ) { 02229 continue; 02230 } 02231 02232 ContinueEnumeration = TRUE; 02233 TempUnicodeString.Length = 0; 02234 IopRegistryDataToUnicodeString(&TempUnicodeString, 02235 (PWSTR)KEY_VALUE_DATA(KeyValueInformation), 02236 KeyValueInformation->DataLength 02237 ); 02238 if (TempUnicodeString.Length) { 02239 02240 // 02241 // We have retrieved a (non-empty) string for this service instance. 02242 // If the user specified a non-zero value for the DesiredAccess 02243 // parameter, we will attempt to open up the corresponding device 02244 // instance key under HKLM\System\Enum. 02245 // 02246 if (DesiredAccess) { 02247 Status = IopOpenRegistryKey(&DeviceInstanceHandle, 02248 SystemEnumHandle, 02249 &TempUnicodeString, 02250 DesiredAccess, 02251 FALSE 02252 ); 02253 } 02254 02255 if (NT_SUCCESS(Status)) { 02256 // 02257 // Invoke the specified callback routine for this device instance. 02258 // 02259 ContinueEnumeration = DevInstCallbackRoutine(DeviceInstanceHandle, 02260 &TempUnicodeString, 02261 Context 02262 ); 02263 if (DesiredAccess) { 02264 ZwClose(DeviceInstanceHandle); 02265 } 02266 } else if (IgnoreNonCriticalErrors) { 02267 continue; 02268 } else { 02269 break; 02270 } 02271 } else { 02272 continue; 02273 } 02274 if (!ContinueEnumeration) { 02275 break; 02276 } 02277 } 02278 02279 if(DesiredAccess) { 02280 ZwClose(SystemEnumHandle); 02281 } 02282 ExFreePool(KeyValueInformation); 02283 } 02284 02285 if(ARGUMENT_PRESENT(ServiceInstanceOrdinal)) { 02286 *ServiceInstanceOrdinal = i; 02287 } 02288 02289 PrepareForReturn: 02290 02291 ZwClose(ServiceEnumHandle); 02292 02293 return Status; 02294 }

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

Definition at line 1690 of file pri_bld/pnpsubs.c.

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

Referenced by IopDeleteKeyRecursiveCallback(), IopGetRootDevices(), and IopInitializeDeviceKey().

01701 : 01702 01703 This routine enumerates all subkeys under the specified key, and calls 01704 the specified callback routine for each subkey. 01705 01706 Arguments: 01707 01708 BaseHandle - Optional handle to the base registry path. If KeyName is also 01709 specified, then KeyName represents a subkey under this path. If KeyName 01710 is not specified, the subkeys are enumerated under this handle. If this 01711 parameter is not specified, then the full path to the base key must be 01712 given in KeyName. 01713 01714 KeyName - Optional name of the key whose subkeys are to be enumerated. 01715 01716 DesiredAccess - Specifies the desired access that the callback routine 01717 needs to the subkeys. If no desired access is specified (i.e., 01718 DesiredAccess is zero), then no handle will be opened for the 01719 subkeys, and the callback will be passed a NULL for its SubKeyHandle 01720 parameter. 01721 01722 IgnoreNonCriticalErrors - Specifies whether this function should 01723 immediately terminate on all errors, or only on critical ones. 01724 An example of a non-critical error is when an enumerated subkey 01725 cannot be opened for the desired access. 01726 01727 SubKeyCallbackRoutine - Supplies a pointer to a function that will 01728 be called for each subkey found under the 01729 specified key. The prototype of the function 01730 is as follows: 01731 01732 typedef BOOLEAN (*PIOP_SUBKEY_CALLBACK_ROUTINE) ( 01733 IN HANDLE SubKeyHandle, 01734 IN PUNICODE_STRING SubKeyName, 01735 IN OUT PVOID Context 01736 ); 01737 01738 where SubKeyHandle is the handle to an enumerated subkey under the 01739 specified key, SubKeyName is its name, and Context is a pointer to 01740 user-defined data. 01741 01742 This function should return TRUE to continue enumeration, or 01743 FALSE to terminate it. 01744 01745 Context - Supplies a pointer to user-defined data that will be passed 01746 in to the callback routine at each subkey invocation. 01747 01748 Return Value: 01749 01750 NT status code indicating whether the subkeys were successfully 01751 enumerated. Note that this does not provide information on the 01752 success or failure of the callback routine--if desired, this 01753 information should be stored in the Context structure. 01754 01755 --*/ 01756 01757 { 01758 NTSTATUS Status; 01759 BOOLEAN CloseHandle = FALSE, ContinueEnumeration; 01760 HANDLE Handle, SubKeyHandle; 01761 ULONG i, RequiredBufferLength; 01762 PKEY_BASIC_INFORMATION KeyInformation = NULL; 01763 // Use an initial key name buffer size large enough for a 20-character key 01764 // (+ terminating NULL) 01765 ULONG KeyInformationLength = sizeof(KEY_BASIC_INFORMATION) + (20 * sizeof(WCHAR)); 01766 UNICODE_STRING SubKeyName; 01767 01768 if(ARGUMENT_PRESENT(KeyName)) { 01769 01770 Status = IopOpenRegistryKey(&Handle, 01771 BaseHandle, 01772 KeyName, 01773 KEY_READ, 01774 FALSE 01775 ); 01776 if(!NT_SUCCESS(Status)) { 01777 return Status; 01778 } else { 01779 CloseHandle = TRUE; 01780 } 01781 01782 } else { 01783 01784 Handle = BaseHandle; 01785 } 01786 01787 // 01788 // Enumerate the subkeys until we run out of them. 01789 // 01790 i = 0; 01791 SubKeyHandle = NULL; 01792 01793 while(TRUE) { 01794 01795 if(!KeyInformation) { 01796 01797 KeyInformation = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, 01798 KeyInformationLength 01799 ); 01800 if(!KeyInformation) { 01801 Status = STATUS_INSUFFICIENT_RESOURCES; 01802 break; 01803 } 01804 } 01805 01806 Status = ZwEnumerateKey(Handle, 01807 i, 01808 KeyBasicInformation, 01809 KeyInformation, 01810 KeyInformationLength, 01811 &RequiredBufferLength 01812 ); 01813 01814 if(!NT_SUCCESS(Status)) { 01815 if(Status == STATUS_BUFFER_OVERFLOW) { 01816 // 01817 // Try again with larger buffer. 01818 // 01819 ExFreePool(KeyInformation); 01820 KeyInformation = NULL; 01821 KeyInformationLength = RequiredBufferLength; 01822 continue; 01823 01824 } else if(Status == STATUS_NO_MORE_ENTRIES) { 01825 // 01826 // break out of loop 01827 // 01828 Status = STATUS_SUCCESS; 01829 break; 01830 01831 } else { 01832 // 01833 // This is a non-critical error. 01834 // 01835 if(IgnoreNonCriticalErrors) { 01836 goto ContinueWithNextSubKey; 01837 } else { 01838 break; 01839 } 01840 } 01841 } 01842 01843 // 01844 // Initialize a unicode string with this key name. Note that this string 01845 // WILL NOT be NULL-terminated. 01846 // 01847 SubKeyName.Length = SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength; 01848 SubKeyName.Buffer = KeyInformation->Name; 01849 01850 // 01851 // If DesiredAccess is non-zero, open a handle to this subkey. 01852 // 01853 if(DesiredAccess) { 01854 Status = IopOpenRegistryKey(&SubKeyHandle, 01855 Handle, 01856 &SubKeyName, 01857 DesiredAccess, 01858 FALSE 01859 ); 01860 if(!NT_SUCCESS(Status)) { 01861 // 01862 // This is a non-critical error. 01863 // 01864 if(IgnoreNonCriticalErrors) { 01865 goto ContinueWithNextSubKey; 01866 } else { 01867 break; 01868 } 01869 } 01870 } 01871 01872 // 01873 // Invoke the supplied callback function for this subkey. 01874 // 01875 ContinueEnumeration = SubKeyCallbackRoutine(SubKeyHandle, &SubKeyName, Context); 01876 01877 if(DesiredAccess) { 01878 ZwClose(SubKeyHandle); 01879 } 01880 01881 if(!ContinueEnumeration) { 01882 // 01883 // Enumeration has been aborted. 01884 // 01885 Status = STATUS_SUCCESS; 01886 break; 01887 01888 } 01889 01890 ContinueWithNextSubKey: 01891 01892 i++; 01893 } 01894 01895 if(KeyInformation) { 01896 ExFreePool(KeyInformation); 01897 } 01898 01899 if(CloseHandle) { 01900 ZwClose(Handle); 01901 } 01902 01903 return Status; 01904 }

NTSTATUS IopCleanupDeviceRegistryValues IN PUNICODE_STRING  InstancePath,
IN BOOLEAN  KeepReference
 

Definition at line 3841 of file pri_bld/pnpsubs.c.

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

Referenced by IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), and IopUnlockDeviceRemovalRelations().

03848 : 03849 03850 This routine cleans up a device instance key when the device is no 03851 longer present/enumerated. If the device is registered to a Service 03852 the Service's enum key will also been cleaned up. 03853 03854 Note the caller must lock the RegistryDeciceResource 03855 03856 Arguments: 03857 03858 InstancePath - supplies a pointer to the name of the device instance key. 03859 03860 KeepReference - supplies a boolean value to indicate if we should remove the 03861 device instance path to device object mapping. 03862 03863 Return Value: 03864 03865 status 03866 03867 --*/ 03868 03869 { 03870 HANDLE handle, instanceHandle; 03871 UNICODE_STRING unicodeValueName; 03872 NTSTATUS status; 03873 ULONG count = 0; 03874 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 03875 03876 PAGED_CODE(); 03877 03878 // 03879 // Open System\CurrentControlSet\Enum 03880 // 03881 03882 status = IopOpenRegistryKey(&handle, 03883 NULL, 03884 &CmRegistryMachineSystemCurrentControlSetEnumName, 03885 KEY_ALL_ACCESS, 03886 FALSE 03887 ); 03888 03889 if (!NT_SUCCESS( status )) { 03890 return status; 03891 } 03892 03893 // 03894 // Open the device instance key 03895 // 03896 03897 status = IopOpenRegistryKey(&instanceHandle, 03898 handle, 03899 InstancePath, 03900 KEY_ALL_ACCESS, 03901 FALSE 03902 ); 03903 03904 ZwClose(handle); 03905 if (!NT_SUCCESS( status )) { 03906 03907 // 03908 // There is no registry key for the ServiceKeyName information. 03909 // 03910 03911 return status; 03912 } 03913 03914 // 03915 // Delete the DeviceReference value name under Control key 03916 // 03917 03918 if (!KeepReference) { 03919 03920 // 03921 // BUGBUG (lonnym)--verify that removal of the following code fragment is valid. 03922 // 03923 #if 0 03924 // 03925 // Set the 'FoundAtEnum' value to false. 03926 // 03927 03928 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_FOUNDATENUM); 03929 tmpValue = 0; 03930 ZwSetValueKey(instanceHandle, 03931 &unicodeValueName, 03932 TITLE_INDEX_VALUE, 03933 REG_DWORD, 03934 &tmpValue, 03935 sizeof(tmpValue) 03936 ); 03937 #endif // (lonnym, verify removal to here) 03938 03939 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL); 03940 status = IopOpenRegistryKey(&handle, 03941 instanceHandle, 03942 &unicodeValueName, 03943 KEY_ALL_ACCESS, 03944 FALSE 03945 ); 03946 if (NT_SUCCESS( status )) { 03947 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DEVICE_REFERENCE); 03948 ZwDeleteValueKey(handle, &unicodeValueName); 03949 ZwClose(handle); 03950 } 03951 03952 // 03953 // Deregister the device from its controlling service's service enum key 03954 // 03955 03956 status = PiDeviceRegistration(InstancePath, 03957 FALSE, 03958 NULL 03959 ); 03960 } 03961 ZwClose(instanceHandle); 03962 03963 return status; 03964 }

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

Definition at line 4279 of file pri_bld/pnpsubs.c.

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

Referenced by IopFilterResourceRequirementsList(), IopQueryConflictListInternal(), IopQueryDeviceResources(), IopReserveBootResourcesInternal(), IopRestoreResourcesInternal(), IoReportResourceUsageInternal(), and MapperMarkKey().

04287 : 04288 04289 This routines converts the input CmResourceList to IO_RESOURCE_REQUIREMENTS_LIST. 04290 04291 Arguments: 04292 04293 SlotNumber - supplies the SlotNumber the resources refer to. 04294 04295 CmResourceList - the cm resource list to convert. 04296 04297 Priority - specifies the priority of the logconfig 04298 04299 Return Value: 04300 04301 returns a IO_RESOURCE_REQUIREMENTS_LISTST if succeeds. Otherwise a NULL value is 04302 returned. 04303 04304 --*/ 04305 { 04306 PIO_RESOURCE_REQUIREMENTS_LIST ioResReqList; 04307 ULONG count = 0, size, i, j; 04308 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc; 04309 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc; 04310 PIO_RESOURCE_DESCRIPTOR ioDesc; 04311 04312 // 04313 // First determine number of descriptors required. 04314 // 04315 04316 cmFullDesc = &CmResourceList->List[0]; 04317 for (i = 0; i < CmResourceList->Count; i++) { 04318 count += cmFullDesc->PartialResourceList.Count; 04319 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0]; 04320 for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) { 04321 size = 0; 04322 switch (cmPartDesc->Type) { 04323 case CmResourceTypeDeviceSpecific: 04324 size = cmPartDesc->u.DeviceSpecificData.DataSize; 04325 count--; 04326 break; 04327 } 04328 cmPartDesc++; 04329 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size); 04330 } 04331 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc; 04332 } 04333 04334 if (count == 0) { 04335 return NULL; 04336 } 04337 04338 // 04339 // Count the extra descriptors for InterfaceType and BusNumber information. 04340 // 04341 04342 count += CmResourceList->Count - 1; 04343 04344 // 04345 // Allocate heap space for IO RESOURCE REQUIREMENTS LIST 04346 // 04347 04348 count++; // add one for CmResourceTypeConfigData 04349 ioResReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePool( 04350 PagedPool, 04351 sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + 04352 count * sizeof(IO_RESOURCE_DESCRIPTOR) 04353 ); 04354 if (!ioResReqList) { 04355 return NULL; 04356 } 04357 04358 // 04359 // Parse the cm resource descriptor and build its corresponding IO resource descriptor 04360 // 04361 04362 ioResReqList->InterfaceType = CmResourceList->List[0].InterfaceType; 04363 ioResReqList->BusNumber = CmResourceList->List[0].BusNumber; 04364 ioResReqList->SlotNumber = SlotNumber; 04365 ioResReqList->Reserved[0] = 0; 04366 ioResReqList->Reserved[1] = 0; 04367 ioResReqList->Reserved[2] = 0; 04368 ioResReqList->AlternativeLists = 1; 04369 ioResReqList->List[0].Version = 1; 04370 ioResReqList->List[0].Revision = 1; 04371 ioResReqList->List[0].Count = count; 04372 04373 // 04374 // Generate a CmResourceTypeConfigData descriptor 04375 // 04376 04377 ioDesc = &ioResReqList->List[0].Descriptors[0]; 04378 ioDesc->Option = IO_RESOURCE_PREFERRED; 04379 ioDesc->Type = CmResourceTypeConfigData; 04380 ioDesc->ShareDisposition = CmResourceShareShared; 04381 ioDesc->Flags = 0; 04382 ioDesc->Spare1 = 0; 04383 ioDesc->Spare2 = 0; 04384 ioDesc->u.ConfigData.Priority = Priority; 04385 ioDesc++; 04386 04387 cmFullDesc = &CmResourceList->List[0]; 04388 for (i = 0; i < CmResourceList->Count; i++) { 04389 if (i != 0) { 04390 04391 // 04392 // Set up descriptor to remember the InterfaceType and BusNumber. 04393 // 04394 04395 ioDesc->Option = IO_RESOURCE_PREFERRED; 04396 ioDesc->Type = CmResourceTypeReserved; 04397 ioDesc->ShareDisposition = CmResourceShareUndetermined; 04398 ioDesc->Flags = 0; 04399 ioDesc->Spare1 = 0; 04400 ioDesc->Spare2 = 0; 04401 if (cmFullDesc->InterfaceType == InterfaceTypeUndefined) { 04402 ioDesc->u.DevicePrivate.Data[0] = PnpDefaultInterfaceType; 04403 } else { 04404 ioDesc->u.DevicePrivate.Data[0] = cmFullDesc->InterfaceType; 04405 } 04406 ioDesc->u.DevicePrivate.Data[1] = cmFullDesc->BusNumber; 04407 ioDesc->u.DevicePrivate.Data[2] = 0; 04408 ioDesc++; 04409 } 04410 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0]; 04411 for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) { 04412 ioDesc->Option = IO_RESOURCE_PREFERRED; 04413 ioDesc->Type = cmPartDesc->Type; 04414 ioDesc->ShareDisposition = cmPartDesc->ShareDisposition; 04415 ioDesc->Flags = cmPartDesc->Flags; 04416 ioDesc->Spare1 = 0; 04417 ioDesc->Spare2 = 0; 04418 04419 size = 0; 04420 switch (cmPartDesc->Type) { 04421 case CmResourceTypePort: 04422 ioDesc->u.Port.MinimumAddress = cmPartDesc->u.Port.Start; 04423 ioDesc->u.Port.MaximumAddress.QuadPart = cmPartDesc->u.Port.Start.QuadPart + 04424 cmPartDesc->u.Port.Length - 1; 04425 ioDesc->u.Port.Alignment = 1; 04426 ioDesc->u.Port.Length = cmPartDesc->u.Port.Length; 04427 ioDesc++; 04428 break; 04429 case CmResourceTypeInterrupt: 04430 #if defined(_X86_) 04431 ioDesc->u.Interrupt.MinimumVector = ioDesc->u.Interrupt.MaximumVector = 04432 cmPartDesc->u.Interrupt.Level; 04433 #else 04434 ioDesc->u.Interrupt.MinimumVector = ioDesc->u.Interrupt.MaximumVector = 04435 cmPartDesc->u.Interrupt.Vector; 04436 #endif 04437 ioDesc++; 04438 break; 04439 case CmResourceTypeMemory: 04440 ioDesc->u.Memory.MinimumAddress = cmPartDesc->u.Memory.Start; 04441 ioDesc->u.Memory.MaximumAddress.QuadPart = cmPartDesc->u.Memory.Start.QuadPart + 04442 cmPartDesc->u.Memory.Length - 1; 04443 ioDesc->u.Memory.Alignment = 1; 04444 ioDesc->u.Memory.Length = cmPartDesc->u.Memory.Length; 04445 ioDesc++; 04446 break; 04447 case CmResourceTypeDma: 04448 ioDesc->u.Dma.MinimumChannel = cmPartDesc->u.Dma.Channel; 04449 ioDesc->u.Dma.MaximumChannel = cmPartDesc->u.Dma.Channel; 04450 ioDesc++; 04451 break; 04452 case CmResourceTypeDeviceSpecific: 04453 size = cmPartDesc->u.DeviceSpecificData.DataSize; 04454 break; 04455 case CmResourceTypeBusNumber: 04456 ioDesc->u.BusNumber.MinBusNumber = cmPartDesc->u.BusNumber.Start; 04457 ioDesc->u.BusNumber.MaxBusNumber = cmPartDesc->u.BusNumber.Start + 04458 cmPartDesc->u.BusNumber.Length - 1; 04459 ioDesc->u.BusNumber.Length = cmPartDesc->u.BusNumber.Length; 04460 ioDesc++; 04461 break; 04462 default: 04463 ioDesc->u.DevicePrivate.Data[0] = cmPartDesc->u.DevicePrivate.Data[0]; 04464 ioDesc->u.DevicePrivate.Data[1] = cmPartDesc->u.DevicePrivate.Data[1]; 04465 ioDesc->u.DevicePrivate.Data[2] = cmPartDesc->u.DevicePrivate.Data[2]; 04466 ioDesc++; 04467 break; 04468 } 04469 cmPartDesc++; 04470 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size); 04471 } 04472 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc; 04473 } 04474 ioResReqList->ListSize = (ULONG)((ULONG_PTR)ioDesc - (ULONG_PTR)ioResReqList); 04475 return ioResReqList; 04476 }

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

Definition at line 695 of file pri_bld/pnpsubs.c.

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

Referenced by IopCreateMadeupNode(), IopInitializeDeviceInstanceKey(), IopProcessNewDeviceNode(), IopServiceInstanceToDeviceInstance(), and IoReportDetectedDevice().

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 87 of file pri_bld/pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumRootName, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), ExReleaseResource, FALSE, IopConcatenateUnicodeStrings(), IopGetRegistryValue(), IopOpenRegistryKey(), IopOpenRegistryKeyPersist(), 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.

Referenced by IopPrepareDriverLoading().

00097 : 00098 00099 This routine creates a new instance node under System\Enum\Root\*Madeup<Name> 00100 key and all the required default value entries. Also a value entry under 00101 Service\ServiceKeyName\Enum is created to point to the newly created madeup 00102 entry. A handle and the keyname of the new key are returned to caller. 00103 Caller must free the unicode string when he is done with it. 00104 00105 Parameters: 00106 00107 ServiceKeyName - Supplies a pointer to the name of the subkey in the 00108 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 00109 that caused the driver to load. This is the RegistryPath parameter 00110 to the DriverEntry routine. 00111 00112 ReturnedHandle - Supplies a variable to receive the handle of the 00113 newly created key. 00114 00115 KeyName - Supplies a variable to receive the name of the newly created 00116 key. 00117 00118 InstanceNumber - supplies a variable to receive the InstanceNumber value 00119 entry created under service\name\enum subkey. 00120 00121 ResourceOwned - supplies a BOOLEAN variable to indicate if caller owns 00122 the registry resource exclusively. 00123 00124 Return Value: 00125 00126 Status code that indicates whether or not the function was successful. 00127 00128 --*/ 00129 00130 { 00131 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 00132 UNICODE_STRING tmpKeyName, unicodeInstanceName, unicodeString; 00133 UNICODE_STRING rootKeyName, unicodeValueName, unicodeKeyName; 00134 HANDLE handle, enumRootHandle, hTreeHandle; 00135 ULONG instance; 00136 UCHAR unicodeBuffer[20]; 00137 ULONG tmpValue, disposition = 0; 00138 NTSTATUS status; 00139 PWSTR p; 00140 BOOLEAN releaseResource = FALSE; 00141 00142 if (!ResourceOwned) { 00143 KeEnterCriticalRegion(); 00144 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 00145 releaseResource = TRUE; 00146 } 00147 00148 // 00149 // Open LocalMachine\System\CurrentControlSet\Enum\Root 00150 // 00151 00152 status = IopOpenRegistryKey(&enumRootHandle, 00153 NULL, 00154 &CmRegistryMachineSystemCurrentControlSetEnumRootName, 00155 KEY_ALL_ACCESS, 00156 FALSE 00157 ); 00158 if (!NT_SUCCESS(status)) { 00159 goto local_exit0; 00160 } 00161 00162 // 00163 // Open, and create if not already exist, System\Enum\Root\LEGACY_<ServiceName> 00164 // First, try to find the ServiceName by extracting it from user supplied 00165 // ServiceKeyName. 00166 // 00167 00168 PiWstrToUnicodeString(&tmpKeyName, REGSTR_KEY_MADEUP); 00169 IopConcatenateUnicodeStrings(&unicodeKeyName, &tmpKeyName, ServiceKeyName); 00170 RtlUpcaseUnicodeString(&unicodeKeyName, &unicodeKeyName, FALSE); 00171 status = IopOpenRegistryKeyPersist(&handle, 00172 enumRootHandle, 00173 &unicodeKeyName, 00174 KEY_ALL_ACCESS, 00175 TRUE, 00176 NULL 00177 ); 00178 ZwClose(enumRootHandle); 00179 if (!NT_SUCCESS(status)) { 00180 RtlFreeUnicodeString(&unicodeKeyName); 00181 goto local_exit0; 00182 } 00183 00184 instance = 1; 00185 00186 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE); 00187 status = ZwSetValueKey( 00188 handle, 00189 &unicodeValueName, 00190 TITLE_INDEX_VALUE, 00191 REG_DWORD, 00192 &instance, 00193 sizeof(instance) 00194 ); 00195 00196 instance--; 00197 *InstanceNumber = instance; 00198 PiUlongToInstanceKeyUnicodeString(&unicodeInstanceName, 00199 unicodeBuffer + sizeof(WCHAR), // reserve first WCHAR space 00200 20 - sizeof(WCHAR), 00201 instance 00202 ); 00203 status = IopOpenRegistryKeyPersist(ReturnedHandle, 00204 handle, 00205 &unicodeInstanceName, 00206 KEY_ALL_ACCESS, 00207 TRUE, 00208 &disposition 00209 ); 00210 ZwClose(handle); 00211 if (!NT_SUCCESS(status)) { 00212 RtlFreeUnicodeString(&unicodeKeyName); 00213 goto local_exit0; 00214 } 00215 00216 // 00217 // Prepare newly created registry key name for returning to caller 00218 // 00219 00220 *(PWSTR)unicodeBuffer = OBJ_NAME_PATH_SEPARATOR; 00221 unicodeInstanceName.Buffer = (PWSTR)unicodeBuffer; 00222 unicodeInstanceName.Length += sizeof(WCHAR); 00223 unicodeInstanceName.MaximumLength += sizeof(WCHAR); 00224 PiWstrToUnicodeString(&rootKeyName, REGSTR_KEY_ROOTENUM); 00225 RtlInitUnicodeString(&tmpKeyName, L"\\"); 00226 IopConcatenateUnicodeStrings(&unicodeString, &tmpKeyName, &unicodeKeyName); 00227 RtlFreeUnicodeString(&unicodeKeyName); 00228 IopConcatenateUnicodeStrings(&tmpKeyName, &rootKeyName, &unicodeString); 00229 RtlFreeUnicodeString(&unicodeString); 00230 IopConcatenateUnicodeStrings(KeyName, &tmpKeyName, &unicodeInstanceName); 00231 00232 if (disposition == REG_CREATED_NEW_KEY) { 00233 00234 // 00235 // Create all the default value entry for the newly created key. 00236 // Service = ServiceKeyName 00237 // FoundAtEnum = 1 00238 // Class = "LegacyDriver" 00239 // ClassGUID = GUID for legacy driver class 00240 // ConfigFlags = 0 00241 // 00242 // Create "Control" subkey with "NewlyCreated" value key 00243 // 00244 00245 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL); 00246 status = IopOpenRegistryKey(&handle, 00247 *ReturnedHandle, 00248 &unicodeValueName, 00249 KEY_ALL_ACCESS, 00250 TRUE 00251 ); 00252 if (NT_SUCCESS(status)) { 00253 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEWLY_CREATED); 00254 tmpValue = 0; 00255 ZwSetValueKey(handle, 00256 &unicodeValueName, 00257 TITLE_INDEX_VALUE, 00258 REG_DWORD, 00259 &tmpValue, 00260 sizeof(tmpValue) 00261 ); 00262 ZwClose(handle); 00263 } 00264 00265 handle = *ReturnedHandle; 00266 00267 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_SERVICE); 00268 p = (PWSTR)ExAllocatePool(PagedPool, 00269 ServiceKeyName->Length + sizeof(UNICODE_NULL)); 00270 if(p) { 00271 RtlMoveMemory(p, ServiceKeyName->Buffer, ServiceKeyName->Length); 00272 p[ServiceKeyName->Length / sizeof (WCHAR)] = UNICODE_NULL; 00273 ZwSetValueKey( 00274 handle, 00275 &unicodeValueName, 00276 TITLE_INDEX_VALUE, 00277 REG_SZ, 00278 p, 00279 ServiceKeyName->Length + sizeof(UNICODE_NULL) 00280 ); 00281 // 00282 // We'll keep the null-terminated service name buffer around for a while, 00283 // because we may need it later on for the DeviceDesc in case the service 00284 // has no DisplayName. 00285 // 00286 // ExFreePool(p); 00287 } 00288 00289 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_LEGACY); 00290 tmpValue = 1; 00291 ZwSetValueKey( 00292 handle, 00293 &unicodeValueName, 00294 TITLE_INDEX_VALUE, 00295 REG_DWORD, 00296 &tmpValue, 00297 sizeof(tmpValue) 00298 ); 00299 00300 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CONFIG_FLAGS); 00301 tmpValue = 0; 00302 ZwSetValueKey( 00303 handle, 00304 &unicodeValueName, 00305 TITLE_INDEX_VALUE, 00306 REG_DWORD, 00307 &tmpValue, 00308 sizeof(tmpValue) 00309 ); 00310 00311 // 00312 // BUGBUG (lonnym)--verify that removal of the following code fragment is OK. 00313 // 00314 #if 0 00315 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_FOUNDATENUM); 00316 tmpValue = 1; 00317 ZwSetValueKey( 00318 handle, 00319 &unicodeValueName, 00320 TITLE_INDEX_VALUE, 00321 REG_DWORD, 00322 &tmpValue, 00323 sizeof(tmpValue) 00324 ); 00325 #endif // (lonnym, verify removal to here) 00326 00327 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CLASS); 00328 ZwSetValueKey( 00329 handle, 00330 &unicodeValueName, 00331 TITLE_INDEX_VALUE, 00332 REG_SZ, 00333 REGSTR_VALUE_LEGACY_DRIVER, 00334 sizeof(REGSTR_VALUE_LEGACY_DRIVER) 00335 ); 00336 00337 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CLASSGUID); 00338 ZwSetValueKey( 00339 handle, 00340 &unicodeValueName, 00341 TITLE_INDEX_VALUE, 00342 REG_SZ, 00343 REGSTR_VALUE_LEGACY_DRIVER_CLASS_GUID, 00344 sizeof(REGSTR_VALUE_LEGACY_DRIVER_CLASS_GUID) 00345 ); 00346 00347 00348 // 00349 // Initialize DeviceDesc= value entry. If the service key has a "DisplayName" 00350 // value entry, it is used as the DeviceDesc value. Otherwise, the service key 00351 // name is used. 00352 // 00353 00354 status = IopOpenServiceEnumKeys(ServiceKeyName, 00355 KEY_READ, 00356 &handle, 00357 NULL, 00358 FALSE 00359 ); 00360 if (NT_SUCCESS(status)) { 00361 00362 keyValueInformation = NULL; 00363 unicodeString.Length = 0; 00364 status = IopGetRegistryValue(handle, 00365 REGSTR_VALUE_DISPLAY_NAME, 00366 &keyValueInformation 00367 ); 00368 if (NT_SUCCESS(status)) { 00369 if (keyValueInformation->Type == REG_SZ) { 00370 if (keyValueInformation->DataLength > sizeof(UNICODE_NULL)) { 00371 IopRegistryDataToUnicodeString(&unicodeString, 00372 (PWSTR)KEY_VALUE_DATA(keyValueInformation), 00373 keyValueInformation->DataLength 00374 ); 00375 } 00376 } 00377 } 00378 if ((unicodeString.Length == 0) && p) { 00379 00380 // 00381 // No DisplayName--use the service key name. 00382 // 00383 00384 unicodeString.Length = ServiceKeyName->Length; 00385 unicodeString.MaximumLength = ServiceKeyName->Length + sizeof(UNICODE_NULL); 00386 unicodeString.Buffer = p; 00387 } 00388 00389 if(unicodeString.Length) { 00390 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DEVICE_DESC); 00391 ZwSetValueKey(*ReturnedHandle, 00392 &unicodeValueName, 00393 TITLE_INDEX_VALUE, 00394 REG_SZ, 00395 unicodeString.Buffer, 00396 unicodeString.Length + sizeof(UNICODE_NULL) 00397 ); 00398 } 00399 if (keyValueInformation) { 00400 ExFreePool(keyValueInformation); 00401 } 00402 ZwClose(handle); 00403 } 00404 00405 if(p) { 00406 ExFreePool(p); 00407 } 00408 } 00409 00410 // 00411 // Create new value entry under ServiceKeyName\Enum to reflect the newly 00412 // added made-up device instance node. 00413 // 00414 00415 ExReleaseResource(&PpRegistryDeviceResource); 00416 KeLeaveCriticalRegion(); 00417 releaseResource = FALSE; 00418 00419 status = PpDeviceRegistration( 00420 KeyName, 00421 TRUE, 00422 NULL, 00423 NULL 00424 ); 00425 00426 if (ResourceOwned) { 00427 KeEnterCriticalRegion(); 00428 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 00429 } 00430 RtlFreeUnicodeString(&tmpKeyName); 00431 if (!NT_SUCCESS( status )) { 00432 00433 // 00434 // 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 }

VOID IopDeleteLegacyKey IN PDRIVER_OBJECT  DriverObject  ) 
 

Definition at line 5338 of file pri_bld/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(), IopGetRegistryValue(), IopOpenRegistryKey(), IopReleaseDeviceResources(), IopSetDevNodeProblem, KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, L, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, _DEVICE_NODE::OverUsed1, _DEVICE_NODE::OverUsed2, PpRegistryDeviceResource, TRUE, and USHORT.

Referenced by IopInitializeBuiltinDriver(), IopLoadDriver(), and IoReportDetectedDevice().

05344 : 05345 05346 This routine checks if the Legacy= value of the driver's legacy_xxx key 05347 is one. If yes, it deletes the Legacy key. 05348 05349 Parameters: 05350 05351 DriverObject - supplies a pointer to the driver object. 05352 05353 Return Value: 05354 05355 None. If anything fails in this routine, the legacy key stays. 05356 05357 --*/ 05358 05359 { 05360 WCHAR buffer[100]; 05361 NTSTATUS status; 05362 UNICODE_STRING deviceName, instanceName, unicodeName, *serviceName; 05363 ULONG length; 05364 HANDLE handle, handle1, handlex, enumHandle; 05365 ULONG legacy; 05366 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 05367 PDEVICE_OBJECT deviceObject; 05368 PDEVICE_NODE deviceNode; 05369 05370 serviceName = &DriverObject->DriverExtension->ServiceKeyName; 05371 05372 KeEnterCriticalRegion(); 05373 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 05374 05375 status = IopOpenRegistryKey(&enumHandle, 05376 NULL, 05377 &CmRegistryMachineSystemCurrentControlSetEnumName, 05378 KEY_ALL_ACCESS, 05379 FALSE 05380 ); 05381 05382 if (!NT_SUCCESS(status)) { 05383 goto exit; 05384 } 05385 05386 length = _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"ROOT\\LEGACY_%s", serviceName->Buffer); 05387 deviceName.MaximumLength = sizeof(buffer); 05388 ASSERT(length <= sizeof(buffer) - 10); 05389 deviceName.Length = (USHORT)(length * sizeof(WCHAR)); 05390 deviceName.Buffer = buffer; 05391 05392 status = IopOpenRegistryKey(&handle1, 05393 enumHandle, 05394 &deviceName, 05395 KEY_ALL_ACCESS, 05396 FALSE 05397 ); 05398 05399 if (NT_SUCCESS(status)) { 05400 05401 deviceName.Buffer[deviceName.Length / sizeof(WCHAR)] = 05402 OBJ_NAME_PATH_SEPARATOR; 05403 deviceName.Length += sizeof(WCHAR); 05404 PiUlongToInstanceKeyUnicodeString( 05405 &instanceName, 05406 buffer + deviceName.Length / sizeof(WCHAR), 05407 sizeof(buffer) - deviceName.Length, 05408 0 05409 ); 05410 deviceName.Length += instanceName.Length; 05411 05412 05413 status = IopOpenRegistryKey( 05414 &handle, 05415 handle1, 05416 &instanceName, 05417 KEY_ALL_ACCESS, 05418 FALSE 05419 ); 05420 if (NT_SUCCESS(status)) { 05421 legacy = 1; 05422 status = IopGetRegistryValue (handle, 05423 REGSTR_VALUE_LEGACY, 05424 &keyValueInformation); 05425 if (NT_SUCCESS(status)) { 05426 if ((keyValueInformation->Type == REG_DWORD) && 05427 (keyValueInformation->DataLength >= sizeof(ULONG))) { 05428 legacy = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 05429 } 05430 ExFreePool(keyValueInformation); 05431 } 05432 if (legacy != 0) { 05433 05434 // 05435 // We also want to delete the madeup device node 05436 // 05437 05438 deviceObject = IopDeviceObjectFromDeviceInstance(handle, NULL); 05439 if (deviceObject) { 05440 05441 PDEVICE_NODE devNodex, devNodey; 05442 05443 deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode; 05444 if (deviceNode) { 05445 if (deviceNode->Flags & DNF_MADEUP) { 05446 05447 // 05448 // Now mark this one deleted. 05449 // 05450 deviceNode->Flags &= ~DNF_STARTED; 05451 IopSetDevNodeProblem(deviceNode, CM_PROB_DEVICE_NOT_THERE); 05452 05453 // 05454 // This is actually doing nothing because DeviceNode->ResourceList is NULL. 05455 // 05456 05457 IopReleaseDeviceResources(deviceNode); 05458 devNodex = deviceNode; 05459 while (devNodex) { 05460 devNodey = devNodex; 05461 devNodex = (PDEVICE_NODE)devNodey->OverUsed2.NextResourceDeviceNode; 05462 devNodey->OverUsed2.NextResourceDeviceNode = NULL; 05463 devNodey->OverUsed1.LegacyDeviceNode = NULL; 05464 } 05465 05466 deviceNode->Flags &= ~DNF_MADEUP; // remove its boot config if any 05467 IoDeleteDevice(deviceObject); 05468 } 05469 } 05470 ObDereferenceObject(deviceObject); // added via IopDeviceObjectFromDeviceInstance 05471 } 05472 05473 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL); 05474 status = IopOpenRegistryKey(&handlex, 05475 handle, 05476 &unicodeName, 05477 KEY_ALL_ACCESS, 05478 FALSE 05479 ); 05480 if (NT_SUCCESS(status)) { 05481 ZwDeleteKey(handlex); 05482 } 05483 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 05484 status = IopOpenRegistryKey(&handlex, 05485 handle, 05486 &unicodeName, 05487 KEY_ALL_ACCESS, 05488 FALSE 05489 ); 05490 if (NT_SUCCESS(status)) { 05491 ZwDeleteKey(handlex); 05492 } 05493 05494 ZwClose(enumHandle); 05495 05496 // 05497 // We need to call IopCleanupDeviceRegistryValue even we are going to 05498 // delete it. Because, it also cleans up related value names in other 05499 // keys. 05500 // 05501 05502 IopCleanupDeviceRegistryValues(&deviceName, FALSE); 05503 ZwDeleteKey(handle); 05504 ZwDeleteKey(handle1); 05505 } else { 05506 ZwClose(handle); 05507 ZwClose(handle1); 05508 ZwClose(enumHandle); 05509 } 05510 } else { 05511 ZwClose(handle1); 05512 ZwClose(enumHandle); 05513 } 05514 } else { 05515 ZwClose(enumHandle); 05516 } 05517 exit: 05518 ExReleaseResource(&PpRegistryDeviceResource); 05519 KeLeaveCriticalRegion(); 05520 return; 05521 }

ULONG IopDetermineResourceListSize IN PCM_RESOURCE_LIST  ResourceList  ) 
 

Definition at line 3523 of file pri_bld/pnpsubs.c.

References List.

Referenced by IopBuildCmResourceLists(), IopChangeInterfaceType(), IopCombineCmResourceList(), IopCombineLegacyResources(), IopLegacyResourceAllocation(), IopMergeCmResourceLists(), IopQueryDeviceResources(), IopReserveBootResources(), IopReserveBootResourcesInternal(), IopRestoreResourcesInternal(), and IoReportDetectedDevice().

03529 : 03530 03531 This routine determines size of the passed in ResourceList 03532 structure. 03533 03534 Arguments: 03535 03536 Configuration1 - Supplies a pointer to the resource list. 03537 03538 Return Value: 03539 03540 size of the resource list structure. 03541 03542 --*/ 03543 03544 { 03545 ULONG totalSize, listSize, descriptorSize, i, j; 03546 PCM_FULL_RESOURCE_DESCRIPTOR fullResourceDesc; 03547 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor; 03548 03549 if (!ResourceList) { 03550 totalSize = 0; 03551 } else { 03552 totalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List); 03553 fullResourceDesc = &ResourceList->List[0]; 03554 for (i = 0; i < ResourceList->Count; i++) { 03555 listSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, 03556 PartialResourceList) + 03557 FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, 03558 PartialDescriptors); 03559 partialDescriptor = &fullResourceDesc->PartialResourceList.PartialDescriptors[0]; 03560 for (j = 0; j < fullResourceDesc->PartialResourceList.Count; j++) { 03561 descriptorSize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); 03562 if (partialDescriptor->Type == CmResourceTypeDeviceSpecific) { 03563 descriptorSize += partialDescriptor->u.DeviceSpecificData.DataSize; 03564 } 03565 listSize += descriptorSize; 03566 partialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) 03567 ((PUCHAR)partialDescriptor + descriptorSize); 03568 } 03569 totalSize += listSize; 03570 fullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) 03571 ((PUCHAR)fullResourceDesc + listSize); 03572 } 03573 } 03574 return totalSize; 03575 }

NTSTATUS IopDeviceCapabilitiesToRegistry IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 5524 of file pri_bld/pnpsubs.c.

References DNF_HAS_BOOT_CONFIG, _DEVICE_CAPABILITIES::DockDevice, _DEVICE_CAPABILITIES::EjectSupported, _DEVICE_NODE::Flags, IopDeviceObjectToDeviceInstance(), IopQueryDeviceCapabilities(), _DEVICE_CAPABILITIES::LockSupported, NT_SUCCESS, NTSTATUS(), PAGED_CODE, _DEVICE_CAPABILITIES::RawDeviceOK, _DEVICE_CAPABILITIES::Removable, _DEVICE_CAPABILITIES::SilentInstall, _DEVICE_CAPABILITIES::SurpriseRemovalOK, TITLE_INDEX_VALUE, and _DEVICE_CAPABILITIES::UniqueID.

Referenced by IopDeviceNodeCapabilitiesToRegistry(), and IopProcessNewDeviceNode().

05530 : 05531 05532 This routine queries and updates device capabilities after device received a start irp. 05533 05534 Arguments: 05535 05536 DeviceObject - supplies a pointer to a device object whose registry 05537 values are to be updated. 05538 05539 Return Value: 05540 05541 status 05542 05543 --*/ 05544 05545 { 05546 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 05547 HANDLE handle; 05548 NTSTATUS status; 05549 UNICODE_STRING unicodeName; 05550 ULONG tmpValue; 05551 DEVICE_CAPABILITIES capabilities; 05552 05553 PAGED_CODE(); 05554 05555 // 05556 // Open the device instance key 05557 // 05558 05559 status = IopDeviceObjectToDeviceInstance(DeviceObject, &handle, KEY_ALL_ACCESS); 05560 if (!NT_SUCCESS(status)) { 05561 return status; 05562 } 05563 05564 status = IopQueryDeviceCapabilities(deviceNode, &capabilities); 05565 if (!NT_SUCCESS(status)) { 05566 return status; 05567 } 05568 05569 if (deviceNode->Flags & DNF_HAS_BOOT_CONFIG) { 05570 capabilities.SurpriseRemovalOK = 0; 05571 } 05572 05573 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_CAPABILITIES); 05574 tmpValue = (capabilities.LockSupported) | 05575 (capabilities.EjectSupported << 1) | 05576 (capabilities.Removable << 2) | 05577 (capabilities.DockDevice << 3) | 05578 (capabilities.UniqueID << 4) | 05579 (capabilities.SilentInstall << 5) | 05580 (capabilities.RawDeviceOK << 6) | 05581 (capabilities.SurpriseRemovalOK << 7); 05582 05583 status = ZwSetValueKey( 05584 handle, 05585 &unicodeName, 05586 TITLE_INDEX_VALUE, 05587 REG_DWORD, 05588 &tmpValue, 05589 sizeof(tmpValue) 05590 ); 05591 05592 ZwClose(handle); 05593 return status; 05594 }

PDEVICE_OBJECT IopDeviceObjectFromDeviceInstance IN HANDLE DeviceInstanceHandle  OPTIONAL,
IN PUNICODE_STRING DeviceInstance  OPTIONAL
 

Definition at line 3651 of file pri_bld/pnpsubs.c.

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

Referenced by IopAddDevicesToBootDriverWorker(), IopDeleteLegacyKey(), IopDriverLoadingFailed(), IopGetDriverDeviceListWorker(), IopInitializeDeviceInstanceKey(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopProcessNewDeviceNode(), IopProcessSetInterfaceState(), IopSetLegacyDeviceInstance(), and IoReportDetectedDevice().

03658 : 03659 03660 This routine receives a DeviceInstance path (or DeviceInstance handle) and 03661 returns a reference to a bus device object for the DeviceInstance. 03662 03663 Arguments: 03664 03665 DeviceInstanceHandle - Supplies a handle to the registry Device Instance key. 03666 If this parameter is NULL, DeviceInstance must specify the registry path. 03667 03668 DeviceInstance - supplies a UNICODE_STRING to specify the device instance path. 03669 if this parameter is NULL, DeviceInstanceHandle must specify the handle 03670 to its registry key. 03671 03672 Returns: 03673 03674 A reference to the desired bus device object. 03675 03676 --*/ 03677 03678 { 03679 NTSTATUS status; 03680 HANDLE handle, deviceHandle = NULL; 03681 PDEVICE_OBJECT deviceReference = NULL; 03682 UNICODE_STRING unicodeName; 03683 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 03684 PDEVICE_NODE deviceNode; 03685 03686 PAGED_CODE(); 03687 03688 if (!ARGUMENT_PRESENT(DeviceInstanceHandle)) { 03689 03690 // 03691 // first open System\CCS\Enum key and then the device instance key. 03692 // 03693 03694 status = IopOpenRegistryKey(&handle, 03695 NULL, 03696 &CmRegistryMachineSystemCurrentControlSetEnumName, 03697 KEY_READ, 03698 FALSE 03699 ); 03700 03701 if (!NT_SUCCESS( status )) { 03702 return deviceReference; 03703 } 03704 03705 ASSERT(DeviceInstance); 03706 status = IopOpenRegistryKey (&deviceHandle, 03707 handle, 03708 DeviceInstance, 03709 KEY_READ, 03710 FALSE 03711 ); 03712 ZwClose(handle); 03713 if (!NT_SUCCESS(status)) { 03714 return deviceReference; 03715 } 03716 DeviceInstanceHandle = deviceHandle; 03717 } 03718 03719 // 03720 // Read the address of device object 03721 // 03722 03723 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL); 03724 status = IopOpenRegistryKey(&handle, 03725 DeviceInstanceHandle, 03726 &unicodeName, 03727 KEY_READ, 03728 FALSE 03729 ); 03730 if (!NT_SUCCESS(status)) { 03731 goto exit; 03732 } 03733 03734 status = IopGetRegistryValue (handle, 03735 REGSTR_VALUE_DEVICE_REFERENCE, 03736 &keyValueInformation); 03737 ZwClose(handle); 03738 if (NT_SUCCESS(status)) { 03739 if ((keyValueInformation->Type == REG_DWORD) && 03740 (keyValueInformation->DataLength == sizeof(ULONG_PTR))) { 03741 03742 deviceReference = *(PDEVICE_OBJECT *)KEY_VALUE_DATA(keyValueInformation); 03743 } 03744 ExFreePool(keyValueInformation); 03745 } 03746 if (!deviceReference) { 03747 goto exit; 03748 } 03749 03750 // 03751 // Make sure the address of the device object is not clobbered, 03752 // unfortunately if the address is truly bogus we will bugcheck since 03753 // try/except doesn't work for kernel addresses. 03754 // 03755 03756 if (deviceReference->Type != IO_TYPE_DEVICE) { 03757 deviceReference = NULL; 03758 } else { 03759 deviceNode = (PDEVICE_NODE)deviceReference->DeviceObjectExtension->DeviceNode; 03760 if (deviceNode && (deviceNode->PhysicalDeviceObject == deviceReference)) { 03761 ObReferenceObject(deviceReference); 03762 } else { 03763 deviceReference = NULL; 03764 } 03765 } 03766 03767 exit: 03768 if (deviceHandle) { 03769 ZwClose(deviceHandle); 03770 } 03771 return deviceReference; 03772 03773 }

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

Definition at line 3776 of file pri_bld/pnpsubs.c.

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

Referenced by IoGetDeviceProperty(), IoOpenDeviceRegistryKey(), IopAssignResourcesToDevices(), IopDeviceCapabilitiesToRegistry(), IopGetDeviceResourcesFromRegistry(), IopIsFirmwareDisabled(), IopNotifySetupDeviceArrival(), IopNotifySetupDevices(), IopQueryDeviceResources(), IopReleaseDeviceResources(), IopStartAndEnumerateDevice(), IopWriteAllocatedResourcesToRegistry(), and IoReportDetectedDevice().

03784 : 03785 03786 This routine receives a DeviceObject pointer and returns a handle to the device 03787 instance path under registry System\ENUM key. 03788 03789 Note, caller must owner the PpRegistryDeviceResource before calling the function, 03790 03791 Arguments: 03792 03793 DeviceObject - supplies a pointer to a physical device object. 03794 03795 DeviceInstanceHandle - Supplies a variable to receive the handle to the registry 03796 device instance key. 03797 03798 DesiredAccess - specifies the access that is needed to this key. 03799 03800 Returns: 03801 03802 NTSTATUS code to indicate success or failure. 03803 03804 --*/ 03805 03806 { 03807 NTSTATUS status; 03808 HANDLE handle; 03809 PDEVICE_NODE deviceNode; 03810 03811 PAGED_CODE(); 03812 03813 status = IopOpenRegistryKey(&handle, 03814 NULL, 03815 &CmRegistryMachineSystemCurrentControlSetEnumName, 03816 KEY_READ, 03817 FALSE 03818 ); 03819 03820 if (!NT_SUCCESS( status )) { 03821 return status; 03822 } 03823 03824 deviceNode = (PDEVICE_NODE) DeviceObject->DeviceObjectExtension->DeviceNode; 03825 if (deviceNode && (deviceNode->InstancePath.Length != 0)) { 03826 status = IopOpenRegistryKey (DeviceInstanceHandle, 03827 handle, 03828 &deviceNode->InstancePath, 03829 DesiredAccess, 03830 FALSE 03831 ); 03832 } else { 03833 status = STATUS_INVALID_DEVICE_REQUEST; 03834 } 03835 ZwClose(handle); 03836 03837 return status; 03838 }

VOID IopDisableDevice IN PDEVICE_NODE  DeviceNode,
IN HANDLE  Handle
 

Referenced by IopIsAnyDeviceInstanceEnabled(), and IopIsDeviceInstanceEnabled().

NTSTATUS IopDriverLoadingFailed IN HANDLE ServiceHandle  OPTIONAL,
IN PUNICODE_STRING ServiceName  OPTIONAL
 

Definition at line 2609 of file pri_bld/pnpsubs.c.

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

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

02616 : 02617 02618 This routine is invoked when driver failed to start. All the device 02619 instances controlled by this driver/service are marked as failing to 02620 start. 02621 02622 Arguments: 02623 02624 ServiceKeyHandle - Optionally, supplies a handle to the driver service node in the 02625 registry that controls this device instance. If this argument is not specified, 02626 then ServiceKeyName is used to specify the service entry. 02627 02628 ServiceKeyName - Optionally supplies the name of the service entry that controls 02629 the device instance. This must be specified if ServiceKeyHandle isn't given. 02630 02631 Returns: 02632 02633 None. 02634 02635 --*/ 02636 02637 { 02638 NTSTATUS status; 02639 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 02640 BOOLEAN closeHandle = FALSE, deletePdo; 02641 HANDLE handle, serviceEnumHandle, controlHandle; 02642 HANDLE sysEnumHandle = NULL; 02643 ULONG deviceFlags, count, newCount, i, j; 02644 UNICODE_STRING unicodeValueName, deviceInstanceName; 02645 WCHAR unicodeBuffer[20]; 02646 02647 // 02648 // Open registry ServiceKeyName\Enum branch 02649 // 02650 02651 if (!ARGUMENT_PRESENT(ServiceHandle)) { 02652 status = IopOpenServiceEnumKeys(ServiceName, 02653 KEY_READ, 02654 &ServiceHandle, 02655 &serviceEnumHandle, 02656 FALSE 02657 ); 02658 closeHandle = TRUE; 02659 } else { 02660 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_ENUM); 02661 status = IopOpenRegistryKey(&serviceEnumHandle, 02662 ServiceHandle, 02663 &unicodeValueName, 02664 KEY_READ, 02665 FALSE 02666 ); 02667 } 02668 if (!NT_SUCCESS( status )) { 02669 02670 // 02671 // No Service Enum key? no device instance. Return FALSE. 02672 // 02673 02674 return status; 02675 } 02676 02677 // 02678 // Set "STARTFAILED" flags. So, we won't load it again. 02679 // 02680 02681 RtlInitUnicodeString(&unicodeValueName, L"INITSTARTFAILED"); 02682 deviceFlags = 1; 02683 ZwSetValueKey( 02684 serviceEnumHandle, 02685 &unicodeValueName, 02686 TITLE_INDEX_VALUE, 02687 REG_DWORD, 02688 &deviceFlags, 02689 sizeof(deviceFlags) 02690 ); 02691 02692 // 02693 // Find out how many device instances listed in the ServiceName's 02694 // Enum key. 02695 // 02696 02697 status = IopGetRegistryValue ( serviceEnumHandle, 02698 REGSTR_VALUE_COUNT, 02699 &keyValueInformation 02700 ); 02701 count = 0; 02702 if (NT_SUCCESS(status)) { 02703 if ((keyValueInformation->Type == REG_DWORD) && 02704 (keyValueInformation->DataLength >= sizeof(ULONG))) { 02705 02706 count = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 02707 } 02708 ExFreePool(keyValueInformation); 02709 } 02710 if (count == 0) { 02711 ZwClose(serviceEnumHandle); 02712 if (closeHandle) { 02713 ZwClose(ServiceHandle); 02714 } 02715 return status; 02716 } 02717 02718 // 02719 // Open HTREE\ROOT\0 key so later we can remove device instance key 02720 // from its AttachedComponents value name. 02721 // 02722 02723 status = IopOpenRegistryKey(&sysEnumHandle, 02724 NULL, 02725 &CmRegistryMachineSystemCurrentControlSetEnumName, 02726 KEY_ALL_ACCESS, 02727 FALSE 02728 ); 02729 02730 // 02731 // Walk through each registered device instance to mark its Problem and 02732 // StatusFlags as fail to start and reset its ActiveService 02733 // 02734 02735 KeEnterCriticalRegion(); 02736 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 02737 02738 newCount = count; 02739 for (i = 0; i < count; i++) { 02740 deletePdo = FALSE; 02741 status = IopServiceInstanceToDeviceInstance ( 02742 ServiceHandle, 02743 ServiceName, 02744 i, 02745 &deviceInstanceName, 02746 &handle, 02747 KEY_ALL_ACCESS 02748 ); 02749 02750 if (NT_SUCCESS(status)) { 02751 02752 PDEVICE_OBJECT deviceObject; 02753 PDEVICE_NODE deviceNode; 02754 02755 // 02756 // If the device instance is a detected device reported during driver's 02757 // DriverEntry we need to clean it up. 02758 // 02759 02760 deviceObject = IopDeviceObjectFromDeviceInstance(handle, NULL); 02761 if (deviceObject) { 02762 deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode; 02763 if (deviceNode) { 02764 02765 IopReleaseDeviceResources(deviceNode); 02766 02767 if ((deviceNode->Flags & DNF_MADEUP) && (deviceNode->Flags & DNF_STARTED)) { 02768 02769 // 02770 // Now mark this one deleted. 02771 // 02772 deviceNode->Flags &= ~DNF_STARTED; 02773 02774 IopSetDevNodeProblem(deviceNode, CM_PROB_DEVICE_NOT_THERE); 02775 deletePdo = TRUE; 02776 } 02777 } 02778 ObDereferenceObject(deviceObject); // added via IopDeviceObjectFromDeviceInstance 02779 } 02780 02781 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL); 02782 controlHandle = NULL; 02783 status = IopOpenRegistryKey(&controlHandle, 02784 handle, 02785 &unicodeValueName, 02786 KEY_ALL_ACCESS, 02787 FALSE 02788 ); 02789 if (NT_SUCCESS(status)) { 02790 02791 status = IopGetRegistryValue(controlHandle, 02792 REGSTR_VALUE_NEWLY_CREATED, 02793 &keyValueInformation); 02794 if (NT_SUCCESS(status)) { 02795 ExFreePool(keyValueInformation); 02796 } 02797 if ((status != STATUS_OBJECT_NAME_NOT_FOUND) && 02798 (status != STATUS_OBJECT_PATH_NOT_FOUND)) { 02799 02800 // 02801 // Remove the instance value name from service enum key 02802 // 02803 02804 PiUlongToUnicodeString(&unicodeValueName, unicodeBuffer, 20, i); 02805 status = ZwDeleteValueKey (serviceEnumHandle, &unicodeValueName); 02806 if (NT_SUCCESS(status)) { 02807 02808 // 02809 // If we can successfaully remove the instance value entry 02810 // from service enum key, we then remove the device instance key 02811 // Otherwise, we go thru normal path to mark driver loading failed 02812 // in the device instance key. 02813 // 02814 02815 newCount--; 02816 02817 ZwDeleteKey(controlHandle); 02818 ZwDeleteKey(handle); 02819 02820 02821 // 02822 // We also want to delete the ROOT\LEGACY_<driver> key 02823 // 02824 02825 if (sysEnumHandle) { 02826 deviceInstanceName.Length -= 5 * sizeof(WCHAR); 02827 deviceInstanceName.Buffer[deviceInstanceName.Length / sizeof(WCHAR)] = 02828 UNICODE_NULL; 02829 status = IopOpenRegistryKey(&handle, 02830 sysEnumHandle, 02831 &deviceInstanceName, 02832 KEY_ALL_ACCESS, 02833 FALSE 02834 ); 02835 if (NT_SUCCESS(status)) { 02836 ZwDeleteKey(handle); 02837 } 02838 } 02839 02840 ExFreePool(deviceInstanceName.Buffer); 02841 02842 // 02843 // If there is a PDO for this device, remove it 02844 // 02845 02846 if (deletePdo) { 02847 IoDeleteDevice(deviceObject); 02848 } 02849 02850 continue; 02851 } 02852 } 02853 } 02854 02855 // 02856 // Reset Control\ActiveService value name. 02857 // 02858 02859 if (controlHandle) { 02860 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VAL_ACTIVESERVICE); 02861 ZwDeleteValueKey(controlHandle, &unicodeValueName); 02862 ZwClose(controlHandle); 02863 } 02864 02865 ZwClose(handle); 02866 ExFreePool(deviceInstanceName.Buffer); 02867 } 02868 } 02869 02870 // 02871 // If some instance value entry is deleted, we need to update the count of instance 02872 // value entries and rearrange the instance value entries under service enum key. 02873 // 02874 02875 if (newCount != count) { 02876 if (newCount != 0) { 02877 j = 0; 02878 i = 0; 02879 while (i < count) { 02880 PiUlongToUnicodeString(&unicodeValueName, unicodeBuffer, 20, i); 02881 status = IopGetRegistryValue(serviceEnumHandle, 02882 unicodeValueName.Buffer, 02883 &keyValueInformation 02884 ); 02885 if (NT_SUCCESS(status)) { 02886 if (i != j) { 02887 02888 // 02889 // Need to change the instance i to instance j 02890 // 02891 02892 ZwDeleteValueKey(serviceEnumHandle, &unicodeValueName); 02893 02894 PiUlongToUnicodeString(&unicodeValueName, unicodeBuffer, 20, j); 02895 ZwSetValueKey (serviceEnumHandle, 02896 &unicodeValueName, 02897 TITLE_INDEX_VALUE, 02898 REG_SZ, 02899 (PVOID)KEY_VALUE_DATA(keyValueInformation), 02900 keyValueInformation->DataLength 02901 ); 02902 } 02903 ExFreePool(keyValueInformation); 02904 j++; 02905 } 02906 i++; 02907 } 02908 } 02909 02910 // 02911 // Don't forget to update the "Count=" and "NextInstance=" value entries 02912 // 02913 02914 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_COUNT); 02915 02916 ZwSetValueKey(serviceEnumHandle, 02917 &unicodeValueName, 02918 TITLE_INDEX_VALUE, 02919 REG_DWORD, 02920 &newCount, 02921 sizeof (newCount) 02922 ); 02923 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE); 02924 02925 ZwSetValueKey(serviceEnumHandle, 02926 &unicodeValueName, 02927 TITLE_INDEX_VALUE, 02928 REG_DWORD, 02929 &newCount, 02930 sizeof (newCount) 02931 ); 02932 } 02933 ZwClose(serviceEnumHandle); 02934 if (closeHandle) { 02935 ZwClose(ServiceHandle); 02936 } 02937 if (sysEnumHandle) { 02938 ZwClose(sysEnumHandle); 02939 } 02940 02941 ExReleaseResource(&PpRegistryDeviceResource); 02942 KeLeaveCriticalRegion(); 02943 02944 return STATUS_SUCCESS; 02945 }

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 4479 of file pri_bld/pnpsubs.c.

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

Referenced by IopGetResourceRequirementsForAssignTable(), and IopQueryDeviceResources().

04488 : 04489 04490 This routines adjusts the input IoList based on input BootConfig. 04491 04492 04493 Arguments: 04494 04495 IoList - supplies the pointer to an IoResourceRequirementsList 04496 04497 CmList - supplies the pointer to a BootConfig. 04498 04499 FilteredList - Supplies a variable to receive the filtered resource 04500 requirements list. 04501 04502 Return Value: 04503 04504 A NTSTATUS code to indicate the result of the function. 04505 04506 --*/ 04507 { 04508 NTSTATUS status; 04509 PIO_RESOURCE_REQUIREMENTS_LIST ioList, newList; 04510 PIO_RESOURCE_LIST ioResourceList, newIoResourceList, selectedResourceList = NULL; 04511 PIO_RESOURCE_DESCRIPTOR ioResourceDescriptor, ioResourceDescriptorEnd; 04512 PIO_RESOURCE_DESCRIPTOR newIoResourceDescriptor, configDataDescriptor; 04513 LONG ioResourceDescriptorCount = 0; 04514 USHORT version; 04515 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc; 04516 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor; 04517 ULONG cmDescriptorCount = 0; 04518 ULONG size, i, j, oldCount, phase; 04519 LONG k, alternativeLists; 04520 BOOLEAN exactMatch; 04521 04522 PAGED_CODE(); 04523 04524 *FilteredList = NULL; 04525 *ExactMatch = FALSE; 04526 04527 // 04528 // Make sure there is some resource requirements to be filtered. 04529 // If no, we will convert CmList/BootConfig to an IoResourceRequirementsList 04530 // 04531 04532 if (IoList == NULL || IoList->AlternativeLists == 0) { 04533 if (CmList && CmList->Count != 0) { 04534 *FilteredList = IopCmResourcesToIoResources (0, CmList, LCPRI_BOOTCONFIG); 04535 } 04536 return STATUS_SUCCESS; 04537 } 04538 04539 // 04540 // Make a copy of the Io Resource Requirements List 04541 // 04542 04543 ioList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, IoList->ListSize); 04544 if (ioList == NULL) { 04545 return STATUS_INSUFFICIENT_RESOURCES; 04546 } 04547 04548 RtlMoveMemory(ioList, IoList, IoList->ListSize); 04549 04550 // 04551 // If there is no BootConfig, simply return the copy of the input Io list. 04552 // 04553 04554 if (CmList == NULL || CmList->Count == 0) { 04555 *FilteredList = ioList; 04556 return STATUS_SUCCESS; 04557 } 04558 04559 // 04560 // First determine minimum number of descriptors required. 04561 // 04562 04563 cmFullDesc = &CmList->List[0]; 04564 for (i = 0; i < CmList->Count; i++) { 04565 cmDescriptorCount += cmFullDesc->PartialResourceList.Count; 04566 cmDescriptor = &cmFullDesc->PartialResourceList.PartialDescriptors[0]; 04567 for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) { 04568 size = 0; 04569 switch (cmDescriptor->Type) { 04570 case CmResourceTypeConfigData: 04571 case CmResourceTypeDevicePrivate: 04572 cmDescriptorCount--; 04573 break; 04574 case CmResourceTypeDeviceSpecific: 04575 size = cmDescriptor->u.DeviceSpecificData.DataSize; 04576 cmDescriptorCount--; 04577 break; 04578 default: 04579 04580 // 04581 // Invalid cmresource list. Ignore it and use io resources 04582 // 04583 04584 if (cmDescriptor->Type == CmResourceTypeNull || 04585 cmDescriptor->Type >= CmResourceTypeMaximum) { 04586 cmDescriptorCount--; 04587 } 04588 } 04589 cmDescriptor++; 04590 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor + size); 04591 } 04592 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor; 04593 } 04594 04595 if (cmDescriptorCount == 0) { 04596 *FilteredList = ioList; 04597 return STATUS_SUCCESS; 04598 } 04599 04600 // 04601 // cmDescriptorCount is the number of BootConfig Descriptors needs. 04602 // 04603 // For each IO list Alternative ... 04604 // 04605 04606 ioResourceList = ioList->List; 04607 k = ioList->AlternativeLists; 04608 while (--k >= 0) { 04609 ioResourceDescriptor = ioResourceList->Descriptors; 04610 ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count; 04611 while (ioResourceDescriptor < ioResourceDescriptorEnd) { 04612 ioResourceDescriptor->Spare1 = 0; 04613 ioResourceDescriptor++; 04614 } 04615 ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd; 04616 } 04617 04618 ioResourceList = ioList->List; 04619 k = alternativeLists = ioList->AlternativeLists; 04620 while (--k >= 0) { 04621 version = ioResourceList->Version; 04622 if (version == 0xffff) { // Convert bogus version to valid number 04623 version = 1; 04624 } 04625 04626 // 04627 // We use Version field to store number of BootConfig found. 04628 // Count field to store new number of descriptor in the alternative list. 04629 // 04630 04631 ioResourceList->Version = 0; 04632 oldCount = ioResourceList->Count; 04633 04634 ioResourceDescriptor = ioResourceList->Descriptors; 04635 ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count; 04636 04637 if (ioResourceDescriptor == ioResourceDescriptorEnd) { 04638 04639 // 04640 // An alternative list with zero descriptor count 04641 // 04642 04643 ioResourceList->Version = 0xffff; // Mark it as invalid 04644 ioList->AlternativeLists--; 04645 continue; 04646 } 04647 04648 exactMatch = TRUE; 04649 04650 // 04651 // For each Cm Resource descriptor ... except DevicePrivate and 04652 // DeviceSpecific... 04653 // 04654 04655 cmFullDesc = &CmList->List[0]; 04656 for (i = 0; i < CmList->Count; i++) { 04657 cmDescriptor = &cmFullDesc->PartialResourceList.PartialDescriptors[0]; 04658 for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) { 04659 size = 0; 04660 switch (cmDescriptor->Type) { 04661 case CmResourceTypeDevicePrivate: 04662 break; 04663 case CmResourceTypeDeviceSpecific: 04664 size = cmDescriptor->u.DeviceSpecificData.DataSize; 04665 break; 04666 default: 04667 if (cmDescriptor->Type == CmResourceTypeNull || 04668 cmDescriptor->Type >= CmResourceTypeMaximum) { 04669 break; 04670 } 04671 04672 // 04673 // Check CmDescriptor against current Io Alternative list 04674 // 04675 04676 for (phase = 0; phase < 2; phase++) { 04677 ioResourceDescriptor = ioResourceList->Descriptors; 04678 while (ioResourceDescriptor < ioResourceDescriptorEnd) { 04679 if ((ioResourceDescriptor->Type == cmDescriptor->Type) && 04680 (ioResourceDescriptor->Spare1 == 0)) { 04681 ULONGLONG min1, max1, min2, max2; 04682 ULONG len1 = 1, len2 = 1, align1, align2; 04683 UCHAR share1, share2; 04684 04685 share2 = ioResourceDescriptor->ShareDisposition; 04686 share1 = cmDescriptor->ShareDisposition; 04687 if ((share1 == CmResourceShareUndetermined) || 04688 (share1 > CmResourceShareShared)) { 04689 share1 = share2; 04690 } 04691 if ((share2 == CmResourceShareUndetermined) || 04692 (share2 > CmResourceShareShared)) { 04693 share2 = share1; 04694 } 04695 align1 = align2 = 1; 04696 04697 switch (cmDescriptor->Type) { 04698 case CmResourceTypePort: 04699 case CmResourceTypeMemory: 04700 min1 = cmDescriptor->u.Port.Start.QuadPart; 04701 max1 = cmDescriptor->u.Port.Start.QuadPart + cmDescriptor->u.Port.Length - 1; 04702 len1 = cmDescriptor->u.Port.Length; 04703 min2 = ioResourceDescriptor->u.Port.MinimumAddress.QuadPart; 04704 max2 = ioResourceDescriptor->u.Port.MaximumAddress.QuadPart; 04705 len2 = ioResourceDescriptor->u.Port.Length; 04706 align2 = ioResourceDescriptor->u.Port.Alignment; 04707 break; 04708 case CmResourceTypeInterrupt: 04709 max1 = min1 = cmDescriptor->u.Interrupt.Vector; 04710 min2 = ioResourceDescriptor->u.Interrupt.MinimumVector; 04711 max2 = ioResourceDescriptor->u.Interrupt.MaximumVector; 04712 break; 04713 case CmResourceTypeDma: 04714 min1 = max1 =cmDescriptor->u.Dma.Channel; 04715 min2 = ioResourceDescriptor->u.Dma.MinimumChannel; 04716 max2 = ioResourceDescriptor->u.Dma.MaximumChannel; 04717 break; 04718 case CmResourceTypeBusNumber: 04719 min1 = cmDescriptor->u.BusNumber.Start; 04720 max1 = cmDescriptor->u.BusNumber.Start + cmDescriptor->u.BusNumber.Length - 1; 04721 len1 = cmDescriptor->u.BusNumber.Length; 04722 min2 = ioResourceDescriptor->u.BusNumber.MinBusNumber; 04723 max2 = ioResourceDescriptor->u.BusNumber.MaxBusNumber; 04724 len2 = ioResourceDescriptor->u.BusNumber.Length; 04725 break; 04726 default: 04727 ASSERT(0); 04728 break; 04729 } 04730 if (phase == 0) { 04731 if (share1 == share2 && min2 == min1 && max2 >= max1 && len2 >= len1) { 04732 04733 // 04734 // For phase 0 match, we want near exact match... 04735 // 04736 04737 if (max2 != max1) { 04738 exactMatch = FALSE; 04739 } 04740 ioResourceList->Version++; 04741 ioResourceDescriptor->Spare1 = 0x80; 04742 if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) { 04743 PIO_RESOURCE_DESCRIPTOR ioDesc; 04744 04745 ioDesc = ioResourceDescriptor; 04746 ioDesc--; 04747 while (ioDesc >= ioResourceList->Descriptors) { 04748 ioDesc->Type = CmResourceTypeNull; 04749 ioResourceList->Count--; 04750 if (ioDesc->Option == IO_RESOURCE_ALTERNATIVE) { 04751 ioDesc--; 04752 } else { 04753 break; 04754 } 04755 } 04756 } 04757 ioResourceDescriptor->Option = IO_RESOURCE_PREFERRED; 04758 ioResourceDescriptor->Flags = cmDescriptor->Flags; 04759 if (ioResourceDescriptor->Type == CmResourceTypePort || 04760 ioResourceDescriptor->Type == CmResourceTypeMemory) { 04761 ioResourceDescriptor->u.Port.MinimumAddress.QuadPart = min1; 04762 ioResourceDescriptor->u.Port.MaximumAddress.QuadPart = min1 + len2 - 1; 04763 ioResourceDescriptor->u.Port.Alignment = 1; 04764 } else if (ioResourceDescriptor->Type == CmResourceTypeBusNumber) { 04765 ioResourceDescriptor->u.BusNumber.MinBusNumber = (ULONG)min1; 04766 ioResourceDescriptor->u.BusNumber.MaxBusNumber = (ULONG)(min1 + len2 - 1); 04767 } 04768 ioResourceDescriptor++; 04769 while (ioResourceDescriptor < ioResourceDescriptorEnd) { 04770 if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) { 04771 ioResourceDescriptor->Type = CmResourceTypeNull; 04772 ioResourceDescriptor++; 04773 ioResourceList->Count--; 04774 } else { 04775 break; 04776 } 04777 } 04778 phase = 1; // skip phase 1 04779 break; 04780 } else { 04781 ioResourceDescriptor++; 04782 } 04783 } else { 04784 exactMatch = FALSE; 04785 if (share1 == share2 && min2 <= min1 && max2 >= max1 && len2 >= len1 && 04786 (min1 & (align2 - 1)) == 0) { 04787 04788 // 04789 // Io range covers Cm range ... Change the Io range to what is specified 04790 // in BootConfig. 04791 // 04792 // 04793 04794 switch (cmDescriptor->Type) { 04795 case CmResourceTypePort: 04796 case CmResourceTypeMemory: 04797 ioResourceDescriptor->u.Port.MinimumAddress.QuadPart = min1; 04798 ioResourceDescriptor->u.Port.MaximumAddress.QuadPart = min1 + len2 - 1; 04799 break; 04800 case CmResourceTypeInterrupt: 04801 case CmResourceTypeDma: 04802 ioResourceDescriptor->u.Interrupt.MinimumVector = (ULONG)min1; 04803 ioResourceDescriptor->u.Interrupt.MaximumVector = (ULONG)max1; 04804 break; 04805 case CmResourceTypeBusNumber: 04806 ioResourceDescriptor->u.BusNumber.MinBusNumber = (ULONG)min1; 04807 ioResourceDescriptor->u.BusNumber.MaxBusNumber = (ULONG)(min1 + len2 - 1); 04808 break; 04809 } 04810 ioResourceList->Version++; 04811 ioResourceDescriptor->Spare1 = 0x80; 04812 ioResourceDescriptor->Flags = cmDescriptor->Flags; 04813 if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) { 04814 PIO_RESOURCE_DESCRIPTOR ioDesc; 04815 04816 ioDesc = ioResourceDescriptor; 04817 ioDesc--; 04818 while (ioDesc >= ioResourceList->Descriptors) { 04819 ioDesc->Type = CmResourceTypeNull; 04820 ioResourceList->Count--; 04821 if (ioDesc->Option == IO_RESOURCE_ALTERNATIVE) { 04822 ioDesc--; 04823 } else { 04824 break; 04825 } 04826 } 04827 } 04828 ioResourceDescriptor->Option = IO_RESOURCE_PREFERRED; 04829 ioResourceDescriptor++; 04830 while (ioResourceDescriptor < ioResourceDescriptorEnd) { 04831 if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) { 04832 ioResourceDescriptor->Type = CmResourceTypeNull; 04833 ioResourceList->Count--; 04834 ioResourceDescriptor++; 04835 } else { 04836 break; 04837 } 04838 } 04839 break; 04840 } else { 04841 ioResourceDescriptor++; 04842 } 04843 } 04844 } else { 04845 ioResourceDescriptor++; 04846 } 04847 } // Don't add any instruction after this ... 04848 } // phase 04849 } // switch 04850 04851 // 04852 // Move to next Cm Descriptor 04853 // 04854 04855 cmDescriptor++; 04856 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor + size); 04857 } 04858 04859 // 04860 // Move to next Cm List 04861 // 04862 04863 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor; 04864 } 04865 04866 if (ioResourceList->Version != (USHORT)cmDescriptorCount) { 04867 04868 // 04869 // If the current alternative list does not cover all the boot config 04870 // descriptors, make it as invalid. 04871 // 04872 04873 ioResourceList->Version = 0xffff; 04874 ioList->AlternativeLists--; 04875 } else { 04876 if ((ioResourceList->Count == cmDescriptorCount) || 04877 (ioResourceList->Count == (cmDescriptorCount + 1) && 04878 ioResourceList->Descriptors[0].Type == CmResourceTypeConfigData)) { 04879 if (selectedResourceList) { 04880 ioResourceList->Version = 0xffff; 04881 ioList->AlternativeLists--; 04882 } else { 04883 selectedResourceList = ioResourceList; 04884 ioResourceDescriptorCount += ioResourceList->Count; 04885 ioResourceList->Version = version; 04886 if (exactMatch) { 04887 *ExactMatch = TRUE; 04888 } 04889 } 04890 } else { 04891 ioResourceDescriptorCount += ioResourceList->Count; 04892 ioResourceList->Version = version; 04893 } 04894 } 04895 ioResourceList->Count = oldCount; 04896 04897 // 04898 // Move to next Io alternative list. 04899 // 04900 04901 ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd; 04902 } 04903 04904 // 04905 // If there is not any valid alternative, convert CmList to Io list. 04906 // 04907 04908 if (ioList->AlternativeLists == 0) { 04909 *FilteredList = IopCmResourcesToIoResources (0, CmList, LCPRI_BOOTCONFIG); 04910 ExFreePool(ioList); 04911 return STATUS_SUCCESS; 04912 } 04913 04914 // 04915 // we have finished filtering the resource requirements list. Now allocate memory 04916 // and rebuild a new list. 04917 // 04918 04919 size = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + 04920 sizeof(IO_RESOURCE_LIST) * (ioList->AlternativeLists - 1) + 04921 sizeof(IO_RESOURCE_DESCRIPTOR) * (ioResourceDescriptorCount); 04922 newList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, size); 04923 if (newList == NULL) { 04924 ExFreePool(ioList); 04925 return STATUS_INSUFFICIENT_RESOURCES; 04926 } 04927 04928 // 04929 // Walk through the io resource requirements list and pick up any valid descriptor. 04930 // 04931 04932 newList->ListSize = size; 04933 newList->InterfaceType = CmList->List->InterfaceType; 04934 newList->BusNumber = CmList->List->BusNumber; 04935 newList->SlotNumber = ioList->SlotNumber; 04936 if (ioList->AlternativeLists > 1) { 04937 *ExactMatch = FALSE; 04938 } 04939 newList->AlternativeLists = ioList->AlternativeLists; 04940 ioResourceList = ioList->List; 04941 newIoResourceList = newList->List; 04942 while (--alternativeLists >= 0) { 04943 ioResourceDescriptor = ioResourceList->Descriptors; 04944 ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count; 04945 if (ioResourceList->Version == 0xffff) { 04946 ioResourceList = (PIO_RESOURCE_LIST)ioResourceDescriptorEnd; 04947 continue; 04948 } 04949 newIoResourceList->Version = ioResourceList->Version; 04950 newIoResourceList->Revision = ioResourceList->Revision; 04951 04952 newIoResourceDescriptor = newIoResourceList->Descriptors; 04953 if (ioResourceDescriptor->Type != CmResourceTypeConfigData) { 04954 newIoResourceDescriptor->Option = IO_RESOURCE_PREFERRED; 04955 newIoResourceDescriptor->Type = CmResourceTypeConfigData; 04956 newIoResourceDescriptor->ShareDisposition = CmResourceShareShared; 04957 newIoResourceDescriptor->Flags = 0; 04958 newIoResourceDescriptor->Spare1 = 0; 04959 newIoResourceDescriptor->Spare2 = 0; 04960 newIoResourceDescriptor->u.ConfigData.Priority = LCPRI_BOOTCONFIG; 04961 configDataDescriptor = newIoResourceDescriptor; 04962 newIoResourceDescriptor++; 04963 } else { 04964 newList->ListSize -= sizeof(IO_RESOURCE_DESCRIPTOR); 04965 configDataDescriptor = newIoResourceDescriptor; 04966 } 04967 04968 while (ioResourceDescriptor < ioResourceDescriptorEnd) { 04969 if (ioResourceDescriptor->Type != CmResourceTypeNull) { 04970 *newIoResourceDescriptor = *ioResourceDescriptor; 04971 newIoResourceDescriptor++; 04972 } 04973 ioResourceDescriptor++; 04974 } 04975 newIoResourceList->Count = (ULONG)(newIoResourceDescriptor - newIoResourceList->Descriptors); 04976 04977 //if (newIoResourceList->Count == (cmDescriptorCount + 1)) { 04978 configDataDescriptor->u.ConfigData.Priority = LCPRI_BOOTCONFIG; 04979 //} 04980 04981 // 04982 // Move to next Io alternative list. 04983 // 04984 04985 newIoResourceList = (PIO_RESOURCE_LIST) newIoResourceDescriptor; 04986 ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd; 04987 } 04988 ASSERT((PUCHAR)newIoResourceList == ((PUCHAR)newList + newList->ListSize)); 04989 04990 *FilteredList = newList; 04991 ExFreePool(ioList); 04992 return STATUS_SUCCESS; 04993 }

VOID IopFreeUnicodeStringList IN PUNICODE_STRING  UnicodeStringList,
IN ULONG  StringCount
 

Definition at line 2570 of file pri_bld/pnpsubs.c.

References Buffer, and ExFreePool().

Referenced by IopGetGroupOrderIndex(), and IopRegMultiSzToUnicodeStrings().

02577 : 02578 02579 This routine frees the buffer for each UNICODE_STRING in the specified list 02580 (there are StringCount of them), and then frees the memory used for the 02581 string list itself. 02582 02583 Arguments: 02584 02585 UnicodeStringList - Supplies a pointer to an array of UNICODE_STRINGs. 02586 02587 StringCount - Supplies the number of strings in the UnicodeStringList array. 02588 02589 Returns: 02590 02591 None. 02592 02593 --*/ 02594 02595 { 02596 ULONG i; 02597 02598 if(UnicodeStringList) { 02599 for(i = 0; i < StringCount; i++) { 02600 if(UnicodeStringList[i].Buffer) { 02601 ExFreePool(UnicodeStringList[i].Buffer); 02602 } 02603 } 02604 ExFreePool(UnicodeStringList); 02605 } 02606 }

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

Definition at line 1471 of file pri_bld/pnpsubs.c.

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

Referenced by IopInitializeDeviceInstanceKey(), and IopIsAnyDeviceInstanceEnabled().

01479 : 01480 01481 This routine retrieves the csconfig flags for the specified device 01482 which is specified by the instance number under ServiceKeyName\Enum. 01483 01484 Arguments: 01485 01486 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01487 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01488 that caused the driver to load. 01489 01490 Instance - Supplies the instance value under ServiceKeyName\Enum key 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 handle; 01503 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 01504 01505 *CsConfigFlags = 0; 01506 01507 status = IopOpenCurrentHwProfileDeviceInstanceKey(&handle, 01508 ServiceKeyName, 01509 Instance, 01510 KEY_READ, 01511 FALSE 01512 ); 01513 if(NT_SUCCESS(status)) { 01514 status = IopGetRegistryValue(handle, 01515 REGSTR_VALUE_CSCONFIG_FLAGS, 01516 &keyValueInformation 01517 ); 01518 if(NT_SUCCESS(status)) { 01519 if((keyValueInformation->Type == REG_DWORD) && 01520 (keyValueInformation->DataLength >= sizeof(ULONG))) { 01521 *CsConfigFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 01522 } 01523 ExFreePool(keyValueInformation); 01524 } 01525 ZwClose(handle); 01526 } 01527 return status; 01528 }

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

Definition at line 3967 of file pri_bld/pnpsubs.c.

References ExAllocatePool, ExFreePool(), FALSE, IopDeviceObjectToDeviceInstance(), IopGetRegistryValue(), IopOpenRegistryKey(), 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.

Referenced by IopInitializeDeviceInstanceKey(), IopPnPDispatch(), and IopQueryDeviceResources().

03977 : 03978 03979 This routine determines the resources decoded by the device specified. 03980 If the device object is a madeup device, we will try to read the resources 03981 from registry. Otherwise, we need to traverse the internal assigned resource 03982 list to compose the resource list. 03983 03984 Arguments: 03985 03986 DeviceObject - supplies a pointer to a device object whose registry 03987 values are to be cleaned up. 03988 03989 ResourceType - 0 for CM_RESOURCE_LIST and 1 for IO_RESOURCE_REQUIREMENTS_LIS 03990 03991 Flags - specify the preference. 03992 03993 Resource - Specified a variable to receive the required resources. 03994 03995 Length - Specified a variable to receive the length of the resource structure. 03996 03997 Return Value: 03998 03999 status 04000 04001 --*/ 04002 04003 { 04004 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 04005 HANDLE handle, handlex; 04006 NTSTATUS status; 04007 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 04008 PCM_RESOURCE_LIST cmResource; 04009 PIO_RESOURCE_REQUIREMENTS_LIST ioResource; 04010 ULONG length; 04011 UNICODE_STRING unicodeName; 04012 PWCHAR valueName = NULL; 04013 04014 *Resource = NULL; 04015 *Length = 0; 04016 04017 // 04018 // Open the LogConfig key of the device instance. 04019 // 04020 04021 status = IopDeviceObjectToDeviceInstance(DeviceObject, &handlex, KEY_READ); 04022 if (!NT_SUCCESS(status)) { 04023 return status; 04024 } 04025 04026 if (ResourceType == QUERY_RESOURCE_LIST) { 04027 04028 // 04029 // Caller is asking for CM_RESOURCE_LIST 04030 // 04031 04032 if (Preference & REGISTRY_ALLOC_CONFIG) { 04033 04034 // 04035 // Try alloc config first 04036 // 04037 04038 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL); 04039 status = IopOpenRegistryKey(&handle, 04040 handlex, 04041 &unicodeName, 04042 KEY_READ, 04043 FALSE 04044 ); 04045 if (NT_SUCCESS(status)) { 04046 status = IopReadDeviceConfiguration (handle, REGISTRY_ALLOC_CONFIG, (PCM_RESOURCE_LIST *)Resource, Length); 04047 ZwClose(handle); 04048 if (NT_SUCCESS(status)) { 04049 ZwClose(handlex); 04050 return status; 04051 } 04052 } 04053 } 04054 04055 handle = NULL; 04056 if (Preference & REGISTRY_FORCED_CONFIG) { 04057 04058 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 04059 status = IopOpenRegistryKey(&handle, 04060 handlex, 04061 &unicodeName, 04062 KEY_READ, 04063 FALSE 04064 ); 04065 if (NT_SUCCESS(status)) { 04066 status = IopReadDeviceConfiguration (handle, REGISTRY_FORCED_CONFIG, (PCM_RESOURCE_LIST *)Resource, Length); 04067 if (NT_SUCCESS(status)) { 04068 ZwClose(handle); 04069 ZwClose(handlex); 04070 return status; 04071 } 04072 } else { 04073 ZwClose(handlex); 04074 return status; 04075 } 04076 } 04077 if (Preference & REGISTRY_BOOT_CONFIG) { 04078 04079 // 04080 // Try alloc config first 04081 // 04082 04083 if (handle == NULL) { 04084 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 04085 status = IopOpenRegistryKey(&handle, 04086 handlex, 04087 &unicodeName, 04088 KEY_READ, 04089 FALSE 04090 ); 04091 if (!NT_SUCCESS(status)) { 04092 ZwClose(handlex); 04093 return status; 04094 } 04095 } 04096 status = IopReadDeviceConfiguration (handle, REGISTRY_BOOT_CONFIG, (PCM_RESOURCE_LIST *)Resource, Length); 04097 } 04098 if (handle) { 04099 ZwClose(handle); 04100 } 04101 } else { 04102 04103 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 04104 status = IopOpenRegistryKey(&handle, 04105 handlex, 04106 &unicodeName, 04107 KEY_READ, 04108 FALSE 04109 ); 04110 if (NT_SUCCESS(status)) { 04111 04112 if (Preference & REGISTRY_OVERRIDE_CONFIGVECTOR) { 04113 valueName = REGSTR_VALUE_OVERRIDE_CONFIG_VECTOR; 04114 } else if (Preference & REGISTRY_BASIC_CONFIGVECTOR) { 04115 valueName = REGSTR_VALUE_BASIC_CONFIG_VECTOR; 04116 } 04117 if (valueName) { 04118 04119 // 04120 // Try to read device's configuration vector 04121 // 04122 04123 status = IopGetRegistryValue (handle, 04124 valueName, 04125 &keyValueInformation); 04126 if (NT_SUCCESS(status)) { 04127 04128 // 04129 // Try to read what caller wants. 04130 // 04131 04132 if ((keyValueInformation->Type == REG_RESOURCE_REQUIREMENTS_LIST) && 04133 (keyValueInformation->DataLength != 0)) { 04134 04135 *Resource = ExAllocatePool(PagedPool, 04136 keyValueInformation->DataLength); 04137 if (*Resource) { 04138 PIO_RESOURCE_REQUIREMENTS_LIST ioResource; 04139 04140 *Length = keyValueInformation->DataLength; 04141 RtlMoveMemory(*Resource, 04142 KEY_VALUE_DATA(keyValueInformation), 04143 keyValueInformation->DataLength); 04144 04145 // 04146 // Process the io resource requirements list to change undefined 04147 // interface type to our default type. 04148 // 04149 04150 ioResource = *Resource; 04151 if (ioResource->InterfaceType == InterfaceTypeUndefined) { 04152 ioResource->BusNumber = 0; 04153 ioResource->InterfaceType = PnpDefaultInterfaceType; 04154 } 04155 } else { 04156 status = STATUS_INVALID_PARAMETER_2; 04157 } 04158 } 04159 ExFreePool(keyValueInformation); 04160 } 04161 } 04162 ZwClose(handle); 04163 } 04164 } 04165 ZwClose(handlex); 04166 return status; 04167 }

USHORT IopGetGroupOrderIndex IN HANDLE  ServiceHandle  ) 
 

Definition at line 5221 of file pri_bld/pnpsubs.c.

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

Referenced by IopCallDriverAddDeviceQueryRoutine(), and IopInitializeBootDrivers().

05227 : 05228 05229 This routine reads the Group value of the service key, finds its position in the 05230 ServiceOrderList. If ServiceHandle is NULL or unrecognized group value, it returns 05231 a value with max group order + 1. 05232 if any. 05233 05234 Parameters: 05235 05236 ServiceHandle - supplies a handle to the service key. 05237 05238 Return Value: 05239 05240 group order index. 05241 05242 --*/ 05243 05244 { 05245 NTSTATUS status; 05246 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 05247 UNICODE_STRING *groupTable, group; 05248 HANDLE handle; 05249 ULONG count, index; 05250 05251 PAGED_CODE(); 05252 05253 // 05254 // Open System\CurrentControlSet\Control\ServiceOrderList 05255 // 05256 05257 PiWstrToUnicodeString(&group, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ServiceGroupOrder"); 05258 status = IopOpenRegistryKey(&handle, 05259 NULL, 05260 &group, 05261 KEY_READ, 05262 FALSE 05263 ); 05264 05265 if (!NT_SUCCESS( status )) { 05266 return NO_MORE_GROUP; 05267 } 05268 05269 // 05270 // Read and build a unicode string array containing all the group names. 05271 // 05272 05273 status = IopGetRegistryValue (handle, 05274 L"List", 05275 &keyValueInformation); 05276 ZwClose(handle); 05277 if (NT_SUCCESS(status)) { 05278 05279 if ((keyValueInformation->Type == REG_MULTI_SZ) && 05280 (keyValueInformation->DataLength != 0)) { 05281 status = IopRegMultiSzToUnicodeStrings(keyValueInformation, &groupTable, &count); 05282 if (!NT_SUCCESS(status)) { 05283 ExFreePool(keyValueInformation); 05284 return NO_MORE_GROUP; 05285 } 05286 } 05287 ExFreePool(keyValueInformation); 05288 } 05289 05290 if (ServiceHandle == NULL) { 05291 IopFreeUnicodeStringList(groupTable, count); 05292 return (USHORT)(count + 1); 05293 } 05294 05295 05296 // 05297 // Read service key's Group value 05298 // 05299 05300 status = IopGetRegistryValue (ServiceHandle, 05301 L"Group", 05302 &keyValueInformation); 05303 if (NT_SUCCESS(status)) { 05304 05305 // 05306 // Try to read what caller wants. 05307 // 05308 05309 if ((keyValueInformation->Type == REG_SZ) && 05310 (keyValueInformation->DataLength != 0)) { 05311 IopRegistryDataToUnicodeString(&group, 05312 (PWSTR)KEY_VALUE_DATA(keyValueInformation), 05313 keyValueInformation->DataLength 05314 ); 05315 } 05316 } else { 05317 05318 // 05319 // If we failed to read the Group value, or no Group value... 05320 // 05321 05322 IopFreeUnicodeStringList(groupTable, count); 05323 return (USHORT)count; 05324 } 05325 05326 index = 0; 05327 for (index = 0; index < count; index++) { 05328 if (RtlEqualUnicodeString(&group, &groupTable[index], TRUE)) { 05329 break; 05330 } 05331 } 05332 ExFreePool(keyValueInformation); 05333 IopFreeUnicodeStringList(groupTable, count); 05334 return (USHORT)index; 05335 }

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

Definition at line 3071 of file pri_bld/pnpsubs.c.

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

Referenced by IopInitializeBuiltinDriver(), IopLoadDriver(), and IopPrepareDriverLoading().

03079 : 03080 03081 This routine checks if any of the devices instances is turned on for the specified 03082 service. This routine is used for Pnp Driver only and is temporary function to support 03083 SUR. 03084 03085 Arguments: 03086 03087 ServiceKeyName - Specifies the service key unicode name 03088 03089 ServiceHandle - Optionally supplies a handle to the service key to be checked. 03090 03091 LegacyIncluded - TRUE, a legacy device instance key is counted as a device instance. 03092 FALSE, a legacy device instance key is not counted. 03093 03094 Returns: 03095 03096 A BOOLEAN value. 03097 03098 --*/ 03099 03100 { 03101 NTSTATUS status; 03102 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 03103 HANDLE serviceEnumHandle, handle, controlHandle; 03104 ULONG i, count, deviceFlags; 03105 UNICODE_STRING unicodeName; 03106 BOOLEAN enabled, setProblem, closeHandle = FALSE; 03107 PDEVICE_OBJECT physicalDeviceObject; 03108 PDEVICE_NODE deviceNode; 03109 03110 // 03111 // Open registry ServiceKeyName\Enum branch 03112 // 03113 03114 if (!ARGUMENT_PRESENT(ServiceHandle)) { 03115 status = IopOpenServiceEnumKeys(ServiceKeyName, 03116 KEY_READ, 03117 &ServiceHandle, 03118 &serviceEnumHandle, 03119 FALSE 03120 ); 03121 closeHandle = TRUE; 03122 } else { 03123 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ENUM); 03124 status = IopOpenRegistryKey(&serviceEnumHandle, 03125 ServiceHandle, 03126 &unicodeName, 03127 KEY_READ, 03128 FALSE 03129 ); 03130 } 03131 if (!NT_SUCCESS( status )) { 03132 03133 // 03134 // No Service Enum key? no device instance. Return FALSE. 03135 // 03136 03137 return FALSE; 03138 } 03139 03140 // 03141 // Find out how many device instances listed in the ServiceName's 03142 // Enum key. 03143 // 03144 03145 status = IopGetRegistryValue ( serviceEnumHandle, 03146 REGSTR_VALUE_COUNT, 03147 &keyValueInformation 03148 ); 03149 ZwClose(serviceEnumHandle); 03150 count = 0; 03151 if (NT_SUCCESS(status)) { 03152 if ((keyValueInformation->Type == REG_DWORD) && 03153 (keyValueInformation->DataLength >= sizeof(ULONG))) { 03154 03155 count = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 03156 } 03157 ExFreePool(keyValueInformation); 03158 } 03159 if (count == 0) { 03160 if (closeHandle) { 03161 ZwClose(ServiceHandle); 03162 } 03163 return FALSE; 03164 } 03165 03166 // 03167 // Walk through each registered device instance to check it is enabled. 03168 // 03169 03170 enabled = FALSE; 03171 for (i = 0; i < count; i++) { 03172 03173 // 03174 // Get device instance handle. If it fails, we will skip this device 03175 // instance. 03176 // 03177 03178 status = IopServiceInstanceToDeviceInstance ( 03179 ServiceHandle, 03180 NULL, 03181 i, 03182 NULL, 03183 &handle, 03184 KEY_ALL_ACCESS 03185 ); 03186 if (!NT_SUCCESS(status)) { 03187 continue; 03188 } 03189 03190 physicalDeviceObject = IopDeviceObjectFromDeviceInstance(handle, NULL); 03191 if (physicalDeviceObject) { 03192 deviceNode = (PDEVICE_NODE)physicalDeviceObject->DeviceObjectExtension->DeviceNode; 03193 if (deviceNode && IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED)) { 03194 ZwClose(handle); 03195 ObDereferenceObject(physicalDeviceObject); 03196 continue; 03197 } 03198 } 03199 03200 // 03201 // Check if the device instance has been disabled. 03202 // First check global flag: CONFIGFLAG and then CSCONFIGFLAG. 03203 // 03204 03205 deviceFlags = 0; 03206 status = IopGetRegistryValue(handle, 03207 REGSTR_VALUE_CONFIG_FLAGS, 03208 &keyValueInformation); 03209 if (NT_SUCCESS(status)) { 03210 if ((keyValueInformation->Type == REG_DWORD) && 03211 (keyValueInformation->DataLength >= sizeof(ULONG))) { 03212 03213 deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 03214 } 03215 ExFreePool(keyValueInformation); 03216 } 03217 03218 if (deviceFlags & CONFIGFLAG_DISABLED) { 03219 03220 // 03221 // Convert this flag into the hardware profile-specific version, so it'll 03222 // look the same as the CsConfigFlags we retrieve below. 03223 // 03224 03225 deviceFlags = CSCONFIGFLAG_DISABLED; 03226 03227 } else { 03228 03229 status = IopGetDeviceInstanceCsConfigFlags( 03230 ServiceKeyName, 03231 i, 03232 &deviceFlags 03233 ); 03234 03235 if (!NT_SUCCESS(status)) { 03236 deviceFlags = 0; 03237 } 03238 } 03239 03240 // 03241 // If the device is disabled (either globally, or specifically for this 03242 // hardware profile), then mark the devnode as DNF_DISABLED. 03243 // 03244 03245 if ((deviceFlags & CSCONFIGFLAG_DISABLED) || (deviceFlags & CSCONFIGFLAG_DO_NOT_START)) { 03246 03247 if (deviceNode) { 03248 IopDisableDevice(deviceNode, handle); 03249 } 03250 } 03251 03252 if (physicalDeviceObject) { 03253 ObDereferenceObject(physicalDeviceObject); 03254 } 03255 03256 // 03257 // Finally, we need to set the STATUSFLAGS of the device instance to 03258 // indicate if the driver is successfully started. 03259 // 03260 03261 if (!(deviceFlags & (CSCONFIGFLAG_DISABLED | CSCONFIGFLAG_DO_NOT_CREATE | CSCONFIGFLAG_DO_NOT_START))) { 03262 03263 ULONG legacy; 03264 03265 // 03266 // Check should legacy instance key be counted as an enabled device 03267 // 03268 03269 if (LegacyIncluded == FALSE) { 03270 03271 // 03272 // The legacy variable must be initialized to zero. Because the device 03273 // instance key may be an enumerated device. In this case, there is no 03274 // legacy value name. 03275 // 03276 03277 legacy = 0; 03278 status = IopGetRegistryValue(handle, 03279 REGSTR_VALUE_LEGACY, 03280 &keyValueInformation 03281 ); 03282 if (NT_SUCCESS(status)) { 03283 if ((keyValueInformation->Type == REG_DWORD) && 03284 (keyValueInformation->DataLength >= sizeof(ULONG))) { 03285 legacy = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 03286 } 03287 ExFreePool(keyValueInformation); 03288 } 03289 } else { 03290 legacy = 0; 03291 } 03292 03293 if (legacy == 0) { 03294 03295 // 03296 // Mark that the driver has at least a device instance to work with. 03297 // 03298 03299 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL); 03300 status = IopOpenRegistryKey(&controlHandle, 03301 handle, 03302 &unicodeName, 03303 KEY_ALL_ACCESS, 03304 TRUE 03305 ); 03306 if (NT_SUCCESS(status)) { 03307 PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_ACTIVESERVICE); 03308 ZwSetValueKey( 03309 controlHandle, 03310 &unicodeName, 03311 TITLE_INDEX_VALUE, 03312 REG_SZ, 03313 ServiceKeyName->Buffer, 03314 ServiceKeyName->Length + sizeof(UNICODE_NULL) 03315 ); 03316 03317 ZwClose(controlHandle); 03318 } 03319 enabled = TRUE; 03320 } 03321 } 03322 ZwClose(handle); 03323 } 03324 03325 if (closeHandle) { 03326 ZwClose(ServiceHandle); 03327 } 03328 return enabled; 03329 }

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

Definition at line 3332 of file pri_bld/pnpsubs.c.

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

Referenced by IopGetDriverDeviceListWorker(), IopInitializeDeviceInstanceKey(), IopProcessNewDeviceNode(), and IopProcessNewProfileStateCallback().

03340 : 03341 03342 This routine checks if the specified devices instances is enabled. 03343 03344 Arguments: 03345 03346 DeviceInstanceHandle - Optionally supplies a handle to the device instance 03347 key to be checked. 03348 03349 DeviceInstance - Specifies the device instance key unicode name. Caller 03350 must at least specified DeviceInstanceHandle or DeviceInstance. 03351 03352 Returns: 03353 03354 A BOOLEAN value. 03355 03356 --*/ 03357 03358 { 03359 NTSTATUS status; 03360 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 03361 HANDLE handle, handle1; 03362 ULONG deviceFlags; 03363 BOOLEAN enabled, closeHandle = FALSE; 03364 UNICODE_STRING unicodeString; 03365 PDEVICE_OBJECT deviceObject = NULL; 03366 PDEVICE_NODE deviceNode = NULL;; 03367 03368 // 03369 // Open registry ServiceKeyName\Enum branch 03370 // 03371 03372 if (!ARGUMENT_PRESENT(DeviceInstanceHandle)) { 03373 status = IopOpenRegistryKey(&handle, 03374 NULL, 03375 &CmRegistryMachineSystemCurrentControlSetEnumName, 03376 KEY_READ, 03377 FALSE 03378 ); 03379 03380 if (NT_SUCCESS( status )) { 03381 03382 status = IopOpenRegistryKey ( 03383 DeviceInstanceHandle, 03384 handle, 03385 DeviceInstance, 03386 KEY_READ, 03387 FALSE 03388 ); 03389 ZwClose(handle); 03390 } 03391 03392 if (!NT_SUCCESS( status )) { 03393 return FALSE; 03394 } 03395 closeHandle = TRUE; 03396 } 03397 03398 enabled = TRUE; 03399 03400 // 03401 // First check the device node 03402 // 03403 03404 deviceObject = IopDeviceObjectFromDeviceInstance(DeviceInstanceHandle, NULL); 03405 if (deviceObject) { 03406 deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode; 03407 if (deviceNode && IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED)) { 03408 enabled = FALSE; 03409 goto exit; 03410 } 03411 } 03412 03413 // 03414 // Check if the device instance has been disabled. 03415 // First check global flag: CONFIGFLAG and then CSCONFIGFLAG. 03416 // 03417 03418 deviceFlags = 0; 03419 status = IopGetRegistryValue(DeviceInstanceHandle, 03420 REGSTR_VALUE_CONFIG_FLAGS, 03421 &keyValueInformation); 03422 if (NT_SUCCESS(status)) { 03423 if ((keyValueInformation->Type == REG_DWORD) && 03424 (keyValueInformation->DataLength >= sizeof(ULONG))) { 03425 deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 03426 } 03427 ExFreePool(keyValueInformation); 03428 } 03429 if (!(deviceFlags & CONFIGFLAG_DISABLED)) { 03430 enabled = TRUE; 03431 03432 // 03433 // See if we can open current hardware profile 03434 // 03435 status = IopOpenRegistryKey(&handle1, 03436 NULL, 03437 &CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, 03438 KEY_READ, 03439 FALSE 03440 ); 03441 if (NT_SUCCESS(status) && DeviceInstance != NULL) { 03442 03443 // 03444 // Now, we must open the System\CCS\Enum key under this. 03445 // 03446 // 03447 // Open system\CurrentControlSet under current hardware profile key 03448 // 03449 03450 PiWstrToUnicodeString(&unicodeString, REGSTR_PATH_CURRENTCONTROLSET); 03451 status = IopOpenRegistryKey(&handle, 03452 handle1, 03453 &unicodeString, 03454 KEY_READ, 03455 FALSE 03456 ); 03457 ZwClose(handle1); 03458 if (NT_SUCCESS(status)) { 03459 PiWstrToUnicodeString(&unicodeString, REGSTR_KEY_ENUM); 03460 status = IopOpenRegistryKey(&handle1, 03461 handle, 03462 &unicodeString, 03463 KEY_READ, 03464 FALSE 03465 ); 03466 ZwClose(handle); 03467 if (NT_SUCCESS(status)) { 03468 status = IopOpenRegistryKey(&handle, 03469 handle1, 03470 DeviceInstance, 03471 KEY_READ, 03472 FALSE 03473 ); 03474 ZwClose(handle1); 03475 if (NT_SUCCESS(status)) { 03476 status = IopGetRegistryValue( 03477 handle, 03478 REGSTR_VALUE_CSCONFIG_FLAGS, 03479 &keyValueInformation 03480 ); 03481 if (NT_SUCCESS(status)) { 03482 if((keyValueInformation->Type == REG_DWORD) && 03483 (keyValueInformation->DataLength >= sizeof(ULONG))) { 03484 deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 03485 } 03486 ExFreePool(keyValueInformation); 03487 } 03488 ZwClose(handle); 03489 if (NT_SUCCESS(status)) { 03490 if ((deviceFlags & CSCONFIGFLAG_DISABLED) || 03491 (deviceFlags & CSCONFIGFLAG_DO_NOT_CREATE) || 03492 (deviceFlags & CSCONFIGFLAG_DO_NOT_START)) { 03493 enabled = FALSE; 03494 } 03495 } 03496 } 03497 } 03498 } 03499 } 03500 } else { 03501 enabled = FALSE; 03502 } 03503 03504 // 03505 // If the device is disabled and has device node associated with it. 03506 // disable the device. 03507 // 03508 03509 if (enabled == FALSE && deviceNode && DisableIfEnabled) { 03510 IopDisableDevice(deviceNode, DeviceInstanceHandle); 03511 } 03512 exit: 03513 if (deviceObject) { 03514 ObDereferenceObject(deviceObject); 03515 } 03516 if (closeHandle) { 03517 ZwClose(DeviceInstanceHandle); 03518 } 03519 return enabled; 03520 }

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 2384 of file pri_bld/pnpsubs.c.

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

Referenced by IopIsReportedAlready().

02393 : 02394 02395 This routine compares two set of configurations and bus information to 02396 determine if the resources indicate the same device. If BusInfo1 and 02397 BusInfo2 both are absent, it means caller wants to compare the raw 02398 resources. 02399 02400 Arguments: 02401 02402 Configuration1 - Supplies a pointer to the first set of resource. 02403 02404 Configuration2 - Supplies a pointer to the second set of resource. 02405 02406 BusInfo1 - Supplies a pointer to the first set of bus information. 02407 02408 BusInfo2 - Supplies a pointer to the second set of bus information. 02409 02410 Return Value: 02411 02412 returns TRUE if the two set of resources indicate the same device; 02413 otherwise a value of FALSE is returned. 02414 02415 --*/ 02416 02417 { 02418 PCM_PARTIAL_RESOURCE_LIST list1, list2; 02419 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor1, descriptor2; 02420 02421 ULONG i, j; 02422 ULONG pass = 0; 02423 02424 // 02425 // The BusInfo for both resources must be both present or not present. 02426 // 02427 02428 if ((ARGUMENT_PRESENT(BusInfo1) && !ARGUMENT_PRESENT(BusInfo2)) || 02429 (!ARGUMENT_PRESENT(BusInfo1) && ARGUMENT_PRESENT(BusInfo2))) { 02430 02431 // 02432 // Unable to determine. 02433 // 02434 02435 return FALSE; 02436 } 02437 02438 // 02439 // Next check resources used by the two devices. 02440 // Currently, we *only* check the Io ports. 02441 // 02442 02443 if (Configuration1->Count == 0 || Configuration2->Count == 0) { 02444 02445 // 02446 // If any one of the configuration data is empty, we assume 02447 // the devices are not duplicates. 02448 // 02449 02450 return FALSE; 02451 } 02452 02453 RedoScan: 02454 02455 list1 = &(Configuration1->List[0].PartialResourceList); 02456 list2 = &(Configuration2->List[0].PartialResourceList); 02457 02458 for(i = 0, descriptor1 = list1->PartialDescriptors; 02459 i < list1->Count; 02460 i++, descriptor1++) { 02461 02462 // 02463 // If this is an i/o port or a memory range then look for a match 02464 // in the other list. 02465 // 02466 02467 if((descriptor1->Type == CmResourceTypePort) || 02468 (descriptor1->Type == CmResourceTypeMemory)) { 02469 02470 for(j = 0, descriptor2 = list2->PartialDescriptors; 02471 j < list2->Count; 02472 j++, descriptor2++) { 02473 02474 // 02475 // If the types match then check to see if both addresses 02476 // match as well. If bus info was provided then go ahead 02477 // and translate the ranges first. 02478 // 02479 02480 if(descriptor1->Type == descriptor2->Type) { 02481 02482 PHYSICAL_ADDRESS range1, range1Translated; 02483 PHYSICAL_ADDRESS range2, range2Translated; 02484 ULONG range1IoSpace, range2IoSpace; 02485 02486 range1 = descriptor1->u.Generic.Start; 02487 range2 = descriptor2->u.Generic.Start; 02488 02489 if((range1.QuadPart == 0) || 02490 (BusInfo1 == NULL) || 02491 (HalTranslateBusAddress( 02492 BusInfo1->BusType, 02493 BusInfo1->BusNumber, 02494 range1, 02495 &range1IoSpace, 02496 &range1Translated) == FALSE)) { 02497 02498 range1Translated = range1; 02499 range1IoSpace = 02500 (descriptor1->Type == CmResourceTypePort) ? TRUE : 02501 FALSE; 02502 } 02503 02504 if((range2.QuadPart == 0) || 02505 (BusInfo2 == NULL) || 02506 (HalTranslateBusAddress( 02507 BusInfo2->BusType, 02508 BusInfo2->BusNumber, 02509 range2, 02510 &range2IoSpace, 02511 &range2Translated) == FALSE)) { 02512 02513 range2Translated = range2; 02514 range2IoSpace = 02515 (descriptor2->Type == CmResourceTypePort) ? TRUE : 02516 FALSE; 02517 } 02518 02519 // 02520 // If the ranges are in the same space and start at the 02521 // same location then break out and go on to the next 02522 // range 02523 // 02524 02525 if((range1Translated.QuadPart == range2Translated.QuadPart) && 02526 (range1IoSpace == range2IoSpace)) { 02527 02528 break; 02529 } 02530 } 02531 } 02532 02533 // 02534 // If we made it all the way through the resource list without 02535 // finding a match then these are not duplicates. 02536 // 02537 02538 if(j == list2->Count) { 02539 return FALSE; 02540 } 02541 } 02542 } 02543 02544 // 02545 // If every resource in list 1 exists in list 2 then we also need to make 02546 // sure that every resource in list 2 exists in list 1. 02547 // 02548 02549 if(pass == 0) { 02550 02551 PVOID tmp ; 02552 02553 tmp = Configuration2; 02554 Configuration2 = Configuration1; 02555 Configuration1 = tmp; 02556 02557 tmp = BusInfo2; 02558 BusInfo2 = BusInfo1; 02559 BusInfo1 = tmp; 02560 02561 pass = 1; 02562 02563 goto RedoScan; 02564 } 02565 02566 return TRUE; 02567 }

BOOLEAN IopIsLegacyDriver IN PDRIVER_OBJECT  DriverObject  ) 
 

Definition at line 5177 of file pri_bld/pnpsubs.c.

References DRVO_LEGACY_DRIVER, FALSE, PAGED_CODE, and TRUE.

Referenced by IopCallDriverAddDeviceQueryRoutine(), IopInitializeBootDrivers(), IopInitializeBuiltinDriver(), and IopLoadDriver().

05183 : 05184 05185 This routine checks if the driver object specifies a legacy driver. 05186 05187 Arguments: 05188 05189 DriverObject - supplies a pointer to the driver object to be checked. 05190 05191 Return Value: 05192 05193 BOOLEAN 05194 05195 --*/ 05196 05197 { 05198 05199 PAGED_CODE(); 05200 05201 // 05202 // If AddDevice entry is not empty it is a wdm driver 05203 // 05204 05205 if (DriverObject->DriverExtension->AddDevice) { 05206 return FALSE; 05207 } 05208 05209 // 05210 // Else if LEGACY flag is set in the driver object, it's a legacy driver. 05211 // 05212 05213 if (DriverObject->Flags & DRVO_LEGACY_DRIVER) { 05214 return TRUE; 05215 } else { 05216 return FALSE; 05217 } 05218 }

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

Definition at line 2297 of file pri_bld/pnpsubs.c.

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

02306 : 02307 02308 This routine marks the device instance specified by TargetKeyName and TargetInstance 02309 as DuplicateOf the device specified by SourceKeyName and SourceInstance. 02310 02311 Arguments: 02312 02313 TargetKeyName - supplies a pointer to the name of service key which will be marked 02314 as duplicate. 02315 02316 TargetInstance - the instance number of the target device. 02317 02318 SourceKeyName - supplies a pointer to the name of service key. 02319 02320 SourceInstance - the instance number of the source device. 02321 02322 02323 Returns: 02324 02325 NTSTATUS code. 02326 02327 --*/ 02328 02329 { 02330 HANDLE handle; 02331 NTSTATUS status; 02332 UNICODE_STRING sourceDeviceString, unicodeValueName; 02333 02334 // 02335 // Open the handle of the target device instance. 02336 // 02337 02338 status = IopServiceInstanceToDeviceInstance( 02339 NULL, 02340 TargetKeyName, 02341 TargetInstance, 02342 NULL, 02343 &handle, 02344 0 02345 ); 02346 if (!NT_SUCCESS(status)) { 02347 return status; 02348 } 02349 02350 // 02351 // Get the name of the source device instance 02352 // 02353 02354 status = IopServiceInstanceToDeviceInstance( 02355 NULL, 02356 SourceKeyName, 02357 SourceInstance, 02358 &sourceDeviceString, 02359 NULL, 02360 0 02361 ); 02362 if (!NT_SUCCESS(status)) { 02363 return status; 02364 } 02365 02366 // 02367 // Write the name of the source device to the DuplicateOf value entry of 02368 // target device key. 02369 // 02370 02371 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DUPLICATEOF); 02372 status = ZwSetValueKey( 02373 handle, 02374 &unicodeValueName, 02375 TITLE_INDEX_VALUE, 02376 REG_SZ, 02377 &sourceDeviceString, 02378 sourceDeviceString.Length + sizeof(WCHAR) 02379 ); 02380 return status; 02381 }

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

Definition at line 5085 of file pri_bld/pnpsubs.c.

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

05093 : 05094 05095 This routines merges two IoLists into one. 05096 05097 05098 Arguments: 05099 05100 IoList1 - supplies the pointer to the first CmResourceList 05101 05102 IoList2 - supplies the pointer to the second CmResourceList 05103 05104 MergedList - Supplies a variable to receive the merged resource 05105 list. 05106 05107 Return Value: 05108 05109 A NTSTATUS code to indicate the result of the function. 05110 05111 --*/ 05112 { 05113 NTSTATUS status = STATUS_SUCCESS; 05114 PCM_RESOURCE_LIST cmList, newList; 05115 ULONG size, size1, size2; 05116 PUCHAR p; 05117 05118 PAGED_CODE(); 05119 05120 *MergedList = NULL; 05121 05122 // 05123 // First handle the easy cases that both IO Lists are empty or any one of 05124 // them is empty. 05125 // 05126 05127 if ((List1 == NULL || List1->Count == 0) && 05128 (List2 == NULL || List2->Count == 0)) { 05129 return status; 05130 } 05131 05132 cmList = NULL; 05133 if (List1 == NULL || List1->Count == 0) { 05134 cmList = List2; 05135 } else if (List2 == NULL || List2->Count == 0) { 05136 cmList = List1; 05137 } 05138 if (cmList) { 05139 size = IopDetermineResourceListSize(cmList); 05140 newList = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool, size); 05141 if (newList == NULL) { 05142 return STATUS_INSUFFICIENT_RESOURCES; 05143 } 05144 RtlMoveMemory(newList, cmList, size); 05145 *MergedList = newList; 05146 return status; 05147 } 05148 05149 // 05150 // Do real work... 05151 // 05152 05153 size1 = IopDetermineResourceListSize(List1); 05154 size2 = IopDetermineResourceListSize(List2); 05155 size = size1 + size2; 05156 newList = (PCM_RESOURCE_LIST) ExAllocatePool( 05157 PagedPool, 05158 size 05159 ); 05160 if (newList == NULL) { 05161 return STATUS_INSUFFICIENT_RESOURCES; 05162 } 05163 p = (PUCHAR)newList; 05164 RtlMoveMemory(p, List1, size1); 05165 p += size1; 05166 RtlMoveMemory(p, 05167 &List2->List[0], 05168 size2 - FIELD_OFFSET(CM_RESOURCE_LIST, List) 05169 ); 05170 newList->Count = List1->Count + List2->Count; 05171 *MergedList = newList; 05172 return status; 05173 05174 }

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

Definition at line 4996 of file pri_bld/pnpsubs.c.

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

Referenced by IopQueryDeviceResources().

05004 : 05005 05006 This routines merges two IoLists into one. 05007 05008 05009 Arguments: 05010 05011 IoList1 - supplies the pointer to the first IoResourceRequirementsList 05012 05013 IoList2 - supplies the pointer to the second IoResourceRequirementsList 05014 05015 MergedList - Supplies a variable to receive the merged resource 05016 requirements list. 05017 05018 Return Value: 05019 05020 A NTSTATUS code to indicate the result of the function. 05021 05022 --*/ 05023 { 05024 NTSTATUS status = STATUS_SUCCESS; 05025 PIO_RESOURCE_REQUIREMENTS_LIST ioList, newList; 05026 ULONG size; 05027 PUCHAR p; 05028 05029 PAGED_CODE(); 05030 05031 *MergedList = NULL; 05032 05033 // 05034 // First handle the easy cases that both IO Lists are empty or any one of 05035 // them is empty. 05036 // 05037 05038 if ((IoList1 == NULL || IoList1->AlternativeLists == 0) && 05039 (IoList2 == NULL || IoList2->AlternativeLists == 0)) { 05040 return status; 05041 } 05042 ioList = NULL; 05043 if (IoList1 == NULL || IoList1->AlternativeLists == 0) { 05044 ioList = IoList2; 05045 } else if (IoList2 == NULL || IoList2->AlternativeLists == 0) { 05046 ioList = IoList1; 05047 } 05048 if (ioList) { 05049 newList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, ioList->ListSize); 05050 if (newList == NULL) { 05051 return STATUS_INSUFFICIENT_RESOURCES; 05052 } 05053 RtlMoveMemory(newList, ioList, ioList->ListSize); 05054 *MergedList = newList; 05055 return status; 05056 } 05057 05058 // 05059 // Do real work... 05060 // 05061 05062 size = IoList1->ListSize + IoList2->ListSize - FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List); 05063 newList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool( 05064 PagedPool, 05065 size 05066 ); 05067 if (newList == NULL) { 05068 return STATUS_INSUFFICIENT_RESOURCES; 05069 } 05070 p = (PUCHAR)newList; 05071 RtlMoveMemory(p, IoList1, IoList1->ListSize); 05072 p += IoList1->ListSize; 05073 RtlMoveMemory(p, 05074 &IoList2->List[0], 05075 size - IoList1->ListSize 05076 ); 05077 newList->ListSize = size; 05078 newList->AlternativeLists += IoList2->AlternativeLists; 05079 *MergedList = newList; 05080 return status; 05081 05082 }

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

Definition at line 1588 of file pri_bld/pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, Create(), FALSE, Handle, IopOpenRegistryKey(), IopServiceInstanceToDeviceInstance(), NT_SUCCESS, NTSTATUS(), NULL, and RtlFreeUnicodeString().

Referenced by IopGetDeviceInstanceCsConfigFlags(), IopGetServiceInstanceCsConfigFlags(), IopSetDeviceInstanceCsConfigFlags(), and IopSetServiceInstanceCsConfigFlags().

01598 : 01599 01600 This routine sets the csconfig flags for the specified device 01601 which is specified by the instance number under ServiceKeyName\Enum. 01602 01603 Arguments: 01604 01605 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01606 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01607 that caused the driver to load. This is the RegistryPath parameter 01608 to the DriverEntry routine. 01609 01610 Instance - Supplies the instance value under ServiceKeyName\Enum key 01611 01612 DesiredAccess - Specifies the desired access that the caller needs to 01613 the key. 01614 01615 Create - Determines if the key is to be created if it does not exist. 01616 01617 Return Value: 01618 01619 status 01620 01621 --*/ 01622 01623 { 01624 NTSTATUS status; 01625 UNICODE_STRING tempUnicodeString; 01626 HANDLE profileHandle, profileEnumHandle, tmpHandle; 01627 01628 // 01629 // See if we can open current hardware profile 01630 // 01631 status = IopOpenRegistryKey(&profileHandle, 01632 NULL, 01633 &CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, 01634 KEY_READ, 01635 Create 01636 ); 01637 if(NT_SUCCESS(status)) { 01638 // 01639 // Now, we must open the System\CCS\Enum key under this. 01640 // 01641 // 01642 // Open system\CurrentControlSet under current hardware profile key 01643 // 01644 01645 PiWstrToUnicodeString(&tempUnicodeString, REGSTR_PATH_CURRENTCONTROLSET); 01646 status = IopOpenRegistryKey(&tmpHandle, 01647 profileHandle, 01648 &tempUnicodeString, 01649 DesiredAccess, 01650 FALSE 01651 ); 01652 ZwClose(profileHandle); 01653 if (!NT_SUCCESS(status)) { 01654 return status; 01655 } 01656 01657 PiWstrToUnicodeString(&tempUnicodeString, REGSTR_KEY_ENUM); 01658 status = IopOpenRegistryKey(&profileEnumHandle, 01659 tmpHandle, 01660 &tempUnicodeString, 01661 KEY_READ, 01662 Create 01663 ); 01664 ZwClose(tmpHandle); 01665 if(NT_SUCCESS(status)) { 01666 01667 status = IopServiceInstanceToDeviceInstance(NULL, 01668 ServiceKeyName, 01669 Instance, 01670 &tempUnicodeString, 01671 NULL, 01672 0 01673 ); 01674 if(NT_SUCCESS(status)) { 01675 status = IopOpenRegistryKey(Handle, 01676 profileEnumHandle, 01677 &tempUnicodeString, 01678 DesiredAccess, 01679 Create 01680 ); 01681 RtlFreeUnicodeString(&tempUnicodeString); 01682 } 01683 ZwClose(profileEnumHandle); 01684 } 01685 } 01686 return status; 01687 }

NTSTATUS IopOpenRegistryKeyPersist OUT PHANDLE  Handle,
IN HANDLE BaseHandle  OPTIONAL,
IN PUNICODE_STRING  KeyName,
IN ACCESS_MASK  DesiredAccess,
IN BOOLEAN  Create,
OUT PULONG Disposition  OPTIONAL
 

Definition at line 1140 of file pri_bld/pnpsubs.c.

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

Referenced by IopCreateMadeupNode().

01151 : 01152 01153 Opens or creates a PERSIST (non-volatile) registry key using the name 01154 passed in based at the BaseHandle node. This name may specify a key 01155 that is actually a registry path, in which case each intermediate subkey 01156 will be created (if Create is TRUE). 01157 01158 NOTE: Creating a registry path (i.e., more than one of the keys in the path 01159 do not presently exist) requires that a BaseHandle be specified. 01160 01161 Arguments: 01162 01163 Handle - Pointer to the handle which will contain the registry key that 01164 was opened. 01165 01166 BaseHandle - Optional handle to the base path from which the key must be opened. 01167 If KeyName specifies a registry path that must be created, then this parameter 01168 must be specified, and KeyName must be a relative path. 01169 01170 KeyName - Name of the Key that must be opened/created (possibly a registry path) 01171 01172 DesiredAccess - Specifies the desired access that the caller needs to 01173 the key. 01174 01175 Create - Determines if the key is to be created if it does not exist. 01176 01177 Disposition - If Create is TRUE, this optional pointer receives a ULONG indicating 01178 whether the key was newly created: 01179 01180 REG_CREATED_NEW_KEY - A new Registry Key was created 01181 REG_OPENED_EXISTING_KEY - An existing Registry Key was opened 01182 01183 Return Value: 01184 01185 The function value is the final status of the operation. 01186 01187 --*/ 01188 01189 { 01190 OBJECT_ATTRIBUTES objectAttributes; 01191 ULONG disposition, baseHandleIndex = 0, keyHandleIndex = 1, closeBaseHandle; 01192 HANDLE handles[2]; 01193 BOOLEAN continueParsing; 01194 PWCHAR pathEndPtr, pathCurPtr, pathBeginPtr; 01195 ULONG pathComponentLength; 01196 UNICODE_STRING unicodeString; 01197 NTSTATUS status; 01198 01199 PAGED_CODE(); 01200 01201 InitializeObjectAttributes(&objectAttributes, 01202 KeyName, 01203 OBJ_CASE_INSENSITIVE, 01204 BaseHandle, 01205 (PSECURITY_DESCRIPTOR) NULL 01206 ); 01207 if(Create) { 01208 // 01209 // Attempt to create the path as specified. We have to try it this 01210 // way first, because it allows us to create a key without a BaseHandle 01211 // (if only the last component of the registry path is not present). 01212 // 01213 status = ZwCreateKey(&(handles[keyHandleIndex]), 01214 DesiredAccess, 01215 &objectAttributes, 01216 0, 01217 (PUNICODE_STRING) NULL, 01218 REG_OPTION_NON_VOLATILE, 01219 &disposition 01220 ); 01221 01222 if(!((status == STATUS_OBJECT_NAME_NOT_FOUND) && ARGUMENT_PRESENT(BaseHandle))) { 01223 // 01224 // Then either we succeeded, or failed, but there's nothing we can do 01225 // about it. In either case, prepare to return. 01226 // 01227 goto PrepareForReturn; 01228 } 01229 01230 } else { 01231 // 01232 // Simply attempt to open the path, as specified. 01233 // 01234 return ZwOpenKey(Handle, 01235 DesiredAccess, 01236 &objectAttributes 01237 ); 01238 } 01239 01240 // 01241 // If we get to here, then there must be more than one element of the 01242 // registry path that does not currently exist. We will now parse the 01243 // specified path, extracting each component and doing a ZwCreateKey on it. 01244 // 01245 handles[baseHandleIndex] = NULL; 01246 handles[keyHandleIndex] = BaseHandle; 01247 closeBaseHandle = 0; 01248 continueParsing = TRUE; 01249 pathBeginPtr = KeyName->Buffer; 01250 pathEndPtr = (PWCHAR)((PCHAR)pathBeginPtr + KeyName->Length); 01251 status = STATUS_SUCCESS; 01252 01253 while(continueParsing) { 01254 // 01255 // There's more to do, so close the previous base handle (if necessary), 01256 // and replace it with the current key handle. 01257 // 01258 if(closeBaseHandle > 1) { 01259 ZwClose(handles[baseHandleIndex]); 01260 } 01261 baseHandleIndex = keyHandleIndex; 01262 keyHandleIndex = (keyHandleIndex + 1) & 1; // toggle between 0 and 1. 01263 handles[keyHandleIndex] = NULL; 01264 01265 // 01266 // Extract next component out of the specified registry path. 01267 // 01268 for(pathCurPtr = pathBeginPtr; 01269 ((pathCurPtr < pathEndPtr) && (*pathCurPtr != OBJ_NAME_PATH_SEPARATOR)); 01270 pathCurPtr++); 01271 01272 if((pathComponentLength = (ULONG)((PCHAR)pathCurPtr - (PCHAR)pathBeginPtr))) { 01273 // 01274 // Then we have a non-empty path component (key name). Attempt 01275 // to create this key. 01276 // 01277 unicodeString.Buffer = pathBeginPtr; 01278 unicodeString.Length = unicodeString.MaximumLength = (USHORT)pathComponentLength; 01279 01280 InitializeObjectAttributes(&objectAttributes, 01281 &unicodeString, 01282 OBJ_CASE_INSENSITIVE, 01283 handles[baseHandleIndex], 01284 (PSECURITY_DESCRIPTOR) NULL 01285 ); 01286 status = ZwCreateKey(&(handles[keyHandleIndex]), 01287 DesiredAccess, 01288 &objectAttributes, 01289 0, 01290 (PUNICODE_STRING) NULL, 01291 REG_OPTION_NON_VOLATILE, 01292 &disposition 01293 ); 01294 if(NT_SUCCESS(status)) { 01295 // 01296 // Increment the closeBaseHandle value, which basically tells us whether 01297 // the BaseHandle passed in has been 'shifted out' of our way, so that 01298 // we should start closing our base handles when we're finished with them. 01299 // 01300 closeBaseHandle++; 01301 } else { 01302 continueParsing = FALSE; 01303 continue; 01304 } 01305 } else { 01306 // 01307 // Either a path separator ('\') was included at the beginning of 01308 // the path, or we hit 2 consecutive separators. 01309 // 01310 status = STATUS_INVALID_PARAMETER; 01311 continueParsing = FALSE; 01312 continue; 01313 } 01314 01315 if((pathCurPtr == pathEndPtr) || 01316 ((pathBeginPtr = pathCurPtr + 1) == pathEndPtr)) { 01317 // 01318 // Then we've reached the end of the path 01319 // 01320 continueParsing = FALSE; 01321 } 01322 } 01323 01324 if(closeBaseHandle > 1) { 01325 ZwClose(handles[baseHandleIndex]); 01326 } 01327 01328 PrepareForReturn: 01329 01330 if(NT_SUCCESS(status)) { 01331 *Handle = handles[keyHandleIndex]; 01332 01333 if(ARGUMENT_PRESENT(Disposition)) { 01334 *Disposition = disposition; 01335 } 01336 } 01337 01338 return status; 01339 }

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

Definition at line 1342 of file pri_bld/pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetServices, FALSE, IopOpenRegistryKey(), NT_SUCCESS, NTSTATUS(), and NULL.

Referenced by IopApplyFunctionToServiceInstances(), IopCallDriverAddDeviceQueryRoutine(), IopCreateMadeupNode(), IopDriverLoadingFailed(), IopGetDriverDeviceList(), IopGetServiceType(), IopIsAnyDeviceInstanceEnabled(), and IopServiceInstanceToDeviceInstance().

01352 : 01353 01354 This routine opens the HKEY_LOCAL_MACHINE\CurrentControlSet\Services\ 01355 ServiceKeyName and its Enum subkey and returns handles for both key. 01356 It is caller's responsibility to close the returned handles. 01357 01358 Arguments: 01359 01360 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01361 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01362 that caused the driver to load. This is the RegistryPath parameter 01363 to the DriverEntry routine. 01364 01365 DesiredAccess - Specifies the desired access to the keys. 01366 01367 ServiceHandle - Supplies a variable to receive a handle to ServiceKeyName. 01368 A NULL ServiceHandle indicates caller does not want need the handle to 01369 the ServiceKeyName. 01370 01371 ServiceEnumHandle - Supplies a variable to receive a handle to ServiceKeyName\Enum. 01372 A NULL ServiceEnumHandle indicates caller does not need the handle to 01373 the ServiceKeyName\Enum. 01374 01375 CreateEnum - Supplies a BOOLEAN variable to indicate should the Enum subkey be 01376 created if not present. 01377 01378 Return Value: 01379 01380 status 01381 01382 --*/ 01383 01384 { 01385 HANDLE handle, serviceHandle, enumHandle; 01386 UNICODE_STRING enumName; 01387 NTSTATUS status; 01388 01389 // 01390 // Open System\CurrentControlSet\Services 01391 // 01392 01393 status = IopOpenRegistryKey(&handle, 01394 NULL, 01395 &CmRegistryMachineSystemCurrentControlSetServices, 01396 DesiredAccess, 01397 FALSE 01398 ); 01399 01400 if (!NT_SUCCESS( status )) { 01401 return status; 01402 } 01403 01404 // 01405 // Open the registry ServiceKeyName key. 01406 // 01407 01408 status = IopOpenRegistryKey(&serviceHandle, 01409 handle, 01410 ServiceKeyName, 01411 DesiredAccess, 01412 FALSE 01413 ); 01414 01415 ZwClose(handle); 01416 if (!NT_SUCCESS( status )) { 01417 01418 // 01419 // There is no registry key for the ServiceKeyName information. 01420 // 01421 01422 return status; 01423 } 01424 01425 if (ARGUMENT_PRESENT(ServiceEnumHandle) || CreateEnum) { 01426 01427 // 01428 // Open registry ServiceKeyName\Enum branch if caller wants 01429 // the handle or wants to create it. 01430 // 01431 01432 PiWstrToUnicodeString(&enumName, REGSTR_KEY_ENUM); 01433 status = IopOpenRegistryKey(&enumHandle, 01434 serviceHandle, 01435 &enumName, 01436 DesiredAccess, 01437 CreateEnum 01438 ); 01439 01440 if (!NT_SUCCESS( status )) { 01441 01442 // 01443 // There is no registry key for the ServiceKeyName\Enum information. 01444 // 01445 01446 ZwClose(serviceHandle); 01447 return status; 01448 } 01449 if (ARGUMENT_PRESENT(ServiceEnumHandle)) { 01450 *ServiceEnumHandle = enumHandle; 01451 } else { 01452 ZwClose(enumHandle); 01453 } 01454 } 01455 01456 // 01457 // if caller wants to have the ServiceKey handle, we return it. Otherwise 01458 // we close it. 01459 // 01460 01461 if (ARGUMENT_PRESENT(ServiceHandle)) { 01462 *ServiceHandle = serviceHandle; 01463 } else { 01464 ZwClose(serviceHandle); 01465 } 01466 01467 return STATUS_SUCCESS; 01468 }

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

Definition at line 753 of file pri_bld/pnpsubs.c.

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

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

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 = NULL; 00785 ULONG tmp, count = 0; 00786 HANDLE serviceEnumHandle = NULL, sysEnumXxxHandle, controlHandle; 00787 UNICODE_STRING unicodeKeyName, unicodeValueName; 00788 BOOLEAN IsPlugPlayDriver = FALSE; 00789 00790 KeEnterCriticalRegion(); 00791 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 00792 00793 // 00794 // Check should this driver be loaded. If it is a PnP driver and has at least 00795 // one device instance enabled, it will be loaded. If it is a legacy driver, 00796 // we need to check if its device has been disabled. 00797 // 00798 00799 if ((Header) && 00800 (Header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)) { 00801 IsPlugPlayDriver = TRUE; 00802 } 00803 if (IsPlugPlayDriver) { 00804 00805 // 00806 // BUGBUG - For SUR, we load the driver only if device instance list is not 00807 // empty and at least one device instance is enabled. 00808 // 00809 00810 if (!IopIsAnyDeviceInstanceEnabled(KeyName, KeyHandle, FALSE)) { 00811 if (PnPDetectionEnabled) { 00812 00813 // 00814 // We need to load WDM driver on TextMode Setup phase. 00815 // 00816 00817 status = STATUS_SUCCESS; 00818 } else { 00819 status = STATUS_PLUGPLAY_NO_DEVICE; 00820 } 00821 goto exit; 00822 00823 } 00824 } else { 00825 00826 // 00827 // If this is a legacy driver, then we need to check if its 00828 // device has been disabled. (There should be NO more than one device 00829 // instance for legacy driver.) 00830 // 00831 00832 if (!IopIsAnyDeviceInstanceEnabled(KeyName, KeyHandle, TRUE)) { 00833 00834 // 00835 // If the device is not enabled, it may be because there is no device 00836 // instance. If this is the case, we need to create a madeup key as 00837 // the device instance for the legacy driver. 00838 // 00839 00840 // 00841 // First open registry ServiceKeyName\Enum branch 00842 // 00843 00844 PiWstrToUnicodeString(&unicodeKeyName, REGSTR_KEY_ENUM); 00845 status = IopOpenRegistryKey(&serviceEnumHandle, 00846 KeyHandle, 00847 &unicodeKeyName, 00848 KEY_ALL_ACCESS, 00849 TRUE 00850 ); 00851 00852 if (!NT_SUCCESS( status )) { 00853 goto exit; 00854 } 00855 00856 // 00857 // Find out how many device instances listed in the ServiceName's 00858 // Enum key. 00859 // 00860 00861 status = IopGetRegistryValue ( serviceEnumHandle, 00862 REGSTR_VALUE_COUNT, 00863 &keyValueInformation 00864 ); 00865 if (NT_SUCCESS(status)) { 00866 if ((keyValueInformation->Type == REG_DWORD) && 00867 (keyValueInformation->DataLength >= sizeof(ULONG))) { 00868 00869 count = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 00870 } 00871 ExFreePool(keyValueInformation); 00872 } else if (status != STATUS_OBJECT_PATH_NOT_FOUND && 00873 status != STATUS_OBJECT_NAME_NOT_FOUND) { 00874 00875 ZwClose(serviceEnumHandle); 00876 goto exit; 00877 } 00878 00879 if (count == 0) { 00880 00881 // 00882 // If there is no Enum key or instance under Enum for the 00883 // legacy driver we will create a madeup node for it. 00884 // 00885 00886 status = IopCreateMadeupNode(KeyName, 00887 &sysEnumXxxHandle, 00888 &unicodeKeyName, 00889 &tmp, 00890 TRUE); 00891 00892 if (!NT_SUCCESS(status)) { 00893 ZwClose(serviceEnumHandle); 00894 goto exit; 00895 } 00896 RtlFreeUnicodeString(&unicodeKeyName); 00897 00898 // 00899 // Create and set Control\ActiveService value 00900 // 00901 00902 PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL); 00903 status = IopOpenRegistryKey(&controlHandle, 00904 sysEnumXxxHandle, 00905 &unicodeValueName, 00906 KEY_ALL_ACCESS, 00907 TRUE 00908 ); 00909 if (NT_SUCCESS(status)) { 00910 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VAL_ACTIVESERVICE); 00911 ZwSetValueKey( 00912 controlHandle, 00913 &unicodeValueName, 00914 TITLE_INDEX_VALUE, 00915 REG_SZ, 00916 KeyName->Buffer, 00917 KeyName->Length + sizeof(UNICODE_NULL) 00918 ); 00919 00920 ZwClose(controlHandle); 00921 } 00922 count++; 00923 00924 // 00925 // Don't forget to update the "Count=" and "NextInstance=" value entries 00926 // 00927 00928 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_COUNT); 00929 00930 ZwSetValueKey(serviceEnumHandle, 00931 &unicodeValueName, 00932 TITLE_INDEX_VALUE, 00933 REG_DWORD, 00934 &count, 00935 sizeof (count) 00936 ); 00937 PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE); 00938 00939 ZwSetValueKey(serviceEnumHandle, 00940 &unicodeValueName, 00941 TITLE_INDEX_VALUE, 00942 REG_DWORD, 00943 &count, 00944 sizeof (count) 00945 ); 00946 ZwClose(sysEnumXxxHandle); 00947 ZwClose(serviceEnumHandle); 00948 } else { 00949 ZwClose(serviceEnumHandle); 00950 status = STATUS_PLUGPLAY_NO_DEVICE; 00951 goto exit; 00952 } 00953 } 00954 } 00955 00956 status = STATUS_SUCCESS; 00957 exit: 00958 ExReleaseResource(&PpRegistryDeviceResource); 00959 KeLeaveCriticalRegion(); 00960 return status; 00961 }

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

Definition at line 4170 of file pri_bld/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.

Referenced by IopGetDeviceResourcesFromRegistry().

04179 : 04180 04181 This routine read the specified ALLOC config or ForcedConfig or Boot config. 04182 04183 Arguments: 04184 04185 Hanle - supplies a handle to the registry key to read resources. 04186 04187 Return Value: 04188 04189 status 04190 04191 --*/ 04192 04193 { 04194 NTSTATUS status; 04195 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 04196 PWCHAR valueName; 04197 04198 *CmResource = NULL; 04199 *Length = 0; 04200 04201 if (Flags == REGISTRY_ALLOC_CONFIG) { 04202 valueName = REGSTR_VALUE_ALLOC_CONFIG; 04203 } else if (Flags == REGISTRY_FORCED_CONFIG) { 04204 valueName = REGSTR_VALUE_FORCED_CONFIG; 04205 } else if (Flags == REGISTRY_BOOT_CONFIG) { 04206 valueName = REGSTR_VALUE_BOOT_CONFIG; 04207 } else { 04208 return STATUS_INVALID_PARAMETER_2; 04209 } 04210 04211 // 04212 // Read the registry value of the desired value name 04213 // 04214 04215 status = IopGetRegistryValue (Handle, 04216 valueName, 04217 &keyValueInformation); 04218 if (NT_SUCCESS(status)) { 04219 04220 // 04221 // Try to read what caller wants. 04222 // 04223 04224 if ((keyValueInformation->Type == REG_RESOURCE_LIST) && 04225 (keyValueInformation->DataLength != 0)) { 04226 *CmResource = ExAllocatePool(PagedPool, 04227 keyValueInformation->DataLength); 04228 if (*CmResource) { 04229 if (*CmResource) { 04230 *Length = keyValueInformation->DataLength; 04231 RtlMoveMemory(*CmResource, 04232 KEY_VALUE_DATA(keyValueInformation), 04233 keyValueInformation->DataLength); 04234 } else { 04235 status = STATUS_INSUFFICIENT_RESOURCES; 04236 } 04237 } 04238 ExFreePool(keyValueInformation); 04239 if (*CmResource) { 04240 PCM_RESOURCE_LIST resourceList; 04241 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc; 04242 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc; 04243 ULONG j, k, size, count; 04244 04245 // 04246 // Process the resource list read from Registry to change undefined 04247 // interface type to our default interface type. 04248 // 04249 04250 resourceList = *CmResource; 04251 cmFullDesc = &resourceList->List[0]; 04252 for (j = 0; j < resourceList->Count; j++) { 04253 if (cmFullDesc->InterfaceType == InterfaceTypeUndefined) { 04254 cmFullDesc->BusNumber = 0; 04255 cmFullDesc->InterfaceType = PnpDefaultInterfaceType; 04256 } 04257 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0]; 04258 for (k = 0; k < cmFullDesc->PartialResourceList.Count; k++) { 04259 size = 0; 04260 switch (cmPartDesc->Type) { 04261 case CmResourceTypeDeviceSpecific: 04262 size = cmPartDesc->u.DeviceSpecificData.DataSize; 04263 break; 04264 } 04265 cmPartDesc++; 04266 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size); 04267 } 04268 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc; 04269 } 04270 } 04271 } else if (keyValueInformation->Type != REG_RESOURCE_LIST) { 04272 status = STATUS_UNSUCCESSFUL; 04273 } 04274 } 04275 return status; 04276 }

PDRIVER_OBJECT IopReferenceDriverObjectByName IN PUNICODE_STRING  DriverName  ) 
 

Definition at line 3578 of file pri_bld/pnpsubs.c.

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

Referenced by IopCallDriverAddDeviceQueryRoutine(), and IopInitializeSystemDrivers().

03584 : 03585 03586 This routine references a driver object by a given driver name. 03587 03588 Arguments: 03589 03590 DriverName - supplies a pointer to the name of the driver whose driver object is 03591 to be referenced. 03592 03593 Returns: 03594 03595 A pointer to a DRIVER_OBJECT if succeeds. Otherwise, a NULL value. 03596 03597 --*/ 03598 03599 { 03600 OBJECT_ATTRIBUTES objectAttributes; 03601 HANDLE driverHandle; 03602 NTSTATUS status; 03603 PDRIVER_OBJECT driverObject; 03604 03605 // 03606 // Make sure the driver name is valid. 03607 // 03608 03609 if (DriverName->Length == 0) { 03610 return NULL; 03611 } 03612 03613 InitializeObjectAttributes(&objectAttributes, 03614 DriverName, 03615 OBJ_CASE_INSENSITIVE, 03616 NULL, 03617 NULL 03618 ); 03619 status = ObOpenObjectByName(&objectAttributes, 03620 IoDriverObjectType, 03621 KernelMode, 03622 NULL, 03623 FILE_READ_ATTRIBUTES, 03624 NULL, 03625 &driverHandle 03626 ); 03627 if (NT_SUCCESS(status)) { 03628 03629 // 03630 // Now reference the driver object. 03631 // 03632 03633 status = ObReferenceObjectByHandle(driverHandle, 03634 0, 03635 IoDriverObjectType, 03636 KernelMode, 03637 &driverObject, 03638 NULL 03639 ); 03640 NtClose(driverHandle); 03641 } 03642 03643 if (NT_SUCCESS(status)) { 03644 return driverObject; 03645 } else { 03646 return NULL; 03647 } 03648 }

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

Definition at line 1907 of file pri_bld/pnpsubs.c.

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

Referenced by IopGetGroupOrderIndex().

01915 : 01916 01917 This routine takes a KEY_VALUE_FULL_INFORMATION structure containing 01918 a REG_MULTI_SZ value, and allocates an array of UNICODE_STRINGs, 01919 initializing each one to a copy of one of the strings in the value entry. 01920 All the resulting UNICODE_STRINGs will be NULL terminated 01921 (MaximumLength = Length + sizeof(UNICODE_NULL)). 01922 01923 It is the responsibility of the caller to free the buffers for each 01924 unicode string, as well as the buffer containing the UNICODE_STRING 01925 array. This may be done by calling IopFreeUnicodeStringList. 01926 01927 Arguments: 01928 01929 KeyValueInformation - Supplies the buffer containing the REG_MULTI_SZ 01930 value entry data. 01931 01932 UnicodeStringList - Receives a pointer to an array of UNICODE_STRINGs, each 01933 initialized with a copy of one of the strings in the REG_MULTI_SZ. 01934 01935 UnicodeStringCount - Receives the number of strings in the 01936 UnicodeStringList. 01937 01938 Returns: 01939 01940 NT status code indicating whether the function was successful. 01941 01942 --*/ 01943 01944 { 01945 PWCHAR p, BufferEnd, StringStart; 01946 ULONG StringCount, i, StringLength; 01947 01948 // 01949 // First, make sure this is really a REG_MULTI_SZ value. 01950 // 01951 if(KeyValueInformation->Type != REG_MULTI_SZ) { 01952 return STATUS_INVALID_PARAMETER; 01953 } 01954 01955 // 01956 // Make a preliminary pass through the buffer to count the number of strings 01957 // There will always be at least one string returned (possibly empty). 01958 // 01959 StringCount = 0; 01960 p = (PWCHAR)KEY_VALUE_DATA(KeyValueInformation); 01961 BufferEnd = (PWCHAR)((PUCHAR)p + KeyValueInformation->DataLength); 01962 while(p != BufferEnd) { 01963 if(!*p) { 01964 StringCount++; 01965 if(((p + 1) == BufferEnd) || !*(p + 1)) { 01966 break; 01967 } 01968 } 01969 p++; 01970 } 01971 if(p == BufferEnd) { 01972 StringCount++; 01973 } 01974 01975 *UnicodeStringList = ExAllocatePool(PagedPool, sizeof(UNICODE_STRING) * StringCount); 01976 if(!(*UnicodeStringList)) { 01977 return STATUS_INSUFFICIENT_RESOURCES; 01978 } 01979 01980 // 01981 // Now, make a second pass through the buffer making copies of each string. 01982 // 01983 i = 0; 01984 StringStart = p = (PWCHAR)KEY_VALUE_DATA(KeyValueInformation); 01985 while(p != BufferEnd) { 01986 if(!*p) { 01987 StringLength = (ULONG)((PUCHAR)p - (PUCHAR)StringStart) + sizeof(UNICODE_NULL); 01988 (*UnicodeStringList)[i].Buffer = ExAllocatePool(PagedPool, StringLength); 01989 01990 if(!((*UnicodeStringList)[i].Buffer)) { 01991 IopFreeUnicodeStringList(*UnicodeStringList, i); 01992 return STATUS_INSUFFICIENT_RESOURCES; 01993 } 01994 01995 RtlMoveMemory((*UnicodeStringList)[i].Buffer, StringStart, StringLength); 01996 01997 (*UnicodeStringList)[i].Length = 01998 ((*UnicodeStringList)[i].MaximumLength = (USHORT)StringLength) 01999 - sizeof(UNICODE_NULL); 02000 02001 i++; 02002 02003 if(((p + 1) == BufferEnd) || !*(p + 1)) { 02004 break; 02005 } else { 02006 StringStart = p + 1; 02007 } 02008 } 02009 p++; 02010 } 02011 if(p == BufferEnd) { 02012 StringLength = (ULONG)((PUCHAR)p - (PUCHAR)StringStart); 02013 (*UnicodeStringList)[i].Buffer = ExAllocatePool(PagedPool, 02014 StringLength + sizeof(UNICODE_NULL) 02015 ); 02016 if(!((*UnicodeStringList)[i].Buffer)) { 02017 IopFreeUnicodeStringList(*UnicodeStringList, i); 02018 return STATUS_INSUFFICIENT_RESOURCES; 02019 } 02020 if(StringLength) { 02021 RtlMoveMemory((*UnicodeStringList)[i].Buffer, StringStart, StringLength); 02022 } 02023 (*UnicodeStringList)[i].Buffer[CB_TO_CWC(StringLength)] = UNICODE_NULL; 02024 02025 (*UnicodeStringList)[i].MaximumLength = 02026 ((*UnicodeStringList)[i].Length = (USHORT)StringLength) 02027 + sizeof(UNICODE_NULL); 02028 } 02029 02030 *UnicodeStringCount = StringCount; 02031 02032 return STATUS_SUCCESS; 02033 }

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

Definition at line 449 of file pri_bld/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 5597 of file pri_bld/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().

Referenced by IopDeviceActionWorker(), and IopInvalidateRelationsInList().

05600 { 05601 PAGED_CODE(); 05602 05603 ASSERT(!(IopDoesDevNodeHaveProblem(DeviceNode) || 05604 (DeviceNode->Flags & (DNF_STARTED | 05605 DNF_ADDED | 05606 DNF_RESOURCE_ASSIGNED | 05607 DNF_RESOURCE_REPORTED)) || 05608 (DeviceNode->UserFlags & DNUF_WILL_BE_REMOVED))); 05609 05610 ASSERT(DeviceNode->Flags & DNF_ENUMERATED); 05611 05612 if (!(DeviceNode->Flags & DNF_ENUMERATED)) { 05613 return STATUS_UNSUCCESSFUL; 05614 } 05615 05616 DeviceNode->UserFlags &= ~DNUF_NEED_RESTART; 05617 05618 #if DBG_SCOPE 05619 DeviceNode->FailureStatus = 0; 05620 if (DeviceNode->PreviousResourceList) { 05621 ExFreePool(DeviceNode->PreviousResourceList); 05622 DeviceNode->PreviousResourceList = NULL; 05623 } 05624 if (DeviceNode->PreviousResourceRequirements) { 05625 ExFreePool(DeviceNode->PreviousResourceRequirements); 05626 DeviceNode->PreviousResourceRequirements = NULL; 05627 } 05628 #endif 05629 05630 // 05631 // Free any existing devnode strings so we can recreate them 05632 // during enumeration. 05633 // 05634 05635 if (DeviceNode->Flags & DNF_PROCESSED) { 05636 05637 DeviceNode->Flags &= ~(DNF_PROCESSED | DNF_ENUMERATION_REQUEST_QUEUED | DNF_RESOURCE_REQUIREMENTS_CHANGED); 05638 05639 if (DeviceNode->ServiceName.Length != 0) { 05640 ExFreePool(DeviceNode->ServiceName.Buffer); 05641 RtlInitUnicodeString(&DeviceNode->ServiceName, NULL); 05642 } 05643 05644 if (DeviceNode->InstanceOrdinal.Length != 0) { 05645 ExFreePool(DeviceNode->InstanceOrdinal.Buffer); 05646 RtlInitUnicodeString(&DeviceNode->InstanceOrdinal, NULL); 05647 } 05648 05649 if (DeviceNode->ResourceRequirements != NULL) { 05650 ExFreePool(DeviceNode->ResourceRequirements); 05651 DeviceNode->ResourceRequirements = NULL; 05652 DeviceNode->Flags &= ~DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED; 05653 } 05654 } 05655 05656 ASSERT(DeviceNode->ServiceName.Length == 0 && 05657 DeviceNode->ServiceName.MaximumLength == 0 && 05658 DeviceNode->ServiceName.Buffer == NULL); 05659 05660 ASSERT(DeviceNode->InstanceOrdinal.Length == 0 && 05661 DeviceNode->InstanceOrdinal.MaximumLength == 0 && 05662 DeviceNode->InstanceOrdinal.Buffer == NULL); 05663 05664 ASSERT(!(DeviceNode->Flags & 05665 ~(DNF_MADEUP | DNF_ENUMERATED | DNF_HAS_BOOT_CONFIG | 05666 DNF_BOOT_CONFIG_RESERVED | DNF_NO_RESOURCE_REQUIRED))); 05667 05668 return STATUS_SUCCESS; 05669 }

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 964 of file pri_bld/pnpsubs.c.

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

Referenced by IopDriverLoadingFailed(), IopIsAnyDeviceInstanceEnabled(), IopMarkDuplicateDevice(), IopOpenCurrentHwProfileDeviceInstanceKey(), and IopSetLegacyDeviceInstance().

00975 : 00976 00977 This routine reads the service node enum entry to find the desired device instance 00978 under the System\Enum tree. It then optionally returns the registry path of the 00979 specified device instance (relative to HKLM\System\Enum) and an open handle 00980 to that registry key. 00981 00982 It is the caller's responsibility to close the handle returned if 00983 DeviceInstanceHandle is supplied, and also to free the (PagedPool) memory 00984 allocated for the unicode string buffer of DeviceInstanceRegistryPath, if 00985 supplied. 00986 00987 Parameters: 00988 00989 ServiceKeyHandle - Optionally, supplies a handle to the driver service node in the 00990 registry that controls this device instance. If this argument is not specified, 00991 then ServiceKeyName is used to specify the service entry. 00992 00993 ServiceKeyName - Optionally supplies the name of the service entry that controls 00994 the device instance. This must be specified if ServiceKeyHandle isn't given. 00995 00996 ServiceInstanceOrdinal - Supplies the instance value under the service entry's 00997 volatile Enum subkey that references the desired device instance. 00998 00999 DeviceInstanceRegistryPath - Optionally, supplies a pointer to a unicode string 01000 that will be initialized with the registry path (relative to HKLM\System\Enum) 01001 to the device instance key. 01002 01003 DeviceInstanceHandle - Optionally, supplies a pointer to a variable that will 01004 receive a handle to the opened device instance registry key. 01005 01006 DesiredAccess - If DeviceInstanceHandle is specified (i.e., the device instance 01007 key is to be opened), then this variable specifies the access that is needed 01008 to this key. 01009 01010 Return Value: 01011 01012 NT status code indicating whether the function was successful. 01013 01014 --*/ 01015 01016 { 01017 WCHAR unicodeBuffer[20]; 01018 UNICODE_STRING unicodeKeyName; 01019 NTSTATUS status; 01020 HANDLE handle; 01021 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 01022 01023 // 01024 // Open registry ServiceKeyName\Enum branch 01025 // 01026 if(ARGUMENT_PRESENT(ServiceKeyHandle)) { 01027 01028 PiWstrToUnicodeString(&unicodeKeyName, REGSTR_KEY_ENUM); 01029 status = IopOpenRegistryKey(&handle, 01030 ServiceKeyHandle, 01031 &unicodeKeyName, 01032 KEY_READ, 01033 FALSE 01034 ); 01035 } else { 01036 01037 status = IopOpenServiceEnumKeys(ServiceKeyName, 01038 KEY_READ, 01039 NULL, 01040 &handle, 01041 FALSE 01042 ); 01043 } 01044 01045 if (!NT_SUCCESS( status )) { 01046 01047 // 01048 // There is no registry key for the ServiceKeyName\Enum information. 01049 // 01050 01051 return status; 01052 } 01053 01054 // 01055 // Read a path to System\Enum hardware tree branch specified by the service 01056 // instance ordinal 01057 // 01058 01059 swprintf(unicodeBuffer, REGSTR_VALUE_STANDARD_ULONG_FORMAT, ServiceInstanceOrdinal); 01060 status = IopGetRegistryValue ( handle, 01061 unicodeBuffer, 01062 &keyValueInformation 01063 ); 01064 01065 ZwClose(handle); 01066 if (!NT_SUCCESS( status )) { 01067 return status; 01068 } else { 01069 if(keyValueInformation->Type == REG_SZ) { 01070 IopRegistryDataToUnicodeString(&unicodeKeyName, 01071 (PWSTR)KEY_VALUE_DATA(keyValueInformation), 01072 keyValueInformation->DataLength 01073 ); 01074 if(!unicodeKeyName.Length) { 01075 status = STATUS_OBJECT_PATH_NOT_FOUND; 01076 } 01077 } else { 01078 status = STATUS_INVALID_PLUGPLAY_DEVICE_PATH; 01079 } 01080 01081 if(!NT_SUCCESS(status)) { 01082 goto PrepareForReturn; 01083 } 01084 } 01085 01086 // 01087 // If the DeviceInstanceHandle argument was specified, open the device instance 01088 // key under HKLM\System\CurrentControlSet\Enum 01089 // 01090 01091 if (ARGUMENT_PRESENT(DeviceInstanceHandle)) { 01092 01093 status = IopOpenRegistryKey(&handle, 01094 NULL, 01095 &CmRegistryMachineSystemCurrentControlSetEnumName, 01096 KEY_READ, 01097 FALSE 01098 ); 01099 01100 if (NT_SUCCESS( status )) { 01101 01102 status = IopOpenRegistryKey (DeviceInstanceHandle, 01103 handle, 01104 &unicodeKeyName, 01105 DesiredAccess, 01106 FALSE 01107 ); 01108 ZwClose(handle); 01109 } 01110 01111 if (!NT_SUCCESS( status )) { 01112 goto PrepareForReturn; 01113 } 01114 } 01115 01116 // 01117 // If the DeviceInstanceRegistryPath argument was specified, then store a 01118 // copy of the device instance path in the supplied unicode string variable. 01119 // 01120 if (ARGUMENT_PRESENT(DeviceInstanceRegistryPath)) { 01121 01122 if (!IopConcatenateUnicodeStrings(DeviceInstanceRegistryPath, 01123 &unicodeKeyName, 01124 NULL)) { 01125 01126 if(ARGUMENT_PRESENT(DeviceInstanceHandle)) { 01127 ZwClose(*DeviceInstanceHandle); 01128 } 01129 status = STATUS_INSUFFICIENT_RESOURCES; 01130 } 01131 } 01132 01133 PrepareForReturn: 01134 01135 ExFreePool(keyValueInformation); 01136 return status; 01137 }

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

Definition at line 1531 of file pri_bld/pnpsubs.c.

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

01539 : 01540 01541 This routine sets the csconfig flags for the specified device 01542 which is specified by the instance number under ServiceKeyName\Enum. 01543 01544 Arguments: 01545 01546 ServiceKeyName - Supplies a pointer to the name of the subkey in the 01547 system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services) 01548 that caused the driver to load. This is the RegistryPath parameter 01549 to the DriverEntry routine. 01550 01551 Instance - Supplies the instance value under ServiceKeyName\Enum key 01552 01553 CsConfigFlags - Supplies the device instance's new CsConfigFlags 01554 01555 Return Value: 01556 01557 status 01558 01559 --*/ 01560 01561 { 01562 HANDLE handle; 01563 NTSTATUS status; 01564 UNICODE_STRING tempUnicodeString; 01565 01566 status = IopOpenCurrentHwProfileDeviceInstanceKey(&handle, 01567 ServiceKeyName, 01568 Instance, 01569 KEY_READ | KEY_WRITE, 01570 TRUE 01571 ); 01572 if(NT_SUCCESS(status)) { 01573 01574 PiWstrToUnicodeString(&tempUnicodeString, REGSTR_VALUE_CSCONFIG_FLAGS); 01575 status = ZwSetValueKey(handle, 01576 &tempUnicodeString, 01577 TITLE_INDEX_VALUE, 01578 REG_DWORD, 01579 &CsConfigFlags, 01580 sizeof(CsConfigFlags) 01581 ); 01582 ZwClose(handle); 01583 } 01584 return status; 01585 }


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