Patch for ReadFile with NULL hEvent

Eric Pouech pouech-eric at wanadoo.fr
Mon May 17 12:15:43 CDT 2004


Eric Pouech a écrit :
>> ...Windows doesn't do it this way, although according to the docs
>> other members of the overlapped structure are modified by Windows.
> 
> Ok, we need to rewrite GetOverlappedResult to use the internal 
> structures (and get the hEvent we might have created in ReadFile), 
> instead of relying on the one from the overlapped struct itself

Does the attached patch help ?
A+
-------------- next part --------------
Index: dlls/kernel/file.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/kernel/file.c,v
retrieving revision 1.19
diff -u -r1.19 file.c
--- dlls/kernel/file.c	13 May 2004 20:21:25 -0000	1.19
+++ dlls/kernel/file.c	17 May 2004 17:13:44 -0000
@@ -492,44 +492,44 @@
 BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped,
                                 LPDWORD lpTransferred, BOOL bWait)
 {
-    DWORD r;
+    DWORD r = WAIT_OBJECT_0;
 
     TRACE("(%p %p %p %x)\n", hFile, lpOverlapped, lpTransferred, bWait);
 
-    if (lpOverlapped==NULL)
+    if (lpOverlapped == NULL)
     {
         ERR("lpOverlapped was null\n");
         return FALSE;
     }
-    if (!lpOverlapped->hEvent)
-    {
-        ERR("lpOverlapped->hEvent was null\n");
-        return FALSE;
-    }
-
     if ( bWait )
     {
-        do {
+        do
+        {
             TRACE("waiting on %p\n",lpOverlapped);
             r = WaitForSingleObjectEx(lpOverlapped->hEvent, INFINITE, TRUE);
             TRACE("wait on %p returned %ld\n",lpOverlapped,r);
-        } while (r==STATUS_USER_APC);
+        } while (r == WAIT_IO_COMPLETION);
     }
     else if ( lpOverlapped->Internal == STATUS_PENDING )
     {
         /* Wait in order to give APCs a chance to run. */
         /* This is cheating, so we must set the event again in case of success -
            it may be a non-manual reset event. */
-        do {
+        do
+        {
             TRACE("waiting on %p\n",lpOverlapped);
             r = WaitForSingleObjectEx(lpOverlapped->hEvent, 0, TRUE);
             TRACE("wait on %p returned %ld\n",lpOverlapped,r);
-        } while (r==STATUS_USER_APC);
-        if ( r == WAIT_OBJECT_0 )
-            NtSetEvent ( lpOverlapped->hEvent, NULL );
+        } while (r == WAIT_IO_COMPLETION);
+        if ( r == WAIT_OBJECT_0 && lpOverlapped->hEvent )
+            NtSetEvent( lpOverlapped->hEvent, NULL );
     }
-
-    if(lpTransferred)
+    if (r == WAIT_FAILED && lpOverlapped->hEvent)
+    {
+        ERR("wait operation failed\n");
+        return FALSE;
+    }
+    if (lpTransferred)
         *lpTransferred = lpOverlapped->InternalHigh;
 
     switch ( lpOverlapped->Internal )
@@ -537,11 +537,11 @@
     case STATUS_SUCCESS:
         return TRUE;
     case STATUS_PENDING:
-        SetLastError ( ERROR_IO_INCOMPLETE );
-        if ( bWait ) ERR ("PENDING status after waiting!\n");
+        SetLastError( ERROR_IO_INCOMPLETE );
+        if ( bWait ) ERR("PENDING status after waiting!\n");
         return FALSE;
     default:
-        SetLastError ( RtlNtStatusToDosError ( lpOverlapped->Internal ) );
+        SetLastError( RtlNtStatusToDosError( lpOverlapped->Internal ) );
         return FALSE;
     }
 }
@@ -635,7 +635,6 @@
     return (HFILE)create_file_OF( path, mode & ~OF_CREATE );
 }
 
-
 /***********************************************************************
  *           _lread   (KERNEL32.@)
  */


More information about the wine-devel mailing list