dlls/kernel/comm.c: not releasing file descriptors?

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Thu Nov 3 03:10:20 CST 2005

>>>>> "Cihan" == Cihan Altinay <cihan at uq.edu.au> writes:

    Cihan> Hi, I am trying to get G-Ware[1] to run under wine which provides
    Cihan> a user interface to set up Echo Canceller Units made by
    Cihan> ClearOne. The unit is connected to the serial port (com1 =
    Cihan> ttyS0).  The only way I can start the program at all is by
    Cihan> configuring wine to act as Windows 95/98 and using native COM
    Cihan> dll's. Furthermore, 'GWare.exe' starts 'PSRServe.exe' under
    Cihan> native Windows but not under wine so I do the following in a bash
    Cihan> file: wine C:\\Program\ Files\\G-Ware\\PSRServe.exe & wine
    Cihan> C:\\Program\ Files\\G-Ware\\GWare.exe

    Cihan> When I connect to the device I get endless

    Cihan>    fixme:comm:COMM_WaitCommEvent EV_RXFLAG not handled

    Cihan> messages before communication breaks with this:

    Cihan>    wine client error:3bc: pipe: Too many open files

    Cihan> After investigating I found out that indeed the number of open
    Cihan> pipes to ttyS0 increases statically so I tried to find the reason
    Cihan> and suspect the following (using the CVS checkout from 20051102):

    Cihan> In the function COMM_WaitCommEvent in /dlls/kernel/comm.c line
    Cihan> 2106 a thread is created for WaitCommEventService. However, in
    Cihan> this branch of the if-statement fd is not released (using
    Cihan> release_comm_fd).  Releasing fd seems to work and the number of
    Cihan> open pipes don't get past 200-300.

I wrote the WaitComEvent code. Probably     
release_comm_fd( commio->handle, fd );
HeapFree(GetProcessHeap(), 0, commio );
needs to be executed for both cases. I am just compiling and testing...

    Cihan> I am new to wine development and this is just a guess and I might
    Cihan> be totally wrong. Unfortunately this does not fix the
    Cihan> communication with the device (It reports timeouts and errors
    Cihan> retrieving values etc).  I guess this has to do with the first
    Cihan> fixme messages I mentioned.  Can anybody tell me what EV_RXFLAG
    Cihan> is used for?  

-> Look under lpEventMask

The program wants to be informed, when the device has sent an Event char. I
don't know about a way to do this in libc/kernel way in Unix. Actually the only
way I see is by polling the serial port andd checking for the event
character in our serial line service thread. Probably more places in the
comm code need to care for the Event character (the DCB structure e.g)

    Cihan> Using WINEDEBUG=+tid,+comm I compared the output to
    Cihan> what Sysinternals PortMon[2] gives me on native Windows and it
    Cihan> really looks promising. Is there a way to display the actual data
    Cihan> that was sent/received through the serial port? I tried
    Cihan> WINEDEBUG=+io which does not work.

Sending/receiving is done via kernel/file.c
Following patch traces all write/reads, so you have to manually look for
those on the serial line.
retrieving revision 1.40
diff -u -w -r1.40 file.c
--- wine/dlls/kernel/file.c     11 Jul 2005 14:23:46 -0000      1.40
+++ wine/dlls/kernel/file.c     5 Sep 2005 08:25:54 -0000
@@ -46,6 +46,7 @@
 #include "wine/server.h"
 HANDLE dos_handles[DOS_TABLE_SIZE];
@@ -377,6 +378,15 @@
     if (status != STATUS_PENDING && bytesRead)
         *bytesRead = io_status->Information;
+    if (TRACE_ON(fileio) && bytesRead && *bytesRead)
+    {
+        int i;
+       DPRINTF("ReadFile %9ld Bytes from %p: 0x", *bytesRead, hFile);
+       for(i=0; i<*bytesRead && i<20; i++)
+           DPRINTF("%02x",((unsigned char*)buffer)[i]);
+       DPRINTF(" %s\n",debugstr_an((unsigned char*)buffer,(*bytesRead>20)?20:*bytesRead));
+      }
     if (status && status != STATUS_END_OF_FILE && status != STATUS_TIMEOUT)
         SetLastError( RtlNtStatusToDosError(status) );
@@ -433,6 +443,15 @@
     TRACE("%p %p %ld %p %p\n", hFile, buffer, bytesToWrite, bytesWritten, overlapped );
+    if (TRACE_ON(fileio) && bytesToWrite)
+      {
+       int i;
+       DPRINTF("WriteFile %8ld Bytes from %p: 0x", bytesToWrite, hFile);
+       for(i=0; i<bytesToWrite && i<20; i++)
+         DPRINTF("%02x",((unsigned char*)buffer)[i]);
+       DPRINTF(" %s\n",debugstr_an(buffer,(bytesToWrite>20)?20:bytesToWrite));
+      }
     if (is_console_handle(hFile))
         return WriteConsoleA(hFile, buffer, bytesToWrite, bytesWritten, NULL);

Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------

More information about the wine-devel mailing list