branch update for HEAD-2003091401
[reactos.git] / ntoskrnl / io / device.c
index 57fde3f..f4397c7 100644 (file)
@@ -11,7 +11,8 @@
 
 /* INCLUDES ****************************************************************/
 
-#include <ddk/ntddk.h>
+#define NTOS_MODE_KERNEL
+#include <ntos.h>
 #include <internal/io.h>
 #include <internal/po.h>
 #include <internal/ldr.h>
@@ -37,6 +38,9 @@
 
 #ifndef LIBCAPTIVE
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice,
                        IN PDEVICE_OBJECT TargetDevice)
@@ -57,6 +61,9 @@ IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice,
 
 #endif /* LIBCAPTIVE */
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
 {
@@ -104,16 +111,36 @@ IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
 
 #ifndef LIBCAPTIVE
 
+/*
+ * @implemented
+ */
 PDEVICE_OBJECT
 STDCALL
 IoGetRelatedDeviceObject (
        IN      PFILE_OBJECT    FileObject
        )
 {
-       return (FileObject->DeviceObject);
+   /*Win NT File System Internals, page 633-634*/
+
+   /*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)
+   {
+      return IoGetAttachedDevice(FileObject->DeviceObject->Vpb->DeviceObject);
+   }
+
+   return IoGetAttachedDevice(FileObject->DeviceObject);
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS
 STDCALL
 IoGetDeviceObjectPointer (
@@ -166,6 +193,9 @@ IoGetDeviceObjectPointer (
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 STDCALL
 IoDetachDevice(PDEVICE_OBJECT TargetDevice)
@@ -176,6 +206,9 @@ IoDetachDevice(PDEVICE_OBJECT TargetDevice)
 
 #endif /* LIBCAPTIVE */
 
+/*
+ * @implemented
+ */
 PDEVICE_OBJECT
 STDCALL
 IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
@@ -196,6 +229,9 @@ IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
 
 #ifndef LIBCAPTIVE
 
+/*
+ * @implemented
+ */
 PDEVICE_OBJECT
 STDCALL
 IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
@@ -211,6 +247,9 @@ IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
    return(Current);
 }
 
+/*
+ * @implemented
+ */
 PDEVICE_OBJECT STDCALL
 IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
                            PDEVICE_OBJECT TargetDevice)
@@ -228,6 +267,9 @@ IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
    return(AttachedDevice);
 }
 
+/*
+ * @unimplemented
+ */
 VOID STDCALL
 IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,
                                 PDRIVER_REINITIALIZE ReinitRoutine,
@@ -251,7 +293,9 @@ IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject,
 NTSTATUS
 IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
                      PUNICODE_STRING ServiceName,
-                     BOOLEAN FileSystem)
+                     BOOLEAN FileSystem,
+                     PVOID DriverImageStart,
+                     ULONG DriverImageSize)
 {
   PDRIVER_OBJECT Object;
   HANDLE DriverHandle = 0;
@@ -261,12 +305,13 @@ IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
   OBJECT_ATTRIBUTES ObjectAttributes;
   NTSTATUS Status;
 
-  DPRINT("IopCreateDriverObject(%p '%wZ' %x)\n", DriverObject, ServiceName, FileSystem);
+  DPRINT("IopCreateDriverObject(%p '%wZ' %x %p %x)\n", DriverObject, ServiceName, FileSystem,
+        DriverImageStart, DriverImageSize);
 
   *DriverObject = NULL;
 
   /*  Create ModuleName string  */
-  if (ServiceName != NULL)
+  if ((ServiceName != NULL) && (ServiceName->Buffer != NULL))
     {
       if (FileSystem == TRUE)
        wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME);
@@ -279,15 +324,15 @@ IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
       DPRINT("Driver name: '%wZ'\n", &DriverName);
     }
 
-  /*  Initialize ObjectAttributes for ModuleObject  */
+  /* Initialize ObjectAttributes for driver object */
   InitializeObjectAttributes(&ObjectAttributes,
-                            (ServiceName != NULL)? &DriverName : NULL,
+                            ((ServiceName != NULL) && (ServiceName->Buffer != NULL))? &DriverName : NULL,
                             OBJ_PERMANENT,
                             NULL,
                             NULL);
 
