test: pnpinit.c File Reference

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

# pnpinit.c File Reference

`#include "iop.h"`

Go to the source code of this file.

## Classes

struct | _ROOT_ENUMERATOR_CONTEXT

## Defines

#define | ALLOW_WORLD_READ_OF_ENUM 1

## Typedefs

typedef _ROOT_ENUMERATOR_CONTEXT | ROOT_ENUMERATOR_CONTEXT
typedef _ROOT_ENUMERATOR_CONTEXT * | PROOT_ENUMERATOR_CONTEXT

## Functions

NTSTATUS | IopPnPDriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
BOOLEAN | IopInitializeDeviceKey (IN HANDLE KeyHandle, IN PUNICODE_STRING KeyName, IN OUT PVOID Context)
BOOLEAN | IopInitializeDeviceInstanceKey (IN HANDLE KeyHandle, IN PUNICODE_STRING KeyName, IN OUT PVOID Context)
NTSTATUS | IopGetServiceType (IN PUNICODE_STRING KeyName, IN PULONG ServiceType)
INTERFACE_TYPE | IopDetermineDefaultInterfaceType (VOID)
NTSTATUS | IopInitializePlugPlayServices (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN ULONG Phase)
NTSTATUS | IopGetRootDevices (PDEVICE_RELATIONS *DeviceRelations)
BOOLEAN | IopIsFirmwareMapperDevicePresent (IN HANDLE KeyHandle)

## Define Documentation

#define ALLOW_WORLD_READ_OF_ENUM 1

| Definition at line 40 of file pnpinit.c.

## Typedef Documentation

typedef struct _ROOT_ENUMERATOR_CONTEXT * PROOT_ENUMERATOR_CONTEXT

| Referenced by IopInitializeDeviceInstanceKey(), and IopInitializeDeviceKey().

typedef struct _ROOT_ENUMERATOR_CONTEXT ROOT_ENUMERATOR_CONTEXT

## Function Documentation

INTERFACE_TYPE IopDetermineDefaultInterfaceType | ( | VOID |  | ) |

Definition at line 1510 of file pnpinit.c.

References HalInstalledBusInformation, HalQuerySystemInformation, IopPnpScratchBuffer1, NT_SUCCESS, NTSTATUS(), and PNP_LARGE_SCRATCH_BUFFER_SIZE.

Referenced by IopInitializePlugPlayServices().

    01516                    :
    01517
    01518     This routine checks if detection flag is set to enable driver detection.
    01519     The detection will be enabled if there is no PCI bus in the machine and only
    01520     on ALPHA machine.
    01521
    01522 Parameters:
    01523
    01524     None.
    01525
    01526 Return Value:
    01527
    01528     BOOLEAN value to indicate if detection is enabled.
    01529
    01530 --*/
    01531
    01532 {
    01533     NTSTATUS status;
    01534     PVOID p;
    01535     PHAL_BUS_INFORMATION pBusInfo;
    01536     ULONG length, i;
    01537     INTERFACE_TYPE interfaceType = Isa;
    01538
    01539     pBusInfo = IopPnpScratchBuffer1;
    01540     length = PNP_LARGE_SCRATCH_BUFFER_SIZE;
    01541     status = HalQuerySystemInformation (
    01542                 HalInstalledBusInformation,
    01543                 length,
    01544                 pBusInfo,
    01545                 &length
    01546                 );
    01547
    01548     if (!NT_SUCCESS(status)) {
    01549
    01550         return interfaceType;
    01551     }
    01552
    01553     //
    01554     // Check installed bus information to make sure there is no existing Pnp Isa
    01555     // bus extender.
    01556     //
    01557
    01558     p = pBusInfo;
    01559     for (i = 0; i < length / sizeof(HAL_BUS_INFORMATION); i++, pBusInfo++) {
    01560         if (pBusInfo->BusType == Isa || pBusInfo->BusType == Eisa) {
    01561             interfaceType = Isa;
    01562             break;
    01563         } else if (pBusInfo->BusType == MicroChannel) {
    01564             interfaceType = MicroChannel;
    01565         }
    01566     }
    01567
    01568     return interfaceType;
    01569 }

NTSTATUS IopGetRootDevices | ( | PDEVICE_RELATIONS * | DeviceRelations | ) |

Definition at line 680 of file pnpinit.c.

References CmRegistryMachineSystemCurrentControlSetEnumRootName, _DEVICE_RELATIONS::Count, _ROOT_ENUMERATOR_CONTEXT::DeviceCount, _ROOT_ENUMERATOR_CONTEXT::DeviceList, ExAcquireResourceExclusive, ExAllocatePool, ExFreePool(), ExReleaseResource, FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS, IopApplyFunctionToSubKeys(), IopCreateRegistryKeyEx(), IopInitializeDeviceKey(), KeEnterCriticalRegion, KeLeaveCriticalRegion, _ROOT_ENUMERATOR_CONTEXT::KeyName, _ROOT_ENUMERATOR_CONTEXT::MaxDeviceCount, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, _DEVICE_RELATIONS::Objects, PAGED_CODE, PagedPool, PDEVICE_OBJECT, PNP_LARGE_SCRATCH_BUFFER_SIZE, PNP_SCRATCH_BUFFER_SIZE, PpRegistryDeviceResource, RtlAppendStringToString(), _ROOT_ENUMERATOR_CONTEXT::Status, and TRUE.

Referenced by IopPnPDispatch().

    00686                    :
    00687
    00688     This routine scans through System\Enum\Root subtree to build a device node for
    00689     each root device.
    00690
    00691 Arguments:
    00692
    00693     DeviceRelations - supplies a variable to receive the returned DEVICE_RELATIONS structure.
    00694
    00695 Return Value:
    00696
    00697     A NTSTATUS code.
    00698
    00699 --*/
    00700
    00701 {
    00702     NTSTATUS status;
    00703     HANDLE baseHandle;
    00704     UNICODE_STRING workName, tmpName;
    00705     PVOID buffer;
    00706     ROOT_ENUMERATOR_CONTEXT context;
    00707     ULONG i;
    00708     PDEVICE_RELATIONS deviceRelations;
    00709
    00710     PAGED_CODE();
    00711
    00712     *DeviceRelations = NULL;
    00713     buffer = ExAllocatePool(PagedPool, PNP_LARGE_SCRATCH_BUFFER_SIZE);
    00714     if (!buffer) {
    00715         return STATUS_INSUFFICIENT_RESOURCES;
    00716     }
    00717
    00718     //
    00719     // Allocate a buffer to store the PDOs enumerated.
    00720     // Note, the the buffer turns out to be not big enough, it will be reallocated dynamically.
    00721     //
    00722
    00723     context.DeviceList = (PDEVICE_OBJECT *) ExAllocatePool(PagedPool, PNP_SCRATCH_BUFFER_SIZE * 2);
    00724     if (context.DeviceList) {
    00725         context.MaxDeviceCount = (PNP_SCRATCH_BUFFER_SIZE * 2) / sizeof(PDEVICE_OBJECT);
    00726         context.DeviceCount = 0;
    00727     } else {
    00728         ExFreePool(buffer);
    00729         return STATUS_INSUFFICIENT_RESOURCES;
    00730     }
    00731
    00732     KeEnterCriticalRegion();
    00733     ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE);
    00734
    00735     //
    00736     // Open System\CurrentControlSet\Enum\Root key and call worker routine to recursively
    00737     // scan through the subkeys.
    00738     //
    00739
    00740     status = IopCreateRegistryKeyEx( &baseHandle,
    00741                                      NULL,
    00742                                      &CmRegistryMachineSystemCurrentControlSetEnumRootName,
    00743                                      KEY_READ,
    00744                                      REG_OPTION_NON_VOLATILE,
    00745                                      NULL
    00746                                      );
    00747
    00748     if (NT_SUCCESS(status)) {
    00749
    00750         workName.Buffer = (PWSTR)buffer;
    00751         RtlFillMemory(buffer, PNP_LARGE_SCRATCH_BUFFER_SIZE, 0);
    00752         workName.MaximumLength = PNP_LARGE_SCRATCH_BUFFER_SIZE;
    00753         workName.Length = 0;
    00754
    00755         //
    00756         // only look at ROOT key
    00757         //
    00758
    00759         PiWstrToUnicodeString(&tmpName, REGSTR_KEY_ROOTENUM);
    00760         RtlAppendStringToString((PSTRING)&workName, (PSTRING)&tmpName);
    00761
    00762         //
    00763         // Enumerate all subkeys under the System\CCS\Enum\Root.
    00764         //
    00765
    00766         context.Status = STATUS_SUCCESS;
    00767         context.KeyName = &workName;
    00768
    00769         status = IopApplyFunctionToSubKeys(baseHandle,
    00770                                            NULL,
    00771                                            KEY_ALL_ACCESS,
    00772                                            FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS,
    00773                                            IopInitializeDeviceKey,
    00774                                            &context
    00775                                            );
    00776         ZwClose(baseHandle);
    00777
    00778         //
    00779         // Build returned information from ROOT_ENUMERATOR_CONTEXT.
    00780         //
    00781
    00782
    00783         status = context.Status;
    00784         if (NT_SUCCESS(status) && context.DeviceCount != 0) {
    00785             deviceRelations = (PDEVICE_RELATIONS) ExAllocatePool(
    00786                 PagedPool,
    00787                 sizeof (DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * context.DeviceCount
    00788                 );
    00789             if (deviceRelations == NULL) {
    00790                 status = STATUS_INSUFFICIENT_RESOURCES;
    00791             } else {
    00792                 deviceRelations->Count = context.DeviceCount;
    00793                 RtlMoveMemory(deviceRelations->Objects,
    00794                               context.DeviceList,
    00795                               sizeof (PDEVICE_OBJECT) * context.DeviceCount);
    00796                 *DeviceRelations = deviceRelations;
    00797             }
    00798         }
    00799         if (!NT_SUCCESS(status)) {
    00800
    00801             //
    00802             // If somehow the enumeration failed, we need to derefernece all the
    00803             // device objects.
    00804             //
    00805
    00806             for (i = 0; i < context.DeviceCount; i++) {
    00807                 ObDereferenceObject(context.DeviceList[i]);
    00808             }
    00809         }
    00810     }
    00811     ExReleaseResource(&PpRegistryDeviceResource);
    00812     KeLeaveCriticalRegion();
    00813     ExFreePool(buffer);
    00814     ExFreePool(context.DeviceList);
    00815     return status;
    00816 }

