[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