According to MSDN, the hEvent member of an OVERLAPPED structure can be
NULL:

  
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/overlapped_str.asp
    OVERLAPPED
      ...
      Members
        ...
        hEvent
          Handle to an event set to the signaled state when the operation
          has been completed. The calling process must set this member
          either to zero or a valid event handle before calling any
          overlapped functions.

A program I'm trying to run takes advantage of this, and as a result
triggered a lot of these errors from Wine:

    err:file:GetOverlappedResult lpOverlapped->hEvent was null

I wrote a patch that solves this, although it may not be the best
solution.

If when ReadFile is called overlapped->hEvent is NULL, the patch
generates a new event with CreateEventA and sets the structure member
to that event.  To create a unique name, it uses the hex address of
the overlapped structure along with a fairly long string, which is
pretty likely to be unique.

This works for the application I'm running.  If this seems like a good
enough solution, I can easily modify the other functions which
initiate an overlapped read to do the same.

----ScottG.
--- wine-20040505/dlls/kernel/file.c	2004-05-03 16:20:54.000000000 -0400
+++ wine-20040505-sg/dlls/kernel/file.c	2004-05-16 00:51:18.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <stdarg.h>
 #include <errno.h>
+#include <stdio.h>
 
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
@@ -262,6 +263,8 @@
     PIO_STATUS_BLOCK    io_status = &iosb;
     HANDLE              hEvent = 0;
     NTSTATUS            status;
+    static HANDLE       default_event = NULL;
+    static char         default_event_name[128];
 
     TRACE("%p %p %ld %p %p\n", hFile, buffer, bytesToRead,
           bytesRead, overlapped );
@@ -282,6 +285,17 @@
         offset.u.LowPart = overlapped->Offset;
         offset.u.HighPart = overlapped->OffsetHigh;
         poffset = &offset;
+	if (!overlapped->hEvent) {
+	        if (!default_event) {
+		        sprintf(default_event_name,"__Wine_Internal_ReadEvent_Overlapped_%p__",overlapped);
+  		        if (!(default_event = CreateEventA(NULL, FALSE, FALSE, default_event_name))) {
+			      SetLastError(ERROR_WRITE_FAULT); /* FIXME */
+			      return FALSE;
+			}
+			overlapped->hEvent = default_event;
+	         } 
+	}
+	    
         hEvent = overlapped->hEvent;
         io_status = (PIO_STATUS_BLOCK)overlapped;
     }

Reply via email to