NTSTATUS IopGetServiceType | ( | IN PUNICODE_STRING | KeyName,
|  | IN PULONG | ServiceType
| ) |

Definition at line 1454 of file pnpinit.c.

References ExFreePool(), FALSE, IopGetRegistryValue(), IopOpenServiceEnumKeys(), KEY_VALUE_DATA, KeyName, L, NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopInitializeDeviceInstanceKey().

    01461                    :
    01462
    01463     This routine returns the controlling service's service type of the specified
    01464     Device instance.
    01465
    01466 Arguments:
    01467
    01468     KeyName - supplies a unicode string to specify the device instance.
    01469
    01470     ServiceType - supplies a pointer to a variable to receive the service type.
    01471
    01472 Return Value:
    01473
    01474     NTSTATUS code.
    01475
    01476 --*/
    01477
    01478 {
    01479     NTSTATUS status;
    01480     HANDLE handle;
    01481     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    01482
    01483
    01484     PAGED_CODE();
    01485
    01486     *ServiceType = -1;
    01487     status = IopOpenServiceEnumKeys (
    01488                              KeyName,
    01489                              KEY_READ,
    01490                              &handle,
    01491                              NULL,
    01492                              FALSE
    01493                              );
    01494     if (NT_SUCCESS(status)) {
    01495         status = IopGetRegistryValue(handle, L"Type", &keyValueInformation);
    01496         if (NT_SUCCESS(status)) {
    01497             if (keyValueInformation->Type == REG_DWORD) {
    01498                 if (keyValueInformation->DataLength >= sizeof(ULONG)) {
    01499                     *ServiceType = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01500                 }
    01501             }
    01502             ExFreePool(keyValueInformation);
    01503         }
    01504         ZwClose(handle);
    01505     }
    01506     return status;
    01507 }

BOOLEAN IopInitializeDeviceInstanceKey | ( | IN HANDLE | KeyHandle,
|  | IN PUNICODE_STRING | KeyName,
|  | IN OUT PVOID | Context
| ) |

Definition at line 879 of file pnpinit.c.

References ArbiterRequestPnpEnumerated, ASSERT, _ROOT_ENUMERATOR_CONTEXT::DeviceCount, _ROOT_ENUMERATOR_CONTEXT::DeviceList, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ADDED, DNF_DUPLICATE, DNF_ENUMERATED, DNF_HAS_BOOT_CONFIG, DNF_LEGACY_DRIVER, DNF_MADEUP, DNF_NO_RESOURCE_REQUIRED, DNF_PROCESSED, DNF_STARTED, DO_BUS_ENUMERATED_DEVICE, DOE_START_PENDING, ExAllocatePool, ExFreePool(), _DEVOBJ_EXTENSION::ExtensionFlags, FALSE, _DEVICE_NODE::Flags, _DEVICE_OBJECT::Flags, _DEVICE_NODE::InstancePath, IoCreateDevice(), IoDeleteDevice(), IopAllocateDeviceNode(), IopClearDevNodeProblem, IopConcatenateUnicodeStrings(), IopCreateRegistryKeyEx(), IopDeviceNodeCapabilitiesToRegistry(), IopDeviceNodeFlagsToCapabilities, IopDeviceObjectFromDeviceInstance(), IopDoesDevNodeHaveProblem, IopGetDeviceInstanceCsConfigFlags(), IopGetDeviceResourcesFromRegistry(), IopGetRegistryValue(), IopGetServiceType(), IopInsertTreeDeviceNode(), IopIsDeviceInstanceEnabled(), IopIsDevNodeProblem, IopIsFirmwareMapperDevicePresent(), IopNotifySetupDeviceArrival(), IoPnpDriverObject, IopNumberDeviceNodes, IopProcessCriticalDevice(), IopRegistryDataToUnicodeString, IopRootDeviceNode, IopSetDevNodeProblem, KeQueryTickCount(), KEY_VALUE_DATA, KeyName, L, _ROOT_ENUMERATOR_CONTEXT::MaxDeviceCount, NT_SUCCESS, NTSTATUS(), NULL, ObReferenceObject, PagedPool, PDEVICE_OBJECT, PNP_SCRATCH_BUFFER_SIZE, PpDeviceRegistration(), PROOT_ENUMERATOR_CONTEXT, QUERY_RESOURCE_LIST, REGISTRY_BOOT_CONFIG, RtlAppendStringToString(), RtlInitUnicodeString(), _ROOT_ENUMERATOR_CONTEXT::Status, TITLE_INDEX_VALUE, TRUE, and USHORT.

Referenced by IopInitializeDeviceKey().

    00887                    :
    00888
    00889     This routine is a callback function for IopApplyFunctionToSubKeys.
    00890     It is called for each subkey under HKLM\System\Enum\Root\DeviceKey.
    00891
    00892 Arguments:
    00893
    00894     KeyHandle - Supplies a handle to this key.
    00895
    00896     KeyName - Supplies the name of this key.
    00897
    00898     Context - points to the ROOT_ENUMERATOR_CONTEXT structure.
    00899
    00900 Returns:
    00901
    00902     TRUE to continue the enumeration.
    00903     FALSE to abort it.
    00904
    00905 --*/
    00906 {
    00907     UNICODE_STRING unicodeName, serviceName;
    00908     PKEY_VALUE_FULL_INFORMATION serviceKeyValueInfo;
    00909     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    00910     NTSTATUS status;
    00911     BOOLEAN isDuplicate = FALSE;
    00912     BOOLEAN configuredBySetup;
    00913     ULONG deviceFlags, instance, tmpValue1;
    00914     ULONG legacy;
    00915     USHORT savedLength;
    00916     PUNICODE_STRING pUnicode;
    00917     HANDLE handle;
    00918     PDEVICE_OBJECT deviceObject;
    00919     PDEVICE_NODE deviceNode = NULL;
    00920     PROOT_ENUMERATOR_CONTEXT enumContext = (PROOT_ENUMERATOR_CONTEXT)Context;
    00921     WCHAR buffer[30];
    00922     UNICODE_STRING deviceName;
    00923     USHORT length;
    00924     LARGE_INTEGER tickCount;
    00925
    00926
    00927     //
    00928     // First off, check to see if this is a phantom device instance (i.e.,
    00929     // registry key only).  If so, we want to totally ignore this key and
    00930     // move on to the next one.
    00931     //
    00932     status = IopGetRegistryValue(KeyHandle,
    00933                                  REGSTR_VAL_PHANTOM,
    00934                                  &keyValueInformation);
    00935
    00936     if (NT_SUCCESS(status)) {
    00937         if ((keyValueInformation->Type == REG_DWORD) &&
    00938             (keyValueInformation->DataLength >= sizeof(ULONG))) {
    00939             tmpValue1 = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    00940         } else {
    00941             tmpValue1 = 0;
    00942         }
    00943
    00944         ExFreePool(keyValueInformation);
    00945
    00946         if (tmpValue1) {
    00947             return TRUE;
    00948         }
    00949     }
    00950
    00951     //
    00952     // Since it is highly likely we are going to report another PDO make sure
    00953     // there will be room in the buffer.
    00954     //
    00955
    00956     if (enumContext->DeviceCount == enumContext->MaxDeviceCount) {
    00957
    00958         PDEVICE_OBJECT *tmpDeviceObjectList;
    00959         ULONG tmpDeviceObjectListSize;
    00960
    00961         //
    00962         // We need to grow our PDO list buffer.
    00963         //
    00964
    00965         tmpDeviceObjectListSize = (enumContext->MaxDeviceCount * sizeof(PDEVICE_OBJECT))
    00966                                         + (PNP_SCRATCH_BUFFER_SIZE * 2);
    00967
    00968         tmpDeviceObjectList = ExAllocatePool(PagedPool, tmpDeviceObjectListSize);
    00969
    00970         if (tmpDeviceObjectList) {
    00971
    00972             RtlCopyMemory( tmpDeviceObjectList,
    00973                            enumContext->DeviceList,
    00974                            enumContext->DeviceCount * sizeof(PDEVICE_OBJECT)
    00975                            );
    00976             ExFreePool(enumContext->DeviceList);
    00977             enumContext->DeviceList = tmpDeviceObjectList;
    00978             enumContext->MaxDeviceCount = tmpDeviceObjectListSize / sizeof(PDEVICE_OBJECT);
    00979
    00980         } else {
    00981
    00982             //
    00983             // We are out of memory.  There is no point going any further
    00984             // since we don't have any place to report the PDOs anyways.
    00985             //
    00986
    00987             enumContext->Status = STATUS_INSUFFICIENT_RESOURCES;
    00988
    00989             return FALSE;
    00990         }
    00991     }
    00992
    00993     //
    00994     // Check if the PDO for the device instance key exists already.  If no,
    00995     // see if we need to create it.
    00996     //
    00997
    00998     deviceObject = IopDeviceObjectFromDeviceInstance(KeyHandle, NULL);
    00999
    01000     if (deviceObject != NULL) {
    01001
    01002         enumContext->DeviceList[enumContext->DeviceCount] = deviceObject;
    01003         enumContext->DeviceCount++;
    01004         return TRUE;
    01005     }
    01006
    01007     //
    01008     // We don't have device object for it.
    01009     // First check if this key was created by firmware mapper.  If yes, make sure
    01010     // the device is still present.
    01011     //
    01012
    01013     if (!IopIsFirmwareMapperDevicePresent(KeyHandle)) {
    01014         return TRUE;
    01015     }
    01016
    01017     //
    01018     // Get the "DuplicateOf" value entry to determine if the device instance
    01019     // should be registered.  If the device instance is duplicate, We don't
    01020     // add it to its service key's enum branch.
    01021     //
    01022
    01023     status = IopGetRegistryValue( KeyHandle,
    01024                                   REGSTR_VALUE_DUPLICATEOF,
    01025                                   &keyValueInformation
    01026                                   );
    01027     if (NT_SUCCESS(status)) {
    01028         if (keyValueInformation->Type == REG_SZ &&
    01029             keyValueInformation->DataLength > 0) {
    01030             isDuplicate = TRUE;
    01031         }
    01032
    01033         ExFreePool(keyValueInformation);
    01034     }
    01035
    01036     //
    01037     // Get the "Service=" value entry from KeyHandle
    01038     //
    01039
    01040     serviceKeyValueInfo = NULL;
    01041
    01042     RtlInitUnicodeString(&serviceName, NULL);
    01043
    01044     status = IopGetRegistryValue ( KeyHandle,
    01045                                    REGSTR_VALUE_SERVICE,
    01046                                    &serviceKeyValueInfo
    01047                                    );
    01048     if (NT_SUCCESS(status)) {
    01049
    01050         //
    01051         // Append the new instance to its corresponding
    01052         // Service\Name\Enum.
    01053         //
    01054
    01055         if (serviceKeyValueInfo->Type == REG_SZ &&
    01056             serviceKeyValueInfo->DataLength != 0) {
    01057
    01058             //
    01059             // Set up ServiceKeyName unicode string
    01060             //
    01061
    01062             IopRegistryDataToUnicodeString(
    01063                                 &serviceName,
    01064                                 (PWSTR)KEY_VALUE_DATA(serviceKeyValueInfo),
    01065                                 serviceKeyValueInfo->DataLength
    01066                                 );
    01067         }
    01068
    01069         //
    01070         // Do not Free serviceKeyValueInfo.  It contains Service Name.
    01071         //
    01072
    01073     }
    01074
    01075     //
    01076     // Combine Context->KeyName, i.e. the device name and KeyName (device instance name)
    01077     // to form device instance path and register this device instance by
    01078     // constructing new value entry for ServiceKeyName\Enum key.
    01079     // i.e., <Number> = <PathToSystemEnumBranch>
    01080     //
    01081
    01082     pUnicode = ((PROOT_ENUMERATOR_CONTEXT)Context)->KeyName;
    01083     savedLength = pUnicode->Length;                  // Save WorkName
    01084     if (pUnicode->Buffer[pUnicode->Length / sizeof(WCHAR) - 1] != OBJ_NAME_PATH_SEPARATOR) {
    01085         pUnicode->Buffer[pUnicode->Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
    01086         pUnicode->Length += 2;
    01087     }
    01088
    01089     RtlAppendStringToString((PSTRING)pUnicode, (PSTRING)KeyName);
    01090
    01091     //
    01092     // For the stuff under Root, we need to expose devnodes for everything
    01093     // except those devices whose CsConfigFlags are set to CSCONFIGFLAG_DO_NOT_CREATE.
    01094     //
    01095
    01096     status = IopGetDeviceInstanceCsConfigFlags( pUnicode, &deviceFlags );
    01097
    01098     if (NT_SUCCESS(status) && (deviceFlags & CSCONFIGFLAG_DO_NOT_CREATE)) {
    01099         ExFreePool(serviceKeyValueInfo);
    01100         return TRUE;
    01101     }
    01102
    01103     //
    01104     // Make sure this device instance is really a "device" by checking
    01105     // the "Legacy" value name.
    01106     //
    01107
    01108     legacy = 0;
    01109     status = IopGetRegistryValue( KeyHandle,
    01110                                   REGSTR_VALUE_LEGACY,
    01111                                   &keyValueInformation
    01112                                   );
    01113     if (NT_SUCCESS(status)) {
    01114
    01115         //
    01116         // If "Legacy=" exists ...
    01117         //
    01118
    01119         if (keyValueInformation->Type == REG_DWORD) {
    01120             if (keyValueInformation->DataLength >= sizeof(ULONG)) {
    01121                 legacy = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01122             }
    01123         }
    01124         ExFreePool(keyValueInformation);
    01125     }
    01126
    01127     if (legacy) {
    01128         BOOLEAN doCreate = FALSE;
    01129
    01130         //
    01131         // Check if the the service for the device instance is a kernel mode
    01132         // driver (even though it is a legacy device instance.) If yes, we will
    01133         // create a PDO for it.
    01134         //
    01135
    01136         if (serviceName.Length) {
    01137             status = IopGetServiceType(&serviceName, &tmpValue1);
    01138             if (NT_SUCCESS(status) && tmpValue1 == SERVICE_KERNEL_DRIVER) {
    01139                 doCreate = TRUE;
    01140             }
    01141         }
    01142
    01143         if (!doCreate)  {
    01144
    01145             //
    01146             // We are not creating PDO for the device instance.  In this case we
    01147             // need to register the device ourself for legacy compatibility.
    01148             //
    01149             // Note we will register this device to its driver even it is a
    01150             // duplicate.  It will be deregistered when the real enumerated
    01151             // device shows up.  We need to do this because the driver which
    01152             // controls the device may be a boot driver.
    01153             //
    01154
    01155             PpDeviceRegistration( pUnicode, TRUE, NULL );
    01156
    01157             //
    01158             // We did not create a PDO.  Release the service and ordinal names.
    01159             //
    01160
    01161             if (serviceKeyValueInfo) {
    01162                 ExFreePool(serviceKeyValueInfo);
    01163             }
    01164
    01165             pUnicode->Length = savedLength;         // Restore WorkName
    01166
    01167             return TRUE;
    01168         }
    01169     }
    01170
    01171     if (serviceKeyValueInfo) {
    01172         ExFreePool(serviceKeyValueInfo);
    01173     }
    01174
    01175     //
    01176     // Create madeup PDO and device node to represent the root device.
    01177     //
    01178
    01179     //
    01180     // Madeup a name for the device object.
    01181     //
    01182
    01183     KeQueryTickCount(&tickCount);
    01184
    01185     length = (USHORT) _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"\\Device\\%04u%x",
    01186                         IopNumberDeviceNodes, tickCount.LowPart);
    01187     deviceName.MaximumLength = sizeof(buffer);
    01188     deviceName.Length = length * sizeof(WCHAR);
    01189     deviceName.Buffer = buffer;
    01190
    01191     //
    01192     // Create madeup PDO and device node to represent the root device.
    01193     //
    01194
    01195     status = IoCreateDevice( IoPnpDriverObject,
    01196                              sizeof(IOPNP_DEVICE_EXTENSION),
    01197                              &deviceName,
    01198                              FILE_DEVICE_CONTROLLER,
    01199                              0,
    01200                              FALSE,
    01201                              &deviceObject );
    01202
    01203     if (NT_SUCCESS(status)) {
    01204
    01205         deviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
    01206         deviceObject->DeviceObjectExtension->ExtensionFlags |= DOE_START_PENDING;
    01207
    01208         deviceNode = IopAllocateDeviceNode(deviceObject);
    01209         if (deviceNode) {
    01210             PCM_RESOURCE_LIST cmResource;
    01211
    01212             deviceNode->Flags = DNF_MADEUP + DNF_PROCESSED + DNF_ENUMERATED;
    01213
    01214             IopInsertTreeDeviceNode(IopRootDeviceNode, deviceNode);
    01215
    01216             //
    01217             // Make a copy of the device instance path and save it in
    01218             // device node.
    01219             //
    01220
    01221             status = IopConcatenateUnicodeStrings(
    01222                                 &deviceNode->InstancePath,
    01223                                 pUnicode,
    01224                                 NULL
    01225                                 );
    01226             if (legacy) {
    01227                 deviceNode->Flags |= DNF_LEGACY_DRIVER + DNF_ADDED + DNF_STARTED +
    01228                                         DNF_NO_RESOURCE_REQUIRED;
    01229             } else {
    01230                 //
    01231                 // The device instance key exists.  We need to propagate the ConfigFlag
    01232                 // to problem and StatusFlags
    01233                 //
    01234
    01235                 deviceFlags = 0;
    01236                 status = IopGetRegistryValue(KeyHandle,
    01237                                                 REGSTR_VALUE_CONFIG_FLAGS,
    01238                                                 &keyValueInformation);
    01239                 if (NT_SUCCESS(status)) {
    01240                     if ((keyValueInformation->Type == REG_DWORD) &&
    01241                         (keyValueInformation->DataLength >= sizeof(ULONG))) {
    01242                         deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01243                     }
    01244                     ExFreePool(keyValueInformation);
    01245                     if (deviceFlags & CONFIGFLAG_REINSTALL) {
    01246                         IopSetDevNodeProblem(deviceNode, CM_PROB_REINSTALL);
    01247                     } else if (deviceFlags & CONFIGFLAG_PARTIAL_LOG_CONF) {
    01248                         IopSetDevNodeProblem(deviceNode, CM_PROB_PARTIAL_LOG_CONF);
    01249                     } else if (deviceFlags & CONFIGFLAG_FAILEDINSTALL) {
    01250                         IopSetDevNodeProblem(deviceNode, CM_PROB_FAILED_INSTALL);
    01251                     }
    01252
    01253                 } else if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND) {
    01254                     IopSetDevNodeProblem(deviceNode, CM_PROB_NOT_CONFIGURED);
    01255                 }
    01256             }
    01257
    01258             if (isDuplicate) {
    01259                 deviceNode->Flags |= DNF_DUPLICATE;
    01260             }
    01261
    01262             //
    01263             // If the key say don't assign any resource, honor it...
    01264             //
    01265
    01266             PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_NO_RESOURCE_AT_INIT);
    01267             status = IopGetRegistryValue( KeyHandle,
    01268                                           unicodeName.Buffer,
    01269                                           &keyValueInformation
    01270                                           );
    01271
    01272             if (NT_SUCCESS(status)) {
    01273                 if (keyValueInformation->Type == REG_DWORD) {
    01274                     if (keyValueInformation->DataLength >= sizeof(ULONG)) {
    01275                         tmpValue1 = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01276
    01277                         if (tmpValue1 != 0) {
    01278                             deviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED;
    01279                         }
    01280                     }
    01281                 }
    01282                 ExFreePool(keyValueInformation);
    01283             }
    01284
    01285             //
    01286             // we need to set initial capabilities, like any other device
    01287             // this will also handle hardware-disabled case
    01288             //
    01289             IopDeviceNodeCapabilitiesToRegistry(deviceNode);
    01290
    01291             if (IopDeviceNodeFlagsToCapabilities(deviceNode)->HardwareDisabled &&
    01292                 !IopIsDevNodeProblem(deviceNode,CM_PROB_NOT_CONFIGURED)) {
    01293                 //
    01294                 // mark the node as hardware disabled, if no other problems
    01295                 //
    01296
    01297                 IopClearDevNodeProblem(deviceNode);
    01298                 IopSetDevNodeProblem(deviceNode, CM_PROB_HARDWARE_DISABLED);
    01299                 //
    01300                 // Issue a PNP REMOVE_DEVICE Irp so when we query resources
    01301                 // we have those required after boot
    01302                 //
    01303                 //status = IopRemoveDevice (deviceNode->PhysicalDeviceObject, IRP_MN_REMOVE_DEVICE);
    01304                 //ASSERT(NT_SUCCESS(status));
    01305             }
    01306
    01307             //
    01308             // Install service for critical devices.
    01309             // however don't do it if we found HardwareDisabled to be set
    01310             //
    01311             if (IopDoesDevNodeHaveProblem(deviceNode) &&
    01312                 !IopDeviceNodeFlagsToCapabilities(deviceNode)->HardwareDisabled) {
    01313                 IopProcessCriticalDevice(deviceNode);
    01314             }
    01315
    01316             //
    01317             // Set DNF_DISABLED flag if the device instance is disabled.
    01318             //
    01319
    01320             ASSERT(!IopDoesDevNodeHaveProblem(deviceNode) ||
    01321                     IopIsDevNodeProblem(deviceNode, CM_PROB_NOT_CONFIGURED) ||
    01322                     IopIsDevNodeProblem(deviceNode, CM_PROB_REINSTALL) ||
    01323                     IopIsDevNodeProblem(deviceNode, CM_PROB_FAILED_INSTALL) ||
    01324                     IopIsDevNodeProblem(deviceNode, CM_PROB_HARDWARE_DISABLED) ||
    01325                     IopIsDevNodeProblem(deviceNode, CM_PROB_PARTIAL_LOG_CONF));
    01326
    01327             if (!IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED) &&
    01328                 !IopIsDevNodeProblem(deviceNode, CM_PROB_HARDWARE_DISABLED) &&
    01329                 !IopIsDeviceInstanceEnabled(KeyHandle, &deviceNode->InstancePath, TRUE)) {
    01330
    01331                 //
    01332                 // Normally IopIsDeviceInstanceEnabled would set
    01333                 // CM_PROB_DISABLED as a side effect (if necessary).  But it
    01334                 // relies on the DeviceReference already being in the registry.
    01335                 // We don't write it out till later so just set the problem
    01336                 // now.
    01337
    01338                 IopSetDevNodeProblem( deviceNode, CM_PROB_DISABLED );
    01339             }
    01340
    01341             status = IopNotifySetupDeviceArrival( deviceNode->PhysicalDeviceObject,
    01342                                                   KeyHandle,
    01343                                                   TRUE);
    01344
    01345             configuredBySetup = NT_SUCCESS(status);
    01346
    01347             status = PpDeviceRegistration( &deviceNode->InstancePath,
    01348                                            TRUE,
    01349                                            &deviceNode->ServiceName
    01350                                            );
    01351
    01352             if (NT_SUCCESS(status) && configuredBySetup &&
    01353                 IopIsDevNodeProblem(deviceNode, CM_PROB_NOT_CONFIGURED)) {
    01354
    01355                 IopClearDevNodeProblem(deviceNode);
    01356             }
    01357
    01358             //
    01359             // Write the addr of the device object to registry
    01360             //
    01361
    01362             PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    01363             status = IopCreateRegistryKeyEx( &handle,
    01364                                              KeyHandle,
    01365                                              &unicodeName,
    01366                                              KEY_ALL_ACCESS,
    01367                                              REG_OPTION_VOLATILE,
    01368                                              NULL
    01369                                              );
    01370             if (NT_SUCCESS(status)) {
    01371
    01372                 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DEVICE_REFERENCE);
    01373                 ZwSetValueKey( handle,
    01374                                &unicodeName,
    01375                                TITLE_INDEX_VALUE,
    01376                                REG_DWORD,
    01377                                (PULONG_PTR)&deviceObject,
    01378                                sizeof(ULONG_PTR)
    01379                                );
    01380                 ZwClose(handle);
    01381             }
    01382
    01383             //
    01384             // Add a reference for config magr
    01385             //
    01386
    01387             ObReferenceObject(deviceObject);
    01388
    01389             //
    01390             // Check if this device has BOOT config.  If yes, reserve them
    01391             //
    01392
    01393             cmResource = NULL;
    01394             status = IopGetDeviceResourcesFromRegistry (
    01395                                 deviceObject,
    01396                                 QUERY_RESOURCE_LIST,
    01397                                 REGISTRY_BOOT_CONFIG,
    01398                                 &cmResource,
    01399                                 &tmpValue1
    01400                                 );
    01401
    01402             if (NT_SUCCESS(status) && cmResource) {
    01403
    01404                 //
    01405                 // Still reserve boot config, even though the device is
    01406                 // disabled.
    01407                 //
    01408
    01409                 status = (*IopReserveResourcesRoutine)(
    01410                                         ArbiterRequestPnpEnumerated,
    01411                                         deviceNode->PhysicalDeviceObject,
    01412                                         cmResource);
    01413                 if (NT_SUCCESS(status)) {
    01414                     deviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
    01415                 }
    01416                 ExFreePool(cmResource);
    01417             }
    01418
    01419             status = STATUS_SUCCESS;
    01420
    01421             //
    01422             // Add a reference for query device relations
    01423             //
    01424
    01425             ObReferenceObject(deviceObject);
    01426
    01427         } else {
    01428             IoDeleteDevice(deviceObject);
    01429             deviceObject = NULL;
    01430             status = STATUS_INSUFFICIENT_RESOURCES;
    01431         }
    01432     }
    01433
    01434     pUnicode->Length = savedLength;                  // Restore WorkName
    01435
    01436     //
    01437     // If we enumerated a root device, add it to the device list
    01438     //
    01439
    01440     if (NT_SUCCESS(status)) {
    01441         ASSERT(deviceObject != NULL);
    01442
    01443         enumContext->DeviceList[enumContext->DeviceCount] = deviceObject;
    01444         enumContext->DeviceCount++;
    01445
    01446         return TRUE;
    01447     } else {
    01448         enumContext->Status = status;
    01449         return FALSE;
    01450     }
    01451 }

BOOLEAN IopInitializeDeviceKey | ( | IN HANDLE | KeyHandle,
|  | IN PUNICODE_STRING | KeyName,
|  | IN OUT PVOID | Context
| ) |

Definition at line 819 of file pnpinit.c.

References FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS, IopApplyFunctionToSubKeys(), IopInitializeDeviceInstanceKey(), KeyName, NT_SUCCESS, NULL, PROOT_ENUMERATOR_CONTEXT, RtlAppendStringToString(), Status, and USHORT.

Referenced by IopGetRootDevices().

    00827                    :
    00828
    00829     This routine is a callback function for IopApplyFunctionToSubKeys.
    00830     It is called for each subkey under HKLM\System\CCS\Enum\BusKey.
    00831
    00832 Arguments:
    00833
    00834     KeyHandle - Supplies a handle to this key.
    00835
    00836     KeyName - Supplies the name of this key.
    00837
    00838     Context - points to the ROOT_ENUMERATOR_CONTEXT structure.
    00839
    00840 Returns:
    00841
    00842     TRUE to continue the enumeration.
    00843     FALSE to abort it.
    00844
    00845 --*/
    00846 {
    00847     USHORT length;
    00848     PWSTR p;
    00849     PUNICODE_STRING unicodeName = ((PROOT_ENUMERATOR_CONTEXT)Context)->KeyName;
    00850
    00851     length = unicodeName->Length;
    00852
    00853     p = unicodeName->Buffer;
    00854     if ( unicodeName->Length / sizeof(WCHAR) != 0) {
    00855         p += unicodeName->Length / sizeof(WCHAR);
    00856         *p = OBJ_NAME_PATH_SEPARATOR;
    00857         unicodeName->Length += sizeof (WCHAR);
    00858     }
    00859
    00860     RtlAppendStringToString((PSTRING)unicodeName, (PSTRING)KeyName);
    00861
    00862     //
    00863     // Enumerate all subkeys under the current device key.
    00864     //
    00865
    00866     IopApplyFunctionToSubKeys(KeyHandle,
    00867                               NULL,
    00868                               KEY_ALL_ACCESS,
    00869                               FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS,
    00870                               IopInitializeDeviceInstanceKey,
    00871                               Context
    00872                               );
    00873     unicodeName->Length = length;
    00874
    00875     return NT_SUCCESS(((PROOT_ENUMERATOR_CONTEXT)Context)->Status);
    00876 }

