mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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
|
COMPONENTS = iface_native iface_additional hallib ntoskrnl
|
||||||
HALS = halx86
|
HALS = halx86
|
||||||
BUS = acpi isapnp
|
BUS = acpi isapnp pci
|
||||||
DLLS = ntdll kernel32 advapi32 crtdll msvcrt fmifs gdi32 msafd \
|
DLLS = ntdll kernel32 advapi32 crtdll msvcrt fmifs gdi32 msafd \
|
||||||
user32 oleaut32 secur32 shell32 ws2_32 version
|
user32 oleaut32 secur32 shell32 ws2_32 version
|
||||||
SUBSYS = smss win32k csrss
|
SUBSYS = smss win32k csrss
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef _INCLUDE_DDK_IOFUNCS_H
|
#ifndef _INCLUDE_DDK_IOFUNCS_H
|
||||||
#define _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 --- */
|
/* --- EXPORTED BY NTOSKRNL --- */
|
||||||
|
|
||||||
|
@ -625,6 +625,10 @@ IoGetConfigurationInformation (
|
||||||
((Irp)->Tail.Overlay.CurrentStackLocation)
|
((Irp)->Tail.Overlay.CurrentStackLocation)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define IoSetNextIrpStackLocation(Irp) { \
|
||||||
|
(Irp)->CurrentLocation--; \
|
||||||
|
(Irp)->Tail.Overlay.CurrentStackLocation--; }
|
||||||
|
|
||||||
#define IoCopyCurrentIrpStackLocationToNext(Irp) { \
|
#define IoCopyCurrentIrpStackLocationToNext(Irp) { \
|
||||||
PIO_STACK_LOCATION IrpSp; \
|
PIO_STACK_LOCATION IrpSp; \
|
||||||
PIO_STACK_LOCATION NextIrpSp; \
|
PIO_STACK_LOCATION NextIrpSp; \
|
||||||
|
@ -634,6 +638,10 @@ IoGetConfigurationInformation (
|
||||||
FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
|
FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
|
||||||
NextIrpSp->Control = 0; }
|
NextIrpSp->Control = 0; }
|
||||||
|
|
||||||
|
#define IoSkipCurrentIrpStackLocation(Irp) \
|
||||||
|
(Irp)->CurrentLocation++; \
|
||||||
|
(Irp)->Tail.Overlay.CurrentStackLocation++;
|
||||||
|
|
||||||
struct _EPROCESS*
|
struct _EPROCESS*
|
||||||
STDCALL
|
STDCALL
|
||||||
IoGetCurrentProcess (
|
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\fs\np\npfs.sys %ROS_INSTALL%\system32\drivers
|
||||||
copy services\bus\acpi\acpi.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\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\ide\ide.sys %ROS_INSTALL%\system32\drivers
|
||||||
copy services\dd\floppy\floppy.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
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -582,7 +582,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Path[0] != L'\\')
|
if ((RelativeTo == RTL_REGISTRY_ABSOLUTE) || (Path[0] != L'\\'))
|
||||||
{
|
{
|
||||||
RtlAppendUnicodeToString(&KeyName,
|
RtlAppendUnicodeToString(&KeyName,
|
||||||
Path);
|
Path);
|
||||||
|
|
|
@ -210,6 +210,7 @@ NtEnumerateKey (
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +224,7 @@ NtEnumerateKey (
|
||||||
if (RegistryFile == CmiVolatileFile)
|
if (RegistryFile == CmiVolatileFile)
|
||||||
{
|
{
|
||||||
ObDereferenceObject (KeyObject);
|
ObDereferenceObject (KeyObject);
|
||||||
|
DPRINT("No more volatile entries\n");
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -241,6 +243,7 @@ NtEnumerateKey (
|
||||||
if(Index >= KeyBlock->NumberOfSubKeys)
|
if(Index >= KeyBlock->NumberOfSubKeys)
|
||||||
{
|
{
|
||||||
ObDereferenceObject (KeyObject);
|
ObDereferenceObject (KeyObject);
|
||||||
|
DPRINT("No more non-volatile entries\n");
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
}
|
}
|
||||||
SubKeyBlock = CurKey->KeyBlock;
|
SubKeyBlock = CurKey->KeyBlock;
|
||||||
|
@ -256,6 +259,7 @@ NtEnumerateKey (
|
||||||
if (SubKeyBlock == NULL)
|
if (SubKeyBlock == NULL)
|
||||||
{
|
{
|
||||||
ObDereferenceObject (KeyObject);
|
ObDereferenceObject (KeyObject);
|
||||||
|
DPRINT("No more entries\n");
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +368,8 @@ NtEnumerateKey (
|
||||||
CmiReleaseBlock(RegistryFile, SubKeyBlock);
|
CmiReleaseBlock(RegistryFile, SubKeyBlock);
|
||||||
ObDereferenceObject (KeyObject);
|
ObDereferenceObject (KeyObject);
|
||||||
|
|
||||||
|
DPRINT("Returning status %x\n", Status);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,12 +126,12 @@ CmiCreateRegistry(PWSTR Filename)
|
||||||
DWORD FreeOffset;
|
DWORD FreeOffset;
|
||||||
int i, j;
|
int i, j;
|
||||||
BLOCK_OFFSET BlockOffset;
|
BLOCK_OFFSET BlockOffset;
|
||||||
DPRINT1("CmiCreateRegistry() Filename '%S'\n", Filename);
|
DPRINT("CmiCreateRegistry() Filename '%S'\n", Filename);
|
||||||
RegistryFile = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_FILE));
|
RegistryFile = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_FILE));
|
||||||
CHECKPOINT1;
|
|
||||||
if (RegistryFile == NULL)
|
if (RegistryFile == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
CHECKPOINT1;
|
|
||||||
if (Filename != NULL)
|
if (Filename != NULL)
|
||||||
{
|
{
|
||||||
UNICODE_STRING TmpFileName;
|
UNICODE_STRING TmpFileName;
|
||||||
|
@ -219,7 +219,7 @@ CHECKPOINT1;
|
||||||
if (RegistryFile->BlockList[0] == NULL)
|
if (RegistryFile->BlockList[0] == NULL)
|
||||||
{
|
{
|
||||||
// Status = STATUS_INSUFFICIENT_RESOURCES;
|
// Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
DPRINT1("error allocating %d bytes for registry\n"
|
DPRINT("error allocating %d bytes for registry\n"
|
||||||
,RegistryFile->FileSize-4096);
|
,RegistryFile->FileSize-4096);
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -232,7 +232,7 @@ CHECKPOINT1;
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
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);
|
,Status,fileOffset.u.LowPart);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ CHECKPOINT1;
|
||||||
tmpHeap = (PHEAP_BLOCK)(((char *)RegistryFile->BlockList [0])+BlockOffset);
|
tmpHeap = (PHEAP_BLOCK)(((char *)RegistryFile->BlockList [0])+BlockOffset);
|
||||||
if (tmpHeap->BlockId != REG_HEAP_ID )
|
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]
|
RegistryFile->BlockList [i]
|
||||||
= tmpHeap;
|
= tmpHeap;
|
||||||
|
|
|
@ -398,7 +398,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Path[0] != L'\\')
|
if ((RelativeTo == RTL_REGISTRY_ABSOLUTE) || (Path[0] != L'\\'))
|
||||||
{
|
{
|
||||||
RtlAppendUnicodeToString(&KeyName,
|
RtlAppendUnicodeToString(&KeyName,
|
||||||
Path);
|
Path);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -44,7 +44,7 @@ typedef struct _DEVICE_NODE
|
||||||
UNICODE_STRING InstancePath;
|
UNICODE_STRING InstancePath;
|
||||||
UNICODE_STRING ServiceName;
|
UNICODE_STRING ServiceName;
|
||||||
//TargetDeviceNotifyList?
|
//TargetDeviceNotifyList?
|
||||||
DEVICE_CAPABILITIES CapabilityFlags;
|
PDEVICE_CAPABILITIES CapabilityFlags;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
ULONG UserFlags;
|
ULONG UserFlags;
|
||||||
ULONG DisableableDepends;
|
ULONG DisableableDepends;
|
||||||
|
@ -52,6 +52,14 @@ typedef struct _DEVICE_NODE
|
||||||
PCM_RESOURCE_LIST CmResourceList;
|
PCM_RESOURCE_LIST CmResourceList;
|
||||||
PCM_RESOURCE_LIST BootResourcesList;
|
PCM_RESOURCE_LIST BootResourcesList;
|
||||||
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
|
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;
|
} DEVICE_NODE, *PDEVICE_NODE;
|
||||||
|
|
||||||
/* For Flags field */
|
/* For Flags field */
|
||||||
|
@ -103,6 +111,121 @@ typedef struct _DEVICE_NODE
|
||||||
#define CM_PROB_FAILED_INSTALL 28
|
#define CM_PROB_FAILED_INSTALL 28
|
||||||
#define CM_PROB_FAILED_ADD 31
|
#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 PDEVICE_NODE IopRootDeviceNode;
|
||||||
|
|
||||||
extern POBJECT_TYPE IoSymbolicLinkType;
|
extern POBJECT_TYPE IoSymbolicLinkType;
|
||||||
|
@ -110,15 +233,6 @@ extern POBJECT_TYPE IoSymbolicLinkType;
|
||||||
VOID
|
VOID
|
||||||
PnpInit(VOID);
|
PnpInit(VOID);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
PnpRootDriverEntry(
|
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
|
||||||
IN PUNICODE_STRING RegistryPath);
|
|
||||||
NTSTATUS
|
|
||||||
PnpRootCreateDevice(
|
|
||||||
PDEVICE_OBJECT *PhysicalDeviceObject);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject);
|
IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -129,7 +243,7 @@ NTSTATUS
|
||||||
IopFreeDeviceNode(PDEVICE_NODE DeviceNode);
|
IopFreeDeviceNode(PDEVICE_NODE DeviceNode);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
IopInterrogateBusExtender(PDEVICE_NODE DeviceNode,
|
IopInterrogateBusExtender(PDEVICE_NODE DeviceNode,
|
||||||
PDEVICE_OBJECT FunctionDeviceObject,
|
PDEVICE_OBJECT Pdo,
|
||||||
BOOLEAN BootDriversOnly);
|
BOOLEAN BootDriversOnly);
|
||||||
VOID
|
VOID
|
||||||
IopLoadBootStartDrivers(VOID);
|
IopLoadBootStartDrivers(VOID);
|
||||||
|
@ -203,4 +317,23 @@ IopInitiatePnpIrp(
|
||||||
ULONG MinorFunction,
|
ULONG MinorFunction,
|
||||||
PIO_STACK_LOCATION Stack);
|
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
|
#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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -358,17 +358,18 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
|
||||||
DriverObject, DeviceNode->Pdo);
|
DriverObject, DeviceNode->Pdo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExFreePool(DriverObject->DriverExtension);
|
|
||||||
ExFreePool(DriverObject);
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
|
||||||
|
|
||||||
DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
|
DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
|
||||||
|
|
||||||
Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo);
|
Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo);
|
||||||
|
|
||||||
if (Fdo == 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");
|
DbgPrint("An FDO was not attached\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
@ -386,8 +387,6 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
|
||||||
{
|
{
|
||||||
DPRINT("IopInitiatePnpIrp() failed\n");
|
DPRINT("IopInitiatePnpIrp() failed\n");
|
||||||
ObDereferenceObject(Fdo);
|
ObDereferenceObject(Fdo);
|
||||||
ExFreePool(DriverObject->DriverExtension);
|
|
||||||
ExFreePool(DriverObject);
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,8 +399,6 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Fdo);
|
ObDereferenceObject(Fdo);
|
||||||
ExFreePool(DriverObject->DriverExtension);
|
|
||||||
ExFreePool(DriverObject);
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,7 +453,9 @@ IopInitializeService(
|
||||||
|
|
||||||
ObDereferenceObject(ModuleObject);
|
ObDereferenceObject(ModuleObject);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
Status = IopInitializeDevice(DeviceNode, TRUE);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -515,6 +514,8 @@ IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Called to initalize a loaded driver
|
* FUNCTION: Called to initalize a loaded driver
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
* DriverEntry = Pointer to driver entry routine
|
||||||
|
* DeviceNode = Pointer to device node
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
WCHAR RegistryKeyBuffer[MAX_PATH];
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
#include <internal/io.h>
|
#include <internal/io.h>
|
||||||
#include <internal/po.h>
|
#include <internal/po.h>
|
||||||
#include <internal/ldr.h>
|
#include <internal/ldr.h>
|
||||||
|
#include <internal/registry.h>
|
||||||
#include <internal/module.h>
|
#include <internal/module.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#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
|
NTSTATUS
|
||||||
IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject)
|
IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject)
|
||||||
{
|
{
|
||||||
|
@ -304,6 +337,10 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
||||||
ExFreePool(Node);
|
ExFreePool(Node);
|
||||||
return Status;
|
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;
|
Node->Pdo = PhysicalDeviceObject;
|
||||||
|
@ -362,7 +399,42 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
|
||||||
|
|
||||||
RtlFreeUnicodeString(&DeviceNode->ServiceName);
|
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);
|
ExFreePool(DeviceNode);
|
||||||
|
|
||||||
|
@ -374,7 +446,7 @@ IopInitiatePnpIrp(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_STATUS_BLOCK IoStatusBlock,
|
PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
ULONG MinorFunction,
|
ULONG MinorFunction,
|
||||||
PIO_STACK_LOCATION Stack)
|
PIO_STACK_LOCATION Stack OPTIONAL)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT TopDeviceObject;
|
PDEVICE_OBJECT TopDeviceObject;
|
||||||
PIO_STACK_LOCATION IrpSp;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
|
@ -393,6 +465,7 @@ IopInitiatePnpIrp(
|
||||||
/* PNP IRPs are always initialized with a status code of
|
/* PNP IRPs are always initialized with a status code of
|
||||||
STATUS_NOT_IMPLEMENTED */
|
STATUS_NOT_IMPLEMENTED */
|
||||||
IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
|
IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
IoStatusBlock->Information = 0;
|
||||||
|
|
||||||
Irp = IoBuildSynchronousFsdRequest(
|
Irp = IoBuildSynchronousFsdRequest(
|
||||||
IRP_MJ_PNP,
|
IRP_MJ_PNP,
|
||||||
|
@ -405,10 +478,14 @@ IopInitiatePnpIrp(
|
||||||
|
|
||||||
IrpSp = IoGetNextIrpStackLocation(Irp);
|
IrpSp = IoGetNextIrpStackLocation(Irp);
|
||||||
IrpSp->MinorFunction = MinorFunction;
|
IrpSp->MinorFunction = MinorFunction;
|
||||||
RtlMoveMemory(
|
|
||||||
&IrpSp->Parameters,
|
if (Stack)
|
||||||
&Stack->Parameters,
|
{
|
||||||
sizeof(Stack->Parameters));
|
RtlMoveMemory(
|
||||||
|
&IrpSp->Parameters,
|
||||||
|
&Stack->Parameters,
|
||||||
|
sizeof(Stack->Parameters));
|
||||||
|
}
|
||||||
|
|
||||||
Status = IoCallDriver(TopDeviceObject, Irp);
|
Status = IoCallDriver(TopDeviceObject, Irp);
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
|
@ -422,166 +499,661 @@ IopInitiatePnpIrp(
|
||||||
Status = IoStatusBlock->Status;
|
Status = IoStatusBlock->Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(TopDeviceObject);
|
||||||
|
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
IopInterrogateBusExtender(
|
IopInterrogateBusExtender(
|
||||||
PDEVICE_NODE DeviceNode,
|
PDEVICE_NODE DeviceNode,
|
||||||
PDEVICE_OBJECT FunctionDeviceObject,
|
PDEVICE_OBJECT Pdo,
|
||||||
BOOLEAN BootDriversOnly)
|
BOOLEAN BootDriversOnly)
|
||||||
{
|
{
|
||||||
|
DEVICETREE_TRAVERSE_CONTEXT Context;
|
||||||
PDEVICE_RELATIONS DeviceRelations;
|
PDEVICE_RELATIONS DeviceRelations;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
UNICODE_STRING DriverName;
|
PDEVICE_NODE ChildDeviceNode;
|
||||||
IO_STACK_LOCATION Stack;
|
IO_STACK_LOCATION Stack;
|
||||||
NTSTATUS Status;
|
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;
|
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
|
||||||
|
|
||||||
Status = IopInitiatePnpIrp(
|
Status = IopInitiatePnpIrp(
|
||||||
FunctionDeviceObject,
|
Pdo,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
IRP_MN_QUERY_DEVICE_RELATIONS,
|
IRP_MN_QUERY_DEVICE_RELATIONS,
|
||||||
&Stack);
|
&Stack);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("IopInitiatePnpIrp() failed\n");
|
DPRINT("IopInitiatePnpIrp() failed\n");
|
||||||
}
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
|
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);
|
DPRINT("Got %d PDOs\n", DeviceRelations->Count);
|
||||||
|
|
||||||
if (DeviceRelations->Count <= 0)
|
#ifdef DBG
|
||||||
{
|
{
|
||||||
DPRINT("No PDOs\n");
|
ULONG i;
|
||||||
ExFreePool(DeviceRelations);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IopCreateDeviceNode(DeviceNode, NULL, &DeviceNode);
|
DPRINT("DeviceRelations %x\n", DeviceRelations);
|
||||||
if (!NT_SUCCESS(Status))
|
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");
|
DPRINT("No resources\n");
|
||||||
|
for (i = 0; i < DeviceRelations->Count; i++)
|
||||||
|
ObDereferenceObject(DeviceRelations->Objects[i]);
|
||||||
ExFreePool(DeviceRelations);
|
ExFreePool(DeviceRelations);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
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);
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID IopLoadBootStartDrivers(VOID)
|
VOID IopLoadBootStartDrivers(VOID)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
IopInterrogateBusExtender(
|
||||||
PKEY_BASIC_INFORMATION KeyInfo;
|
IopRootDeviceNode,
|
||||||
PDEVICE_NODE DeviceNode;
|
IopRootDeviceNode->Pdo,
|
||||||
UNICODE_STRING KeyName;
|
TRUE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID PnpInit(VOID)
|
VOID PnpInit(VOID)
|
||||||
{
|
{
|
||||||
|
PDEVICE_OBJECT Pdo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("Called\n");
|
DPRINT("Called\n");
|
||||||
|
@ -590,25 +1162,44 @@ VOID PnpInit(VOID)
|
||||||
|
|
||||||
Status = IopCreateDriverObject(&IopRootDriverObject);
|
Status = IopCreateDriverObject(&IopRootDriverObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CPRINT("IoCreateDriverObject() failed\n");
|
CPRINT("IoCreateDriverObject() failed\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(PHASE1_INITIALIZATION_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
PnpRootDriverEntry(IopRootDriverObject, NULL);
|
Status = IoCreateDevice(
|
||||||
|
IopRootDriverObject,
|
||||||
Status = IoCreateDevice(IopRootDriverObject, 0, NULL,
|
0,
|
||||||
FILE_DEVICE_CONTROLLER, 0, FALSE, &IopRootDeviceNode->Pdo);
|
NULL,
|
||||||
|
FILE_DEVICE_CONTROLLER,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&Pdo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CPRINT("IoCreateDevice() failed\n");
|
CPRINT("IoCreateDevice() failed\n");
|
||||||
KeBugCheck(0);
|
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->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||||
|
|
||||||
|
IopRootDeviceNode->DriverObject = IopRootDriverObject;
|
||||||
|
|
||||||
|
PnpRootDriverEntry(IopRootDriverObject, NULL);
|
||||||
|
|
||||||
IopRootDriverObject->DriverExtension->AddDevice(
|
IopRootDriverObject->DriverExtension->AddDevice(
|
||||||
IopRootDriverObject, IopRootDeviceNode->Pdo);
|
IopRootDriverObject,
|
||||||
|
IopRootDeviceNode->Pdo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -13,55 +13,168 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <internal/io.h>
|
#include <internal/io.h>
|
||||||
|
#include <internal/registry.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
#define ENUM_NAME_ROOT L"Root"
|
||||||
|
|
||||||
/* DATA **********************************************************************/
|
/* DATA **********************************************************************/
|
||||||
|
|
||||||
typedef struct _PNPROOT_DEVICE {
|
typedef struct _PNPROOT_DEVICE {
|
||||||
|
// Entry on device list
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
|
// Physical Device Object of device
|
||||||
PDEVICE_OBJECT Pdo;
|
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;
|
} 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;
|
PDEVICE_OBJECT PnpRootDeviceObject;
|
||||||
LIST_ENTRY PnpRootDeviceListHead;
|
|
||||||
ULONG PnpRootDeviceListCount;
|
|
||||||
KSPIN_LOCK PnpRootDeviceListLock;
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
/* Physical Device Object routines */
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PnpRootCreateDevice(
|
PnpRootCreateDevice(
|
||||||
PDEVICE_OBJECT *PhysicalDeviceObject)
|
PDEVICE_OBJECT *PhysicalDeviceObject)
|
||||||
{
|
{
|
||||||
|
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||||
|
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
PPNPROOT_DEVICE Device;
|
PPNPROOT_DEVICE Device;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* This function should be obsoleted soon */
|
||||||
|
|
||||||
DPRINT("Called\n");
|
DPRINT("Called\n");
|
||||||
|
|
||||||
|
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
|
Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
|
||||||
if (!Device)
|
if (!Device)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
Status = IoCreateDevice(PnpRootDeviceObject->DriverObject, 0,
|
RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
|
||||||
NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
|
|
||||||
if (!NT_SUCCESS(Status))
|
Status = IoCreateDevice(
|
||||||
{
|
PnpRootDeviceObject->DriverObject,
|
||||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
sizeof(PNPROOT_PDO_DEVICE_EXTENSION),
|
||||||
ExFreePool(Device);
|
NULL,
|
||||||
return Status;
|
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;
|
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,
|
&Device->ListEntry,
|
||||||
&PnpRootDeviceListLock);
|
&DeviceExtension->DeviceListLock);
|
||||||
|
|
||||||
|
DeviceExtension->DeviceListCount++;
|
||||||
|
|
||||||
*PhysicalDeviceObject = Device->Pdo;
|
*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
|
NTSTATUS
|
||||||
PnpRootQueryBusRelations(
|
PnpRootQueryBusRelations(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_STACK_LOCATION IrpSp)
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||||
|
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
PDEVICE_RELATIONS Relations;
|
PDEVICE_RELATIONS Relations;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PPNPROOT_DEVICE Device;
|
PPNPROOT_DEVICE Device;
|
||||||
|
@ -84,33 +590,92 @@ PnpRootQueryBusRelations(
|
||||||
|
|
||||||
DPRINT("Called\n");
|
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) *
|
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
|
||||||
(PnpRootDeviceListCount - 1);
|
(DeviceExtension->DeviceListCount - 1);
|
||||||
|
|
||||||
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
|
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
|
||||||
if (!Relations)
|
if (!Relations)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
Relations->Count = PnpRootDeviceListCount;
|
Relations->Count = DeviceExtension->DeviceListCount;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
CurrentEntry = PnpRootDeviceListHead.Flink;
|
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
|
||||||
while (CurrentEntry != &PnpRootDeviceListHead)
|
while (CurrentEntry != &DeviceExtension->DeviceListHead)
|
||||||
{
|
{
|
||||||
Device = CONTAINING_RECORD(
|
Device = CONTAINING_RECORD(CurrentEntry, PNPROOT_DEVICE, ListEntry);
|
||||||
CurrentEntry, PNPROOT_DEVICE, ListEntry);
|
|
||||||
|
|
||||||
if (!Device->Pdo) {
|
if (!Device->Pdo)
|
||||||
|
{
|
||||||
/* Create a physical device object for the
|
/* Create a physical device object for the
|
||||||
device as it does not already have one */
|
device as it does not already have one */
|
||||||
Status = IoCreateDevice(DeviceObject->DriverObject, 0,
|
Status = IoCreateDevice(
|
||||||
NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
|
DeviceObject->DriverObject,
|
||||||
if (!NT_SUCCESS(Status)) {
|
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);
|
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
||||||
ExFreePool(Relations);
|
ExFreePool(Relations);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("Created PDO %x\n", Device->Pdo);
|
||||||
|
|
||||||
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
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
|
/* Reference the physical device object. The PnP manager
|
||||||
|
@ -122,13 +687,21 @@ PnpRootQueryBusRelations(
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PnpRootQueryDeviceRelations(
|
PnpRootQueryDeviceRelations(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -139,42 +712,52 @@ PnpRootQueryDeviceRelations(
|
||||||
|
|
||||||
DPRINT("Called\n");
|
DPRINT("Called\n");
|
||||||
|
|
||||||
switch (IrpSp->Parameters.QueryDeviceRelations.Type)
|
switch (IrpSp->Parameters.QueryDeviceRelations.Type) {
|
||||||
{
|
|
||||||
case BusRelations:
|
case BusRelations:
|
||||||
Status = PnpRootQueryBusRelations(DeviceObject, Irp, IrpSp);
|
Status = PnpRootQueryBusRelations(DeviceObject, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
PnpRootPnpControl(
|
PnpRootFdoPnpControl(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
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;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("Called\n");
|
DPRINT("Called\n");
|
||||||
|
|
||||||
|
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
Status = Irp->IoStatus.Status;
|
Status = Irp->IoStatus.Status;
|
||||||
|
|
||||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
switch (IrpSp->MinorFunction)
|
switch (IrpSp->MinorFunction) {
|
||||||
{
|
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
Status = PnpRootQueryDeviceRelations(DeviceObject, Irp, IrpSp);
|
Status = PnpRootQueryDeviceRelations(DeviceObject, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_START_DEVICE:
|
||||||
PnpRootDeviceListCount = 0;
|
DeviceExtension->State = dsStarted;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -187,24 +770,32 @@ PnpRootPnpControl(
|
||||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status != STATUS_PENDING)
|
if (Status != STATUS_PENDING) {
|
||||||
{
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Status = Status;
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
PnpRootPowerControl(
|
PnpRootFdoPowerControl(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
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;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -212,70 +803,150 @@ PnpRootPowerControl(
|
||||||
DPRINT("Called\n");
|
DPRINT("Called\n");
|
||||||
|
|
||||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
switch (IrpSp->MinorFunction)
|
|
||||||
{
|
switch (IrpSp->MinorFunction) {
|
||||||
default:
|
default:
|
||||||
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status != STATUS_PENDING)
|
if (Status != STATUS_PENDING) {
|
||||||
{
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Status = Status;
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Leaving. Status 0x%X\n", Status);
|
DPRINT("Leaving. Status 0x%X\n", Status);
|
||||||
|
|
||||||
return 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
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
PnpRootAddDevice(
|
PnpRootAddDevice(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT Ldo;
|
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("Called\n");
|
DPRINT("Called\n");
|
||||||
|
|
||||||
Status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_BUS_EXTENDER,
|
Status = IoCreateDevice(
|
||||||
FILE_DEVICE_SECURE_OPEN, TRUE, &PnpRootDeviceObject);
|
DriverObject,
|
||||||
if (!NT_SUCCESS(Status))
|
sizeof(PNPROOT_FDO_DEVICE_EXTENSION),
|
||||||
{
|
NULL,
|
||||||
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
|
FILE_DEVICE_BUS_EXTENDER,
|
||||||
KeBugCheck(0);
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
return Status;
|
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)
|
RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
|
||||||
{
|
|
||||||
DbgPrint("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject);
|
|
||||||
KeBugCheck(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PhysicalDeviceObject)
|
DeviceExtension->IsFDO = TRUE;
|
||||||
{
|
|
||||||
DbgPrint("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject);
|
|
||||||
KeBugCheck(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeListHead(&PnpRootDeviceListHead);
|
DeviceExtension->State = dsStopped;
|
||||||
PnpRootDeviceListCount = 0;
|
|
||||||
KeInitializeSpinLock(&PnpRootDeviceListLock);
|
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;
|
PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
DPRINT("Done\n");
|
//PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
|
||||||
|
|
||||||
|
DPRINT("Done AddDevice()\n");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
PnpRootDriverEntry(
|
PnpRootDriverEntry(
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/main.c
|
* FILE: ntoskrnl/ke/main.c
|
||||||
|
@ -84,9 +84,10 @@ typedef struct
|
||||||
} SERVICE, *PSERVICE;
|
} SERVICE, *PSERVICE;
|
||||||
|
|
||||||
SERVICE Services[] = {
|
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"keyboard", L"Standard Keyboard Driver", L"Base", 0, 1},
|
||||||
{L"blue", L"Bluescreen 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"vgamp", L"VGA Miniport", L"Base", 0, 1},
|
||||||
{L"minixfs", L"Minix File System", L"File system", 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},
|
{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"mouclass", L"Mouse Class Driver", L"Pointer Class", 0, 1},
|
||||||
{L"ndis", L"NDIS System Driver", L"NDIS Wrapper", 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"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,}
|
{NULL,}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
//#define FULLREG
|
||||||
|
|
||||||
VOID CreateDefaultRegistryForLegacyDriver(
|
VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
PSERVICE Service)
|
PSERVICE Service)
|
||||||
{
|
{
|
||||||
|
#ifdef FULLREG
|
||||||
WCHAR LegacyDriver[] = L"LegacyDriver";
|
WCHAR LegacyDriver[] = L"LegacyDriver";
|
||||||
|
#endif
|
||||||
WCHAR InstancePath[MAX_PATH];
|
WCHAR InstancePath[MAX_PATH];
|
||||||
WCHAR KeyNameBuffer[MAX_PATH];
|
WCHAR KeyNameBuffer[MAX_PATH];
|
||||||
WCHAR Name[MAX_PATH];
|
WCHAR Name[MAX_PATH];
|
||||||
UNICODE_STRING KeyName;
|
UNICODE_STRING KeyName;
|
||||||
HANDLE KeyHandle;
|
HANDLE KeyHandle;
|
||||||
|
#ifdef FULLREG
|
||||||
DWORD DwordData;
|
DWORD DwordData;
|
||||||
|
#endif
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
WCHAR ImagePath[MAX_PATH];
|
WCHAR ImagePath[MAX_PATH];
|
||||||
|
@ -146,7 +153,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef FULLREG
|
||||||
DwordData = 0;
|
DwordData = 0;
|
||||||
Length = sizeof(DWORD);
|
Length = sizeof(DWORD);
|
||||||
Status = RtlWriteRegistryValue(
|
Status = RtlWriteRegistryValue(
|
||||||
|
@ -177,7 +184,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
|
Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
|
||||||
Status = RtlWriteRegistryValue(
|
Status = RtlWriteRegistryValue(
|
||||||
RTL_REGISTRY_HANDLE,
|
RTL_REGISTRY_HANDLE,
|
||||||
|
@ -192,7 +199,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef FULLREG
|
||||||
DwordData = 0;
|
DwordData = 0;
|
||||||
Length = Length = sizeof(DWORD);
|
Length = Length = sizeof(DWORD);
|
||||||
Status = RtlWriteRegistryValue(
|
Status = RtlWriteRegistryValue(
|
||||||
|
@ -208,7 +215,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Length = (wcslen(Service->ServiceName) + 1) * sizeof(WCHAR);
|
Length = (wcslen(Service->ServiceName) + 1) * sizeof(WCHAR);
|
||||||
Status = RtlWriteRegistryValue(
|
Status = RtlWriteRegistryValue(
|
||||||
RTL_REGISTRY_HANDLE,
|
RTL_REGISTRY_HANDLE,
|
||||||
|
@ -226,6 +233,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
|
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
|
|
||||||
|
|
||||||
/* Services section */
|
/* Services section */
|
||||||
|
|
||||||
Status = RtlpGetRegistryHandle(
|
Status = RtlpGetRegistryHandle(
|
||||||
|
@ -238,7 +246,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef FULLREG
|
||||||
Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
|
Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
|
||||||
Status = RtlWriteRegistryValue(
|
Status = RtlWriteRegistryValue(
|
||||||
RTL_REGISTRY_HANDLE,
|
RTL_REGISTRY_HANDLE,
|
||||||
|
@ -284,7 +292,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
wcscpy(ImagePath, L"\\SystemRoot\\System32\\drivers\\");
|
wcscpy(ImagePath, L"\\SystemRoot\\System32\\drivers\\");
|
||||||
wcscat(ImagePath, Service->ServiceName);
|
wcscat(ImagePath, Service->ServiceName);
|
||||||
wcscat(ImagePath, L".sys");
|
wcscat(ImagePath, L".sys");
|
||||||
|
@ -303,7 +311,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if FULLREG
|
||||||
DwordData = Service->Start;
|
DwordData = Service->Start;
|
||||||
Length = sizeof(DWORD);
|
Length = sizeof(DWORD);
|
||||||
Status = RtlWriteRegistryValue(
|
Status = RtlWriteRegistryValue(
|
||||||
|
@ -335,7 +343,7 @@ VOID CreateDefaultRegistryForLegacyDriver(
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
NtClose(KeyHandle);
|
NtClose(KeyHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,14 +355,14 @@ VOID CreateDefaultRegistry()
|
||||||
Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
|
Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,7 +1059,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
|
||||||
* This should be done by the boot loader.
|
* This should be done by the boot loader.
|
||||||
*/
|
*/
|
||||||
strcpy (KeLoaderCommandLine,
|
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);
|
strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
|
||||||
|
|
||||||
KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -882,6 +882,11 @@ VOID LdrLoadAutoConfigDrivers (VOID)
|
||||||
|
|
||||||
#endif /* KDBG */
|
#endif /* KDBG */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PCI bus driver
|
||||||
|
*/
|
||||||
|
//LdrLoadAutoConfigDriver( L"pci.sys" );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keyboard driver
|
* Keyboard driver
|
||||||
*/
|
*/
|
||||||
|
@ -951,7 +956,7 @@ VOID LdrLoadAutoConfigDrivers (VOID)
|
||||||
/*
|
/*
|
||||||
* Ancillary Function Driver
|
* Ancillary Function Driver
|
||||||
*/
|
*/
|
||||||
//LdrLoadAutoConfigDriver(L"afd.sys");
|
LdrLoadAutoConfigDriver(L"afd.sys");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -990,7 +995,11 @@ NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename,
|
||||||
BOOLEAN BootDriversOnly)
|
BOOLEAN BootDriversOnly)
|
||||||
{
|
{
|
||||||
PMODULE_OBJECT ModuleObject;
|
PMODULE_OBJECT ModuleObject;
|
||||||
|
WCHAR Buffer[MAX_PATH];
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG Length;
|
||||||
|
LPWSTR Start;
|
||||||
|
LPWSTR Ext;
|
||||||
|
|
||||||
ModuleObject = LdrLoadModule(Filename);
|
ModuleObject = LdrLoadModule(Filename);
|
||||||
if (!ModuleObject)
|
if (!ModuleObject)
|
||||||
|
@ -998,6 +1007,25 @@ NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename,
|
||||||
return STATUS_UNSUCCESSFUL;
|
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);
|
Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue