mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Enumerate legacy devices
svn path=/trunk/; revision=2254
This commit is contained in:
parent
9baaca2418
commit
09237b9213
13 changed files with 1705 additions and 258 deletions
|
@ -11,7 +11,7 @@ include $(PATH_TO_TOP)/rules.mak
|
|||
#
|
||||
COMPONENTS = iface_native iface_additional hallib ntoskrnl
|
||||
HALS = halx86
|
||||
BUS = acpi isapnp
|
||||
BUS = acpi isapnp pci
|
||||
DLLS = ntdll kernel32 advapi32 crtdll msvcrt fmifs gdi32 msafd \
|
||||
user32 oleaut32 secur32 shell32 ws2_32 version
|
||||
SUBSYS = smss win32k csrss
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef _INCLUDE_DDK_IOFUNCS_H
|
||||
#define _INCLUDE_DDK_IOFUNCS_H
|
||||
/* $Id: iofuncs.h,v 1.25 2001/09/05 09:21:09 ekohl Exp $ */
|
||||
/* $Id: iofuncs.h,v 1.26 2001/09/16 13:19:31 chorns Exp $ */
|
||||
|
||||
/* --- EXPORTED BY NTOSKRNL --- */
|
||||
|
||||
|
@ -625,6 +625,10 @@ IoGetConfigurationInformation (
|
|||
((Irp)->Tail.Overlay.CurrentStackLocation)
|
||||
*/
|
||||
|
||||
#define IoSetNextIrpStackLocation(Irp) { \
|
||||
(Irp)->CurrentLocation--; \
|
||||
(Irp)->Tail.Overlay.CurrentStackLocation--; }
|
||||
|
||||
#define IoCopyCurrentIrpStackLocationToNext(Irp) { \
|
||||
PIO_STACK_LOCATION IrpSp; \
|
||||
PIO_STACK_LOCATION NextIrpSp; \
|
||||
|
@ -634,6 +638,10 @@ IoGetConfigurationInformation (
|
|||
FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
|
||||
NextIrpSp->Control = 0; }
|
||||
|
||||
#define IoSkipCurrentIrpStackLocation(Irp) \
|
||||
(Irp)->CurrentLocation++; \
|
||||
(Irp)->Tail.Overlay.CurrentStackLocation++;
|
||||
|
||||
struct _EPROCESS*
|
||||
STDCALL
|
||||
IoGetCurrentProcess (
|
||||
|
|
|
@ -25,6 +25,7 @@ copy services\fs\ms\msfs.sys %ROS_INSTALL%\system32\drivers
|
|||
copy services\fs\np\npfs.sys %ROS_INSTALL%\system32\drivers
|
||||
copy services\bus\acpi\acpi.sys %ROS_INSTALL%\system32\drivers
|
||||
copy services\bus\isapnp\isapnp.sys %ROS_INSTALL%\system32\drivers
|
||||
copy services\bus\pci\pci.sys %ROS_INSTALL%\system32\drivers
|
||||
copy services\dd\ide\ide.sys %ROS_INSTALL%\system32\drivers
|
||||
copy services\dd\floppy\floppy.sys %ROS_INSTALL%\system32\drivers
|
||||
copy services\input\keyboard\keyboard.sys %ROS_INSTALL%\system32\drivers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: registry.c,v 1.7 2001/09/01 15:36:43 chorns Exp $
|
||||
/* $Id: registry.c,v 1.8 2001/09/16 13:19:31 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -582,7 +582,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
|
|||
|
||||
}
|
||||
|
||||
if (Path[0] != L'\\')
|
||||
if ((RelativeTo == RTL_REGISTRY_ABSOLUTE) || (Path[0] != L'\\'))
|
||||
{
|
||||
RtlAppendUnicodeToString(&KeyName,
|
||||
Path);
|
||||
|
|
|
@ -210,6 +210,7 @@ NtEnumerateKey (
|
|||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -223,6 +224,7 @@ NtEnumerateKey (
|
|||
if (RegistryFile == CmiVolatileFile)
|
||||
{
|
||||
ObDereferenceObject (KeyObject);
|
||||
DPRINT("No more volatile entries\n");
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
else
|
||||
|
@ -241,6 +243,7 @@ NtEnumerateKey (
|
|||
if(Index >= KeyBlock->NumberOfSubKeys)
|
||||
{
|
||||
ObDereferenceObject (KeyObject);
|
||||
DPRINT("No more non-volatile entries\n");
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
SubKeyBlock = CurKey->KeyBlock;
|
||||
|
@ -256,6 +259,7 @@ NtEnumerateKey (
|
|||
if (SubKeyBlock == NULL)
|
||||
{
|
||||
ObDereferenceObject (KeyObject);
|
||||
DPRINT("No more entries\n");
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
|
@ -364,6 +368,8 @@ NtEnumerateKey (
|
|||
CmiReleaseBlock(RegistryFile, SubKeyBlock);
|
||||
ObDereferenceObject (KeyObject);
|
||||
|
||||
DPRINT("Returning status %x\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,12 +126,12 @@ CmiCreateRegistry(PWSTR Filename)
|
|||
DWORD FreeOffset;
|
||||
int i, j;
|
||||
BLOCK_OFFSET BlockOffset;
|
||||
DPRINT1("CmiCreateRegistry() Filename '%S'\n", Filename);
|
||||
DPRINT("CmiCreateRegistry() Filename '%S'\n", Filename);
|
||||
RegistryFile = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_FILE));
|
||||
CHECKPOINT1;
|
||||
|
||||
if (RegistryFile == NULL)
|
||||
return NULL;
|
||||
CHECKPOINT1;
|
||||
|
||||
if (Filename != NULL)
|
||||
{
|
||||
UNICODE_STRING TmpFileName;
|
||||
|
@ -219,7 +219,7 @@ CHECKPOINT1;
|
|||
if (RegistryFile->BlockList[0] == NULL)
|
||||
{
|
||||
// Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
DPRINT1("error allocating %d bytes for registry\n"
|
||||
DPRINT("error allocating %d bytes for registry\n"
|
||||
,RegistryFile->FileSize-4096);
|
||||
ZwClose(FileHandle);
|
||||
return NULL;
|
||||
|
@ -232,7 +232,7 @@ CHECKPOINT1;
|
|||
ZwClose(FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("error %x reading registry file at offset %x\n"
|
||||
DPRINT("error %x reading registry file at offset %x\n"
|
||||
,Status,fileOffset.u.LowPart);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ CHECKPOINT1;
|
|||
tmpHeap = (PHEAP_BLOCK)(((char *)RegistryFile->BlockList [0])+BlockOffset);
|
||||
if (tmpHeap->BlockId != REG_HEAP_ID )
|
||||
{
|
||||
DPRINT1("bad BlockId %x,offset %x\n",tmpHeap->BlockId,fileOffset.u.LowPart);
|
||||
DPRINT("bad BlockId %x,offset %x\n",tmpHeap->BlockId,fileOffset.u.LowPart);
|
||||
}
|
||||
RegistryFile->BlockList [i]
|
||||
= tmpHeap;
|
||||
|
|
|
@ -398,7 +398,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
|
|||
break;
|
||||
}
|
||||
|
||||
if (Path[0] != L'\\')
|
||||
if ((RelativeTo == RTL_REGISTRY_ABSOLUTE) || (Path[0] != L'\\'))
|
||||
{
|
||||
RtlAppendUnicodeToString(&KeyName,
|
||||
Path);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: io.h,v 1.13 2001/09/01 15:36:44 chorns Exp $
|
||||
/* $Id: io.h,v 1.14 2001/09/16 13:19:31 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -44,7 +44,7 @@ typedef struct _DEVICE_NODE
|
|||
UNICODE_STRING InstancePath;
|
||||
UNICODE_STRING ServiceName;
|
||||
//TargetDeviceNotifyList?
|
||||
DEVICE_CAPABILITIES CapabilityFlags;
|
||||
PDEVICE_CAPABILITIES CapabilityFlags;
|
||||
ULONG Flags;
|
||||
ULONG UserFlags;
|
||||
ULONG DisableableDepends;
|
||||
|
@ -52,6 +52,14 @@ typedef struct _DEVICE_NODE
|
|||
PCM_RESOURCE_LIST CmResourceList;
|
||||
PCM_RESOURCE_LIST BootResourcesList;
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
|
||||
/* Not NT's */
|
||||
UNICODE_STRING DeviceID;
|
||||
UNICODE_STRING InstanceID;
|
||||
UNICODE_STRING HardwareIDs;
|
||||
UNICODE_STRING CompatibleIDs;
|
||||
UNICODE_STRING DeviceText;
|
||||
UNICODE_STRING DeviceTextLocation;
|
||||
PPNP_BUS_INFORMATION BusInformation;
|
||||
} DEVICE_NODE, *PDEVICE_NODE;
|
||||
|
||||
/* For Flags field */
|
||||
|
@ -103,6 +111,121 @@ typedef struct _DEVICE_NODE
|
|||
#define CM_PROB_FAILED_INSTALL 28
|
||||
#define CM_PROB_FAILED_ADD 31
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopDeviceNodeSetFlag(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG Flag);
|
||||
*/
|
||||
#define IopDeviceNodeSetFlag(DeviceNode, Flag)((DeviceNode)->Flags |= (Flag))
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopDeviceNodeClearFlag(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG Flag);
|
||||
*/
|
||||
#define IopDeviceNodeClearFlag(DeviceNode, Flag)((DeviceNode)->Flags &= ~(Flag))
|
||||
|
||||
/*
|
||||
* BOOLEAN
|
||||
* IopDeviceNodeHasFlag(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG Flag);
|
||||
*/
|
||||
#define IopDeviceNodeHasFlag(DeviceNode, Flag)(((DeviceNode)->Flags & (Flag)) > 0)
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopDeviceNodeSetUserFlag(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG UserFlag);
|
||||
*/
|
||||
#define IopDeviceNodeSetUserFlag(DeviceNode, UserFlag)((DeviceNode)->UserFlags |= (UserFlag))
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopDeviceNodeClearUserFlag(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG UserFlag);
|
||||
*/
|
||||
#define IopDeviceNodeClearUserFlag(DeviceNode, UserFlag)((DeviceNode)->UserFlags &= ~(UserFlag))
|
||||
|
||||
/*
|
||||
* BOOLEAN
|
||||
* IopDeviceNodeHasUserFlag(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG UserFlag);
|
||||
*/
|
||||
#define IopDeviceNodeHasUserFlag(DeviceNode, UserFlag)(((DeviceNode)->UserFlags & (UserFlag)) > 0)
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopDeviceNodeSetProblem(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG Problem);
|
||||
*/
|
||||
#define IopDeviceNodeSetProblem(DeviceNode, Problem)((DeviceNode)->Problem |= (Problem))
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopDeviceNodeClearProblem(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG Problem);
|
||||
*/
|
||||
#define IopDeviceNodeClearProblem(DeviceNode, Problem)((DeviceNode)->Problem &= ~(Problem))
|
||||
|
||||
/*
|
||||
* BOOLEAN
|
||||
* IopDeviceNodeHasProblem(
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* ULONG Problem);
|
||||
*/
|
||||
#define IopDeviceNodeHasProblem(DeviceNode, Problem)(((DeviceNode)->Problem & (Problem)) > 0)
|
||||
|
||||
|
||||
/*
|
||||
Called on every visit of a node during a preorder-traversal of the device
|
||||
node tree.
|
||||
If the routine returns STATUS_UNSUCCESSFUL the traversal will stop and
|
||||
STATUS_SUCCESS is returned to the caller who initiated the tree traversal.
|
||||
Any other returned status code will be returned to the caller. If a status
|
||||
code that indicates an error (other than STATUS_UNSUCCESSFUL) is returned,
|
||||
the traversal is stopped immediately and the status code is returned to
|
||||
the caller.
|
||||
*/
|
||||
typedef NTSTATUS (*DEVICETREE_TRAVERSE_ROUTINE)(
|
||||
PDEVICE_NODE DeviceNode,
|
||||
PVOID Context);
|
||||
|
||||
/* Context information for traversing the device tree */
|
||||
typedef struct _DEVICETREE_TRAVERSE_CONTEXT
|
||||
{
|
||||
/* Current device node during a traversal */
|
||||
PDEVICE_NODE DeviceNode;
|
||||
/* Initial device node where we start the traversal */
|
||||
PDEVICE_NODE FirstDeviceNode;
|
||||
/* Action routine to be called for every device node */
|
||||
DEVICETREE_TRAVERSE_ROUTINE Action;
|
||||
/* Context passed to the action routine */
|
||||
PVOID Context;
|
||||
} DEVICETREE_TRAVERSE_CONTEXT, *PDEVICETREE_TRAVERSE_CONTEXT;
|
||||
|
||||
/*
|
||||
* VOID
|
||||
* IopInitDeviceTreeTraverseContext(
|
||||
* PDEVICETREE_TRAVERSE_CONTEXT DeviceTreeTraverseContext,
|
||||
* PDEVICE_NODE DeviceNode,
|
||||
* DEVICETREE_TRAVERSE_ROUTINE Action,
|
||||
* PVOID Context);
|
||||
*/
|
||||
#define IopInitDeviceTreeTraverseContext( \
|
||||
_DeviceTreeTraverseContext, _DeviceNode, _Action, _Context) { \
|
||||
(_DeviceTreeTraverseContext)->FirstDeviceNode = (_DeviceNode); \
|
||||
(_DeviceTreeTraverseContext)->Action = (_Action); \
|
||||
(_DeviceTreeTraverseContext)->Context = (_Context); }
|
||||
|
||||
|
||||
extern PDEVICE_NODE IopRootDeviceNode;
|
||||
|
||||
extern POBJECT_TYPE IoSymbolicLinkType;
|
||||
|
@ -110,15 +233,6 @@ extern POBJECT_TYPE IoSymbolicLinkType;
|
|||
VOID
|
||||
PnpInit(VOID);
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootDriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath);
|
||||
NTSTATUS
|
||||
PnpRootCreateDevice(
|
||||
PDEVICE_OBJECT *PhysicalDeviceObject);
|
||||
|
||||
NTSTATUS
|
||||
IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject);
|
||||
NTSTATUS
|
||||
|
@ -129,7 +243,7 @@ NTSTATUS
|
|||
IopFreeDeviceNode(PDEVICE_NODE DeviceNode);
|
||||
NTSTATUS
|
||||
IopInterrogateBusExtender(PDEVICE_NODE DeviceNode,
|
||||
PDEVICE_OBJECT FunctionDeviceObject,
|
||||
PDEVICE_OBJECT Pdo,
|
||||
BOOLEAN BootDriversOnly);
|
||||
VOID
|
||||
IopLoadBootStartDrivers(VOID);
|
||||
|
@ -203,4 +317,23 @@ IopInitiatePnpIrp(
|
|||
ULONG MinorFunction,
|
||||
PIO_STACK_LOCATION Stack);
|
||||
|
||||
BOOLEAN
|
||||
IopCreateUnicodeString(
|
||||
PUNICODE_STRING Destination,
|
||||
PWSTR Source,
|
||||
POOL_TYPE PoolType);
|
||||
|
||||
|
||||
/* pnproot.c */
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootDriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath);
|
||||
|
||||
NTSTATUS
|
||||
PnpRootCreateDevice(
|
||||
PDEVICE_OBJECT *PhysicalDeviceObject);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: device.c,v 1.33 2001/09/01 15:36:44 chorns Exp $
|
||||
/* $Id: device.c,v 1.34 2001/09/16 13:19:32 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -358,17 +358,18 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
|
|||
DriverObject, DeviceNode->Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(DriverObject->DriverExtension);
|
||||
ExFreePool(DriverObject);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
|
||||
|
||||
DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
|
||||
|
||||
Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo);
|
||||
|
||||
if (Fdo == DeviceNode->Pdo)
|
||||
{
|
||||
/* FIXME: What do we do? Unload the driver? */
|
||||
/* FIXME: What do we do? Unload the driver or just disable the device? */
|
||||
DbgPrint("An FDO was not attached\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
@ -386,8 +387,6 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
|
|||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed\n");
|
||||
ObDereferenceObject(Fdo);
|
||||
ExFreePool(DriverObject->DriverExtension);
|
||||
ExFreePool(DriverObject);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
@ -400,8 +399,6 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(Fdo);
|
||||
ExFreePool(DriverObject->DriverExtension);
|
||||
ExFreePool(DriverObject);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
|
@ -456,7 +453,9 @@ IopInitializeService(
|
|||
|
||||
ObDereferenceObject(ModuleObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
Status = IopInitializeDevice(DeviceNode, TRUE);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -515,6 +514,8 @@ IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
|
|||
/*
|
||||
* FUNCTION: Called to initalize a loaded driver
|
||||
* ARGUMENTS:
|
||||
* DriverEntry = Pointer to driver entry routine
|
||||
* DeviceNode = Pointer to device node
|
||||
*/
|
||||
{
|
||||
WCHAR RegistryKeyBuffer[MAX_PATH];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pnpmgr.c,v 1.3 2001/09/01 15:36:44 chorns Exp $
|
||||
/* $Id: pnpmgr.c,v 1.4 2001/09/16 13:19:32 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -15,6 +15,7 @@
|
|||
#include <internal/io.h>
|
||||
#include <internal/po.h>
|
||||
#include <internal/ldr.h>
|
||||
#include <internal/registry.h>
|
||||
#include <internal/module.h>
|
||||
|
||||
#define NDEBUG
|
||||
|
@ -248,6 +249,38 @@ IoUnregisterPlugPlayNotification(
|
|||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IopCreateUnicodeString(
|
||||
PUNICODE_STRING Destination,
|
||||
PWSTR Source,
|
||||
POOL_TYPE PoolType)
|
||||
{
|
||||
ULONG Length;
|
||||
|
||||
if (!Source)
|
||||
{
|
||||
RtlInitUnicodeString(Destination, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Length = (wcslen(Source) + 1) * sizeof(WCHAR);
|
||||
|
||||
Destination->Buffer = ExAllocatePool(PoolType, Length);
|
||||
|
||||
if (Destination->Buffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(Destination->Buffer, Source, Length);
|
||||
|
||||
Destination->MaximumLength = Length;
|
||||
|
||||
Destination->Length = Length - sizeof(WCHAR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject)
|
||||
{
|
||||
|
@ -304,6 +337,10 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
|||
ExFreePool(Node);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* This is for drivers passed on the command line to ntoskrnl.exe */
|
||||
IopDeviceNodeSetFlag(Node, DNF_STARTED);
|
||||
IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER);
|
||||
}
|
||||
|
||||
Node->Pdo = PhysicalDeviceObject;
|
||||
|
@ -362,7 +399,42 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
|
|||
|
||||
RtlFreeUnicodeString(&DeviceNode->ServiceName);
|
||||
|
||||
/* FIXME: Other fields may need to be released */
|
||||
if (DeviceNode->CapabilityFlags)
|
||||
{
|
||||
ExFreePool(DeviceNode->CapabilityFlags);
|
||||
}
|
||||
|
||||
if (DeviceNode->CmResourceList)
|
||||
{
|
||||
ExFreePool(DeviceNode->CmResourceList);
|
||||
}
|
||||
|
||||
if (DeviceNode->BootResourcesList)
|
||||
{
|
||||
ExFreePool(DeviceNode->BootResourcesList);
|
||||
}
|
||||
|
||||
if (DeviceNode->ResourceRequirementsList)
|
||||
{
|
||||
ExFreePool(DeviceNode->ResourceRequirementsList);
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&DeviceNode->DeviceID);
|
||||
|
||||
RtlFreeUnicodeString(&DeviceNode->InstanceID);
|
||||
|
||||
RtlFreeUnicodeString(&DeviceNode->HardwareIDs);
|
||||
|
||||
RtlFreeUnicodeString(&DeviceNode->CompatibleIDs);
|
||||
|
||||
RtlFreeUnicodeString(&DeviceNode->DeviceText);
|
||||
|
||||
RtlFreeUnicodeString(&DeviceNode->DeviceTextLocation);
|
||||
|
||||
if (DeviceNode->BusInformation)
|
||||
{
|
||||
ExFreePool(DeviceNode->BusInformation);
|
||||
}
|
||||
|
||||
ExFreePool(DeviceNode);
|
||||
|
||||
|
@ -374,7 +446,7 @@ IopInitiatePnpIrp(
|
|||
PDEVICE_OBJECT DeviceObject,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
ULONG MinorFunction,
|
||||
PIO_STACK_LOCATION Stack)
|
||||
PIO_STACK_LOCATION Stack OPTIONAL)
|
||||
{
|
||||
PDEVICE_OBJECT TopDeviceObject;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
@ -393,6 +465,7 @@ IopInitiatePnpIrp(
|
|||
/* PNP IRPs are always initialized with a status code of
|
||||
STATUS_NOT_IMPLEMENTED */
|
||||
IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoStatusBlock->Information = 0;
|
||||
|
||||
Irp = IoBuildSynchronousFsdRequest(
|
||||
IRP_MJ_PNP,
|
||||
|
@ -405,10 +478,14 @@ IopInitiatePnpIrp(
|
|||
|
||||
IrpSp = IoGetNextIrpStackLocation(Irp);
|
||||
IrpSp->MinorFunction = MinorFunction;
|
||||
RtlMoveMemory(
|
||||
&IrpSp->Parameters,
|
||||
&Stack->Parameters,
|
||||
sizeof(Stack->Parameters));
|
||||
|
||||
if (Stack)
|
||||
{
|
||||
RtlMoveMemory(
|
||||
&IrpSp->Parameters,
|
||||
&Stack->Parameters,
|
||||
sizeof(Stack->Parameters));
|
||||
}
|
||||
|
||||
Status = IoCallDriver(TopDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
|
@ -422,166 +499,661 @@ IopInitiatePnpIrp(
|
|||
Status = IoStatusBlock->Status;
|
||||
}
|
||||
|
||||
ObDereferenceObject(TopDeviceObject);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IopQueryCapabilities(
|
||||
PDEVICE_OBJECT Pdo,
|
||||
PDEVICE_CAPABILITIES *Capabilities)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PDEVICE_CAPABILITIES Caps;
|
||||
IO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack\n");
|
||||
|
||||
*Capabilities = NULL;
|
||||
|
||||
Caps = ExAllocatePool(PagedPool, sizeof(DEVICE_CAPABILITIES));
|
||||
if (!Caps)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Caps, sizeof(DEVICE_CAPABILITIES));
|
||||
Caps->Size = sizeof(DEVICE_CAPABILITIES);
|
||||
Caps->Version = 1;
|
||||
Caps->Address = -1;
|
||||
Caps->UINumber = -1;
|
||||
|
||||
Stack.Parameters.DeviceCapabilities.Capabilities = Caps;
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_CAPABILITIES,
|
||||
&Stack);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*Capabilities = Caps;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IopTraverseDeviceTreeNode(
|
||||
PDEVICETREE_TRAVERSE_CONTEXT Context)
|
||||
{
|
||||
PDEVICE_NODE ParentDeviceNode;
|
||||
PDEVICE_NODE ChildDeviceNode;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Copy context data so we don't overwrite it in subsequent calls to this function */
|
||||
ParentDeviceNode = Context->DeviceNode;
|
||||
|
||||
/* Call the action routine */
|
||||
Status = (Context->Action)(ParentDeviceNode, Context->Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Traversal of all children nodes */
|
||||
for (ChildDeviceNode = ParentDeviceNode->Child;
|
||||
ChildDeviceNode != NULL;
|
||||
ChildDeviceNode = ChildDeviceNode->NextSibling)
|
||||
{
|
||||
/* Pass the current device node to the action routine */
|
||||
Context->DeviceNode = ChildDeviceNode;
|
||||
|
||||
Status = IopTraverseDeviceTreeNode(Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IopTraverseDeviceTree(
|
||||
PDEVICETREE_TRAVERSE_CONTEXT Context)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Context %x\n", Context);
|
||||
|
||||
DPRINT("IopTraverseDeviceTree(DeviceNode %x FirstDeviceNode %x Action %x Context %x)\n",
|
||||
Context->DeviceNode, Context->FirstDeviceNode, Context->Action, Context->Context);
|
||||
|
||||
/* Start from the specified device node */
|
||||
Context->DeviceNode = Context->FirstDeviceNode;
|
||||
|
||||
/* Recursively traverse the device tree */
|
||||
Status = IopTraverseDeviceTreeNode(Context);
|
||||
if (Status == STATUS_UNSUCCESSFUL)
|
||||
{
|
||||
/* The action routine just wanted to terminate the traversal with status
|
||||
code STATUS_SUCCESS */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IopActionInterrogateDeviceStack(
|
||||
PDEVICE_NODE DeviceNode,
|
||||
PVOID Context)
|
||||
/*
|
||||
* FUNCTION: Retrieve information for all (direct) child nodes of a parent node
|
||||
* ARGUMENTS:
|
||||
* DeviceNode = Pointer to device node
|
||||
* Context = Pointer to parent node to retrieve child node information for
|
||||
* NOTES:
|
||||
* We only return a status code indicating an error (STATUS_UNSUCCESSFUL)
|
||||
* when we reach a device node which is not a direct child of the device node
|
||||
* for which we retrieve information of child nodes for. Any errors that occur
|
||||
* is logged instead so that all child services have a chance of beeing
|
||||
* interrogated.
|
||||
*/
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PDEVICE_NODE ParentDeviceNode;
|
||||
WCHAR InstancePath[MAX_PATH];
|
||||
IO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("DeviceNode %x Context %x\n", DeviceNode, Context);
|
||||
|
||||
DPRINT("PDO %x\n", DeviceNode->Pdo);
|
||||
|
||||
|
||||
ParentDeviceNode = (PDEVICE_NODE)Context;
|
||||
|
||||
/* We are called for the parent too, but we don't need to do special
|
||||
handling for this node */
|
||||
if (DeviceNode == ParentDeviceNode)
|
||||
{
|
||||
DPRINT("Success\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make sure this device node is a direct child of the parent device node
|
||||
that is given as an argument */
|
||||
if (DeviceNode->Parent != ParentDeviceNode)
|
||||
{
|
||||
/* Stop the traversal immediately and indicate successful operation */
|
||||
DPRINT("Stop\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: For critical errors, cleanup and disable device, but always return STATUS_SUCCESS */
|
||||
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
|
||||
|
||||
Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceNode->Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_ID,
|
||||
&Stack);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlInitUnicodeString(
|
||||
&DeviceNode->DeviceID,
|
||||
(LPWSTR)IoStatusBlock.Information);
|
||||
|
||||
/* FIXME: Check for valid characters, if there is invalid characters then bugcheck */
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
RtlInitUnicodeString(&DeviceNode->DeviceID, NULL);
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
|
||||
|
||||
Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceNode->Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_ID,
|
||||
&Stack);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlInitUnicodeString(
|
||||
&DeviceNode->InstanceID,
|
||||
(LPWSTR)IoStatusBlock.Information);
|
||||
|
||||
/* FIXME: Check for valid characters, if there is invalid characters then bugcheck */
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
RtlInitUnicodeString(&DeviceNode->InstanceID, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: SEND IRP_QUERY_ID.BusQueryHardwareIDs */
|
||||
/* FIXME: SEND IRP_QUERY_ID.BusQueryCompatibleIDs */
|
||||
|
||||
|
||||
Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
|
||||
|
||||
Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
|
||||
Stack.Parameters.QueryDeviceText.LocaleId = 0; // FIXME
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceNode->Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_DEVICE_TEXT,
|
||||
&Stack);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlInitUnicodeString(
|
||||
&DeviceNode->DeviceText,
|
||||
(LPWSTR)IoStatusBlock.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
RtlInitUnicodeString(&DeviceNode->DeviceText, NULL);
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
|
||||
|
||||
Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
|
||||
Stack.Parameters.QueryDeviceText.LocaleId = 0; // FIXME
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceNode->Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_DEVICE_TEXT,
|
||||
&Stack);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlInitUnicodeString(
|
||||
&DeviceNode->DeviceTextLocation,
|
||||
(LPWSTR)IoStatusBlock.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
RtlInitUnicodeString(&DeviceNode->DeviceTextLocation, NULL);
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceNode->Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_BUS_INFORMATION,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DeviceNode->BusInformation =
|
||||
(PPNP_BUS_INFORMATION)IoStatusBlock.Information;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
DeviceNode->BusInformation = NULL;
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceNode->Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_RESOURCES,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DeviceNode->BootResourcesList =
|
||||
(PCM_RESOURCE_LIST)IoStatusBlock.Information;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
DeviceNode->BootResourcesList = NULL;
|
||||
}
|
||||
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceNode->Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_RESOURCE_REQUIREMENTS,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DeviceNode->ResourceRequirementsList =
|
||||
(PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
||||
DeviceNode->ResourceRequirementsList = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Assemble the instance path for the device */
|
||||
|
||||
wcscpy(InstancePath, DeviceNode->DeviceID.Buffer);
|
||||
wcscat(InstancePath, L"\\");
|
||||
wcscat(InstancePath, DeviceNode->InstanceID.Buffer);
|
||||
|
||||
if (!DeviceNode->CapabilityFlags->UniqueID)
|
||||
{
|
||||
DPRINT("Instance ID is not unique\n");
|
||||
/* FIXME: Add information from parent bus driver to InstancePath */
|
||||
}
|
||||
|
||||
if (!IopCreateUnicodeString(&DeviceNode->InstancePath, InstancePath, PagedPool)) {
|
||||
DPRINT("No resources\n");
|
||||
/* FIXME: Cleanup and disable device */
|
||||
}
|
||||
|
||||
DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IopActionConfigureChildServices(
|
||||
PDEVICE_NODE DeviceNode,
|
||||
PVOID Context)
|
||||
/*
|
||||
* FUNCTION: Retrieve configuration for all (direct) child nodes of a parent node
|
||||
* ARGUMENTS:
|
||||
* DeviceNode = Pointer to device node
|
||||
* Context = Pointer to parent node to retrieve child node configuration for
|
||||
* NOTES:
|
||||
* We only return a status code indicating an error (STATUS_UNSUCCESSFUL)
|
||||
* when we reach a device node which is not a direct child of the device
|
||||
* node for which we configure child services for. Any errors that occur is
|
||||
* logged instead so that all child services have a chance of beeing
|
||||
* configured.
|
||||
*/
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
PDEVICE_NODE ParentDeviceNode;
|
||||
PUNICODE_STRING Service;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("DeviceNode %x Context %x\n", DeviceNode, Context);
|
||||
|
||||
ParentDeviceNode = (PDEVICE_NODE)Context;
|
||||
|
||||
/* We are called for the parent too, but we don't need to do special
|
||||
handling for this node */
|
||||
if (DeviceNode == ParentDeviceNode)
|
||||
{
|
||||
DPRINT("Success\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make sure this device node is a direct child of the parent device node
|
||||
that is given as an argument */
|
||||
if (DeviceNode->Parent != ParentDeviceNode)
|
||||
{
|
||||
/* Stop the traversal immediately and indicate successful operation */
|
||||
DPRINT("Stop\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Retrieve configuration from Enum key */
|
||||
|
||||
Service = &DeviceNode->ServiceName;
|
||||
|
||||
Status = RtlpGetRegistryHandle(
|
||||
RTL_REGISTRY_ENUM,
|
||||
DeviceNode->InstancePath.Buffer,
|
||||
TRUE,
|
||||
&KeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
||||
|
||||
RtlInitUnicodeString(Service, NULL);
|
||||
|
||||
QueryTable[0].Name = L"Service";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||||
QueryTable[0].EntryContext = Service;
|
||||
|
||||
Status = RtlQueryRegistryValues(
|
||||
RTL_REGISTRY_HANDLE,
|
||||
(PWSTR)KeyHandle,
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
NtClose(KeyHandle);
|
||||
|
||||
DPRINT("RtlQueryRegistryValues() returned status %x\n", Status);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: Log the error */
|
||||
CPRINT("Could not retrieve configuration for device %S (Status %x)\n",
|
||||
DeviceNode->InstancePath.Buffer, Status);
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
DPRINT("Got Service %S\n", Service->Buffer);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IopActionInitChildServices(
|
||||
PDEVICE_NODE DeviceNode,
|
||||
PVOID Context)
|
||||
/*
|
||||
* FUNCTION: Initialize the service for all (direct) child nodes of a parent node
|
||||
* ARGUMENTS:
|
||||
* DeviceNode = Pointer to device node
|
||||
* Context = Pointer to parent node to initialize child node services for
|
||||
* NOTES:
|
||||
* If the driver image for a service is not loaded and initialized
|
||||
* it is done here too.
|
||||
* We only return a status code indicating an error (STATUS_UNSUCCESSFUL)
|
||||
* when we reach a device node which is not a direct child of the device
|
||||
* node for which we initialize child services for. Any errors that occur is
|
||||
* logged instead so that all child services have a chance of beeing
|
||||
* initialized.
|
||||
*/
|
||||
{
|
||||
PDEVICE_NODE ParentDeviceNode;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("DeviceNode %x Context %x\n", DeviceNode, Context);
|
||||
|
||||
ParentDeviceNode = (PDEVICE_NODE)Context;
|
||||
|
||||
/* We are called for the parent too, but we don't need to do special
|
||||
handling for this node */
|
||||
if (DeviceNode == ParentDeviceNode)
|
||||
{
|
||||
DPRINT("Success\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make sure this device node is a direct child of the parent device node
|
||||
that is given as an argument */
|
||||
if (DeviceNode->Parent != ParentDeviceNode)
|
||||
{
|
||||
/* Stop the traversal immediately and indicate successful operation */
|
||||
DPRINT("Stop\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED) &&
|
||||
!IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) &&
|
||||
!IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED))
|
||||
{
|
||||
Status = IopInitializeDeviceNodeService(DeviceNode);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED);
|
||||
|
||||
/* FIXME: Log the error (possibly in IopInitializeDeviceNodeService) */
|
||||
CPRINT("Initialization of service %S failed (Status %x)\n",
|
||||
DeviceNode->ServiceName.Buffer, Status);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Service %S is disabled or already initialized\n",
|
||||
DeviceNode->ServiceName.Buffer);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
IopInterrogateBusExtender(
|
||||
PDEVICE_NODE DeviceNode,
|
||||
PDEVICE_OBJECT FunctionDeviceObject,
|
||||
PDEVICE_OBJECT Pdo,
|
||||
BOOLEAN BootDriversOnly)
|
||||
{
|
||||
DEVICETREE_TRAVERSE_CONTEXT Context;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
UNICODE_STRING DriverName;
|
||||
PDEVICE_NODE ChildDeviceNode;
|
||||
IO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to bus driver\n");
|
||||
DPRINT("DeviceNode %x Pdo %x BootDriversOnly %d\n", DeviceNode, Pdo, BootDriversOnly);
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
|
||||
|
||||
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
FunctionDeviceObject,
|
||||
Pdo,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_DEVICE_RELATIONS,
|
||||
&Stack);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed\n");
|
||||
}
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
|
||||
|
||||
if ((!DeviceRelations) || (DeviceRelations->Count <= 0))
|
||||
{
|
||||
DPRINT("No PDOs\n");
|
||||
if (DeviceRelations)
|
||||
{
|
||||
ExFreePool(DeviceRelations);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
DPRINT("Got %d PDOs\n", DeviceRelations->Count);
|
||||
|
||||
if (DeviceRelations->Count <= 0)
|
||||
{
|
||||
DPRINT("No PDOs\n");
|
||||
ExFreePool(DeviceRelations);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#ifdef DBG
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
Status = IopCreateDeviceNode(DeviceNode, NULL, &DeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
DPRINT("DeviceRelations %x\n", DeviceRelations);
|
||||
DPRINT("Count %x\n", DeviceRelations->Count);
|
||||
for (i = 0; i < DeviceRelations->Count; i++)
|
||||
DPRINT("Object(PDO) %x\n", DeviceRelations->Objects[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create device nodes for all discovered devices */
|
||||
for (i = 0; i < DeviceRelations->Count; i++)
|
||||
{
|
||||
Status = IopCreateDeviceNode(
|
||||
DeviceNode,
|
||||
DeviceRelations->Objects[i],
|
||||
&ChildDeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("No resources\n");
|
||||
for (i = 0; i < DeviceRelations->Count; i++)
|
||||
ObDereferenceObject(DeviceRelations->Objects[i]);
|
||||
ExFreePool(DeviceRelations);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* FIXME: Use registry to find name of driver and only load driver if not
|
||||
already loaded. If loaded, just call AddDevice() */
|
||||
Status = LdrLoadDriver(&DriverName, DeviceNode, FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Don't free the device node, just log the error and return */
|
||||
/* FIXME: Log the error */
|
||||
CPRINT("Driver load failed, status (%x)\n", Status);
|
||||
ExFreePool(DeviceRelations);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(DeviceRelations);
|
||||
|
||||
|
||||
/* Retrieve information about all discovered children from the bus driver */
|
||||
|
||||
IopInitDeviceTreeTraverseContext(
|
||||
&Context,
|
||||
DeviceNode,
|
||||
IopActionInterrogateDeviceStack,
|
||||
DeviceNode);
|
||||
|
||||
Status = IopTraverseDeviceTree(&Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* Retrieve configuration from the registry for discovered children */
|
||||
|
||||
IopInitDeviceTreeTraverseContext(
|
||||
&Context,
|
||||
DeviceNode,
|
||||
IopActionConfigureChildServices,
|
||||
DeviceNode);
|
||||
|
||||
Status = IopTraverseDeviceTree(&Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize services for discovered children */
|
||||
|
||||
IopInitDeviceTreeTraverseContext(
|
||||
&Context,
|
||||
DeviceNode,
|
||||
IopActionInitChildServices,
|
||||
DeviceNode);
|
||||
|
||||
Status = IopTraverseDeviceTree(&Context);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID IopLoadBootStartDrivers(VOID)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PKEY_BASIC_INFORMATION KeyInfo;
|
||||
PDEVICE_NODE DeviceNode;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
ULONG BufferSize;
|
||||
ULONG ResultSize;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
DPRINT("Loading boot start drivers\n");
|
||||
|
||||
BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH+1) * sizeof(WCHAR);
|
||||
KeyInfo = ExAllocatePool(PagedPool, BufferSize);
|
||||
if (!KeyInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(
|
||||
&KeyName,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtOpenKey() failed (Status %x)\n", Status);
|
||||
ExFreePool(KeyInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
do {
|
||||
Status = ZwEnumerateKey(
|
||||
KeyHandle,
|
||||
Index,
|
||||
KeyBasicInformation,
|
||||
KeyInfo,
|
||||
BufferSize,
|
||||
&ResultSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwEnumerateKey() (Status %x)\n", Status);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Terminate the string */
|
||||
KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
|
||||
|
||||
/* Use IopRootDeviceNode for now */
|
||||
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CPRINT("IopCreateDeviceNode() failed with status 0x%X\n", Status);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!RtlCreateUnicodeString(&DeviceNode->ServiceName, KeyInfo->Name))
|
||||
{
|
||||
CPRINT("RtlCreateUnicodeString() failed\n");
|
||||
IopFreeDeviceNode(DeviceNode);
|
||||
break;
|
||||
}
|
||||
|
||||
Status = IopInitializeDeviceNodeService(DeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: Write an entry in the system error log */
|
||||
CPRINT("Could not load boot start driver: %wZ, status 0x%X\n",
|
||||
&DeviceNode->ServiceName, Status);
|
||||
|
||||
IopFreeDeviceNode(DeviceNode);
|
||||
}
|
||||
|
||||
Index++;
|
||||
} while (TRUE);
|
||||
|
||||
DPRINT("Services found: %d\n", Index);
|
||||
|
||||
NtClose(KeyHandle);
|
||||
|
||||
ExFreePool(KeyInfo);
|
||||
IopInterrogateBusExtender(
|
||||
IopRootDeviceNode,
|
||||
IopRootDeviceNode->Pdo,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
VOID PnpInit(VOID)
|
||||
{
|
||||
PDEVICE_OBJECT Pdo;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
@ -590,25 +1162,44 @@ VOID PnpInit(VOID)
|
|||
|
||||
Status = IopCreateDriverObject(&IopRootDriverObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CPRINT("IoCreateDriverObject() failed\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
{
|
||||
CPRINT("IoCreateDriverObject() failed\n");
|
||||
KeBugCheck(PHASE1_INITIALIZATION_FAILED);
|
||||
}
|
||||
|
||||
PnpRootDriverEntry(IopRootDriverObject, NULL);
|
||||
|
||||
Status = IoCreateDevice(IopRootDriverObject, 0, NULL,
|
||||
FILE_DEVICE_CONTROLLER, 0, FALSE, &IopRootDeviceNode->Pdo);
|
||||
Status = IoCreateDevice(
|
||||
IopRootDriverObject,
|
||||
0,
|
||||
NULL,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
0,
|
||||
FALSE,
|
||||
&Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CPRINT("IoCreateDevice() failed\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
{
|
||||
CPRINT("IoCreateDevice() failed\n");
|
||||
KeBugCheck(PHASE1_INITIALIZATION_FAILED);
|
||||
}
|
||||
|
||||
Status = IopCreateDeviceNode(
|
||||
NULL,
|
||||
Pdo,
|
||||
&IopRootDeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CPRINT("Insufficient resources\n");
|
||||
KeBugCheck(PHASE1_INITIALIZATION_FAILED);
|
||||
}
|
||||
|
||||
IopRootDeviceNode->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||
|
||||
IopRootDeviceNode->DriverObject = IopRootDriverObject;
|
||||
|
||||
PnpRootDriverEntry(IopRootDriverObject, NULL);
|
||||
|
||||
IopRootDriverObject->DriverExtension->AddDevice(
|
||||
IopRootDriverObject, IopRootDeviceNode->Pdo);
|
||||
IopRootDriverObject,
|
||||
IopRootDeviceNode->Pdo);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pnproot.c,v 1.5 2001/09/01 15:36:44 chorns Exp $
|
||||
/* $Id: pnproot.c,v 1.6 2001/09/16 13:19:32 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -13,55 +13,168 @@
|
|||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/io.h>
|
||||
#include <internal/registry.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define ENUM_NAME_ROOT L"Root"
|
||||
|
||||
/* DATA **********************************************************************/
|
||||
|
||||
typedef struct _PNPROOT_DEVICE {
|
||||
// Entry on device list
|
||||
LIST_ENTRY ListEntry;
|
||||
// Physical Device Object of device
|
||||
PDEVICE_OBJECT Pdo;
|
||||
// Service name
|
||||
UNICODE_STRING ServiceName;
|
||||
// Device ID
|
||||
UNICODE_STRING DeviceID;
|
||||
// Instance ID
|
||||
UNICODE_STRING InstanceID;
|
||||
// Device description
|
||||
UNICODE_STRING DeviceDescription;
|
||||
} PNPROOT_DEVICE, *PPNPROOT_DEVICE;
|
||||
|
||||
typedef enum {
|
||||
dsStopped,
|
||||
dsStarted,
|
||||
dsPaused,
|
||||
dsRemoved,
|
||||
dsSurpriseRemoved
|
||||
} PNPROOT_DEVICE_STATE;
|
||||
|
||||
|
||||
typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION
|
||||
{
|
||||
// Pointer to device object, this device extension is associated with
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
// Wether this device extension is for an FDO or PDO
|
||||
BOOLEAN IsFDO;
|
||||
// Wether the device is removed
|
||||
BOOLEAN Removed;
|
||||
// Current device power state for the device
|
||||
DEVICE_POWER_STATE DevicePowerState;
|
||||
} __attribute((packed)) PNPROOT_COMMON_DEVICE_EXTENSION, *PPNPROOT_COMMON_DEVICE_EXTENSION;
|
||||
|
||||
/* Physical Device Object device extension for a child device */
|
||||
typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
|
||||
{
|
||||
// Common device data
|
||||
PNPROOT_COMMON_DEVICE_EXTENSION;
|
||||
// Device ID
|
||||
UNICODE_STRING DeviceID;
|
||||
// Instance ID
|
||||
UNICODE_STRING InstanceID;
|
||||
} __attribute((packed)) PNPROOT_PDO_DEVICE_EXTENSION, *PPNPROOT_PDO_DEVICE_EXTENSION;
|
||||
|
||||
/* Functional Device Object device extension for the PCI driver device object */
|
||||
typedef struct _PNPROOT_FDO_DEVICE_EXTENSION
|
||||
{
|
||||
// Common device data
|
||||
PNPROOT_COMMON_DEVICE_EXTENSION;
|
||||
// Physical Device Object
|
||||
PDEVICE_OBJECT Pdo;
|
||||
// Lower device object
|
||||
PDEVICE_OBJECT Ldo;
|
||||
// Current state of the driver
|
||||
PNPROOT_DEVICE_STATE State;
|
||||
// Namespace device list
|
||||
LIST_ENTRY DeviceListHead;
|
||||
// Number of (not removed) devices in device list
|
||||
ULONG DeviceListCount;
|
||||
// Lock for namespace device list
|
||||
// FIXME: Use fast mutex instead?
|
||||
KSPIN_LOCK DeviceListLock;
|
||||
} __attribute((packed)) PNPROOT_FDO_DEVICE_EXTENSION, *PPNPROOT_FDO_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
PDEVICE_OBJECT PnpRootDeviceObject;
|
||||
LIST_ENTRY PnpRootDeviceListHead;
|
||||
ULONG PnpRootDeviceListCount;
|
||||
KSPIN_LOCK PnpRootDeviceListLock;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/* Physical Device Object routines */
|
||||
|
||||
NTSTATUS
|
||||
PnpRootCreateDevice(
|
||||
PDEVICE_OBJECT *PhysicalDeviceObject)
|
||||
{
|
||||
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PPNPROOT_DEVICE Device;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* This function should be obsoleted soon */
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension;
|
||||
|
||||
Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
|
||||
if (!Device)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = IoCreateDevice(PnpRootDeviceObject->DriverObject, 0,
|
||||
NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||
ExFreePool(Device);
|
||||
return Status;
|
||||
}
|
||||
RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
|
||||
|
||||
Status = IoCreateDevice(
|
||||
PnpRootDeviceObject->DriverObject,
|
||||
sizeof(PNPROOT_PDO_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
0,
|
||||
FALSE,
|
||||
&Device->Pdo);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||
ExFreePool(Device);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||
|
||||
ObReferenceObject(Device->Pdo);
|
||||
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
ExInterlockedInsertTailList(&PnpRootDeviceListHead,
|
||||
//Device->Pdo->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
|
||||
|
||||
PdoDeviceExtension->IsFDO = FALSE;
|
||||
|
||||
PdoDeviceExtension->DeviceObject = Device->Pdo;
|
||||
|
||||
PdoDeviceExtension->DevicePowerState = PowerDeviceD0;
|
||||
|
||||
if (!IopCreateUnicodeString(
|
||||
&PdoDeviceExtension->DeviceID,
|
||||
ENUM_NAME_ROOT \
|
||||
L"\\LEGACY_UNKNOWN",
|
||||
PagedPool))
|
||||
{
|
||||
/* FIXME: */
|
||||
DPRINT("IopCreateUnicodeString() failed\n");
|
||||
}
|
||||
|
||||
if (!IopCreateUnicodeString(
|
||||
&PdoDeviceExtension->InstanceID,
|
||||
L"0000",
|
||||
PagedPool))
|
||||
{
|
||||
/* FIXME: */
|
||||
DPRINT("IopCreateUnicodeString() failed\n");
|
||||
}
|
||||
|
||||
ExInterlockedInsertTailList(
|
||||
&DeviceExtension->DeviceListHead,
|
||||
&Device->ListEntry,
|
||||
&PnpRootDeviceListLock);
|
||||
&DeviceExtension->DeviceListLock);
|
||||
|
||||
DeviceExtension->DeviceListCount++;
|
||||
|
||||
*PhysicalDeviceObject = Device->Pdo;
|
||||
|
||||
|
@ -69,12 +182,405 @@ PnpRootCreateDevice(
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PdoQueryId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
|
||||
UNICODE_STRING String;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
// Irp->IoStatus.Information = 0;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
RtlInitUnicodeString(&String, NULL);
|
||||
|
||||
switch (IrpSp->Parameters.QueryId.IdType) {
|
||||
case BusQueryDeviceID:
|
||||
Status = IopCreateUnicodeString(
|
||||
&String,
|
||||
DeviceExtension->DeviceID.Buffer,
|
||||
PagedPool);
|
||||
|
||||
DPRINT("DeviceID: %S\n", String.Buffer);
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
||||
break;
|
||||
|
||||
case BusQueryHardwareIDs:
|
||||
case BusQueryCompatibleIDs:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case BusQueryInstanceID:
|
||||
Status = IopCreateUnicodeString(
|
||||
&String,
|
||||
DeviceExtension->InstanceID.Buffer,
|
||||
PagedPool);
|
||||
|
||||
DPRINT("InstanceID: %S\n", String.Buffer);
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
||||
break;
|
||||
|
||||
case BusQueryDeviceSerialNumber:
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PnpRootPdoPnpControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle Plug and Play IRPs for the child device
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to physical device object of the child device
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction) {
|
||||
#if 0
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
|
||||
break;
|
||||
|
||||
case IRP_MN_EJECT:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
/* FIXME: Possibly handle for RemovalRelations */
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_DEVICE_TEXT:
|
||||
break;
|
||||
#endif
|
||||
case IRP_MN_QUERY_ID:
|
||||
Status = PdoQueryId(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
#if 0
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_RESOURCES:
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_SET_LOCK:
|
||||
break;
|
||||
|
||||
case IRP_MN_START_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
break;
|
||||
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
PnpRootPdoPowerControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle power management IRPs for the child device
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to physical device object of the child device
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction) {
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* Functional Device Object routines */
|
||||
|
||||
NTSTATUS
|
||||
PnpRootFdoReadDeviceInfo(
|
||||
PPNPROOT_DEVICE Device)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
PUNICODE_STRING DeviceDesc;
|
||||
WCHAR KeyName[MAX_PATH];
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
/* Retrieve configuration from Enum key */
|
||||
|
||||
DeviceDesc = &Device->DeviceDescription;
|
||||
|
||||
wcscpy(KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
|
||||
wcscat(KeyName, ENUM_NAME_ROOT);
|
||||
wcscat(KeyName, L"\\");
|
||||
wcscat(KeyName, Device->ServiceName.Buffer);
|
||||
wcscat(KeyName, L"\\");
|
||||
wcscat(KeyName, Device->InstanceID.Buffer);
|
||||
|
||||
DPRINT("KeyName %S\n", KeyName);
|
||||
|
||||
Status = RtlpGetRegistryHandle(
|
||||
RTL_REGISTRY_ABSOLUTE,
|
||||
KeyName,
|
||||
FALSE,
|
||||
&KeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
||||
|
||||
RtlInitUnicodeString(DeviceDesc, NULL);
|
||||
|
||||
QueryTable[0].Name = L"DeviceDesc";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||||
QueryTable[0].EntryContext = DeviceDesc;
|
||||
|
||||
Status = RtlQueryRegistryValues(
|
||||
RTL_REGISTRY_HANDLE,
|
||||
(PWSTR)KeyHandle,
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
NtClose(KeyHandle);
|
||||
|
||||
DPRINT("RtlQueryRegistryValues() returned status %x\n", Status);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: */
|
||||
}
|
||||
|
||||
DPRINT("Got device description: %S\n", DeviceDesc->Buffer);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PnpRootFdoEnumerateDevices(
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PKEY_BASIC_INFORMATION KeyInfo;
|
||||
UNICODE_STRING KeyName;
|
||||
PPNPROOT_DEVICE Device;
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
HANDLE KeyHandle;
|
||||
ULONG BufferSize;
|
||||
ULONG ResultSize;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH+1) * sizeof(WCHAR);
|
||||
KeyInfo = ExAllocatePool(PagedPool, BufferSize);
|
||||
if (!KeyInfo)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(
|
||||
&KeyName,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \
|
||||
ENUM_NAME_ROOT);
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtOpenKey() failed (Status %x)\n", Status);
|
||||
ExFreePool(KeyInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
|
||||
there are more entries in the list than found in the registry as some
|
||||
drivers are passed on the command line */
|
||||
// DeviceExtension->DeviceListCount = 0;
|
||||
|
||||
Index = 0;
|
||||
do {
|
||||
Status = ZwEnumerateKey(
|
||||
KeyHandle,
|
||||
Index,
|
||||
KeyBasicInformation,
|
||||
KeyInfo,
|
||||
BufferSize,
|
||||
&ResultSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwEnumerateKey() (Status %x)\n", Status);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Terminate the string */
|
||||
KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
|
||||
|
||||
Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
|
||||
if (!Device)
|
||||
{
|
||||
/* FIXME: */
|
||||
break;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
|
||||
|
||||
if (!IopCreateUnicodeString(&Device->ServiceName, KeyInfo->Name, PagedPool))
|
||||
{
|
||||
/* FIXME: */
|
||||
DPRINT("IopCreateUnicodeString() failed\n");
|
||||
}
|
||||
|
||||
wcscpy(Buffer, ENUM_NAME_ROOT);
|
||||
wcscat(Buffer, L"\\");
|
||||
wcscat(Buffer, KeyInfo->Name);
|
||||
|
||||
if (!IopCreateUnicodeString(&Device->DeviceID, Buffer, PagedPool))
|
||||
{
|
||||
/* FIXME: */
|
||||
DPRINT("IopCreateUnicodeString() failed\n");
|
||||
}
|
||||
|
||||
DPRINT("Got entry: %S\n", Device->DeviceID.Buffer);
|
||||
|
||||
if (!IopCreateUnicodeString(
|
||||
&Device->InstanceID,
|
||||
L"0000",
|
||||
PagedPool))
|
||||
{
|
||||
/* FIXME: */
|
||||
DPRINT("IopCreateUnicodeString() failed\n");
|
||||
}
|
||||
|
||||
Status = PnpRootFdoReadDeviceInfo(Device);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status);
|
||||
/* FIXME: */
|
||||
}
|
||||
|
||||
ExInterlockedInsertTailList(
|
||||
&DeviceExtension->DeviceListHead,
|
||||
&Device->ListEntry,
|
||||
&DeviceExtension->DeviceListLock);
|
||||
|
||||
DeviceExtension->DeviceListCount++;
|
||||
|
||||
Index++;
|
||||
} while (TRUE);
|
||||
|
||||
DPRINT("Entries found: %d\n", Index);
|
||||
|
||||
NtClose(KeyHandle);
|
||||
|
||||
ExFreePool(KeyInfo);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PnpRootQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_RELATIONS Relations;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PPNPROOT_DEVICE Device;
|
||||
|
@ -84,33 +590,92 @@ PnpRootQueryBusRelations(
|
|||
|
||||
DPRINT("Called\n");
|
||||
|
||||
Status = PnpRootFdoEnumerateDevices(DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (Irp->IoStatus.Information)
|
||||
{
|
||||
/* FIXME: Another bus driver has already created a DEVICE_RELATIONS
|
||||
structure so we must merge this structure with our own */
|
||||
}
|
||||
|
||||
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
|
||||
(PnpRootDeviceListCount - 1);
|
||||
(DeviceExtension->DeviceListCount - 1);
|
||||
|
||||
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
|
||||
if (!Relations)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Relations->Count = PnpRootDeviceListCount;
|
||||
Relations->Count = DeviceExtension->DeviceListCount;
|
||||
|
||||
i = 0;
|
||||
CurrentEntry = PnpRootDeviceListHead.Flink;
|
||||
while (CurrentEntry != &PnpRootDeviceListHead)
|
||||
{
|
||||
Device = CONTAINING_RECORD(
|
||||
CurrentEntry, PNPROOT_DEVICE, ListEntry);
|
||||
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||
while (CurrentEntry != &DeviceExtension->DeviceListHead)
|
||||
{
|
||||
Device = CONTAINING_RECORD(CurrentEntry, PNPROOT_DEVICE, ListEntry);
|
||||
|
||||
if (!Device->Pdo) {
|
||||
if (!Device->Pdo)
|
||||
{
|
||||
/* Create a physical device object for the
|
||||
device as it does not already have one */
|
||||
Status = IoCreateDevice(DeviceObject->DriverObject, 0,
|
||||
NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
Status = IoCreateDevice(
|
||||
DeviceObject->DriverObject,
|
||||
sizeof(PNPROOT_PDO_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
0,
|
||||
FALSE,
|
||||
&Device->Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||
ExFreePool(Relations);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT("Created PDO %x\n", Device->Pdo);
|
||||
|
||||
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||
|
||||
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
//Device->Pdo->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
|
||||
|
||||
PdoDeviceExtension->IsFDO = FALSE;
|
||||
|
||||
PdoDeviceExtension->DeviceObject = Device->Pdo;
|
||||
|
||||
PdoDeviceExtension->DevicePowerState = PowerDeviceD0;
|
||||
|
||||
if (!IopCreateUnicodeString(
|
||||
&PdoDeviceExtension->DeviceID,
|
||||
Device->DeviceID.Buffer,
|
||||
PagedPool))
|
||||
{
|
||||
DPRINT("Insufficient resources\n");
|
||||
/* FIXME: */
|
||||
}
|
||||
|
||||
DPRINT("DeviceID: %S PDO %x\n",
|
||||
PdoDeviceExtension->DeviceID.Buffer,
|
||||
Device->Pdo);
|
||||
|
||||
if (!IopCreateUnicodeString(
|
||||
&PdoDeviceExtension->InstanceID,
|
||||
Device->InstanceID.Buffer,
|
||||
PagedPool))
|
||||
{
|
||||
DPRINT("Insufficient resources\n");
|
||||
/* FIXME: */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Reference the physical device object. The PnP manager
|
||||
|
@ -122,13 +687,21 @@ PnpRootQueryBusRelations(
|
|||
i++;
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = (ULONG)Relations;
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Relations;
|
||||
}
|
||||
else
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
PnpRootQueryDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -139,42 +712,52 @@ PnpRootQueryDeviceRelations(
|
|||
|
||||
DPRINT("Called\n");
|
||||
|
||||
switch (IrpSp->Parameters.QueryDeviceRelations.Type)
|
||||
{
|
||||
switch (IrpSp->Parameters.QueryDeviceRelations.Type) {
|
||||
case BusRelations:
|
||||
Status = PnpRootQueryBusRelations(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootPnpControl(
|
||||
PnpRootFdoPnpControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle Plug and Play IRPs for the root bus device object
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to functional device object of the root bus driver
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction)
|
||||
{
|
||||
switch (IrpSp->MinorFunction) {
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
Status = PnpRootQueryDeviceRelations(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
|
||||
|
||||
case IRP_MN_START_DEVICE:
|
||||
PnpRootDeviceListCount = 0;
|
||||
DeviceExtension->State = dsStarted;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
|
@ -187,24 +770,32 @@ PnpRootPnpControl(
|
|||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
if (Status != STATUS_PENDING) {
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootPowerControl(
|
||||
PnpRootFdoPowerControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle power management IRPs for the root bus device object
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to functional device object of the root bus driver
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
@ -212,70 +803,150 @@ PnpRootPowerControl(
|
|||
DPRINT("Called\n");
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
switch (IrpSp->MinorFunction)
|
||||
{
|
||||
|
||||
switch (IrpSp->MinorFunction) {
|
||||
default:
|
||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING)
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
if (Status != STATUS_PENDING) {
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootPnpControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle Plug and Play IRPs
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to PDO or FDO
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
DPRINT("DeviceObject %x DeviceExtension %x IsFDO %d\n",
|
||||
DeviceObject,
|
||||
DeviceExtension,
|
||||
DeviceExtension->IsFDO);
|
||||
|
||||
if (DeviceExtension->IsFDO) {
|
||||
Status = PnpRootFdoPnpControl(DeviceObject, Irp);
|
||||
} else {
|
||||
Status = PnpRootPdoPnpControl(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootPowerControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handle power management IRPs
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to PDO or FDO
|
||||
* Irp = Pointer to IRP that should be handled
|
||||
* RETURNS:
|
||||
* Status
|
||||
*/
|
||||
{
|
||||
PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (DeviceExtension->IsFDO) {
|
||||
Status = PnpRootFdoPowerControl(DeviceObject, Irp);
|
||||
} else {
|
||||
Status = PnpRootPdoPowerControl(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||
{
|
||||
PDEVICE_OBJECT Ldo;
|
||||
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called\n");
|
||||
|
||||
Status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_BUS_EXTENDER,
|
||||
FILE_DEVICE_SECURE_OPEN, TRUE, &PnpRootDeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||
KeBugCheck(0);
|
||||
return Status;
|
||||
}
|
||||
Status = IoCreateDevice(
|
||||
DriverObject,
|
||||
sizeof(PNPROOT_FDO_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_BUS_EXTENDER,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
TRUE,
|
||||
&PnpRootDeviceObject);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
CPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||
KeBugCheck(PHASE1_INITIALIZATION_FAILED);
|
||||
}
|
||||
|
||||
Ldo = IoAttachDeviceToDeviceStack(PnpRootDeviceObject, PhysicalDeviceObject);
|
||||
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension;
|
||||
|
||||
if (!PnpRootDeviceObject)
|
||||
{
|
||||
DbgPrint("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject);
|
||||
KeBugCheck(0);
|
||||
}
|
||||
RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
|
||||
|
||||
if (!PhysicalDeviceObject)
|
||||
{
|
||||
DbgPrint("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject);
|
||||
KeBugCheck(0);
|
||||
}
|
||||
DeviceExtension->IsFDO = TRUE;
|
||||
|
||||
InitializeListHead(&PnpRootDeviceListHead);
|
||||
PnpRootDeviceListCount = 0;
|
||||
KeInitializeSpinLock(&PnpRootDeviceListLock);
|
||||
DeviceExtension->State = dsStopped;
|
||||
|
||||
DeviceExtension->Ldo = IoAttachDeviceToDeviceStack(
|
||||
PnpRootDeviceObject,
|
||||
PhysicalDeviceObject);
|
||||
|
||||
if (!PnpRootDeviceObject) {
|
||||
CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject);
|
||||
KeBugCheck(PHASE1_INITIALIZATION_FAILED);
|
||||
}
|
||||
|
||||
if (!PhysicalDeviceObject) {
|
||||
CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject);
|
||||
KeBugCheck(PHASE1_INITIALIZATION_FAILED);
|
||||
}
|
||||
|
||||
InitializeListHead(&DeviceExtension->DeviceListHead);
|
||||
|
||||
DeviceExtension->DeviceListCount = 0;
|
||||
|
||||
KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
|
||||
|
||||
PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
DPRINT("Done\n");
|
||||
//PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
DPRINT("Done AddDevice()\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PnpRootDriverEntry(
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: main.c,v 1.105 2001/09/04 21:06:27 ekohl Exp $
|
||||
/* $Id: main.c,v 1.106 2001/09/16 13:19:32 chorns Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
|
@ -84,9 +84,10 @@ typedef struct
|
|||
} SERVICE, *PSERVICE;
|
||||
|
||||
SERVICE Services[] = {
|
||||
{L"pci", L"PCI Bus Driver", L"Boot Bus Extender", 0, 1},
|
||||
{L"keyboard", L"Standard Keyboard Driver", L"Base", 0, 1},
|
||||
{L"blue", L"Bluescreen Driver", L"Base", 0, 1},
|
||||
{L"vidport", L"Video Port Driver", L"Base", 0, 1},
|
||||
/* {L"vidport", L"Video Port Driver", L"Base", 0, 1},
|
||||
{L"vgamp", L"VGA Miniport", L"Base", 0, 1},
|
||||
{L"minixfs", L"Minix File System", L"File system", 0, 1},
|
||||
{L"msfs", L"Mail Slot File System", L"File system", 0, 1},
|
||||
|
@ -95,22 +96,28 @@ SERVICE Services[] = {
|
|||
{L"mouclass", L"Mouse Class Driver", L"Pointer Class", 0, 1},
|
||||
{L"ndis", L"NDIS System Driver", L"NDIS Wrapper", 0, 1},
|
||||
{L"ne2000", L"Novell Eagle 2000 Driver", L"NDIS", 0, 1},
|
||||
{L"afd", L"AFD Networking Support Environment", L"TDI", 0, 1},
|
||||
{L"afd", L"AFD Networking Support Environment", L"TDI", 0, 1},*/
|
||||
{NULL,}
|
||||
};
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
//#define FULLREG
|
||||
|
||||
VOID CreateDefaultRegistryForLegacyDriver(
|
||||
PSERVICE Service)
|
||||
{
|
||||
#ifdef FULLREG
|
||||
WCHAR LegacyDriver[] = L"LegacyDriver";
|
||||
#endif
|
||||
WCHAR InstancePath[MAX_PATH];
|
||||
WCHAR KeyNameBuffer[MAX_PATH];
|
||||
WCHAR Name[MAX_PATH];
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
#ifdef FULLREG
|
||||
DWORD DwordData;
|
||||
#endif
|
||||
ULONG Length;
|
||||
NTSTATUS Status;
|
||||
WCHAR ImagePath[MAX_PATH];
|
||||
|
@ -146,7 +153,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FULLREG
|
||||
DwordData = 0;
|
||||
Length = sizeof(DWORD);
|
||||
Status = RtlWriteRegistryValue(
|
||||
|
@ -177,7 +184,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
NtClose(KeyHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
|
||||
Status = RtlWriteRegistryValue(
|
||||
RTL_REGISTRY_HANDLE,
|
||||
|
@ -192,7 +199,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
NtClose(KeyHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FULLREG
|
||||
DwordData = 0;
|
||||
Length = Length = sizeof(DWORD);
|
||||
Status = RtlWriteRegistryValue(
|
||||
|
@ -208,7 +215,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
NtClose(KeyHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
Length = (wcslen(Service->ServiceName) + 1) * sizeof(WCHAR);
|
||||
Status = RtlWriteRegistryValue(
|
||||
RTL_REGISTRY_HANDLE,
|
||||
|
@ -226,6 +233,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
|
||||
NtClose(KeyHandle);
|
||||
|
||||
|
||||
/* Services section */
|
||||
|
||||
Status = RtlpGetRegistryHandle(
|
||||
|
@ -238,7 +246,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FULLREG
|
||||
Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
|
||||
Status = RtlWriteRegistryValue(
|
||||
RTL_REGISTRY_HANDLE,
|
||||
|
@ -284,7 +292,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
NtClose(KeyHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
wcscpy(ImagePath, L"\\SystemRoot\\System32\\drivers\\");
|
||||
wcscat(ImagePath, Service->ServiceName);
|
||||
wcscat(ImagePath, L".sys");
|
||||
|
@ -303,7 +311,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
NtClose(KeyHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
#if FULLREG
|
||||
DwordData = Service->Start;
|
||||
Length = sizeof(DWORD);
|
||||
Status = RtlWriteRegistryValue(
|
||||
|
@ -335,7 +343,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
|||
NtClose(KeyHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
NtClose(KeyHandle);
|
||||
}
|
||||
|
||||
|
@ -347,14 +355,14 @@ VOID CreateDefaultRegistry()
|
|||
Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
||||
CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
||||
CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1051,7 +1059,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
|
|||
* This should be done by the boot loader.
|
||||
*/
|
||||
strcpy (KeLoaderCommandLine,
|
||||
"multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=COM1");
|
||||
"multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
|
||||
strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
|
||||
|
||||
KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: loader.c,v 1.89 2001/09/01 15:36:44 chorns Exp $
|
||||
/* $Id: loader.c,v 1.90 2001/09/16 13:19:32 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -882,6 +882,11 @@ VOID LdrLoadAutoConfigDrivers (VOID)
|
|||
|
||||
#endif /* KDBG */
|
||||
|
||||
/*
|
||||
* PCI bus driver
|
||||
*/
|
||||
//LdrLoadAutoConfigDriver( L"pci.sys" );
|
||||
|
||||
/*
|
||||
* Keyboard driver
|
||||
*/
|
||||
|
@ -951,7 +956,7 @@ VOID LdrLoadAutoConfigDrivers (VOID)
|
|||
/*
|
||||
* Ancillary Function Driver
|
||||
*/
|
||||
//LdrLoadAutoConfigDriver(L"afd.sys");
|
||||
LdrLoadAutoConfigDriver(L"afd.sys");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -990,7 +995,11 @@ NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename,
|
|||
BOOLEAN BootDriversOnly)
|
||||
{
|
||||
PMODULE_OBJECT ModuleObject;
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
NTSTATUS Status;
|
||||
ULONG Length;
|
||||
LPWSTR Start;
|
||||
LPWSTR Ext;
|
||||
|
||||
ModuleObject = LdrLoadModule(Filename);
|
||||
if (!ModuleObject)
|
||||
|
@ -998,6 +1007,25 @@ NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename,
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Set a service name for the device node */
|
||||
|
||||
/* Get the service name from the module name */
|
||||
Start = wcsrchr(ModuleObject->BaseName.Buffer, L'\\');
|
||||
if (Start == NULL)
|
||||
Start = ModuleObject->BaseName.Buffer;
|
||||
else
|
||||
Start++;
|
||||
|
||||
Ext = wcsrchr(ModuleObject->BaseName.Buffer, L'.');
|
||||
if (Ext != NULL)
|
||||
Length = Ext - Start;
|
||||
else
|
||||
Length = wcslen(Start);
|
||||
|
||||
wcsncpy(Buffer, Start, Length);
|
||||
RtlInitUnicodeString(&DeviceNode->ServiceName, Buffer);
|
||||
|
||||
|
||||
Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue