Enumerate legacy devices

svn path=/trunk/; revision=2254
This commit is contained in:
Casper Hornstrup 2001-09-16 13:19:32 +00:00
parent 9baaca2418
commit 09237b9213
13 changed files with 1705 additions and 258 deletions

View file

@ -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

View file

@ -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 (

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -398,7 +398,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
break;
}
if (Path[0] != L'\\')
if ((RelativeTo == RTL_REGISTRY_ABSOLUTE) || (Path[0] != L'\\'))
{
RtlAppendUnicodeToString(&KeyName,
Path);

View file

@ -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

View file

@ -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];

View file

@ -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 */

View file

@ -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(

View file

@ -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;

View file

@ -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))
{