-  /*  Create module object  */
-  Status = ObCreateObject(&DriverHandle,
+  /* Create module object */
+  Status = ObRosCreateObject(&DriverHandle,
                           STANDARD_RIGHTS_REQUIRED,
                           &ObjectAttributes,
                           IoDriverObjectType,
@@ -314,6 +359,9 @@ IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
 
   Object->Type = InternalDriverType;
 
+  Object->DriverStart = DriverImageStart;
+  Object->DriverSize = DriverImageSize;
+
   for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)
     {
        Object->MajorFunction[i] = (PDRIVER_DISPATCH) IopDefaultDispatchFunction;
@@ -369,7 +417,7 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
         {
           /* FIXME: What do we do? Unload the driver or just disable the device? */
           DbgPrint("An FDO was not attached\n");
-          KeBugCheck(0);
+          KEBUGCHECK(0);
         }
 
       /* FIXME: Put some resources in the IRP for the device */
@@ -440,7 +488,8 @@ IopInitializeService(
       return(Status);
     }
 
-    Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, FALSE);
+    Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, FALSE,
+                                ModuleObject->Base, ModuleObject->Length);
     if (!NT_SUCCESS(Status))
     {
       LdrUnloadModule(ModuleObject);
@@ -507,7 +556,9 @@ IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode)
 NTSTATUS
 IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
                    PDEVICE_NODE DeviceNode,
-                   BOOLEAN FileSystemDriver)
+                   BOOLEAN FileSystemDriver,
+                   PVOID DriverImageStart,
+                   ULONG DriverImageSize)
 /*
  * FUNCTION: Called to initalize a loaded driver
  * ARGUMENTS:
@@ -525,7 +576,9 @@ IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
 
   Status = IopCreateDriverObject(&DriverObject,
                                 &DeviceNode->ServiceName,
-                                FileSystemDriver);
+                                FileSystemDriver,
+                                DriverImageStart,
+                                DriverImageSize);
   if (!NT_SUCCESS(Status))
     {
       return(Status);
@@ -563,9 +616,12 @@ IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 IoAttachDevice(PDEVICE_OBJECT SourceDevice,
-              PUNICODE_STRING TargetDevice,
+          PUNICODE_STRING TargetDeviceName,
               PDEVICE_OBJECT* AttachedDevice)
 /*
  * FUNCTION: Layers a device over the highest device in a device stack
@@ -575,7 +631,25 @@ IoAttachDevice(PDEVICE_OBJECT SourceDevice,
  *       AttachedDevice (OUT) = Caller storage for the device attached to
  */
 {
-  UNIMPLEMENTED;
+   NTSTATUS       Status;
+   PFILE_OBJECT   FileObject;
+   PDEVICE_OBJECT TargetDevice;
+     
+   Status = IoGetDeviceObjectPointer(TargetDeviceName,
+                                     FILE_READ_ATTRIBUTES,
+                                     &FileObject,
+                                     &TargetDevice);
+   
+   if (!NT_SUCCESS(Status))
+   {
+      return Status;
+   }
+
+   *AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice,
+                                                 TargetDevice);
+
+   ObDereferenceObject(FileObject);
+   return STATUS_SUCCESS;
 }
 
 #endif /* LIBCAPTIVE */
@@ -590,14 +664,20 @@ IopCreateDevice(PVOID ObjectBody,
    DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n",
          ObjectBody, Parent, RemainingPath);
    
+#ifndef LIBCAPTIVE
    if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
      {
        return(STATUS_UNSUCCESSFUL);
      }
+#endif /* LIBCAPTIVE */
    
    return(STATUS_SUCCESS);
 }
 
+
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 IoCreateDevice(PDRIVER_OBJECT DriverObject,
               ULONG DeviceExtensionSize,
@@ -660,7 +740,7 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
    if (DeviceName != NULL)
      {
        InitializeObjectAttributes(&ObjectAttributes,DeviceName,0,NULL,NULL);
-       Status = ObCreateObject(NULL,
+       Status = ObRosCreateObject(NULL,
                                0,
                                &ObjectAttributes,
                                IoDeviceObjectType,
@@ -668,7 +748,7 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
      }
    else
      {
-       Status = ObCreateObject(NULL,
+       Status = ObRosCreateObject(NULL,
                                0,
                                NULL,
                                IoDeviceObjectType,
@@ -688,7 +768,7 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject,
    
    if (!NT_SUCCESS(Status))
      {
-       DPRINT("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status);
+       DPRINT("IoCreateDevice() ObRosCreateObject failed, status: 0x%08X\n", Status);
        return(Status);
      }