Commit in reactos/ntoskrnl on MAIN
include/internal/io.h+37-401.40 -> 1.41
                /ldr.h-51.26 -> 1.27
io/device.c+463-7371.68 -> 1.69
  /driver.c+690-2831.38 -> 1.39
  /iomgr.c+20-71.45 -> 1.46
  /pnpmgr.c+57-131.27 -> 1.28
ldr/loader.c+1-1021.140 -> 1.141
+1268-1187
7 modified files
- Rewritten some driver loading functions to get higher control of the driver loading and initialization process (Fixes bug #263).
- Added support for lower level filter drivers.

reactos/ntoskrnl/include/internal
io.h 1.40 -> 1.41
diff -u -r1.40 -r1.41
--- io.h	21 Mar 2004 18:58:52 -0000	1.40
+++ io.h	27 Mar 2004 19:41:31 -0000	1.41
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: io.h,v 1.40 2004/03/21 18:58:52 navaraf Exp $
+/* $Id: io.h,v 1.41 2004/03/27 19:41:31 navaraf Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -32,6 +32,7 @@
 
 #include <ddk/ntddk.h>
 #include <internal/ob.h>
+#include <internal/module.h>
 
 
 #ifndef __USE_W32API
@@ -62,7 +63,6 @@
   struct _DEVICE_NODE *PrevSibling;
   struct _DEVICE_NODE *NextSibling;
   struct _DEVICE_NODE *Child;
-  PDRIVER_OBJECT DriverObject;
   PDEVICE_OBJECT Pdo;
   UNICODE_STRING InstancePath;
   UNICODE_STRING ServiceName;
@@ -266,19 +266,6 @@
 NTSTATUS
 IopFreeDeviceNode(PDEVICE_NODE DeviceNode);
 
-NTSTATUS
-IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
-		      PUNICODE_STRING ServiceName,
-		      BOOLEAN FileSystemDriver,
-		      PVOID DriverImageStart,
-		      ULONG DriverImageSize);
-NTSTATUS
-IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
-		    PDEVICE_NODE DeviceNode,
-		    BOOLEAN FileSystemDriver,
-		    PVOID DriverImageStart,
-		    ULONG DriverImageSize,
-		    BOOLEAN BootDriver);
 VOID
 IoInitCancelHandling(VOID);
 VOID
@@ -388,37 +375,48 @@
 
 /* device.c */
 
-NTSTATUS
-IopAttachFilterDrivers(
-  PDEVICE_NODE DeviceNode,
-  BOOLEAN Lower);
-
-NTSTATUS
-IopInitializeService(
-  PDEVICE_NODE DeviceNode,
-  PUNICODE_STRING ServiceName,
-  PUNICODE_STRING ImagePath);
+NTSTATUS FASTCALL
+IopInitializeDevice(
+   PDEVICE_NODE DeviceNode,
+   PDRIVER_OBJECT DriverObject);
 
 /* driver.c */
 
-VOID
-IopInitializeBootDrivers(
-  VOID);
+VOID FASTCALL
+IopInitializeBootDrivers(VOID);
 
-VOID
-IopInitializeSystemDrivers(
-  VOID);
+VOID FASTCALL
+IopInitializeSystemDrivers(VOID);
 
-NTSTATUS
-IopInitializeDeviceNodeService(
-  PDEVICE_NODE DeviceNode,
-  PUNICODE_STRING ServiceName,
-  BOOLEAN BootDriverOnly);
+NTSTATUS FASTCALL
+IopCreateDriverObject(
+   PDRIVER_OBJECT *DriverObject,
+   PUNICODE_STRING ServiceName,
+   BOOLEAN FileSystemDriver,
+   PVOID DriverImageStart,
+   ULONG DriverImageSize);
+
+NTSTATUS FASTCALL
+IopLoadServiceModule(
+   IN PUNICODE_STRING ServiceName,
+   OUT PMODULE_OBJECT *ModuleObject);
 
-VOID
+NTSTATUS FASTCALL
+IopInitializeDriverModule(
+   IN PDEVICE_NODE DeviceNode,
+   IN PMODULE_OBJECT ModuleObject,
+   IN BOOLEAN FileSystemDriver,
+   OUT PDRIVER_OBJECT *DriverObject);
+
+NTSTATUS FASTCALL
+IopAttachFilterDrivers(
+   PDEVICE_NODE DeviceNode,
+   BOOLEAN Lower);
+
+VOID FASTCALL
 IopMarkLastReinitializeDriver(VOID);
 
-VOID
+VOID FASTCALL
 IopReinitializeDrivers(VOID);
 
 /* pnpmgr.c */
@@ -431,7 +429,6 @@
 NTSTATUS
 IopInvalidateDeviceRelations(
    IN PDEVICE_NODE DeviceNode,
-   IN DEVICE_RELATION_TYPE Type,
-   IN BOOLEAN BootDriver);
+   IN DEVICE_RELATION_TYPE Type);
 
 #endif

reactos/ntoskrnl/include/internal
ldr.h 1.26 -> 1.27
diff -u -r1.26 -r1.27
--- ldr.h	13 Sep 2003 06:17:51 -0000	1.26
+++ ldr.h	27 Mar 2004 19:41:31 -0000	1.27
@@ -35,11 +35,6 @@
 	);
 
 NTSTATUS
-LdrInitializeBootStartDriver(IN PVOID ModuleLoadBase,
-			     IN PCHAR FileName,
-			     IN ULONG ModuleLength);
-
-NTSTATUS
 LdrpMapSystemDll (
 	HANDLE	ProcessHandle,
 	PVOID	* LdrStartupAddress

reactos/ntoskrnl/io
device.c 1.68 -> 1.69
diff -u -r1.68 -r1.69
--- device.c	21 Mar 2004 18:58:53 -0000	1.68
+++ device.c	27 Mar 2004 19:41:32 -0000	1.69
@@ -1,4 +1,4 @@
-/* $Id: device.c,v 1.68 2004/03/21 18:58:53 navaraf Exp $
+/* $Id: device.c,v 1.69 2004/03/27 19:41:32 navaraf Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel
@@ -9,7 +9,7 @@
  *                 15/05/98: Created
  */
 
-/* INCLUDES ****************************************************************/
+/* INCLUDES *******************************************************************/
 
 #define NTOS_MODE_KERNEL
 #include <ntos.h>
@@ -22,99 +22,219 @@
 #include <roscfg.h>
 
 #define NDEBUG
-//#define DBG
 #include <internal/debug.h>
 
-/* GLOBALS *******************************************************************/
+#define ASSERT assert
+
+/* GLOBALS ********************************************************************/
 
-#define TAG_DRIVER             TAG('D', 'R', 'V', 'R')
-#define TAG_DRIVER_EXTENSION   TAG('D', 'R', 'V', 'E')
 #define TAG_DEVICE_EXTENSION   TAG('D', 'E', 'X', 'T')
 
-#define DRIVER_REGISTRY_KEY_BASENAME  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
+/* PRIVATE FUNCTIONS **********************************************************/
+
+NTSTATUS FASTCALL
+IopInitializeDevice(
+   PDEVICE_NODE DeviceNode,
+   PDRIVER_OBJECT DriverObject)
+{
+   IO_STATUS_BLOCK IoStatusBlock;
+   IO_STACK_LOCATION Stack;
+   PDEVICE_OBJECT Fdo;
+   NTSTATUS Status;
+
+   if (DriverObject->DriverExtension->AddDevice)
+   {
+      /* This is a Plug and Play driver */
+      DPRINT("Plug and Play driver found\n");
+
+      ASSERT(DeviceNode->Pdo);
+
+      DPRINT("Calling driver AddDevice entrypoint at %08lx\n",
+         DriverObject->DriverExtension->AddDevice);
+
+      Status = DriverObject->DriverExtension->AddDevice(
+         DriverObject, DeviceNode->Pdo);
+
+      if (!NT_SUCCESS(Status))
+      {
+         return Status;
+      }
+
+      Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo);
+
+      if (Fdo == DeviceNode->Pdo)
+      {
+         /* FIXME: What do we do? Unload the driver or just disable the device? */
+         DbgPrint("An FDO was not attached\n");
+         KEBUGCHECK(0);
+      }
+
+      IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
+
+      DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
+
+      /* FIXME: Put some resources in the IRP for the device */
+      Stack.Parameters.StartDevice.AllocatedResources = NULL;
+      Stack.Parameters.StartDevice.AllocatedResourcesTranslated = NULL;
+
+      Status = IopInitiatePnpIrp(
+         Fdo,
+         &IoStatusBlock,
+         IRP_MN_START_DEVICE,
+         &Stack);
+
+      if (!NT_SUCCESS(Status))
+      {
+          DPRINT("IopInitiatePnpIrp() failed\n");
+          ObDereferenceObject(Fdo);
+          return Status;
+      }
+
+      if (Fdo->DeviceType == FILE_DEVICE_BUS_EXTENDER)
+      {
+         DPRINT("Bus extender found\n");
+
+         Status = IopInvalidateDeviceRelations(DeviceNode, BusRelations);
+
+         if (!NT_SUCCESS(Status))
+         {
+            ObDereferenceObject(Fdo);
+            return Status;
+         }
+      }
+      else if (Fdo->DeviceType == FILE_DEVICE_ACPI)
+      {
+#ifdef ACPI
+         static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
+
+         /* There can be only one system power device */
+         if (!SystemPowerDeviceNodeCreated)
+         {
+            PopSystemPowerDeviceNode = DeviceNode;
+            SystemPowerDeviceNodeCreated = TRUE;
+         }
+#endif /* ACPI */
+      }
+      ObDereferenceObject(Fdo);
+   }
+
+   return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+IopCreateDevice(
+   PVOID ObjectBody,
+   PVOID Parent,
+   PWSTR RemainingPath,
+   POBJECT_ATTRIBUTES ObjectAttributes)
+{
+   DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n",
+      ObjectBody, Parent, RemainingPath);
+   
+   if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
+      return STATUS_UNSUCCESSFUL;
+   
+   return STATUS_SUCCESS;
+}
 
-/* FUNCTIONS ***************************************************************/
+/* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
- * @implemented
+ * IoAttachDeviceByPointer
+ *
+ * Status
+ *    @implemented
  */
+
 NTSTATUS STDCALL
-IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice,
-			IN PDEVICE_OBJECT TargetDevice)
+IoAttachDeviceByPointer(
+   IN PDEVICE_OBJECT SourceDevice,
+   IN PDEVICE_OBJECT TargetDevice)
 {
-	PDEVICE_OBJECT AttachedDevice;
+   PDEVICE_OBJECT AttachedDevice;
 
-	DPRINT("IoAttachDeviceByPointer(SourceDevice %x, TargetDevice %x)\n",
-	       SourceDevice,
-	       TargetDevice);
+   DPRINT("IoAttachDeviceByPointer(SourceDevice %x, TargetDevice %x)\n",
+      SourceDevice, TargetDevice);
 
-	AttachedDevice = IoAttachDeviceToDeviceStack (SourceDevice,
-	                                              TargetDevice);
-	if (AttachedDevice == NULL)
-		return STATUS_NO_SUCH_DEVICE;
+   AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice, TargetDevice);
+   if (AttachedDevice == NULL)
+      return STATUS_NO_SUCH_DEVICE;
 
-	return STATUS_SUCCESS;
+   return STATUS_SUCCESS;
 }
 
-
 /*
- * @implemented
+ * IoDeleteDevice
+ *
+ * Status
+ *    @implemented
  */
+
 VOID STDCALL
 IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
 {
-	PDEVICE_OBJECT Previous;
+   PDEVICE_OBJECT Previous;
 
-	if (DeviceObject->Flags & DO_SHUTDOWN_REGISTERED)
-		IoUnregisterShutdownNotification(DeviceObject);
+   if (DeviceObject->Flags & DO_SHUTDOWN_REGISTERED)
+      IoUnregisterShutdownNotification(DeviceObject);
 
-	/* remove the timer if it exists */
-	if (DeviceObject->Timer)
-	{
-		IoStopTimer(DeviceObject);
-		ExFreePool(DeviceObject->Timer);
-	}
-
-	/* free device extension */
-	if (DeviceObject->DeviceObjectExtension)
-		ExFreePool (DeviceObject->DeviceObjectExtension);
+   /* Remove the timer if it exists */
+   if (DeviceObject->Timer)
+   {
+      IoStopTimer(DeviceObject);
+      ExFreePool(DeviceObject->Timer);
+   }
 
-	/* remove device from driver device list */
-	Previous = DeviceObject->DriverObject->DeviceObject;
-	if (Previous == DeviceObject)
-	{
-		DeviceObject->DriverObject->DeviceObject = DeviceObject->NextDevice;
-	}
-	else
-	{
-		while (Previous->NextDevice != DeviceObject)
-			Previous = Previous->NextDevice;
-		Previous->NextDevice = DeviceObject->NextDevice;
-	}
+   /* Free device extension */
+   if (DeviceObject->DeviceObjectExtension)
+      ExFreePool(DeviceObject->DeviceObjectExtension);
+
+   /* Remove device from driver device list */
+   Previous = DeviceObject->DriverObject->DeviceObject;
+   if (Previous == DeviceObject)
+   {
+      DeviceObject->DriverObject->DeviceObject = DeviceObject->NextDevice;
+   }
+   else
+   {
+      while (Previous->NextDevice != DeviceObject)
+         Previous = Previous->NextDevice;
+      Previous->NextDevice = DeviceObject->NextDevice;
+   }
 
-	ObDereferenceObject (DeviceObject);
+   ObDereferenceObject(DeviceObject);
 }
 
-
 /*
- * @implemented
+ * IoGetRelatedDeviceObject
+ *
+ * Remarks
+ *    See "Windows NT File System Internals", page 633 - 634.
+ *
+ * Status
+ *    @implemented
  */
-PDEVICE_OBJECT
-STDCALL
-IoGetRelatedDeviceObject (
-	IN	PFILE_OBJECT	FileObject
-	)
+
+PDEVICE_OBJECT STDCALL
+IoGetRelatedDeviceObject(
+   IN PFILE_OBJECT FileObject)
 {
-   /*Win NT File System Internals, page 633-634*/
+   /*
+    * Get logical volume mounted on a physical/virtual/logical device
+    */
 
-   /*get logical volume mounted on a physical/virtual/logical device*/
    if (FileObject->Vpb && FileObject->Vpb->DeviceObject)
    {
       return IoGetAttachedDevice(FileObject->Vpb->DeviceObject);
    }
 
-   /*check if fileobject has an associated device object mounted by some other file system*/
-   if (FileObject->DeviceObject->Vpb && FileObject->DeviceObject->Vpb->DeviceObject)
+   /*
+    * Check if file object has an associated device object mounted by some
+    * other file system.
+    */
+
+   if (FileObject->DeviceObject->Vpb &&
+       FileObject->DeviceObject->Vpb->DeviceObject)
    {
       return IoGetAttachedDevice(FileObject->DeviceObject->Vpb->DeviceObject);
    }
@@ -122,636 +242,228 @@
    return IoGetAttachedDevice(FileObject->DeviceObject);
 }
 
-
 /*
- * @implemented
+ * IoGetDeviceObjectPointer
+ *
+ * Status
+ *    @implemented
  */
-NTSTATUS
-STDCALL
-IoGetDeviceObjectPointer (
-	IN	PUNICODE_STRING	ObjectName,
-	IN	ACCESS_MASK	DesiredAccess,
-	OUT	PFILE_OBJECT	* FileObject,
-	OUT	PDEVICE_OBJECT	* DeviceObject)
-{
-	OBJECT_ATTRIBUTES ObjectAttributes;
-	IO_STATUS_BLOCK StatusBlock;
-	PFILE_OBJECT LocalFileObject;
-	HANDLE FileHandle;
-	NTSTATUS Status;
-
-	DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x, FileObject %p DeviceObject %p)\n",
-	       ObjectName,
-	       DesiredAccess,
-	       FileObject,
-	       DeviceObject);
-
-	InitializeObjectAttributes (&ObjectAttributes,
-	                            ObjectName,
-	                            0,
-	                            NULL,
-	                            NULL);
-
-	Status = NtOpenFile (&FileHandle,
-	                     DesiredAccess,
-	                     &ObjectAttributes,
-	                     &StatusBlock,
-	                     0,
-	                     FILE_NON_DIRECTORY_FILE);
-	if (!NT_SUCCESS(Status))
-		return Status;
-
-	Status = ObReferenceObjectByHandle (FileHandle,
-	                                    0,
-	                                    IoFileObjectType,
-	                                    KernelMode,
-	                                    (PVOID*)&LocalFileObject,
-	                                    NULL);
-	if (NT_SUCCESS(Status))
-	{
-		*DeviceObject = IoGetRelatedDeviceObject (LocalFileObject);
-		*FileObject = LocalFileObject;
-	}
-	NtClose (FileHandle);
-
-	return Status;
-}
 
+NTSTATUS STDCALL
+IoGetDeviceObjectPointer(
+   IN PUNICODE_STRING ObjectName,
+   IN ACCESS_MASK DesiredAccess,
+   OUT PFILE_OBJECT *FileObject,
+   OUT PDEVICE_OBJECT *DeviceObject)
+{
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   IO_STATUS_BLOCK StatusBlock;
+   PFILE_OBJECT LocalFileObject;
+   HANDLE FileHandle;
+   NTSTATUS Status;
+
+   DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x, FileObject %p DeviceObject %p)\n",
+      ObjectName, DesiredAccess, FileObject, DeviceObject);
+
+   InitializeObjectAttributes(
+      &ObjectAttributes,
+      ObjectName,
+      0,
+      NULL,
+      NULL);
+
+   Status = NtOpenFile(
+      &FileHandle,
+      DesiredAccess,
+      &ObjectAttributes,
+      &StatusBlock,
+      0,
+      FILE_NON_DIRECTORY_FILE);
+
+   if (!NT_SUCCESS(Status))
+      return Status;
+
+   Status = ObReferenceObjectByHandle(
+      FileHandle,
+      0,
+      IoFileObjectType,
+      KernelMode,
+      (PVOID*)&LocalFileObject,
+      NULL);
+
+   if (NT_SUCCESS(Status))
+   {
+      *DeviceObject = IoGetRelatedDeviceObject(LocalFileObject);
+      *FileObject = LocalFileObject;
+   }
+
+   NtClose(FileHandle);
+
+   return Status;
+}
 
 /*
- * @unimplemented
+ * IoDetachDevice
+ *
+ * Status
+ *    @unimplemented
  */
-VOID
-STDCALL
+
+VOID STDCALL
 IoDetachDevice(PDEVICE_OBJECT TargetDevice)
 {
-//   UNIMPLEMENTED;
    DPRINT("IoDetachDevice(TargetDevice %x) - UNIMPLEMENTED\n", TargetDevice);
 }
 
-
 /*
- * @implemented
+ * IoGetAttachedDevice
+ *
+ * Status
+ *    @implemented
  */
-PDEVICE_OBJECT
-STDCALL
+
+PDEVICE_OBJECT STDCALL
 IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
 {
    PDEVICE_OBJECT Current = DeviceObject;
    
-//   DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject);
-   
-   while (Current->AttachedDevice!=NULL)
-     {
-	Current = Current->AttachedDevice;
-//	DPRINT("Current %x\n",Current);
-     }
+   while (Current->AttachedDevice != NULL)
+      Current = Current->AttachedDevice;
 
-//   DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject);
-   return(Current);
+   return Current;
 }
 
 /*
- * @implemented
+ * IoGetAttachedDeviceReference
+ *
+ * Status
+ *    @implemented
  */
-PDEVICE_OBJECT
-STDCALL
+
+PDEVICE_OBJECT STDCALL
 IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
 {
-   PDEVICE_OBJECT Current = DeviceObject;
-
-   while (Current->AttachedDevice!=NULL)
-     {
-	Current = Current->AttachedDevice;
-     }
-
+   PDEVICE_OBJECT Current = IoGetAttachedDevice(DeviceObject);
    ObReferenceObject(Current);
-   return(Current);
+   return Current;
 }
 
 /*
- * @implemented
+ * IoAttachDeviceToDeviceStack
+ *
+ * Status
+ *    @implemented
  */
+
 PDEVICE_OBJECT STDCALL
-IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
-			    PDEVICE_OBJECT TargetDevice)
+IoAttachDeviceToDeviceStack(
+   PDEVICE_OBJECT SourceDevice,
+   PDEVICE_OBJECT TargetDevice)
 {
    PDEVICE_OBJECT AttachedDevice;
    
    DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n",
-	  SourceDevice,TargetDevice);
+      SourceDevice, TargetDevice);
 
    AttachedDevice = IoGetAttachedDevice(TargetDevice);
    AttachedDevice->AttachedDevice = SourceDevice;
    SourceDevice->AttachedDevice = NULL;
    SourceDevice->StackSize = AttachedDevice->StackSize + 1;
    SourceDevice->Vpb = AttachedDevice->Vpb;
-   return(AttachedDevice);
-}
-
-
-NTSTATUS STDCALL
-IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject,
-			   PIRP Irp)
-{
-  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-  Irp->IoStatus.Information = 0;
-
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
-  return(STATUS_NOT_IMPLEMENTED);
-}
-
-
-NTSTATUS
-IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
-		      PUNICODE_STRING ServiceName,
-		      BOOLEAN FileSystem,
-		      PVOID DriverImageStart,
-		      ULONG DriverImageSize)
-{
-  PDRIVER_OBJECT Object;
-  ULONG i;
-  WCHAR NameBuffer[MAX_PATH];
-  UNICODE_STRING DriverName;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  NTSTATUS Status;
-
-  DPRINT("IopCreateDriverObject(%p '%wZ' %x %p %x)\n", DriverObject, ServiceName, FileSystem,
-	 DriverImageStart, DriverImageSize);
-
-  *DriverObject = NULL;
-
-  /*  Create ModuleName string  */
-  if ((ServiceName != NULL) && (ServiceName->Buffer != NULL))
-    {
-      if (FileSystem == TRUE)
-	wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME);
-      else
-	wcscpy(NameBuffer, DRIVER_ROOT_NAME);
-      wcscat(NameBuffer, ServiceName->Buffer);
-
-      RtlInitUnicodeString(&DriverName,
-			   NameBuffer);
-      DPRINT("Driver name: '%wZ'\n", &DriverName);
-    }
-
-  /* Initialize ObjectAttributes for driver object */
-  InitializeObjectAttributes(&ObjectAttributes,
-			     ((ServiceName != NULL) && (ServiceName->Buffer != NULL))? &DriverName : NULL,
-			     OBJ_PERMANENT,
-			     NULL,
-			     NULL);
-
-  /* Create driver object */
-  Status = ObCreateObject(KernelMode,
-                          IoDriverObjectType,
-                          &ObjectAttributes,
-                          KernelMode,
-                          NULL,
-                          sizeof(DRIVER_OBJECT),
-                          0,
-                          0,
-                          (PVOID*)&Object);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
-
-  /* Create driver extension */
-  Object->DriverExtension = (PDRIVER_EXTENSION)
-    ExAllocatePoolWithTag(NonPagedPool,
-       sizeof(DRIVER_EXTENSION),
-       TAG_DRIVER_EXTENSION);
-  if (Object->DriverExtension == NULL)
-    {
-      ExFreePool(Object);
-      return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-
-  RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
-
-  Object->Type = InternalDriverType;
-
-  Object->DriverStart = DriverImageStart;
-  Object->DriverSize = DriverImageSize;
-
-  for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)
-    {
-       Object->MajorFunction[i] = (PDRIVER_DISPATCH) IopDefaultDispatchFunction;
-    }
-
-  *DriverObject = Object;
-
-  return STATUS_SUCCESS;
-}
-
-
-NTSTATUS STDCALL
-IopAttachFilterDriversCallback(
-  PWSTR ValueName,
-  ULONG ValueType,
-  PVOID ValueData,
-  ULONG ValueLength,
-  PVOID Context,
-  PVOID EntryContext)
-{
-  PDEVICE_NODE DeviceNode = Context;
-  UNICODE_STRING ServiceName;
-  PWCHAR Filters;
-
-  Filters = ValueData;
-  while (((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
-         *Filters != 0)
-  {
-    DPRINT1("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
-    ServiceName.Buffer = Filters;
-    ServiceName.MaximumLength = 
-    ServiceName.Length = wcslen(Filters) * sizeof(WCHAR);
-    IopInitializeDeviceNodeService(
-      DeviceNode,
-      &ServiceName,
-      FALSE);  
-    Filters += (ServiceName.Length / sizeof(WCHAR)) + 1;
-  }
-
-  return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-IopAttachFilterDrivers(
-  PDEVICE_NODE DeviceNode,
-  BOOLEAN Lower)
-{
-  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-  PWCHAR KeyBuffer;
-  UNICODE_STRING Class;
-  WCHAR ClassBuffer[40];
-  NTSTATUS Status;
-
-  /*
-   * First load the device filters
-   */
-  
-  QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
-  if (Lower)
-    QueryTable[0].Name = L"LowerFilters";
-  else
-    QueryTable[0].Name = L"UpperFilters";
-  QueryTable[0].EntryContext = NULL;
-  QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[1].QueryRoutine = NULL;
-  QueryTable[1].Name = NULL;
-
-  KeyBuffer = ExAllocatePool(
-    PagedPool, 
-    (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
-  wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
-  wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);  
-
-  RtlQueryRegistryValues(
-    RTL_REGISTRY_ABSOLUTE,
-    KeyBuffer,
-    QueryTable,
-    DeviceNode,
-    NULL);
-
-  /*
-   * Now get the class GUID
-   */
-
-  Class.Length = 0;
-  Class.MaximumLength = 40 * sizeof(WCHAR);
-  Class.Buffer = ClassBuffer;
-  QueryTable[0].QueryRoutine = NULL;
-  QueryTable[0].Name = L"ClassGUID";
-  QueryTable[0].EntryContext = &Class;
-  QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
-
-  Status = RtlQueryRegistryValues(
-    RTL_REGISTRY_ABSOLUTE,
-    KeyBuffer,
-    QueryTable,
-    DeviceNode,
-    NULL);
-
-  ExFreePool(KeyBuffer);
-
-  /*
-   * Load the class filter driver
-   */
-
-  if (NT_SUCCESS(Status))
-  {
-    QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
-    if (Lower)
-      QueryTable[0].Name = L"LowerFilters";
-    else
-      QueryTable[0].Name = L"UpperFilters";
-    QueryTable[0].EntryContext = NULL;
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
-
-    KeyBuffer = ExAllocatePool(PagedPool, (58 * sizeof(WCHAR)) + Class.Length);
-    wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\");
-    wcscat(KeyBuffer, ClassBuffer);
-
-    RtlQueryRegistryValues(
-      RTL_REGISTRY_ABSOLUTE,
-      KeyBuffer,
-      QueryTable,
-      DeviceNode,
-      NULL);
-
-    ExFreePool(KeyBuffer);
-  }
-  
-  return STATUS_SUCCESS;
-}
-
-
-NTSTATUS 
-IopInitializeDevice(PDEVICE_NODE DeviceNode,
-                    BOOLEAN BootDriver)
-{
-  IO_STATUS_BLOCK IoStatusBlock;
-  PDRIVER_OBJECT DriverObject;
-  IO_STACK_LOCATION Stack;
-  PDEVICE_OBJECT Fdo;
-  NTSTATUS Status;
-
-  DriverObject = DeviceNode->DriverObject;
-
-  if (DriverObject->DriverExtension->AddDevice)
-    {
-      /* This is a Plug and Play driver */
-      DPRINT("Plug and Play driver found\n");
-
-      assert(DeviceNode->Pdo);
-
-      DPRINT("Calling driver AddDevice entrypoint at %08lx\n",
-        DriverObject->DriverExtension->AddDevice);
-      Status = DriverObject->DriverExtension->AddDevice(
-        DriverObject, DeviceNode->Pdo);
-      if (!NT_SUCCESS(Status))
-        {
-	        return(Status);
-        }
-
-      IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
-
-      DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
-
-      Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo);
-
-      if (Fdo == DeviceNode->Pdo)
-        {
-          /* FIXME: What do we do? Unload the driver or just disable the device? */
-          DbgPrint("An FDO was not attached\n");
-          KEBUGCHECK(0);
-        }
-
-      /* FIXME: Put some resources in the IRP for the device */
-      Stack.Parameters.StartDevice.AllocatedResources = NULL;
-      Stack.Parameters.StartDevice.AllocatedResourcesTranslated = NULL;
-
-      Status = IopInitiatePnpIrp(
-        Fdo,
-        &IoStatusBlock,
-        IRP_MN_START_DEVICE,
-        &Stack);
-      if (!NT_SUCCESS(Status))
-        {
-          DPRINT("IopInitiatePnpIrp() failed\n");
-          ObDereferenceObject(Fdo);
-	        return(Status);
-        }
-
-      if (Fdo->DeviceType == FILE_DEVICE_BUS_EXTENDER)
-        {
-          DPRINT("Bus extender found\n");
-
-          Status = IopInvalidateDeviceRelations(
-             DeviceNode, BusRelations, BootDriver);
-          if (!NT_SUCCESS(Status))
-            {
-              ObDereferenceObject(Fdo);
-              return(Status);
-            }
-        }
-      else if (Fdo->DeviceType == FILE_DEVICE_ACPI)
-        {
-#ifdef ACPI
-          static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
-
-          /* There can be only one system power device */
-          if (!SystemPowerDeviceNodeCreated)
-            {
-              PopSystemPowerDeviceNode = DeviceNode;
-              SystemPowerDeviceNodeCreated = TRUE;
-            }
-#endif /* ACPI */
-        }
-      ObDereferenceObject(Fdo);
-    }
-
-  return STATUS_SUCCESS;
+   return AttachedDevice;
 }
 
-NTSTATUS
-IopInitializeService(
-  PDEVICE_NODE DeviceNode,
-  PUNICODE_STRING ServiceName,
-  PUNICODE_STRING ImagePath)
-{
-  PMODULE_OBJECT ModuleObject;
-  NTSTATUS Status;
-
-  ModuleObject = LdrGetModuleObject(ServiceName);
-  if (ModuleObject == NULL)
-  {
-    /* The module is currently not loaded, so load it now */
-
-    Status = LdrLoadModule(ImagePath, &ModuleObject);
-    if (!NT_SUCCESS(Status))
-    {
-      /* FIXME: Log the error */
-      CPRINT("Driver load failed\n");
-      return(Status);
-    }
-
-    Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, FALSE,
-				 ModuleObject->Base, ModuleObject->Length,
-				 FALSE);
-    if (!NT_SUCCESS(Status))
-    {
-      LdrUnloadModule(ModuleObject);
-
-      /* FIXME: Log the error */
-      CPRINT("A driver failed to initialize\n");
-      return(Status);
-    }
-  } else
-  {
-    /* FIXME: This doesn't work for two devices with the same driver */
-    Status = IopInitializeDevice(DeviceNode, FALSE);
-  }
-
-  return(Status);
-}
-
-NTSTATUS
-IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
-		    PDEVICE_NODE DeviceNode,
-		    BOOLEAN FileSystemDriver,
-		    PVOID DriverImageStart,
-		    ULONG DriverImageSize,
-		    BOOLEAN BootDriver)
-/*
- * FUNCTION: Called to initalize a loaded driver
- * ARGUMENTS:
- *   DriverEntry = Pointer to driver entry routine
- *   DeviceNode  = Pointer to device node
- */
-{
-  WCHAR RegistryKeyBuffer[MAX_PATH];
-  PDRIVER_OBJECT DriverObject;
-  UNICODE_STRING RegistryKey;
-  NTSTATUS Status;
-
-  DPRINT("IopInitializeDriver(DriverEntry %08lx, DeviceNode %08lx)\n",
-    DriverEntry, DeviceNode);
-
-  Status = IopCreateDriverObject(&DriverObject,
-				 &DeviceNode->ServiceName,
-				 FileSystemDriver,
-				 DriverImageStart,
-				 DriverImageSize);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
-
-  DeviceNode->DriverObject = DriverObject;
-
-  if (DeviceNode->ServiceName.Buffer)
-    {
-      wcscpy(RegistryKeyBuffer, DRIVER_REGISTRY_KEY_BASENAME);
-      wcscat(RegistryKeyBuffer, DeviceNode->ServiceName.Buffer);
-      RtlInitUnicodeString(&RegistryKey, RegistryKeyBuffer);
-    }
-  else
-    {
-      RtlInitUnicodeString(&RegistryKey, NULL);
-    }
-
-  DPRINT("RegistryKey: %wZ\n", &RegistryKey);
-  DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry);
-
-  IopMarkLastReinitializeDriver();
-
-  Status = DriverEntry(DriverObject, &RegistryKey);
-  if (!NT_SUCCESS(Status))
-    {
-      DeviceNode->DriverObject = NULL;
-      ExFreePool(DriverObject->DriverExtension);
-      ObMakeTemporaryObject(DriverObject);
-      ObDereferenceObject(DriverObject);
-      return(Status);
-    }
-
-  IopReinitializeDrivers();
-
-  Status = IopInitializeDevice(DeviceNode, BootDriver);
-
-  return(Status);
-}
-
-
 /*
- * @implemented
+ * IoAttachDevice
+ *
+ * Layers a device over the highest device in a device stack.
+ *
+ * Parameters
+ *    SourceDevice
+ *       Device to be attached.
+ *
+ *    TargetDevice
+ *       Name of the target device.
+ *
+ *    AttachedDevice
+ *       Caller storage for the device attached to.
+ *
+ * Status
+ *    @implemented
  */
+
 NTSTATUS STDCALL
-IoAttachDevice(PDEVICE_OBJECT SourceDevice,
-          PUNICODE_STRING TargetDeviceName,
-	       PDEVICE_OBJECT* AttachedDevice)
-/*
- * FUNCTION: Layers a device over the highest device in a device stack
- * ARGUMENTS:
- *       SourceDevice = Device to attached
- *       TargetDevice = Name of the target device
- *       AttachedDevice (OUT) = Caller storage for the device attached to
- */
+IoAttachDevice(
+   PDEVICE_OBJECT SourceDevice,
+   PUNICODE_STRING TargetDeviceName,
+   PDEVICE_OBJECT *AttachedDevice)
 {
-   NTSTATUS       Status;
-   PFILE_OBJECT   FileObject;
+   NTSTATUS Status;
+   PFILE_OBJECT FileObject;
    PDEVICE_OBJECT TargetDevice;
      
-   Status = IoGetDeviceObjectPointer(TargetDeviceName,
-                                     FILE_READ_ATTRIBUTES,
-                                     &FileObject,
-                                     &TargetDevice);
+   Status = IoGetDeviceObjectPointer(
+      TargetDeviceName,
+      FILE_READ_ATTRIBUTES,
+      &FileObject,
+      &TargetDevice);
    
    if (!NT_SUCCESS(Status))
    {
       return Status;
    }
 
-   *AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice,
-                                                 TargetDevice);
+   *AttachedDevice = IoAttachDeviceToDeviceStack(
+      SourceDevice,
+      TargetDevice);
 
    ObDereferenceObject(FileObject);
-   return STATUS_SUCCESS;
-}
 
[truncated at 1000 lines; 363 more skipped]

reactos/ntoskrnl/io
driver.c 1.38 -> 1.39
diff -u -r1.38 -r1.39
--- driver.c	21 Mar 2004 18:58:53 -0000	1.38
+++ driver.c	27 Mar 2004 19:41:32 -0000	1.39
@@ -1,4 +1,4 @@
-/* $Id: driver.c,v 1.38 2004/03/21 18:58:53 navaraf Exp $
+/* $Id: driver.c,v 1.39 2004/03/27 19:41:32 navaraf Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel
@@ -83,58 +83,611 @@
 #define TAG_DRIVER             TAG('D', 'R', 'V', 'R')
 #define TAG_DRIVER_EXTENSION   TAG('D', 'R', 'V', 'E')
 
+#define DRIVER_REGISTRY_KEY_BASENAME  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 NTSTATUS STDCALL
-IopCreateDriver(PVOID ObjectBody,
-		PVOID Parent,
-		PWSTR RemainingPath,
-		POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-	 ObjectBody,
-	 Parent,
-	 RemainingPath);
-  if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
+IopCreateDriver(
+   PVOID ObjectBody,
+   PVOID Parent,
+   PWSTR RemainingPath,
+   POBJECT_ATTRIBUTES ObjectAttributes)
+{
+   DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",
+      ObjectBody, Parent, RemainingPath);
 
-  return(STATUS_SUCCESS);
+   if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
+      return STATUS_UNSUCCESSFUL;
+
+   return STATUS_SUCCESS;
 }
 
 
 VOID INIT_FUNCTION
 IopInitDriverImplementation(VOID)
 {
-  /*  Register the process object type  */
-  IoDriverObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-  IoDriverObjectType->Tag = TAG('D', 'R', 'V', 'R');
-  IoDriverObjectType->TotalObjects = 0;
-  IoDriverObjectType->TotalHandles = 0;
-  IoDriverObjectType->MaxObjects = ULONG_MAX;
-  IoDriverObjectType->MaxHandles = ULONG_MAX;
-  IoDriverObjectType->PagedPoolCharge = 0;
-  IoDriverObjectType->NonpagedPoolCharge = sizeof(DRIVER_OBJECT);
-  IoDriverObjectType->Dump = NULL;
-  IoDriverObjectType->Open = NULL;
-  IoDriverObjectType->Close = NULL;
-  IoDriverObjectType->Delete = NULL;
-  IoDriverObjectType->Parse = NULL;
-  IoDriverObjectType->Security = NULL;
-  IoDriverObjectType->QueryName = NULL;
-  IoDriverObjectType->OkayToClose = NULL;
-  IoDriverObjectType->Create = IopCreateDriver;
-  IoDriverObjectType->DuplicationNotify = NULL;
-  RtlRosInitUnicodeStringFromLiteral(&IoDriverObjectType->TypeName, L"Driver");
-
-  ObpCreateTypeObject(IoDriverObjectType);
-
-  InitializeListHead(&DriverReinitListHead);
-  KeInitializeSpinLock(&DriverReinitListLock);
-  DriverReinitTailEntry = NULL;
+   /* Register the process object type */
+   IoDriverObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+   IoDriverObjectType->Tag = TAG('D', 'R', 'V', 'R');
+   IoDriverObjectType->TotalObjects = 0;
+   IoDriverObjectType->TotalHandles = 0;
+   IoDriverObjectType->MaxObjects = ULONG_MAX;
+   IoDriverObjectType->MaxHandles = ULONG_MAX;
+   IoDriverObjectType->PagedPoolCharge = 0;
+   IoDriverObjectType->NonpagedPoolCharge = sizeof(DRIVER_OBJECT);
+   IoDriverObjectType->Dump = NULL;
+   IoDriverObjectType->Open = NULL;
+   IoDriverObjectType->Close = NULL;
+   IoDriverObjectType->Delete = NULL;
+   IoDriverObjectType->Parse = NULL;
+   IoDriverObjectType->Security = NULL;
+   IoDriverObjectType->QueryName = NULL;
+   IoDriverObjectType->OkayToClose = NULL;
+   IoDriverObjectType->Create = IopCreateDriver;
+   IoDriverObjectType->DuplicationNotify = NULL;
+   RtlRosInitUnicodeStringFromLiteral(&IoDriverObjectType->TypeName, L"Driver");
+
+   ObpCreateTypeObject(IoDriverObjectType);
+
+   InitializeListHead(&DriverReinitListHead);
+   KeInitializeSpinLock(&DriverReinitListLock);
+   DriverReinitTailEntry = NULL;
+}
+
+NTSTATUS STDCALL
+IopDefaultDispatchFunction(
+   PDEVICE_OBJECT DeviceObject,
+   PIRP Irp)
+{
+   Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+   Irp->IoStatus.Information = 0;
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+   return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS FASTCALL
+IopCreateDriverObject(
+   PDRIVER_OBJECT *DriverObject,
+   PUNICODE_STRING ServiceName,
+   BOOLEAN FileSystem,
+   PVOID DriverImageStart,
+   ULONG DriverImageSize)
+{
+   PDRIVER_OBJECT Object;
+   ULONG i;
+   WCHAR NameBuffer[MAX_PATH];
+   UNICODE_STRING DriverName;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   NTSTATUS Status;
+
+   DPRINT("IopCreateDriverObject(%p '%wZ' %x %p %x)\n",
+      DriverObject, ServiceName, FileSystem, DriverImageStart, DriverImageSize);
+
+   *DriverObject = NULL;
+
+   /* Create ModuleName string */
+   if (ServiceName != NULL && ServiceName->Buffer != NULL)
+   {
+      if (FileSystem == TRUE)
+         wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME);
+      else
+         wcscpy(NameBuffer, DRIVER_ROOT_NAME);
+      wcscat(NameBuffer, ServiceName->Buffer);
+
+      RtlInitUnicodeString(&DriverName, NameBuffer);
+      DPRINT("Driver name: '%wZ'\n", &DriverName);
+   }
+   else
+   {
+      RtlInitUnicodeString(&DriverName, NULL);
+   }
+
+   /* Initialize ObjectAttributes for driver object */
+   InitializeObjectAttributes(
+      &ObjectAttributes,
+      &DriverName,
+      OBJ_PERMANENT,
+      NULL,
+      NULL);
+
+   /* Create driver object */
+   Status = ObCreateObject(
+      KernelMode,
+      IoDriverObjectType,
+      &ObjectAttributes,
+      KernelMode,
+      NULL,
+      sizeof(DRIVER_OBJECT),
+      0,
+      0,
+      (PVOID*)&Object);
+
+   if (!NT_SUCCESS(Status))
+   {
+      return Status;
+   }
+
+   /* Create driver extension */
+   Object->DriverExtension = (PDRIVER_EXTENSION)
+      ExAllocatePoolWithTag(
+         NonPagedPool,
+         sizeof(DRIVER_EXTENSION),
+         TAG_DRIVER_EXTENSION);
+
+   if (Object->DriverExtension == NULL)
+   {
+      ExFreePool(Object);
+      return STATUS_NO_MEMORY;
+   }
+
+   RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
+
+   Object->Type = InternalDriverType;
+   Object->DriverStart = DriverImageStart;
+   Object->DriverSize = DriverImageSize;
+
+   for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+      Object->MajorFunction[i] = IopDefaultDispatchFunction;
+
+   *DriverObject = Object;
+
+   return STATUS_SUCCESS;
+}
+
+/*
+ * IopDisplayLoadingMessage
+ *
+ * Display 'Loading XXX...' message.
+ */
+
+VOID FASTCALL
+IopDisplayLoadingMessage(PWCHAR ServiceName)
+{
+   CHAR TextBuffer[256];
+   sprintf(TextBuffer, "Loading %S...\n", ServiceName);
+   HalDisplayString(TextBuffer);
+}
+
+/*
+ * IopNormalizeImagePath
+ *
+ * Normalize an image path to contain complete path.
+ *
+ * Parameters
+ *    ImagePath
+ *       The input path and on exit the result path. ImagePath.Buffer
+ *       must be allocated by ExAllocatePool on input. Caller is responsible
+ *       for freeing the buffer when it's no longer needed.
+ *
+ *    ServiceName
+ *       Name of the service that ImagePath belongs to.
+ *
+ * Return Value
+ *    Status
+ *
+ * Remarks
+ *    The input image path isn't freed on error.
+ */
+
+NTSTATUS FASTCALL
+IopNormalizeImagePath(
+   IN OUT PUNICODE_STRING ImagePath,
+   IN PUNICODE_STRING ServiceName)
+{
+   UNICODE_STRING InputImagePath;
+
+   RtlCopyMemory(
+      &InputImagePath,
+      ImagePath,
+      sizeof(UNICODE_STRING));
+
+   if (InputImagePath.Length == 0)
+   {
+      ImagePath->Length = (33 * sizeof(WCHAR)) + ServiceName->Length;
+      ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL);
+      ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength);
+      if (ImagePath->Buffer == NULL)
+         return STATUS_NO_MEMORY;
+
+      wcscpy(ImagePath->Buffer, L"\\SystemRoot\\system32\\drivers\\");
+      wcscat(ImagePath->Buffer, ServiceName->Buffer);
+      wcscat(ImagePath->Buffer, L".sys");
+   } else
+   if (InputImagePath.Buffer[0] != L'\\')
+   {
+      ImagePath->Length = (12 * sizeof(WCHAR)) + InputImagePath.Length;
+      ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL);
+      ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength);
+      if (ImagePath->Buffer == NULL)
+         return STATUS_NO_MEMORY;
+
+      wcscpy(ImagePath->Buffer, L"\\SystemRoot\\");
+      wcscat(ImagePath->Buffer, InputImagePath.Buffer);
+      RtlFreeUnicodeString(&InputImagePath);
+   }
+
+   return STATUS_SUCCESS;
+}
+
+/*
+ * IopLoadServiceModule
+ *
+ * Load a module specified by registry settings for service.
+ *
+ * Parameters
+ *    ServiceName
+ *       Name of the service to load.
+ *
+ * Return Value
+ *    Status
+ */
+
+NTSTATUS FASTCALL
+IopLoadServiceModule(
+   IN PUNICODE_STRING ServiceName,
+   OUT PMODULE_OBJECT *ModuleObject)
+{
+   RTL_QUERY_REGISTRY_TABLE QueryTable[3];
+   ULONG ServiceStart;
+   UNICODE_STRING ServiceImagePath;
+   NTSTATUS Status;
+
+   /*
+    * Get information about the service.
+    */
+
+   RtlZeroMemory(QueryTable, sizeof(QueryTable));
+
+   RtlInitUnicodeString(&ServiceImagePath, NULL);
+
+   QueryTable[0].Name = L"Start";
+   QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+   QueryTable[0].EntryContext = &ServiceStart;
+
+   QueryTable[1].Name = L"ImagePath";
+   QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+   QueryTable[1].EntryContext = &ServiceImagePath;
+
+   Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
+      ServiceName->Buffer, QueryTable, NULL, NULL);
+
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status);
+      return Status;
+   }
+
+   IopDisplayLoadingMessage(ServiceName->Buffer);
+
+   /*
+    * Normalize the image path for all later processing.
+    */
+
+   Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName);
+
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
+      return Status;
+   }
+
+   /*
+    * Load the module.
+    */
+
+   *ModuleObject = LdrGetModuleObject(&ServiceImagePath);
+
+   if (*ModuleObject == NULL)
+   {
+      /*
+       * Special case for boot modules that were loaded by boot loader.
+       */
+
+      if (ServiceStart == 0)
+      {
+         ULONG i;
+         CHAR SearchName[256];
+         PCHAR ModuleName;
+         PLOADER_MODULE KeLoaderModules =
+            (PLOADER_MODULE)KeLoaderBlock.ModsAddr;
+
+         Status = STATUS_UNSUCCESSFUL;
+
+         /*
+          * FIXME:
+          * Improve this searching algorithm by using the image name
+          * stored in registry entry ImageName and use the whole path
+          * (requires change in FreeLoader).
+          */
+
+         _snprintf(SearchName, sizeof(SearchName), "%wZ.sys", ServiceName);
+         for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+         {
+            ModuleName = (PCHAR)KeLoaderModules[i].String;
+            if (!strcmp(ModuleName, SearchName))
+            {
+               /* Tell, that the module is already loaded */
+               KeLoaderModules[i].Reserved = 1;
+
+               Status = LdrProcessModule(
+                  (PVOID)KeLoaderModules[i].ModStart,
+                  &ServiceImagePath,
+                  ModuleObject);
+
+               break;
+            }
+         }
+      }
+
+      /*
+       * Case for rest of the drivers (except disabled)
+       */
+
+      else if (ServiceStart < 4)
+      {
+         DPRINT("Loading module\n");
+         Status = LdrLoadModule(&ServiceImagePath, ModuleObject);
+      }
+   }
+   else
+   {
+      DPRINT("Module already loaded\n");
+      Status = STATUS_SUCCESS;
+   }
+
+   RtlFreeUnicodeString(&ServiceImagePath);
+
+   /*
+    * Now check if the module was loaded successfully.
+    */
+
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("Module loading failed (Status %x)\n", Status);
+   }
+
+   DPRINT("Module loading (Status %x)\n", Status);
+
+   return Status;
+}
+
+/*
+ * IopInitializeDriverModule
+ *
+ * Initalize a loaded driver.
+ *
+ * Parameters
+ *    DeviceNode
+ *       Pointer to device node.
+ *
+ *    ModuleObject
+ *       Module object representing the driver. It can be retrieve by
+ *       IopLoadServiceModule.
+ *
+ *    FileSystemDriver
+ *       Set to TRUE for file system drivers.
+ *
+ *    DriverObject
+ *       On successful return this contains the driver object representing
+ *       the loaded driver.
+ */
+
+NTSTATUS FASTCALL
+IopInitializeDriverModule(
+   IN PDEVICE_NODE DeviceNode,
+   IN PMODULE_OBJECT ModuleObject,
+   IN BOOLEAN FileSystemDriver,
+   OUT PDRIVER_OBJECT *DriverObject)
+{
+   UNICODE_STRING RegistryKey;
+   PDRIVER_INITIALIZE DriverEntry = ModuleObject->EntryPoint;
+   NTSTATUS Status;
+
+   Status = IopCreateDriverObject(
+      DriverObject,
+      &DeviceNode->ServiceName,
+      FileSystemDriver,
+      ModuleObject->Base,
+      ModuleObject->Length);
+
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("IopCreateDriverObject failed (Status %x)\n", Status);
+      return Status;
+   }
+
+   if (DeviceNode->ServiceName.Buffer)
+   {
+      RegistryKey.Length = DeviceNode->ServiceName.Length +
+         sizeof(DRIVER_REGISTRY_KEY_BASENAME);
+      RegistryKey.MaximumLength = RegistryKey.Length + sizeof(UNICODE_NULL);
+      RegistryKey.Buffer = ExAllocatePool(PagedPool, RegistryKey.MaximumLength);
+      wcscpy(RegistryKey.Buffer, DRIVER_REGISTRY_KEY_BASENAME);
+      wcscat(RegistryKey.Buffer, DeviceNode->ServiceName.Buffer);
+   }
+   else
+   {
+      RtlInitUnicodeString(&RegistryKey, NULL);
+   }
+
+   DPRINT("RegistryKey: %wZ\n", &RegistryKey);
+   DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry);
+
+   IopMarkLastReinitializeDriver();
+
+   Status = DriverEntry(*DriverObject, &RegistryKey);
+   if (!NT_SUCCESS(Status))
+   {
+      ExFreePool((*DriverObject)->DriverExtension);
+      ObMakeTemporaryObject(DriverObject);
+      ObDereferenceObject(DriverObject);
+      return Status;
+   }
+
+   IopReinitializeDrivers();
+
+   return STATUS_SUCCESS;
+}
+
+/*
+ * IopAttachFilterDriversCallback
+ *
+ * Internal routine used by IopAttachFilterDrivers.
+ */
+
+NTSTATUS STDCALL
+IopAttachFilterDriversCallback(
+   PWSTR ValueName,
+   ULONG ValueType,
+   PVOID ValueData,
+   ULONG ValueLength,
+   PVOID Context,
+   PVOID EntryContext)
+{
+   PDEVICE_NODE DeviceNode = Context;
+   UNICODE_STRING ServiceName;
+   PWCHAR Filters;
+   PMODULE_OBJECT ModuleObject;
+   PDRIVER_OBJECT DriverObject;
+   NTSTATUS Status;
+
+   
+   for (Filters = ValueData;
+        ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
+        *Filters != 0;
+        Filters += (ServiceName.Length / sizeof(WCHAR)) + 1)
+   {
+      DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
+      ServiceName.Buffer = Filters;
+      ServiceName.MaximumLength = 
+      ServiceName.Length = wcslen(Filters) * sizeof(WCHAR);
+
+      /* Load and initialize the filter driver */
+      Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
+      if (!NT_SUCCESS(Status))
+         continue;
+
+      Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE, &DriverObject);
+      if (!NT_SUCCESS(Status))
+         continue;
+
+      Status = IopInitializeDevice(DeviceNode, DriverObject);
+      if (!NT_SUCCESS(Status))
+         continue;
+   }
+
+   return STATUS_SUCCESS;
+}
+
+/*
+ * IopAttachFilterDrivers
+ *
+ * Load filter drivers for specified device node.
+ *
+ * Parameters
+ *    Lower
+ *       Set to TRUE for loading lower level filters or FALSE for upper
+ *       level filters.
+ */
+
+NTSTATUS FASTCALL
+IopAttachFilterDrivers(
+   PDEVICE_NODE DeviceNode,
+   BOOLEAN Lower)
+{
+   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+   PWCHAR KeyBuffer;
+   UNICODE_STRING Class;
+   WCHAR ClassBuffer[40];
+   NTSTATUS Status;
+
+   /*
+    * First load the device filters
+    */
+   
+   QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
+   if (Lower)
+     QueryTable[0].Name = L"LowerFilters";
+   else
+     QueryTable[0].Name = L"UpperFilters";
+   QueryTable[0].EntryContext = NULL;
+   QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+   QueryTable[1].QueryRoutine = NULL;
+   QueryTable[1].Name = NULL;
+
+   KeyBuffer = ExAllocatePool(
+      PagedPool, 
+      (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
+   wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+   wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);  
+
+   RtlQueryRegistryValues(
+      RTL_REGISTRY_ABSOLUTE,
+      KeyBuffer,
+      QueryTable,
+      DeviceNode,
+      NULL);
+
+   /*
+    * Now get the class GUID
+    */
+
+   Class.Length = 0;
+   Class.MaximumLength = 40 * sizeof(WCHAR);
+   Class.Buffer = ClassBuffer;
+   QueryTable[0].QueryRoutine = NULL;
+   QueryTable[0].Name = L"ClassGUID";
+   QueryTable[0].EntryContext = &Class;
+   QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
+
+   Status = RtlQueryRegistryValues(
+      RTL_REGISTRY_ABSOLUTE,
+      KeyBuffer,
+      QueryTable,
+      DeviceNode,
+      NULL);
+
+   ExFreePool(KeyBuffer);
+
+   /*
+    * Load the class filter driver
+    */
+
+   if (NT_SUCCESS(Status))
+   {
+      QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
+      if (Lower)
+         QueryTable[0].Name = L"LowerFilters";
+      else
+         QueryTable[0].Name = L"UpperFilters";
+      QueryTable[0].EntryContext = NULL;
+      QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+
+      KeyBuffer = ExAllocatePool(PagedPool, (58 * sizeof(WCHAR)) + Class.Length);
+      wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\");
+      wcscat(KeyBuffer, ClassBuffer);
+
+      RtlQueryRegistryValues(
+         RTL_REGISTRY_ABSOLUTE,
+         KeyBuffer,
+         QueryTable,
+         DeviceNode,
+         NULL);
+
+      ExFreePool(KeyBuffer);
+   }
+   
+   return STATUS_SUCCESS;
 }
 
+
+
+
+
+
+
+
 static NTSTATUS STDCALL
 IopCreateGroupListEntry(PWSTR ValueName,
 			ULONG ValueType,
@@ -420,26 +973,12 @@
 }
 
 /*
- * IopDisplayLoadingMessage
- *
- * Display 'Loading XXX...' message.
- */
-
-VOID
-IopDisplayLoadingMessage(PWCHAR ServiceName)
-{
-   CHAR TextBuffer[256];
-   sprintf(TextBuffer, "Loading %S...\n", ServiceName);
-   HalDisplayString(TextBuffer);
-}
-
-/*
  * IopInitializeBuiltinDriver
  *
  * Initialize a driver that is already loaded in memory.
  */
 
-NTSTATUS INIT_FUNCTION
+NTSTATUS FASTCALL
 IopInitializeBuiltinDriver(
    PDEVICE_NODE ModuleDeviceNode,
    PVOID ModuleLoadBase,
@@ -448,6 +987,7 @@
 {
    PMODULE_OBJECT ModuleObject;
    PDEVICE_NODE DeviceNode;
+   PDRIVER_OBJECT DriverObject;
    NTSTATUS Status;
    CHAR TextBuffer[256];
    PCHAR FileNameWithoutPath;
@@ -516,15 +1056,19 @@
    /*
     * Initialize the driver
     */
-   Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode,
-      FALSE, ModuleObject->Base, ModuleObject->Length, TRUE);
+   Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE,
+      &DriverObject);
+   
    if (!NT_SUCCESS(Status))
    {
       if (ModuleDeviceNode == NULL)
          IopFreeDeviceNode(DeviceNode);
       CPRINT("Driver load failed, status (%x)\n", Status);
+      return Status;
    }
 
+   Status = IopInitializeDevice(DeviceNode, DriverObject);
+
    return Status;
 }
 
@@ -540,7 +1084,7 @@
  *    None
  */
 
-VOID INIT_FUNCTION
+VOID FASTCALL
 IopInitializeBootDrivers(VOID)
 {
    ULONG BootDriverCount;
@@ -621,7 +1165,7 @@
  *    None
  */
 
-VOID INIT_FUNCTION
+VOID FASTCALL
 IopInitializeSystemDrivers(VOID)
 {
    PLIST_ENTRY GroupEntry;
@@ -689,212 +1233,6 @@
 }
 
 /*
- * IopGetDriverNameFromServiceKey
- *
- * Returns a module path from service registry key.
- *
- * Parameters
- *    RelativeTo
- *       Relative path identifier.
- *    PathName
- *       Relative key path name.
- *    ImagePath
- *       The result path.
- *
- * Return Value
- *    Status
- */
-
-NTSTATUS STDCALL
-IopGetDriverNameFromServiceKey(
-  ULONG RelativeTo,
-  PWSTR PathName,
-  PUNICODE_STRING ImagePath)
-{
-   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-   UNICODE_STRING RegistryImagePath;
-   NTSTATUS Status;
-   PWSTR ServiceName;
-
-   RtlZeroMemory(&QueryTable, sizeof(QueryTable));
-   RtlInitUnicodeString(&RegistryImagePath, NULL);
-
-   QueryTable[0].Name = L"ImagePath";
-   QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
-   QueryTable[0].EntryContext = &RegistryImagePath;
-
-   Status = RtlQueryRegistryValues(RelativeTo,
-      PathName, QueryTable, NULL, NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
-      RtlFreeUnicodeString(&RegistryImagePath);
-      return STATUS_UNSUCCESSFUL;
-   }
-
-   if (RegistryImagePath.Length == 0)
-   {
-      ServiceName = wcsrchr(PathName, L'\\');
-      if (ServiceName == NULL)
-      {
-         ServiceName = PathName;
-      }
-      else
-      {
-         ServiceName++;
-      }
-      
-      ImagePath->Length = (33 + wcslen(ServiceName)) * sizeof(WCHAR);
-      ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL);
-      ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength);
-      if (ImagePath->Buffer == NULL)
-      {
-         return STATUS_UNSUCCESSFUL;
-      }
-      wcscpy(ImagePath->Buffer, L"\\SystemRoot\\system32\\drivers\\");
-      wcscat(ImagePath->Buffer, ServiceName);
-      wcscat(ImagePath->Buffer, L".sys");
-   } else
-   if (RegistryImagePath.Buffer[0] != L'\\')
-   {
-      ImagePath->Length = (12 + wcslen(RegistryImagePath.Buffer)) * sizeof(WCHAR);
-      ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL);
-      ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength);
-      if (ImagePath->Buffer == NULL)
-      {
-         RtlFreeUnicodeString(&RegistryImagePath);
-         return STATUS_UNSUCCESSFUL;
-      }
-      wcscpy(ImagePath->Buffer, L"\\SystemRoot\\");
-      wcscat(ImagePath->Buffer, RegistryImagePath.Buffer);
-      RtlFreeUnicodeString(&RegistryImagePath);
-   } else
-   {
-      ImagePath->Length = RegistryImagePath.Length;
-      ImagePath->MaximumLength = RegistryImagePath.MaximumLength;
-      ImagePath->Buffer = RegistryImagePath.Buffer;
-   }
-
-   return STATUS_SUCCESS;
-}
-
-/*
- * IopInitializeDeviceNodeService
- *
- * Initialize service for given device node.
- *
- * Parameters
- *    DeviceNode
- *       The device node to initialize service for.
- *    BootDriverOnly
- *       Initialize driver only if it's marked as boot start.
- *
- * Return Value
- *    Status
- */
-
-NTSTATUS
-IopInitializeDeviceNodeService(
-   PDEVICE_NODE DeviceNode,
-   PUNICODE_STRING ServiceName,
-   BOOLEAN BootDriverOnly)
-{
-   NTSTATUS Status;
-   ULONG ServiceStart;
-   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-
-   if (ServiceName == NULL || ServiceName->Buffer == NULL)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
-
-   /*
-    * Get service start value
-    */
-
-   RtlZeroMemory(QueryTable, sizeof(QueryTable));
-   QueryTable[0].Name = L"Start";
-   QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
-   QueryTable[0].EntryContext = &ServiceStart;
-   Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
-      ServiceName->Buffer, QueryTable, NULL, NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status);
-      return Status;
-   }
-
-   if (BootDriverOnly)
-   {
-      PLOADER_MODULE KeLoaderModules = (PLOADER_MODULE)KeLoaderBlock.ModsAddr;
-
-      /*
-       * Find and initialize boot driver
-       */
-      if (ServiceStart == 0 /*SERVICE_BOOT_START*/)
-      {
-         ULONG i;
-         CHAR SearchName[256];
-         ULONG ModuleStart, ModuleSize;
-         PCHAR ModuleName;
-
-         _snprintf(SearchName, sizeof(SearchName), "%wZ.sys", ServiceName);
-         for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-         {
-            ModuleStart = KeLoaderModules[i].ModStart;
-            ModuleSize = KeLoaderModules[i].ModEnd - ModuleStart;
-            ModuleName = (PCHAR)KeLoaderModules[i].String;
-            if (!strcmp(ModuleName, SearchName))
-            {
-               IopInitializeBuiltinDriver(DeviceNode,
-                  (PVOID)ModuleStart, ModuleName, ModuleSize);
-               /* Tell, that the module is already loaded */
-               KeLoaderModules[i].Reserved = 1;
-            }
-         }
-         return STATUS_SUCCESS;
-      } else
-      {
-         return STATUS_UNSUCCESSFUL;
-      }
-   } else
-   if (ServiceStart < 4)
-   {
-      UNICODE_STRING ImagePath;
-
-      /*
-       * Get service path
-       */
-      Status = IopGetDriverNameFromServiceKey(RTL_REGISTRY_SERVICES,
-          ServiceName->Buffer, &ImagePath);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status);
-         return Status;
-      }
-
-      /*
-       * Display loading message
-       */
-      IopDisplayLoadingMessage(ServiceName->Buffer);
-
-      /*
-       * Load the service
-       */
-      Status = IopInitializeService(DeviceNode, ServiceName, &ImagePath);
-
-      /*
-       * Free the service path
-       */
-      RtlFreeUnicodeString(&ImagePath);
-   }
-   else
-      Status = STATUS_UNSUCCESSFUL;
-
-   return Status;
-}
-
-/*
  * IopUnloadDriver
  *
  * Unloads a device driver.
@@ -902,6 +1240,7 @@
  * Parameters
  *    DriverServiceName
  *       Name of the service to unload (registry key).
+ *
  *    UnloadPnpDrivers
  *       Whether to unload Plug & Plug or only legacy drivers. If this
  *       parameter is set to FALSE, the routine will unload only legacy
@@ -917,7 +1256,9 @@
 NTSTATUS STDCALL
 IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
 {
+   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
    UNICODE_STRING ImagePath;
+   UNICODE_STRING ServiceName;
    UNICODE_STRING ObjectName;
    PDRIVER_OBJECT DriverObject;
    PMODULE_OBJECT ModuleObject;
@@ -927,17 +1268,21 @@
    DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName, UnloadPnpDrivers);
 
    /*
-    * Get the service name from the module name
+    * Get the service name from the registry key name
     */
+
    Start = wcsrchr(DriverServiceName->Buffer, L'\\');
    if (Start == NULL)
       Start = DriverServiceName->Buffer;
    else
       Start++;
 
+   RtlInitUnicodeString(&ServiceName, Start);
+
    /*
     * Construct the driver object name
     */
+
    ObjectName.Length = (wcslen(Start) + 8) * sizeof(WCHAR);
    ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
    ObjectName.Buffer = ExAllocatePool(NonPagedPool, ObjectName.MaximumLength);
@@ -948,8 +1293,10 @@
    /*
     * Find the driver object
     */
+
    Status = ObReferenceObjectByName(&ObjectName, 0, 0, 0, IoDriverObjectType,
       KernelMode, 0, (PVOID*)&DriverObject);
+
    if (!NT_SUCCESS(Status))
[truncated at 1000 lines; 224 more skipped]

reactos/ntoskrnl/io
iomgr.c 1.45 -> 1.46
diff -u -r1.45 -r1.46
--- iomgr.c	31 Dec 2003 14:20:26 -0000	1.45
+++ iomgr.c	27 Mar 2004 19:41:32 -0000	1.46
@@ -1,4 +1,4 @@
-/* $Id: iomgr.c,v 1.45 2003/12/31 14:20:26 hbirr Exp $
+/* $Id: iomgr.c,v 1.46 2004/03/27 19:41:32 navaraf Exp $
  *
  * COPYRIGHT:            See COPYING in the top level directory
  * PROJECT:              ReactOS kernel
@@ -16,6 +16,7 @@
 #include <internal/ob.h>
 #include <internal/io.h>
 #include <internal/pool.h>
+#include <internal/module.h>
 #include <rosrtl/string.h>
 
 #define NDEBUG
@@ -367,6 +368,8 @@
 IoInit2(VOID)
 {
   PDEVICE_NODE DeviceNode;
+  PDRIVER_OBJECT DriverObject;
+  MODULE_OBJECT ModuleObject;
   NTSTATUS Status;
 
   KeInitializeSpinLock (&IoStatisticsLock);
@@ -383,12 +386,15 @@
       return;
     }
 
-  Status = IopInitializeDriver(RawFsDriverEntry,
+  ModuleObject.Base = NULL;
+  ModuleObject.Length = 0;
+  ModuleObject.EntryPoint = RawFsDriverEntry;
+
+  Status = IopInitializeDriverModule(
     DeviceNode,
+    &ModuleObject,
     TRUE,
-    NULL,
-    0,
-    FALSE);
+    &DriverObject);
   if (!NT_SUCCESS(Status))
     {
       IopFreeDeviceNode(DeviceNode);
@@ -396,13 +402,20 @@
       return;
     }
 
+  Status = IopInitializeDevice(DeviceNode, DriverObject);
+  if (!NT_SUCCESS(Status))
+    {
+      IopFreeDeviceNode(DeviceNode);
+      CPRINT("IopInitializeDevice() failed with status (%x)\n", Status);
+      return;
+    }
+
   /*
    * Initialize PnP root releations
    */
   IopInvalidateDeviceRelations(
     IopRootDeviceNode,
-    BusRelations,
-    TRUE);
+    BusRelations);
 }
 
 /*

reactos/ntoskrnl/io
pnpmgr.c 1.27 -> 1.28
diff -u -r1.27 -r1.28
--- pnpmgr.c	21 Mar 2004 18:58:53 -0000	1.27
+++ pnpmgr.c	27 Mar 2004 19:41:32 -0000	1.28
@@ -1,4 +1,4 @@
-/* $Id: pnpmgr.c,v 1.27 2004/03/21 18:58:53 navaraf Exp $
+/* $Id: pnpmgr.c,v 1.28 2004/03/27 19:41:32 navaraf Exp $
  *
  * COPYRIGHT:      See COPYING in the top level directory
  * PROJECT:        ReactOS kernel
@@ -1068,15 +1068,28 @@
        !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) &&
        !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED))
    {
-      Status = IopInitializeDeviceNodeService(
-         DeviceNode,
-         &DeviceNode->ServiceName,
-         BootDrivers);
+      PMODULE_OBJECT ModuleObject;
+      PDRIVER_OBJECT DriverObject;
+
+      Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
       if (NT_SUCCESS(Status))
       {
-         IopAttachFilterDrivers(DeviceNode, FALSE);
-         IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
-      } else
+         Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE, &DriverObject);
+         if (NT_SUCCESS(Status))
+         {
+            /* Attach lower level filter drivers. */
+            IopAttachFilterDrivers(DeviceNode, TRUE);
+            /* Initialize the function driver for the device node */
+            Status = IopInitializeDevice(DeviceNode, DriverObject);
+            if (NT_SUCCESS(Status))
+            {
+               IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
+               /* Attach upper level filter drivers. */
+               IopAttachFilterDrivers(DeviceNode, FALSE);
+            }
+         }
+      }
+      else
       {
          /*
           * Don't disable when trying to load only boot drivers
@@ -1138,6 +1151,7 @@
  * Parameters
  *    DeviceNode
  *       Top device node to start initializing services.
+ *
  *    BootDrivers
  *       When set to TRUE, only drivers marked as boot start will
  *       be loaded. Otherwise, all drivers will be loaded.
@@ -1177,15 +1191,18 @@
 
 NTSTATUS
 IopInvalidateDeviceRelations(
-  IN PDEVICE_NODE DeviceNode,
-  IN DEVICE_RELATION_TYPE Type,
-  IN BOOLEAN BootDriver)
+   IN PDEVICE_NODE DeviceNode,
+   IN DEVICE_RELATION_TYPE Type)
 {
    DEVICETREE_TRAVERSE_CONTEXT Context;
    PDEVICE_RELATIONS DeviceRelations;
    IO_STATUS_BLOCK IoStatusBlock;
    PDEVICE_NODE ChildDeviceNode;
    IO_STACK_LOCATION Stack;
+   BOOL BootDrivers;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   UNICODE_STRING LinkName;
+   HANDLE Handle;
    NTSTATUS Status;
    ULONG i;
 
@@ -1277,11 +1294,38 @@
    }
 
    /*
+    * Get the state of the system boot. If the \\SystemRoot link isn't
+    * created yet, we will assume that it's possible to load only boot
+    * drivers.
+    */
+
+   RtlInitUnicodeString(&LinkName, L"\\SystemRoot");
+
+   InitializeObjectAttributes(
+      &ObjectAttributes,
+      &LinkName,
+      0,
+      NULL,
+      NULL);
+
+   Status = NtOpenFile(
+      &Handle,
+      FILE_ALL_ACCESS,
+      &ObjectAttributes,
+      &IoStatusBlock,
+      0,
+      0);
+ 
+   BootDrivers = NT_SUCCESS(Status) ? FALSE : TRUE;
+
+   NtClose(Handle);
+
+   /*
     * Initialize services for discovered children. Only boot drivers will
     * be loaded from boot driver!
     */
 
-   Status = IopInitializePnpServices(DeviceNode, BootDriver);
+   Status = IopInitializePnpServices(DeviceNode, BootDrivers);
    if (!NT_SUCCESS(Status))
    {
       DPRINT("IopInitializePnpServices() failed with status (%x)\n", Status);
@@ -1326,8 +1370,8 @@
       CPRINT("Insufficient resources\n");
       KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
    }
+
    IopRootDeviceNode->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-   IopRootDeviceNode->DriverObject = IopRootDriverObject;
    PnpRootDriverEntry(IopRootDriverObject, NULL);
    IopRootDriverObject->DriverExtension->AddDevice(
       IopRootDriverObject,

reactos/ntoskrnl/ldr
loader.c 1.140 -> 1.141
diff -u -r1.140 -r1.141
--- loader.c	7 Mar 2004 11:59:10 -0000	1.140
+++ loader.c	27 Mar 2004 19:41:32 -0000	1.141
@@ -1,4 +1,4 @@
-/* $Id: loader.c,v 1.140 2004/03/07 11:59:10 navaraf Exp $
+/* $Id: loader.c,v 1.141 2004/03/27 19:41:32 navaraf Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -449,107 +449,6 @@
 }
 
 
-NTSTATUS INIT_FUNCTION
-LdrInitializeBootStartDriver(PVOID ModuleLoadBase,
-			     PCHAR FileName,
-			     ULONG ModuleLength)
-{
-  PMODULE_OBJECT ModuleObject;
-  UNICODE_STRING ModuleName;
-  PDEVICE_NODE DeviceNode;
-  NTSTATUS Status;
-
-  WCHAR Buffer[MAX_PATH];
-  ULONG Length;
-  LPWSTR Start;
-  LPWSTR Ext;
-  PCHAR FileExt;
-  CHAR TextBuffer [256];
-  ULONG x, y, cx, cy;
-
-  HalQueryDisplayParameters(&x, &y, &cx, &cy);
-  RtlFillMemory(TextBuffer, x, ' ');
-  TextBuffer[x] = '\0';
-  HalSetDisplayParameters(0, y-1);
-  HalDisplayString(TextBuffer);
-
-  sprintf(TextBuffer, "Initializing %s...\n", FileName);
-  HalSetDisplayParameters(0, y-1);
-  HalDisplayString(TextBuffer);
-  HalSetDisplayParameters(cx, cy);
-
-  /*  Split the filename into base name and extension  */
-  FileExt = strrchr(FileName, '.');
-  if (FileExt != NULL)
-    Length = FileExt - FileName;
-  else
-    Length = strlen(FileName);
-
-  if ((FileExt != NULL) && (strcmp(FileExt, ".sym") == 0))
-    {
-      KDB_SYMBOLFILE_HOOK(ModuleLoadBase, FileName, Length);
-      return(STATUS_SUCCESS);
-    }
-  else if ((FileExt != NULL) && !(strcmp(FileExt, ".sys") == 0))
-    {
-      CPRINT("Ignoring non-driver file %s\n", FileName);
-      return STATUS_SUCCESS;
-    }
-
-  /* Use IopRootDeviceNode for now */
-  Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
-  if (!NT_SUCCESS(Status))
-    {
-      CPRINT("Driver load failed, status (%x)\n", Status);
-      return(Status);
-    }
-
-  RtlCreateUnicodeStringFromAsciiz(&ModuleName,
-				   FileName);
-  Status = LdrProcessModule(ModuleLoadBase,
-			    &ModuleName,
-			    &ModuleObject);
-  RtlFreeUnicodeString(&ModuleName);
-  if (ModuleObject == NULL)
-    {
-      IopFreeDeviceNode(DeviceNode);
-      CPRINT("Driver load failed, status (%x)\n", Status);
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-
-  /* 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);
-  Buffer[Length] = 0;
-  RtlCreateUnicodeString(&DeviceNode->ServiceName, Buffer);
-
-  Status = IopInitializeDriver(ModuleObject->EntryPoint,
-			       DeviceNode, FALSE,
-			       ModuleObject->Base,
-			       ModuleObject->Length,
-			       TRUE);
-  if (!NT_SUCCESS(Status))
-    {
-      IopFreeDeviceNode(DeviceNode);
-      CPRINT("Driver load failed, status (%x)\n", Status);
-    }
-
-  return(Status);
-}
-
-
 NTSTATUS
 LdrProcessModule(PVOID ModuleLoadBase,
 		 PUNICODE_STRING ModuleName,
CVSspam 0.2.8