Solved

MFC ReadFile issue

Posted on 2002-04-23
12
1,467 Views
Last Modified: 2013-11-25
I am trying to write some software that will talk over a serial port, async, and in the background.

When I set up my port, I use overlaped comms cuz of the async...

     HANDLE com_port = CreateFile(
          "COM1",
          GENERIC_READ | GENERIC_WRITE,
          0,                                   // comm devices must be opened w/exclusive-access
          NULL,                              // no security attributes
          OPEN_EXISTING,                    // comm devices must use OPEN_EXISTING
          FILE_FLAG_OVERLAPPED,          // overlapped I/O
          NULL);                              // hTemplate must be NULL for comm devices

In this mode, I then setup timeouts and settings to the right speed etc.

I am able to connect a remote Hyperterm with a NULL modem cable and I can send data with write File...

     BOOL w = WriteFile(comms_channel,
          msg.buffer(),
          msg.length(),
          &written,
          &ov);

But I cannot receive data with a read file... (the overlap below is a different one to the one used for the write... I also tried using the same one, or none at all, all round)

          bResult = ReadFile(
               hCommPortHandle,     // handle to file to read from
               &chInputByte,       // pointer to buffer that receives data
               1,                         // number of bytes to read
               &iLengthRead,          // pointer to number of bytes read
               &ov);                    // pointer to overalp structure for data

Without an overlapped port, the read succeeds, but there is no data there... when I connect a local hyperterm... there is definately data in the receive buffer.

Microsoft documentation is pants with regard to the overlapped data stuff, and I cannot get it to work... there was an example of setting the ov.hEvent to be another handle and this is set when the read is finished... but there was no documentation for that either.

Anyone know how I can recieve data over a COM port under windows 2K/NT using a file handle asynchronously whilst writing on it.

Thanks
Nigel.
0
Comment
Question by:nigel5
  • 6
  • 5
12 Comments
 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962360
Have you tried FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED?

Plus it isn't clear from your example that you are using the same "com_port" HANDLE for your read & write.
0
 

Author Comment

by:nigel5
ID: 6962387
Ah, the com_port handle does change thought the code... :)

It is the same port handle.

After giving the FILE_FLAG_NO_BUFFERING thing a go, still nothing. I sent down a several KB of keypresses, and nothing, when I loaded hyperterm back on the port,,, I got the last few dozen bytes.

Cheers
N.
0
 

Author Comment

by:nigel5
ID: 6962414
Sorry,  I should clarify my last comment, the port handle name does change throughout the code, but thats because I have 3 different threads running, wach using a differnet name... cuz I ripped the code out of the manual in different places.
0
 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962424
hmmm - different treads operating on the same file. That's very gutsy. I would have assumed that one would do your open and start your asynchronous read and write off from the same thread and use WaitForMultipleObjects to handle the action.
If the o/s does anysort of "critical section" protection of it's file i/o code then a multitread access could well have problems.
0
 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962468
do you have an email address ?
cheers
ggrundy@bigpond.com
0
 

Author Comment

by:nigel5
ID: 6962474
I always get ERROR_IO_PENDING when I do a read file.

I have not set up the hEvent as I dunno how that works, and MS documentation is pants.
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6962497
I've knocked together some code
(untested because I can't be bothered setting up a null modem) which I can send you IF I have an email address.
0
 

Author Comment

by:nigel5
ID: 6962654
Currently at nigel.johnson@bt.com

Thanks.
N.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6964794
It is much easier to use synchronous operation.  All com port transactions are:

    send something
    wait for the expected reply or a timeout

so what needs to be asynchronous?

-- Dan
0
 

Author Comment

by:nigel5
ID: 6964862
I am building a generic comms wrapper for a serial command unit... basically remote comms for an autonymous vehicle. Both units share a data pool, and they have to keep the values synchronised. When a value changes at one end, it is broadcast and should change in all the other data pools.

I talk to the remote comms devices by RS232, and the problem is that I won't be requesting all the data to change... (the baud rate is 4K8, so that'd be eating bandwidth.)

In Solaris, async comms is probably one of the simplest things to do... mind you, so is using third party softwre like greenleaf or WFC... but I want to run on a PC (cuz of the GUI front end) and I don't want to deal with redistributing other peoples products.

Besides, once I have Async comms, I can make sync comms out of my base class. :)
0
 
LVL 3

Accepted Solution

by:
GGRUNDY earned 100 total points
ID: 6965262
Try this


  HANDLE vEvent[3]={CreateEvent(NULL, false, false, "Quit"),
                    CreateEvent(NULL, false, false, NULL),
                    CreateEvent(NULL, false, false, NULL)
                    };
  OVERLAPPED ov1={0}; ov1.hEvent = vEvent[1];
  OVERLAPPED ov2={0}; ov2.hEvent = vEvent[2];
  char zOut[] = "hello";
  char zIn[2];

  DWORD dwWritten;
  DWORD dwRead;
  BOOL isOK;

  HANDLE hPort =
ateFile(
         "COM2",
         GENERIC_READ | GENERIC_WRITE,
         0,                                   // comm devices must be opened
w/exclusive-access
         NULL,                              // no security attributes
         OPEN_EXISTING,                    // comm devices must use
OPEN_EXISTING
         FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING ,             //
overlapped I/O
         NULL);                              // hTemplate must be NULL for
comm devices


     isOK = WriteFile(hPort,   zOut,  lstrlen(zOut),  &dwWritten,  &ov1);
     isOK = ReadFile( hPort,   zIn,   1,   &dwRead,  &ov2);  
   
     bool isMore = true;
     do{
        DWORD dw = WaitForMultipleObjects(3, vEvent, false, INFINITE);
       dw -= WAIT_OBJECT_0 ;
       switch(dw){
         case 0:isMore = false; break;
         case 1:{
           isOK = WriteFile(hPort,  zOut,  lstrlen(zOut),  &dwWritten,
&ov1);
           break;
           }


         case 2:{
          TRACE("0x%02x\n", zIn[0]);
           isOK = ReadFile( hPort,  zIn,  1,  &dwRead,  &ov2);
           break;
           }
         }
       }while(isMore);

  CancelIo(hPort);





0
 

Author Comment

by:nigel5
ID: 6965983
Thanks. with some jiggling with my threads, that did it.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now