I end up showing my ignorance :-)
Ok, I see how it is supposed to work, so I changed it back to FD_TYPE_DEFAULT. It looks like my real troubles is caused by the snippet of code that decides when the read is successful:
if (io_status->Information >= fileio->count || fileio->fd_type == FD_TYPE_SOCKET ) io_status->u.Status = STATUS_SUCCESS; else io_status->u.Status = STATUS_PENDING;
For the app in question, when I turn on debugging for ntdll I get:
trace:ntdll:FILE_AsyncReadService 0x42295b4f 0x42295fe1 1 trace:ntdll:FILE_AsyncReadService read 1 more bytes 7/1040 so far, io_status->u.Status=0x103
trace:ntdll:FILE_AsyncReadService 0x42295b4f 0x42295fe1 1 trace:ntdll:FILE_AsyncReadService read 1 more bytes 8/1040 so far, io_status->u.Status=0x103
trace:ntdll:FILE_AsyncReadService 0x42295b4f 0x42295fe1 1 trace:ntdll:FILE_AsyncReadService read 1 more bytes 9/1040 so far, io_status->u.Status=0x103
The tracing of io_status->u.Status was added by myself. I'm not sure if the problem is not perhaps caused by the fact that u.Status is always 0x103 (STATUS_PENDING) and never becomes 0x0 (STATUS_SUCCESS). Of course, if I change the FD_TYPE to FD_TYPE_SOCKET, the result is always STATUS_SUCCESS, which is probably what the app wants. Not knowing much about the API or how Windows implements it (haven't programmed in the windows environment for 7 years now) I'm not even sure if this is some kind of a windows quirk exploited by this app.
If my experience with unix in general is anything to go by, then it would be acceptable to provide a 1040 byte buffer, and read as much data into it as you can (which is almost always less than the 1040 you _could_ theoretically read in one go), then return STATUS_SUCCESS. Is it the same for windows? Obviously the above code will return STATUS_PENDING until it has read 1040 bytes, and only then will it return STATUS_SUCCESS.
A bit of background: the software is supposed to talk to a Casio point of sale system. This POS device pumps out the letter "C" on the serial port, about once every 5 seconds. That is why the ntdll trace above shows a character by character receive. I get the feeling the app is really just waiting for the first "C" to arrive, but after 60 seconds it times out. The app is of course closed source, and I get the feeling the actual communication is done by code in a .dll file provided by Casio. Ie, no chance of fixing up the windows app.
regards, Izak
Alexandre Julliard wrote:
You can't, the pread() call is supposed to fail with ESPIPE, in which case we fall back to a normal read. Doesn't this work for you? What error does the pread() call return?