+IRP_MJ_WRITE handler
authorshort <>
Mon, 20 Jan 2003 23:26:30 +0000 (23:26 +0000)
committershort <>
Mon, 20 Jan 2003 23:26:30 +0000 (23:26 +0000)
src/libcaptive/storage/media.c

index 5607c1d..92d384d 100644 (file)
@@ -28,6 +28,7 @@
 #include "captive/macros.h"
 #include "reactos/ddk/mmfuncs.h"       /* for MmGetMdlByteCount() */
 #include "captive/unicode.h"
+#include <glib/gmacros.h>
 
 
 static gboolean validate_DeviceObject(DEVICE_OBJECT *DeviceObject)
@@ -239,17 +240,23 @@ done:     /* 'err:' but we flow here even during success */
 }
 
 
+struct MajorFunction_READ_WRITE_func_Parameters {
+               ULONG Length;
+               ULONG Key;
+               LARGE_INTEGER ByteOffset;
+               };
+
 /* FIXME: We should comply with PDRIVER_DISPATCH prototype but unfortunately
  * CAPTIVE_STDCALL prevents us to do so at least in RedHat gcc-3.2-4 (gcc bug?).
  */
-#define MajorFunction_READ ((PDRIVER_DISPATCH)MajorFunction_READ_func)
-static NTSTATUS CAPTIVE_STDCALL MajorFunction_READ_func(IN DEVICE_OBJECT *DeviceObject,IN IRP *Irp)
+#define MajorFunction_READ_WRITE ((PDRIVER_DISPATCH)MajorFunction_READ_WRITE_func)
+static NTSTATUS CAPTIVE_STDCALL MajorFunction_READ_WRITE_func(IN DEVICE_OBJECT *DeviceObject,IN IRP *Irp)
 {
 IO_STACK_LOCATION *IrpStack;
-gsize bytesread;
 gpointer buffer=NULL;
 GIOStatus erriostatus;
 struct captive_DriverObject *captive_DriverObject;
+const struct MajorFunction_READ_WRITE_func_Parameters *Parameters;
 
   g_return_val_if_fail(TRUE==validate_DeviceObject(DeviceObject),STATUS_INVALID_PARAMETER);
        g_return_val_if_fail(Irp!=NULL,STATUS_INVALID_PARAMETER);
@@ -258,13 +265,23 @@ struct captive_DriverObject *captive_DriverObject;
 
        Irp->IoStatus.Information=0;    /* request-specific, may get overriden later */
        IrpStack=IoGetCurrentIrpStackLocation(Irp);
-       g_assert(IrpStack->MajorFunction==IRP_MJ_READ);
+       g_assert(IrpStack->MajorFunction==IRP_MJ_READ || IrpStack->MajorFunction==IRP_MJ_WRITE);
        g_assert(IrpStack->MinorFunction==0);
 
-       /* What is 'IrpStack->Parameters.Read.Key'? */
-       g_assert(0==(IrpStack->Parameters.Read.Length%captive_DriverObject->DiskGeometry.BytesPerSector));
-       g_assert(0==(IrpStack->Parameters.Read.ByteOffset.QuadPart%captive_DriverObject->DiskGeometry.BytesPerSector));
-       g_assert(IrpStack->Parameters.Read.ByteOffset.QuadPart>=0);
+#define READ_WRITE_ASSERT_PARAMETERS_OFFSET(struct_a,struct_b,member) \
+               g_assert(G_STRUCT_OFFSET(typeof(IrpStack->Parameters.struct_a),member) \
+                               ==G_STRUCT_OFFSET(typeof(IrpStack->Parameters.struct_b),member))
+       READ_WRITE_ASSERT_PARAMETERS_OFFSET(Read,Write,Length);
+       READ_WRITE_ASSERT_PARAMETERS_OFFSET(Read,Write,Key);
+       READ_WRITE_ASSERT_PARAMETERS_OFFSET(Read,Write,ByteOffset);
+       READ_WRITE_ASSERT_PARAMETERS_OFFSET(Read,Write,ByteOffset.QuadPart);
+#undef READ_WRITE_ASSERT_PARAMETERS_OFFSET
+
+       switch (IrpStack->MajorFunction) {
+               case IRP_MJ_READ:  Parameters=(const struct MajorFunction_READ_WRITE_func_Parameters *)&IrpStack->Parameters.Read; break;
+               case IRP_MJ_WRITE: Parameters=(const struct MajorFunction_READ_WRITE_func_Parameters *)&IrpStack->Parameters.Write; break;
+               default: g_assert_not_reached();
+               }
 
        /* Autodetect 'buffer' as we are !DO_BUFFERED_IO && !DO_DIRECT_IO hybrid */
        if (Irp->UserBuffer) {
@@ -280,26 +297,46 @@ struct captive_DriverObject *captive_DriverObject;
                 * initialization of 'Irp->UserBuffer'.
                 */
                g_assert(buffer==Irp->MdlAddress->StartVa);
-               g_assert(IrpStack->Parameters.Read.Length<=MmGetMdlByteCount(Irp->MdlAddress));
+               g_assert(Parameters->Length<=MmGetMdlByteCount(Irp->MdlAddress));
                buffer=MmGetSystemAddressForMdl(Irp->MdlAddress);
                }
        g_assert(buffer!=NULL);
 
        erriostatus=g_io_channel_seek_position(captive_image_iochannel,
-                       IrpStack->Parameters.Read.ByteOffset.QuadPart,  /* offset */
+                       Parameters->ByteOffset.QuadPart,        /* offset */
                        G_SEEK_SET,     /* type */
                        NULL);  /* error */
        g_assert(erriostatus==G_IO_STATUS_NORMAL);
 
-       erriostatus=g_io_channel_read_chars(captive_image_iochannel,
-                       buffer, /* buf */
-                       IrpStack->Parameters.Read.Length,       /* count */
-                       &bytesread,     /* bytesread */
-                       NULL);  /* error */
-       g_assert(erriostatus==G_IO_STATUS_NORMAL);
-       g_assert(bytesread==IrpStack->Parameters.Read.Length);
+       switch (IrpStack->MajorFunction) {
+               case IRP_MJ_READ: {
+gsize bytesread;
+
+                       erriostatus=g_io_channel_read_chars(captive_image_iochannel,
+                                       buffer, /* buf */
+                                       Parameters->Length,     /* count */
+                                       &bytesread,     /* bytesread */
+                                       NULL);  /* error */
+                       g_assert(erriostatus==G_IO_STATUS_NORMAL);
+                       g_assert(bytesread==Parameters->Length);
+                       } break;
+
+               case IRP_MJ_WRITE: {
+gsize byteswritten;
+
+                       erriostatus=g_io_channel_write_chars(captive_image_iochannel,
+                                       buffer, /* buf */
+                                       Parameters->Length,     /* count */
+                                       &byteswritten,  /* byteswritten */
+                                       NULL);  /* error */
+                       g_assert(erriostatus==G_IO_STATUS_NORMAL);
+                       g_assert(byteswritten==Parameters->Length);
+                       } break;
+
+               default: g_assert_not_reached();
+               }
 
-       Irp->IoStatus.Information=IrpStack->Parameters.Read.Length;
+       Irp->IoStatus.Information=Parameters->Length;
        Irp->IoStatus.Status=STATUS_SUCCESS;
 
        /* PASSTHRU */
@@ -386,7 +423,8 @@ NTSTATUS err;
        DeviceExtension->DiskGeometry=&captive_DriverObject->DiskGeometry;
 
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MajorFunction_DEVICE_CONTROL;
-       DriverObject->MajorFunction[IRP_MJ_READ          ]=MajorFunction_READ;
+       DriverObject->MajorFunction[IRP_MJ_READ          ]=MajorFunction_READ_WRITE;
+       DriverObject->MajorFunction[IRP_MJ_WRITE         ]=MajorFunction_READ_WRITE;
 
        return STATUS_SUCCESS;
 }