Win32API question

I am trying to use Ruby's Win32API interface to access the windows file
i/o in order to make a serial port connection. However the code below
gives the error '[BUG] Segmentation fault' when GetOverlappedResult()
is called. Any ideas would be gratefully received.

# Windows constants.
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 0x00000003
FILE_FLAG_OVERLAPPED = 0x40000000
NULL = 0x00000000

# Create objects to access Windows file system API.
CreateFile = Win32API.new("Kernel32", "CreateFile", "PLLLLLL", "L")
CloseHandle = Win32API.new("Kernel32","CloseHandle", "L", "N")
ReadFile = Win32API.new("Kernel32","ReadFile","LPLLP","N")
WriteFile = Win32API.new("Kernel32","WriteFile","LPLLP","N")
SetCommState = Win32API.new("Kernel32","SetCommState","LP","N")
SetCommTimeouts = Win32API.new("Kernel32","SetCommTimeouts","LP","N")
GetLastError = Win32API.new("Kernel32","GetLastError", "V", "N")
GetCommState = Win32API.new("Kernel32","GetCommState", "LP", "N")
GetOverlappedResult = Win32API.new("Kernel32","GetOverlappedResult",
"LPLL", "L")
CreateEvent = Win32API.new("Kernel32","CreateEvent", "LLLP", "L")

# --------------------------------
# Setup com1
# --------------------------------

# Get a file handle
hFile = CreateFile.Call("com1", GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL)
report

# Create and populate overlapped structures
hEvent_write = CreateEvent.Call(0,0,0,0); report
overlapped_write = [0,0,0,0,hEvent_write].pack("L*")

hEvent_read = CreateEvent.Call(0,0,0,0); report
overlapped_read = [0,0,0,0,hEvent_read].pack("L*")

# Create DCB and set com state.
dcb = "\0"*80
GetCommState.Call(hFile, dcb); report
dcb[5] = 150 # Set to 38400 baud.

SetCommState.Call(hFile, dcb); report

# Set timeouts
CommTimeouts = [2,1,1,0,0].pack("L*")
SetCommTimeouts.Call(hFile, CommTimeouts); report

# --------------------------------
# Test
# --------------------------------
numwritten = 0
outbuff = "Test"

# Write to com port
WriteFile.Call(hFile,outbuff,outbuff.size,numwritten,overlapped_write);report

# The next call fails!
res = GetOverlappedResult.Call(hFile,overlapped_write,numwritten,1)

CloseHandle.Call(hFile)

PWR wrote:

I am trying to use Ruby's Win32API interface to access the windows file
i/o in order to make a serial port connection. However the code below
gives the error '[BUG] Segmentation fault' when GetOverlappedResult()
is called. Any ideas would be gratefully received.

Have you checked out http://grub.ath.cx/win32serial/ as an alternative?
I played around with this library a couple of weeks ago and it looks
pretty good...

PWR wrote:

# Write to com port
WriteFile.Call(hFile,outbuff,outbuff.size,numwritten,overlapped_write);repo­rt

# The next call fails!
res = GetOverlappedResult.Call(hFile,overlapped_write,numwritten,1)

Checking

it appears as Windows 95/98/ME only accept the DeviceIoControl function
opening up the session. You appear to be opening the session with
WriteFile. What version of Windows are you using?

PWR wrote:

I am trying to use Ruby's Win32API interface to access the windows file
i/o in order to make a serial port connection. However the code below
gives the error '[BUG] Segmentation fault' when GetOverlappedResult()
is called. Any ideas would be gratefully received.

....

ReadFile = Win32API.new("Kernel32","ReadFile","LPLLP","N")
WriteFile = Win32API.new("Kernel32","WriteFile","LPLLP","N")

Looking at a sample script I made that read/wrote to the serial port
using win32api my ReadFile and WriteFile calls were constructed
differently. Specifically:

WriteFile = Win32API.new("kernel32", "WriteFile", 'LPLPL', 'L')
ReadFile = Win32API.new("kernel32", "ReadFile", 'LPLPL', 'L')

Try using them constructed this way and see if things work...

PWR wrote:

I am trying to use Ruby's Win32API interface to access the windows file
i/o in order to make a serial port connection. However the code below
gives the error '[BUG] Segmentation fault' when GetOverlappedResult()
is called. Any ideas would be gratefully received.

Yeh; what Wayne and Greg said. Here are my changes:

ReadFile = Win32API.new("Kernel32","ReadFile","LPLLP","N")

  ReadFile = Win32API.new('Kernel32','ReadFile','LPLPP','I')

WriteFile = Win32API.new("Kernel32","WriteFile","LPLLP","N")

  WriteFile = Win32API.new('Kernel32','WriteFile','LPLPP','I')

GetOverlappedResult = Win32API.new("Kernel32","GetOverlappedResult", "LPLL", "L")

  GetOverlappedResult = Win32API.new('Kernel32','GetOverlappedResult', 'LPPI', 'I')

numwritten = 0

  numwritten = "\0"*4

# Write to com port
WriteFile.Call(hFile,outbuff,outbuff.size,numwritten,overlapped_write);report

#-> reports ... [997, "Overlapped I/O operation is in progress. "]
#-> ... but continues ... (nothing attached to COM1)

daz

···

--

GetLastError = Win32API.new("Kernel32", "GetLastError", "V", "N")

#-> ... com1_serial.rb: 18: warning: unknown type 'V'
  GetLastError = Win32API.new('Kernel32', 'GetLastError', '', 'L')

Thanks for the reply. I have had a go with the Win32Serial library but
I appeared to lose characters when trying to get fast comms working in
both directions. I think that this may be due to it not using
overlapped comms - I'd be interested to know if you have tried it with
continuous data at a fast baud rate.

Problem solved! Thankyou very much.

PWR wrote:

I'd be interested to know if you have tried it with
continuous data at a fast baud rate.

Nope. Just some here-and-there testing that didn't involve a continuous
data stream. I was trying to use it to parse ISDN communication data,
but the problem was that Windows assigned virtual COM ports to the ISDN
B channels. The data I needed to capture was coming over the D channel.
Since I couldn't use Win32Serial for this purpose I stopped playing
around with it.

Hi PWR,
One minor thing. I think the line
GetOverlappedResult = Win32API.new("Kernel32","GetOverlappedResult",
"LPLL", "L")
Should instead specify "LPPL".
Unfortunately, even with this change it still gets the same crash.
If you have access to a C/C++ development environment, have you tried
running the corresponding code there?

Wayne