#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)
}
+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);
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) {
* 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 */
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;
}