Link to home
Start Free TrialLog in
Avatar of Levente
Levente

asked on

Why this Win API serial port access doesn't work under W2k?

I need to write to and read from the COM port. I have the following code which works under Win98, but fails under Win2k. What on earth I'm doing wrong?

Thank you for you help,
Levente

--------------------------------------------------------
function TComport.Open(const ComPort: String): boolean;
var DCB : TDCB;
begin
   Handle := CreateFile( PChar('\\.\' + ComPort),
                         GENERIC_READ or GENERIC_WRITE,
                         0,
                         nil,
                         OPEN_EXISTING,
                         FILE_FLAG_OVERLAPPED,
                         0);

   DCB.DCBlength := sizeof(TDCB);
   GetCommState(Handle, DCB);
   DCB.BaudRate := CBR_9600;
   SetCommState(Handle,DCB);
end;

procedure TComPort.Close;
begin
  CloseHandle(Handle);
end;

procedure TComPort.WriteStr(const Buffer: string);
var WriteBuffer:  array [0..15] of char;
    CharsToWrite, CharsWritten: cardinal;
begin
   CharsToWrite:= length(buffer);
   move(Buffer[1], WriteBuffer, CharsToWrite);
   WriteFile(Handle, WriteBuffer, CharsToWrite, CharsWritten, NIL);
end;

procedure TComPort.ReadStr(var Buffer: string; const CharToRead: Word);
var CharsRead: Cardinal;
    ReadBuffer: array [0..15] of char;
begin
  ReadFile( Handle, ReadBuffer, CharToRead, CharsRead, NIL);
  Buffer:= ReadBuffer;
end;

Avatar of Motaz
Motaz

I have a component called Async32, it works fine for me for more than 2 years without any problems, and it is very easy to use.

Tell me your E-Mail and I can send it to you if you want.
Motaz
Change FILE_FLAG_OVERLAPPED to FILE_ATTRIBUTE_NORMAL.

I don't know why/if it works on Win95 but if you open a com port with FILE_FLAG_OVERLAPPED you MUST supply a valid pointer to an overlapped structure as the last parameter to readfile and writefile. Since you are supplying a NIL pointer you should not have opened the file with FILE_FLAG_OVERLAPPED.
Avatar of Levente

ASKER

Motaz,

I'd appreciate if you sent me that component to slv@freemail.hu. It may give me hints.

zebada,

I tried FILE_ATTRIBUTE_NORMAL but it still fails under Win2K.

Levente
You do not say in what way it goes wrong!

Maybe you need to call:
SetupComm(Handle, RxBufferSize, TxBufferSize);
To ensure the buffer sizes are OK.
Or if you do not get data in/out:
NT/Win2k has a different default serial port setting for handshaking. Since you do not setup handshaking in your code the settings the com port had last are used. So you may need you to wire the cable slightly differently: i.e. connect DTR to DSR (at the plug on the NT machine) to get NT/Win2k to enable the port.
Let me know.....
 
Avatar of Levente

ASKER

I tried SetupComm, but it doesn't work under W2k.

Is there any tool which catches and logs the bytes sent to the serial port? This way I may be able to debug what's going wrong.

Thanks,
Levente
Hi!

Like zebada already said you have problem in FILE_FLAG_OVERLAPPED. I tried your code and on my
Win2000 it definitively works. Try again nad change to FILE_ATTRIBUTE_NORMAL.

It should be

Handle := CreateFile( PChar('\\.\' + ComPort),
                        GENERIC_READ or GENERIC_WRITE,
                        0,
                        nil,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        0);

If ComPort is 'Com1' it is opened and it works for read and write. About your read procedure > Before open and close port you should always set handle to INVALID_HANDLE_VALUE and always check it before read or write. Also before read it is good to check how much to read. Perhaps like this.

function GetInCount:LongInt;
var statPort:TCOMSTAT;
    dwErrorCode:DWORD;
begin
 Result:=0;
 if Handle<>INVALID_HANDLE_VALUE then
  begin
   ClearCommError(Handle,dwErrorCode,@statPort);
   Result:=statPort.cbInQue;
  end;
end;

I am doing it like this for 5 years on NT and Win2000 mascines without problems, except that for ports beyond 8 I use sintaks '//./COM'+ value of port.
Good luck!
Avatar of Levente

ASKER

TomazB,

Thank you for your help. I tried your code and the result is that GetInCount function returns 0, even under Win98.

What device do you attach to the COM port to test your code? I'm using a proprietary hardware device (a friend of mine has made a device to control stepping motors), so is it possible that our device works in a way that Win2k cannot read data from it?

Thank you,
Levente
ASKER CERTIFIED SOLUTION
Avatar of TomazB
TomazB
Flag of Slovenia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Szia!

Azt hiszem nem tévedek a neveddel kapcsolatban, úgyhogy írok magyarul inkább, mint angolul.
Nagyon nagy gondban vagyok, szakdolgozathoz kellene a soros port kezelés. Olvastam a te régi problémádat, hogy winNT alatt ment a programod, Win9x alatt nem. Nekem ez pont fordítva van! :-( Tudnál segíteni?

Üdv:
Jani
trantor@europe.com
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from TomazB

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
Thank you for your response

Paul (pnh73)
EE Cleanup Volunteer