NTSTATUS IopInitializePlugPlayServices | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock,
|  | IN ULONG | Phase
| ) |

Definition at line 93 of file pnpinit.c.

References ASSERT, BUS_TYPE_GUID_LIST, CmRegistryMachineSystemCurrentControlSet, CmRegistryMachineSystemCurrentControlSetEnumName, DNF_ADDED, DNF_ENUMERATED, DNF_MADEUP, DNF_NO_RESOURCE_REQUIRED, DNF_PROCESSED, DNF_STARTED, DO_BUS_ENUMERATED_DEVICE, EisaBuildEisaDeviceNode(), ExAllocatePool, ExFreePool(), ExInitializeFastMutex, ExInitializeResource, FALSE, _DEVICE_OBJECT::Flags, _DEVICE_NODE::Flags, _DEVICE_NODE::InstancePath, IoCreateDevice(), IoCreateDriver(), IoDeleteDevice(), IoDeleteDriver(), IopAllocateDeviceNode(), IopBusNumberInitialize(), IopBusTypeGuidList, IopCreateRegistryKeyEx(), IopDetermineDefaultInterfaceType(), IopDeviceTreeLock, IopDmaInitialize(), IopDockDeviceCount, IopDockDeviceListHead, IopDockDeviceListLock, IopGetRegistryValue(), IopInitializePlugPlayNotification(), IopInitReservedResourceList, IopIrqInitialize(), IopMemInitialize(), IOPNP_DEVICE_EXTENSION, IoPnpDriverObject, IopOpenRegistryKeyEx(), IopPendingEjects, IopPendingSurpriseRemovals, IopPnPDriverEntry(), IopPnpEnumerationRequestList, IopPnpScratchBuffer1, IopPnpScratchBuffer2, IopPnPSpinLock, IopPortInitialize(), IopRequestDeviceAction(), IopReserveBootResources(), IopReserveResourcesRoutine, IopRootDeviceNode, IopWarmEjectLock, IopWarmEjectPdo, KeInitializeEvent, KeInitializeSpinLock(), KEY_VALUE_DATA, _BUS_TYPE_GUID_LIST::Lock, MapperConstructRootEnumTree(), MapperFreeList(), MapperPhantomizeDetectedComPorts(), MapperProcessFirmwareTree(), NT_SUCCESS, NtClose(), NTSTATUS(), NULL, PagedPool, _DEVICE_NODE::PhysicalDeviceObject, PiEnumerationLock, PiEventQueueEmpty, PNP_DETECTION_ENABLED_DEFAULT, PNP_LARGE_SCRATCH_BUFFER_SIZE, PnPBiosMapper(), PnpDefaultInterfaceType, PnPDetectionEnabled, PnPInitialized, PpInitializeNotification(), ReenumerateRootDevices, RtlAddAccessAllowedAceEx(), RtlCreateAcl(), RtlCreateSecurityDescriptor(), RtlInitUnicodeString(), RtlLengthSid(), RtlSetDaclSecurityDescriptor(), RtlValidSecurityDescriptor(), SeLocalSystemSid, SeWorldSid, TRUE, and VOID().

