test: pri_bld/pnpsubs.c File Reference

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 }