[Wine-patches] [eter-1.0.10 2/7] Add implementation of IRP_MJ_WRITE handling.
Alexander Morozov
amorozov на etersoft.ru
Вт Июн 30 15:52:16 MSD 2009
----------- следующая часть -----------
From 3673386fe40a1037c528e9bf75fe1c012afb2e99 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 30 Jun 2009 13:30:41 +0400
Subject: [eter-1.0.10 2/7] 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 d78ad0d..0720f4c 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -132,7 +132,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)
#define UPKEY_NKEY_DATA_SIZE 8192
@@ -552,6 +554,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)
@@ -614,14 +659,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.2
Подробная информация о списке рассылки Wine-patches