4

I have opened a file using

HANDLE handle= 
    CreateFileW(
        fileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 
        FILE_FLAG_OVERLAPPED, NULL);

The file handle is then used for asynchronous read operations:

ReadFile(handle, buffer, 1, NULL, &overlapped);

This works. However, I want to do a synchronous write now. WriteFile documentation states that

If hFile was opened with FILE_FLAG_OVERLAPPED, the following conditions are in effect:
• The lpOverlapped parameter must point to a valid and unique OVERLAPPED structure, otherwise the function can incorrectly report that the write operation is complete.

When the lpOverlapepd parameter is omitted, ERROR_INVALID_PARAMETER is returned by GetLastError(). Opening two handles, one for reading and one for writing does also not work since the second handle produces a ERROR_ACCESS_DENIED error.

How can I open the file for asynchronous reads and synchronous writes? I don't want to increase code complexity unnecessarily.

Etan
  • 17,014
  • 17
  • 89
  • 148
  • I want to use the I/O Completion Port to perform other I/O operations simultaneously to the ones on the COM port. – Etan Jul 12 '11 at 14:47

2 Answers2

4

Synchronous writes can be achieved by creating a manual reset event for the write operation, writing to the file (using the event in the overlapped structure for your write operation) and then immediately waiting for the event.

Depending on whether your asynchronous read needs to be asynchronous with your write, you may need to make sure you use a compatible wait so that your read completion routine can be called otherwise the read will take place and the data will be stored in the buffer but you cannot process it.

tinman
  • 6,348
  • 1
  • 30
  • 43
  • It is okay if the write blocks the read completion routine for a short time since the writes don't take much time. The read buffer will be processed as soon as the write completes, that's ok. – Etan Jul 12 '11 at 13:10
0

Open two handles, one for async read the other for sync write, just make sure that you set the file share attributes (FILE_SHARE_READ|FILE_SHARE_WRITE). Haven't tested it.

Djole
  • 1,145
  • 5
  • 10
  • `The CreateFile function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, the dwShareMode parameter must be zero (exclusive access), and the hTemplateFile parameter must be NULL. Read, write, or read/write access can be specified, and the handle can be opened for overlapped I/O.` Forgot to mention that dwShareMode has to be 0 since the file handle is for a communications resource. – Etan Jul 12 '11 at 11:52
  • Since I've dealt with the COM port before I would say that you are stuck with using async in both cases then. Create one thread to wait when there are chars in RX buff and use the main thread for port writes (this is true for RS232 only if you want RS485 you have to introduce locks that forbid you to write when reading) – Djole Jul 12 '11 at 12:16
  • The other proposed answer worked well :-) The application should be as simple as possible, sticking to one thread and faking the synchronous write as proposed are both methods to simplify it :-) – Etan Jul 12 '11 at 13:25