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;
}