Referenced by IoInitSystem().

    00100                    :
    00101
    00102     This routine initializes kernel mode Plug and Play services.
    00103
    00104 Arguments:
    00105
    00106     LoaderBlock - supplies a pointer to the LoaderBlock passed in from the
    00107         OS Loader.
    00108
    00109 Returns:
    00110
    00111     NTSTATUS code for sucess or reason of failure.
    00112
    00113 --*/
    00114 {
    00115     NTSTATUS status;
    00116     HANDLE hTreeHandle, parentHandle, handle, hCurrentControlSet = NULL;
    00117     UNICODE_STRING unicodeName;
    00118     PKEY_VALUE_FULL_INFORMATION detectionInfo;
    00119     PDEVICE_OBJECT deviceObject;
    00120     ULONG disposition;
    00121
    00122     if (Phase == 0) {
    00123         PnPInitialized = FALSE;
    00124
    00125         //
    00126         // Allocate two one-page scratch buffers to be used by our
    00127         // initialization code.  This avoids constant pool allocations.
    00128         //
    00129
    00130         IopPnpScratchBuffer1 = ExAllocatePool(PagedPool, PNP_LARGE_SCRATCH_BUFFER_SIZE);
    00131         if (!IopPnpScratchBuffer1) {
    00132             return STATUS_INSUFFICIENT_RESOURCES;
    00133         }
    00134         IopPnpScratchBuffer2 = ExAllocatePool(PagedPool, PNP_LARGE_SCRATCH_BUFFER_SIZE);
    00135         if (!IopPnpScratchBuffer2) {
    00136             ExFreePool(IopPnpScratchBuffer1);
    00137             return STATUS_INSUFFICIENT_RESOURCES;
    00138         }
    00139
    00140         IopInitReservedResourceList = NULL;
    00141
    00142         IopReserveResourcesRoutine = IopReserveBootResources;
    00143
    00144         //
    00145         // Determine the PnpDefaultInterfaceType.  For root enumerated devices if the Interface
    00146         // type of their resource list or resource requirements list are undefined.  We will use
    00147         // the default type instead.
    00148         //
    00149
    00150         PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType();
    00151
    00152         //
    00153         // Initialize root arbiters
    00154         //
    00155
    00156         status = IopPortInitialize();
    00157         if (!NT_SUCCESS(status)) {
    00158             goto init_Exit0;
    00159         }
    00160
    00161         status = IopMemInitialize();
    00162         if (!NT_SUCCESS(status)) {
    00163             goto init_Exit0;
    00164         }
    00165
    00166         status = IopDmaInitialize();
    00167         if (!NT_SUCCESS(status)) {
    00168             goto init_Exit0;
    00169         }
    00170
    00171         status = IopIrqInitialize();
    00172         if (!NT_SUCCESS(status)) {
    00173             goto init_Exit0;
    00174         }
    00175
    00176         status = IopBusNumberInitialize();
    00177         if (!NT_SUCCESS(status)) {
    00178             goto init_Exit0;
    00179         }
    00180
    00181         //
    00182         // Next open/create System\CurrentControlSet\Enum\Root key.
    00183         //
    00184
    00185         status = IopOpenRegistryKeyEx( &hCurrentControlSet,
    00186                                        NULL,
    00187                                        &CmRegistryMachineSystemCurrentControlSet,
    00188                                        KEY_ALL_ACCESS
    00189                                        );
    00190         if (!NT_SUCCESS(status)) {
    00191             hCurrentControlSet = NULL;
    00192             goto init_Exit0;
    00193         }
    00194
    00195         PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ENUM);
    00196         status = IopCreateRegistryKeyEx( &handle,
    00197                                          hCurrentControlSet,
    00198                                          &unicodeName,
    00199                                          KEY_ALL_ACCESS,
    00200                                          REG_OPTION_NON_VOLATILE,
    00201                                          &disposition
    00202                                          );
    00203         if (!NT_SUCCESS(status)) {
    00204             goto init_Exit0;
    00205         }
    00206
    00207         if (disposition == REG_CREATED_NEW_KEY) {
    00208             SECURITY_DESCRIPTOR     newSD;
    00209             PACL                    newDacl;
    00210             ULONG                   sizeDacl;
    00211
    00212             status = RtlCreateSecurityDescriptor( &newSD,
    00213                                                   SECURITY_DESCRIPTOR_REVISION );
    00214             ASSERT( NT_SUCCESS( status ) );
    00215
    00216             //
    00217             // calculate the size of the new DACL
    00218             //
    00219             sizeDacl = sizeof(ACL);
    00220             sizeDacl += sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeLocalSystemSid) - sizeof(ULONG);
    00221
    00222 #if ALLOW_WORLD_READ_OF_ENUM
    00223             sizeDacl += sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeWorldSid) - sizeof(ULONG);
    00224 #endif
    00225
    00226             //
    00227             // create and initialize the new DACL
    00228             //
    00229             newDacl = ExAllocatePool(PagedPool, sizeDacl);
    00230
    00231             if (newDacl != NULL) {
    00232
    00233                 status = RtlCreateAcl(newDacl, sizeDacl, ACL_REVISION);
    00234
    00235                 ASSERT( NT_SUCCESS( status ) );
    00236
    00237                 //
    00238                 // Add just the local system full control ace to this new DACL
    00239                 //
    00240                 status = RtlAddAccessAllowedAceEx( newDacl,
    00241                                                    ACL_REVISION,
    00242                                                    CONTAINER_INHERIT_ACE,
    00243                                                    KEY_ALL_ACCESS,
    00244                                                    SeLocalSystemSid
    00245                                                    );
    00246                 ASSERT( NT_SUCCESS( status ) );
    00247
    00248 #if ALLOW_WORLD_READ_OF_ENUM
    00249                 //
    00250                 // Add just the local system full control ace to this new DACL
    00251                 //
    00252                 status = RtlAddAccessAllowedAceEx( newDacl,
    00253                                                    ACL_REVISION,
    00254                                                    CONTAINER_INHERIT_ACE,
    00255                                                    KEY_READ,
    00256                                                    SeWorldSid
    00257                                                    );
    00258                 ASSERT( NT_SUCCESS( status ) );
    00259
    00260 #endif
    00261                 //
    00262                 // Set the new DACL in the absolute security descriptor
    00263                 //
    00264                 status = RtlSetDaclSecurityDescriptor( (PSECURITY_DESCRIPTOR) &newSD,
    00265                                                        TRUE,
    00266                                                        newDacl,
    00267                                                        FALSE
    00268                                                        );
    00269
    00270                 ASSERT( NT_SUCCESS( status ) );
    00271
    00272                 //
    00273                 // validate the new security descriptor
    00274                 //
    00275                 status = RtlValidSecurityDescriptor(&newSD);
    00276
    00277                 ASSERT( NT_SUCCESS( status ) );
    00278
    00279                 status = ZwSetSecurityObject( handle,
    00280                                               DACL_SECURITY_INFORMATION,
    00281                                               &newSD
    00282                                               );
    00283                 if (!NT_SUCCESS(status)) {
    00284
    00285                     KdPrint(("IopInitializePlugPlayServices: ZwSetSecurityObject on Enum key failed, status = %8.8X\n", status));
    00286                 }
    00287
    00288                 ExFreePool(newDacl);
    00289             } else {
    00290
    00291                 KdPrint(("IopInitializePlugPlayServices: ExAllocatePool failed allocating DACL for Enum key\n"));
    00292             }
    00293         }
    00294
    00295         parentHandle = handle;
    00296         PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ROOTENUM);
    00297         status = IopCreateRegistryKeyEx( &handle,
    00298                                          parentHandle,
    00299                                          &unicodeName,
    00300                                          KEY_ALL_ACCESS,
    00301                                          REG_OPTION_NON_VOLATILE,
    00302                                          NULL
    00303                                          );
    00304         NtClose(parentHandle);
    00305         if (!NT_SUCCESS(status)) {
    00306             goto init_Exit0;
    00307         }
    00308         NtClose(handle);
    00309
    00310         //
    00311         // Create the registry entry for the root of the hardware tree (HTREE\ROOT\0).
    00312         //
    00313
    00314         status = IopOpenRegistryKeyEx( &handle,
    00315                                        NULL,
    00316                                        &CmRegistryMachineSystemCurrentControlSetEnumName,
    00317                                        KEY_ALL_ACCESS
    00318                                        );
    00319         if (NT_SUCCESS(status)) {
    00320             PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_ROOT_DEVNODE);
    00321             status = IopCreateRegistryKeyEx( &hTreeHandle,
    00322                                              handle,
    00323                                              &unicodeName,
    00324                                              KEY_ALL_ACCESS,
    00325                                              REG_OPTION_NON_VOLATILE,
    00326                                              NULL
    00327                                              );
    00328             NtClose(handle);
    00329             if (NT_SUCCESS(status)) {
    00330                 NtClose(hTreeHandle);
    00331             }
    00332         }
    00333
    00334         //
    00335         // Before creating device node tree, we need to initialize the device
    00336         // tree lock.
    00337         //
    00338
    00339         InitializeListHead(&IopPendingEjects);
    00340         InitializeListHead(&IopPendingSurpriseRemovals);
    00341         InitializeListHead(&IopPnpEnumerationRequestList);
    00342         ExInitializeResource(&IopDeviceTreeLock);
    00343         KeInitializeEvent(&PiEventQueueEmpty, NotificationEvent, TRUE );
    00344         KeInitializeEvent(&PiEnumerationLock, NotificationEvent, TRUE );
    00345         KeInitializeSpinLock(&IopPnPSpinLock);
    00346
    00347         //
    00348         // Initialize the list of dock devices, and its lock.
    00349         //
    00350         InitializeListHead(&IopDockDeviceListHead);
    00351         ExInitializeFastMutex(&IopDockDeviceListLock);
    00352         IopDockDeviceCount = 0;
    00353
    00354         //
    00355         // Initialize warm docking variables.
    00356         //
    00357         IopWarmEjectPdo = NULL;
    00358         KeInitializeEvent(&IopWarmEjectLock, SynchronizationEvent, TRUE );
    00359
    00360         //
    00361         // Create a PnP manager's driver object to own all the detected PDOs.
    00362         //
    00363
    00364         RtlInitUnicodeString(&unicodeName, PNPMGR_STR_PNP_DRIVER);
    00365         status = IoCreateDriver (&unicodeName, IopPnPDriverEntry);
    00366         if (NT_SUCCESS(status)) {
    00367
    00368             //
    00369             // Create empty device node tree, i.e., only contains only root device node
    00370             //     (No need to initialize Parent, Child and Sibling links.)
    00371
    00372             status = IoCreateDevice( IoPnpDriverObject,
    00373                                      sizeof(IOPNP_DEVICE_EXTENSION),
    00374                                      NULL,
    00375                                      FILE_DEVICE_CONTROLLER,
    00376                                      0,
    00377                                      FALSE,
    00378                                      &deviceObject );
    00379
    00380             if (NT_SUCCESS(status)) {
    00381                 deviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
    00382                 IopRootDeviceNode = IopAllocateDeviceNode(deviceObject);
    00383
    00384                 if (!IopRootDeviceNode) {
    00385                     IoDeleteDevice(deviceObject);
    00386                     IoDeleteDriver(IoPnpDriverObject);
    00387                     status = STATUS_INSUFFICIENT_RESOURCES;
    00388                 } else {
    00389                     IopRootDeviceNode->Flags |= DNF_STARTED + DNF_PROCESSED + DNF_ENUMERATED +
    00390                                                 DNF_MADEUP + DNF_NO_RESOURCE_REQUIRED +
    00391                                                 DNF_ADDED;
    00392
    00393                     IopRootDeviceNode->InstancePath.Buffer = ExAllocatePool( PagedPool,
    00394                                                                              sizeof(REGSTR_VAL_ROOT_DEVNODE));
    00395
    00396                     if (IopRootDeviceNode->InstancePath.Buffer != NULL) {
    00397                         IopRootDeviceNode->InstancePath.MaximumLength = sizeof(REGSTR_VAL_ROOT_DEVNODE);
    00398                         IopRootDeviceNode->InstancePath.Length = sizeof(REGSTR_VAL_ROOT_DEVNODE) - sizeof(WCHAR);
    00399
    00400                         RtlMoveMemory( IopRootDeviceNode->InstancePath.Buffer,
    00401                                        REGSTR_VAL_ROOT_DEVNODE,
    00402                                        sizeof(REGSTR_VAL_ROOT_DEVNODE));
    00403                     } else {
    00404                         //
    00405                         // BUGBUG - Need to bugcheck here
    00406                         //
    00407
    00408                         ASSERT(FALSE);
    00409                     }
    00410                 }
    00411             }
    00412         }
    00413
    00414         if (!NT_SUCCESS(status)) {
    00415             goto init_Exit0;
    00416         }
    00417
    00418         //
    00419         // Initialize PnPDetectionEnabled flag to determine should Wdm driver be loaded
    00420         // to run detection code.
    00421         // This is stored as a REG_DWORD under HKLM\System\CurrentControlSet\Control\Pnp\DetectionEnabled
    00422         // if it is not present then PNP_DETECTION_ENABLED_DEFAULT is used
    00423         //
    00424
    00425         //
    00426         // Open HKLM\System\CurrentControlSet\Control\Pnp
    00427         //
    00428
    00429         PiWstrToUnicodeString(&unicodeName, REGSTR_PATH_CONTROL_PNP);
    00430         status = IopCreateRegistryKeyEx( &handle,
    00431                                          hCurrentControlSet,
    00432                                          &unicodeName,
    00433                                          KEY_ALL_ACCESS,
    00434                                          REG_OPTION_NON_VOLATILE,
    00435                                          NULL
    00436                                          );
    00437         if (!NT_SUCCESS(status)) {
    00438             goto init_Exit0;
    00439         }
    00440
    00441         //
    00442         // Get the value of DetectionEnabled key if it exisit otherwise use the default
    00443         //
    00444
    00445         PnPDetectionEnabled = PNP_DETECTION_ENABLED_DEFAULT;
    00446
    00447         status = IopGetRegistryValue(handle,
    00448                                      REGSTR_VALUE_DETECTION_ENABLED,
    00449                                      &detectionInfo
    00450                                      );
    00451
    00452         if (NT_SUCCESS(status)) {
    00453
    00454             if (detectionInfo->Type == REG_DWORD && detectionInfo->DataLength == sizeof(ULONG)) {
    00455                 PnPDetectionEnabled = (BOOLEAN) *(KEY_VALUE_DATA(detectionInfo));
    00456             }
    00457
    00458             ExFreePool(detectionInfo);
    00459         }
    00460
    00461         NtClose(handle);
    00462
    00463         //
    00464         // Initialize the kernel mode pnp notification system
    00465         //
    00466
    00467         status = PpInitializeNotification();
    00468         if (!NT_SUCCESS(status)) {
    00469             goto init_Exit0;
    00470         }
    00471
    00472         IopInitializePlugPlayNotification();
    00473
    00474         //
    00475         // Initialize table for holding bus type guid list.
    00476         //
    00477
    00478         IopBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(BUS_TYPE_GUID_LIST));
    00479         if (IopBusTypeGuidList == NULL) {
    00480             status = STATUS_INSUFFICIENT_RESOURCES;
    00481             goto init_Exit0;
    00482         }
    00483
    00484         RtlZeroMemory( IopBusTypeGuidList, sizeof(BUS_TYPE_GUID_LIST));
    00485
    00486         ExInitializeFastMutex(&IopBusTypeGuidList->Lock);
    00487
    00488         //
    00489         // Enumerate the ROOT bus synchronously.
    00490         //
    00491
    00492         IopRequestDeviceAction(IopRootDeviceNode->PhysicalDeviceObject, ReenumerateRootDevices, NULL, NULL);
    00493
    00494 init_Exit0:
    00495
    00496         //
    00497         // If we managed to open the Current Control Set close it
    00498         //
    00499
    00500         if(hCurrentControlSet) {
    00501             NtClose(hCurrentControlSet);
    00502         }
    00503
    00504         if (!NT_SUCCESS(status)) {
    00505             ExFreePool(IopPnpScratchBuffer1);
    00506             ExFreePool(IopPnpScratchBuffer2);
    00507         }
    00508
    00509     } else if (Phase == 1) {
    00510
    00511         BOOLEAN legacySerialPortMappingOnly = FALSE;
    00512
    00513         //
    00514         // Next open/create System\CurrentControlSet\Enum\Root key.
    00515         //
    00516
    00517         status = IopOpenRegistryKeyEx( &hCurrentControlSet,
    00518                                        NULL,
    00519                                        &CmRegistryMachineSystemCurrentControlSet,
    00520                                        KEY_ALL_ACCESS
    00521                                        );
    00522         if (!NT_SUCCESS(status)) {
    00523             hCurrentControlSet = NULL;
    00524             goto init_Exit1;
    00525         }
    00526
    00527         //
    00528         // Open HKLM\System\CurrentControlSet\Control\Pnp
    00529         //
    00530
    00531         PiWstrToUnicodeString(&unicodeName, REGSTR_PATH_CONTROL_PNP);
    00532         status = IopCreateRegistryKeyEx( &handle,
    00533                                          hCurrentControlSet,
    00534                                          &unicodeName,
    00535                                          KEY_ALL_ACCESS,
    00536                                          REG_OPTION_NON_VOLATILE,
    00537                                          NULL
    00538                                          );
    00539         if (!NT_SUCCESS(status)) {
    00540             goto init_Exit1;
    00541         }
    00542
    00543         //
    00544         // Check the "DisableFirmwareMapper" value entry to see whether we
    00545         // should skip mapping ntdetect/firmware reported devices (except for
    00546         // COM ports, which we always map).
    00547         //
    00548
    00549         status = IopGetRegistryValue(handle,
    00550                                      REGSTR_VALUE_DISABLE_FIRMWARE_MAPPER,
    00551                                      &detectionInfo
    00552                                      );
    00553
    00554         if (NT_SUCCESS(status)) {
    00555
    00556             if (detectionInfo->Type == REG_DWORD && detectionInfo->DataLength == sizeof(ULONG)) {
    00557                 legacySerialPortMappingOnly = (BOOLEAN) *(KEY_VALUE_DATA(detectionInfo));
    00558             }
    00559
    00560             ExFreePool(detectionInfo);
    00561
    00562         }
    00563         NtClose(handle);
    00564
    00565         //
    00566         // Collect the necessary firmware tree information.
    00567         //
    00568
    00569         MapperProcessFirmwareTree(legacySerialPortMappingOnly);
    00570
    00571         //
    00572         // Map this into the root enumerator tree
    00573         //
    00574
    00575         MapperConstructRootEnumTree(legacySerialPortMappingOnly);
    00576
    00577 #if i386
    00578         if (!legacySerialPortMappingOnly) {
    00579
    00580             //
    00581             // Now do the PnP BIOS enumerated devnodes.
    00582             //
    00583             extern NTSTATUS PnPBiosMapper(VOID);
    00584
    00585             status = PnPBiosMapper();
    00586
    00587             //
    00588             // If the previous call succeeds, we have a PNPBios, turn any newly
    00589             // created ntdetect COM ports into phantoms
    00590             //
    00591             if (NT_SUCCESS (status)) {
    00592                 MapperPhantomizeDetectedComPorts();
    00593             }
    00594         }
    00595         EisaBuildEisaDeviceNode();
    00596 #endif
    00597
    00598         //
    00599         // We're done with the firmware mapper device list.
    00600         //
    00601
    00602         MapperFreeList();
    00603
    00604
    00605         //
    00606         // Enumerate the ROOT bus synchronously.
    00607         //
    00608
    00609         IopRequestDeviceAction(IopRootDeviceNode->PhysicalDeviceObject, ReenumerateRootDevices, NULL, NULL);
    00610
    00611 init_Exit1:
    00612
    00613         //
    00614         // If we managed to open the Current Control Set close it
    00615         //
    00616
    00617         if(hCurrentControlSet) {
    00618             NtClose(hCurrentControlSet);
    00619         }
    00620
    00621         //
    00622         // Free our scratch buffers and exit.
    00623         //
    00624
    00625         ExFreePool(IopPnpScratchBuffer1);
    00626         ExFreePool(IopPnpScratchBuffer2);
    00627         status = STATUS_SUCCESS;
    00628     } else {
    00629         status = STATUS_INVALID_PARAMETER_1;
    00630     }
    00631
    00632     return status;
    00633 }

