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_CONTEXTPROOT_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 }


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