[Wine-patches] [eterhack 3/3] Add implementation of IRP_MJ_WRITE handling.
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пт Май 29 18:23:40 MSD 2009
----------- следующая часть -----------
From 4e1134ac1921ecd829fe5722fa3dad1a544437d3 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Fri, 29 May 2009 17:35:45 +0400
Subject: [eterhack 3/3] Add implementation of IRP_MJ_WRITE handling.
---
dlls/ntdll/file.c | 7 ++++-
dlls/ntoskrnl.exe/ntoskrnl.c | 60 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 6a98f95..f04f975 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -523,7 +523,9 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL
}
-#define IOCTL_WINE_DRIVER_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, \
+#define IOCTL_WINE_DRIVER_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, \
+ METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_WINE_DRIVER_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x101, \
METHOD_BUFFERED, FILE_ANY_ACCESS)
static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
@@ -917,6 +919,9 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
status = server_get_unix_fd( hFile, FILE_WRITE_DATA, &unix_handle,
&needs_close, &type, &options );
+ if (status == STATUS_BAD_DEVICE_TYPE)
+ return server_ioctl_file( hFile, hEvent, apc, apc_user, io_status,
+ IOCTL_WINE_DRIVER_WRITE, buffer, length, buffer, length );
if (status) return status;
if (!virtual_check_buffer_for_read( buffer, length ))
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index c96ccc0..2ba37d3 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -134,7 +134,9 @@ struct HandleInstance
ULONG refs;
};
-#define IOCTL_WINE_DRIVER_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, \
+#define IOCTL_WINE_DRIVER_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, \
+ METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_WINE_DRIVER_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x101, \
METHOD_BUFFERED, FILE_ANY_ACCESS)
#ifdef __i386__
@@ -612,6 +614,49 @@ static NTSTATUS process_read( DEVICE_OBJECT *device, void *buff, ULONG *size )
return status;
}
+/* process IRP_MJ_WRITE request for a given device */
+static NTSTATUS process_write( DEVICE_OBJECT *device, void *buff, ULONG *size )
+{
+ PIRP irp;
+ PIO_STACK_LOCATION irpsp;
+ NTSTATUS status;
+ LARGE_INTEGER count;
+ MDL mdl;
+
+ irp = IoAllocateIrp( device->StackSize, FALSE );
+ if (irp == NULL)
+ return STATUS_NO_MEMORY;
+ irp->RequestorMode = UserMode;
+ irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation - 1;
+ irpsp->DeviceObject = device;
+ irpsp->MajorFunction = IRP_MJ_WRITE;
+ irpsp->Parameters.Write.Length = *size;
+ device->CurrentIrp = irp;
+
+ if (device->Flags & DO_DIRECT_IO)
+ {
+ mdl.Next = NULL;
+ mdl.Size = sizeof(mdl);
+ mdl.MdlFlags = MDL_PAGES_LOCKED;
+ mdl.StartVa = buff;
+ mdl.MappedSystemVa = buff;
+ mdl.ByteCount = *size;
+ mdl.ByteOffset = 0;
+ irp->MdlAddress = &mdl;
+ }
+ else if (device->Flags & DO_BUFFERED_IO)
+ irp->AssociatedIrp.SystemBuffer = buff;
+ else irp->UserBuffer = buff;
+
+ KeQueryTickCount( &count ); /* update the global KeTickCount */
+ status = IoCallDriver( device, irp );
+ irp->IoStatus.Information = *size;
+ if (irp->MdlAddress == NULL) /* for UPKey.sys */
+ *size = (status == STATUS_SUCCESS) ? irp->IoStatus.Information : 0;
+ IoFreeIrp( irp );
+ return status;
+}
+
/***********************************************************************
* wine_ntoskrnl_main_loop (Not a Windows API)
@@ -674,14 +719,19 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
else out_buff = NULL;
while (device->AttachedDevice)
device = device->AttachedDevice;
- if (code != IOCTL_WINE_DRIVER_READ)
+ if (code == IOCTL_WINE_DRIVER_READ)
{
- status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
+ memcpy( out_buff, in_buff, min( in_size, out_size ) );
+ status = process_read( device, out_buff, &out_size );
}
- else
+ else if (code == IOCTL_WINE_DRIVER_WRITE)
{
memcpy( out_buff, in_buff, min( in_size, out_size ) );
- status = process_read( device, out_buff, &out_size );
+ status = process_write( device, out_buff, &out_size );
+ }
+ else
+ {
+ status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
}
break;
case STATUS_BUFFER_OVERFLOW:
--
1.6.3.1
Подробная информация о списке рассылки Wine-patches