BOOLEAN IopIsFirmwareMapperDevicePresent | ( | IN HANDLE | KeyHandle | ) |

Definition at line 1572 of file pnpinit.c.

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

Referenced by IopInitializeDeviceInstanceKey().

    01578                    :
    01579
    01580     This routine checks if the registry key is created by FirmwareMapper.
    01581     If Yes, it further checks if the device for the key is present in this
    01582     boot.
    01583
    01584 Parameters:
    01585
    01586     KeyHandle - Specifies a handle to the registry key to be checked.
    01587
    01588 Return Value:
    01589
    01590     A BOOLEAN vaStatus code that indicates whether or not the function was successful.
    01591
    01592 --*/
    01593 {
    01594     NTSTATUS status;
    01595     HANDLE handle;
    01596     UNICODE_STRING unicodeName;
    01597     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    01598     ULONG tmp = 0;
    01599
    01600     PAGED_CODE();
    01601
    01602     //
    01603     // First check to see if this device instance key is a firmware-created one
    01604     //
    01605
    01606     status = IopGetRegistryValue (KeyHandle,
    01607                                   REGSTR_VAL_FIRMWAREIDENTIFIED,
    01608                                   &keyValueInformation);
    01609     if (NT_SUCCESS(status)) {
    01610         if ((keyValueInformation->Type == REG_DWORD) &&
    01611             (keyValueInformation->DataLength == sizeof(ULONG))) {
    01612
    01613             tmp = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01614         }
    01615         ExFreePool(keyValueInformation);
    01616     }
    01617     if (tmp == 0) {
    01618         return TRUE;
    01619     }
    01620
    01621     //
    01622     // Make sure the device is present.
    01623     //
    01624
    01625     PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    01626     status = IopOpenRegistryKeyEx( &handle,
    01627                                    KeyHandle,
    01628                                    &unicodeName,
    01629                                    KEY_READ
    01630                                    );
    01631     if (!NT_SUCCESS(status)) {
    01632         return FALSE;
    01633     }
    01634
    01635     status = IopGetRegistryValue (handle,
    01636                                   REGSTR_VAL_FIRMWAREMEMBER,
    01637                                   &keyValueInformation);
    01638     ZwClose(handle);
    01639     tmp = 0;
    01640
    01641     if (NT_SUCCESS(status)) {
    01642         if ((keyValueInformation->Type == REG_DWORD) &&
    01643             (keyValueInformation->DataLength == sizeof(ULONG))) {
    01644
    01645             tmp = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01646         }
    01647         ExFreePool(keyValueInformation);
    01648     }
    01649     if (!tmp) {
    01650         return FALSE;
    01651     } else {
    01652         return TRUE;
    01653     }
    01654 }

