[PATCH:] fix overlapped I/O problems

Martin Wilck Martin.Wilck at fujitsu-siemens.com
Fri Nov 9 13:10:55 CST 2001


Hi,

The included patch (against CVS 2001-11-08) fixes two problems
with overlapped I/O:

1) Overlapped ReadFile() didn't work on normal files because
   file_get_info() never returned FD_TYPE_OVERLAPPED.

2) According to the MS docs, the lpOverlapped argument's Offset and
   OffsetHigh fields contain the offset from which to read.
   This was not honoured by the current implementation which
   only did sequential reads.

Regards,
Martin

-- 
Martin Wilck                Phone: +49 5251 8 15113
Fujitsu Siemens Computers   Fax:   +49 5251 8 20409
Heinz-Nixdorf-Ring 1	    mailto:Martin.Wilck at Fujitsu-Siemens.com
D-33106 Paderborn           http://www.fujitsu-siemens.com/primergy

Index: files/file.c
===================================================================
RCS file: /home/wine/wine/files/file.c,v
retrieving revision 1.119
diff -u -r1.119 file.c
--- files/file.c	2001/10/24 00:23:25	1.119
+++ files/file.c	2001/11/09 17:35:29
@@ -1275,6 +1275,7 @@
 {
     LPOVERLAPPED lpOverlapped = ovp->lpOverlapped;
     int result, r;
+    off_t ofs;

     TRACE("%p %p %08x\n", lpOverlapped, ovp->buffer, events );

@@ -1294,9 +1295,18 @@
         goto async_end;
     }

+    ofs = lpOverlapped->Offset + ((off_t)lpOverlapped->OffsetHigh << 32)
+	+ lpOverlapped->InternalHigh;
+
     /* check to see if the data is ready (non-blocking) */
-    result = read(ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh],
-                  ovp->count - lpOverlapped->InternalHigh);
+    /* Use the offset as given in the Overlapped structure */
+    result = pread (ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh],
+		    ovp->count - lpOverlapped->InternalHigh, ofs);
+
+    /* If pread fails, try a normal read */
+    if (result == -1 && errno == ESPIPE)
+	result = read (ovp->fd, &ovp->buffer[lpOverlapped->InternalHigh],
+		       ovp->count - lpOverlapped->InternalHigh);

     if ( (result<0) && ((errno == EAGAIN) || (errno == EINTR)))
     {
@@ -1444,6 +1454,7 @@
 {
     int unix_handle, result;
     DWORD type;
+    off_t ofs;

     TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToRead,
           bytesRead, overlapped );
@@ -1466,7 +1477,11 @@
         }

         /* see if we can read some data already (this shouldn't block) */
-        result = read( unix_handle, buffer, bytesToRead );
+	ofs = overlapped->Offset + ((off_t)overlapped->OffsetHigh << 32);
+	/* Try using the user-given offset first, fall back to read otherwise */
+        result = pread( unix_handle, buffer, bytesToRead, ofs);
+	if (result == -1 && errno == ESPIPE)
+	    result = read( unix_handle, buffer, bytesToRead );
         close(unix_handle);

         if(result<0)
Index: server/file.c
===================================================================
RCS file: /home/wine/wine/server/file.c,v
retrieving revision 1.48
diff -u -r1.48 file.c
--- server/file.c	2001/10/24 00:23:26	1.48
+++ server/file.c	2001/11/09 17:35:29
@@ -307,6 +307,10 @@
         req->index_low   = st.st_ino;
         req->serial      = 0; /* FIXME */
     }
+
+    if (file->flags & FILE_FLAG_OVERLAPPED)
+	return FD_TYPE_OVERLAPPED;
+
     return FD_TYPE_DEFAULT;
 }








More information about the wine-devel mailing list