OS: Ubuntu 14.04 LTS 64-bit
There are no additional changes to winecfg or registry, and winetricks is not used. Wine prefix is set in default 64 bit.
I'm attempting to port a C program which makes extensive use of Windows libraries into Linux. The program uses the Reliable Asynchronous Transfer Protocol (RATP) that opens an Universal Asynchronous Receiver/Transmitter (UART) serial connection with an external device (hardware) to the computer.
The program itself uses ReadFileEx to read from the device into a ReadBuffer, and the CompletionRoutine of the ReadFileEx function pushes the contents of ReadBuffer into the RecieveBuffer. It's with the data in the RecieveBuffer that error checking, searching for Syn byte, data manipulation, etc is performed.
Vice-versa the WriteFileEx function writes to the device from a PendingBuffer the contents of a TransferBuffer depending on a flag, and the CompletionRoutine of the WriteFileEx function manipulates this flag. The TransferBuffer's contents is manipulated by the rest of the program to create the correct packets to transmit.
An always on loop in the main puts the program into an Alert-able wait state with SleepEx(1u, TRUE) and checks for events to process. The program also uses a Semaphore to lock/unlock the functions called by both CompletionRoutines.
The program expects specific packets to be read after transmitting into the device specific packets, and does its state calculations, ACK/SYNC, time outs, and re-transmissions in chronological order as a part of the start up sequence.
The problem I've been having is this:
On Windows, the expected behavior when compiling the C code with Microsoft Visual Studio 2010 is that ReadFileEx is passed a nNumberOfBytesToRead parameter of x. The function completes and returns success, GetLastError returns 0. The CompletionRoutine of ReadFileEx is called afterwards with a dwNumberOfBytesTransfered which is <=x that is the expected amount of data to be read from the device.
E.g.
READ START 32
READ END 32
System error: 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (contents of ReadBuffer)
event
WRITE START 7
WRITE END 7
System error: 0
<---------W1-------->
WRITE CompletionRoutine 7
Read CompletionRoutine 4
<---------R1---------> (values moved by ReadFileEx CompletionRoutine into RecieveBuffer)
READ START 32
READ END 32
System error: 0
<---------R1---------> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
event
Read CompletionRoutine 6
<---------R2---------->
READ START 32
READ END 32
System error: 0
<---------R2----------> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
event
ReadCompletionRoutine 8
<---------R3---------->
READ START 32
READ END 32
System error: 0
<---------R3----------> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
event
Done
On Ubuntu compiling with winemaker and then running the host.exe file, ReadFileEx is passed a nNumberOfBytesToRead parameter of x. The function completes and returns success, GetLastError returns 0. The CompletionRoutine of ReadFileEx is called afterwards with a dwNumberOfBytesTransfered which is always x. This throws the synchronization out of order since it appears that the ReadFileEx CompletionRoutine does not get called unless the full x amount of data is read, cutting off packets in the middle, overwriting good packets, or breaks synchronization with the respective WriteFileEx command (multiple WriteFileEx commands may have to occur before the full x Bytes can be read).
E.g (same block of code)
The data itself that is read on Ubuntu-Wine correspond to the correct packets when cross referenced with windows, but it is very difficult to recover the specific packets as well as prevent the possible cutting off and overwriting of good packets.READ START 32
READ END 32
System error: 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (contents of ReadBuffer)
event
WRITE START 7
WRITE END 7
System error: 0
<---------W1-------->
WRITE CompletionRoutine 7
Read CompletionRoutine 32
<---------R1---------><-------------R2-----------><-----------R3(?)---------<->---------R3(?)-------->
*Received messages can share a few byte values, and the sync byte is always the same value, so it's difficult to discern where the overlap is
READ START 32
READ END 32
System error: 0
<---------R1---------><-------------R2-----------><-----------R3(?)---------<->---------R3(?)-------->
event
Done
Is there something specific about how ReadFileEx finds the "end of line" or "end of data" when reading from a device which is different from how it is handled in Wine? Or is this an issue with the Overlapped structure or alertable wait states itself? What would be a potential work around other than completely re-writing the code with out use of the Overlapped asynchronous structure?
The Overlapped Structure is declared / initialized as thus:
Code: Select all
typedef struct TAG_UARTA
{
void* FileHandle
BOOLEAN PortOpen
OVERLAPPED OverlappedR;
OVERLAPPED OverlappedT;
} UARTAFunction;
void UARTAsync_Init()
{
memset(&itsUARTAsync.OverlappedT, 0, sizeof(itsUARTAsync.OverlappedT));
itsUARTAsync.OverlappedT.Offset = 4096;
itsUARTAsync.OverlappedT.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
memset(&itsUARTAsync.OverlappedR, 0, sizeof(itsUARTAsync.OverlappedR));
itsUARTAsync.OverlappedR.Offset = 4096;
itsUARTAsync.OverlappedR.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}