NTSTATUS IopPnPDriverEntry | ( | IN PDRIVER_OBJECT | DriverObject,
|  | IN PUNICODE_STRING | RegistryPath
| ) |

Definition at line 636 of file pnpinit.c.

References _DRIVER_EXTENSION::AddDevice, _DRIVER_OBJECT::DriverExtension, IoPnpDriverObject, IopPnPAddDevice(), IopPnPDispatch(), IopPowerDispatch(), IRP_MJ_PNP, IRP_MJ_POWER, and PDRIVER_ADD_DEVICE.

Referenced by IopInitializePlugPlayServices().

    00643                    :
    00644
    00645     This is the callback function when we call IoCreateDriver to create a
    00646     PnP Driver Object.  In this function, we need to remember the DriverObject.
    00647
    00648 Arguments:
    00649
    00650     DriverObject - Pointer to the driver object created by the system.
    00651
    00652     RegistryPath - is NULL.
    00653
    00654 Return Value:
    00655
    00656    STATUS_SUCCESS
    00657
    00658 --*/
    00659
    00660 {
    00661     //
    00662     // File the pointer to our driver object away
    00663     //
    00664
    00665     IoPnpDriverObject = DriverObject;
    00666
    00667     //
    00668     // Fill in the driver object
    00669     //
    00670
    00671     DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)IopPnPAddDevice;
    00672     DriverObject->MajorFunction[ IRP_MJ_PNP ] = IopPnPDispatch;
    00673     DriverObject->MajorFunction[ IRP_MJ_POWER ] = IopPowerDispatch;
    00674
    00675     return STATUS_SUCCESS;
    00676
    00677 }