Index: trunk/src/kernel32/Fileio.cpp
===================================================================
--- trunk/src/kernel32/Fileio.cpp	(revision 7560)
+++ trunk/src/kernel32/Fileio.cpp	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: Fileio.cpp,v 1.61 2001-12-06 15:57:51 sandervl Exp $ */
+/* $Id: Fileio.cpp,v 1.62 2001-12-07 11:28:09 sandervl Exp $ */
 
 /*
@@ -1660,4 +1660,7 @@
               BOOL, bWait)                /* [in] wait for the transfer to complete ? */
 {
+  //NOTE: According to the SDK docs lpOverlapped->hEvent can be 0. This function
+  //      is supposed to wait on the file handle in that case. We don't support
+  //      this, so we just fail.
   if(lpOverlapped == NULL || lpOverlapped->hEvent == 0) {
       dprintf(("!ERROR!: lpOverlapped == NULL || lpOverlapped->hEvent == 0"));
Index: trunk/src/kernel32/hmcomm.cpp
===================================================================
--- trunk/src/kernel32/hmcomm.cpp	(revision 7560)
+++ trunk/src/kernel32/hmcomm.cpp	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: hmcomm.cpp,v 1.27 2001-12-05 18:06:00 sandervl Exp $ */
+/* $Id: hmcomm.cpp,v 1.28 2001-12-07 11:28:09 sandervl Exp $ */
 
 /*
@@ -9,6 +9,4 @@
  * 2001 Sander van Leeuwen <sandervl@xs4all.nl>
  *
- * TODO: Overlapped IO only supports one request at a time
- * TODO: Overlapped IO not thread safe
  *
  */
@@ -21,5 +19,4 @@
 #include "handlenames.h"
 #include <heapstring.h>
-#include "hmdevice.h"
 #include "hmcomm.h"
 #include "oslibdos.h"
@@ -61,26 +58,31 @@
 #define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
 
+static BOOL CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
+static BOOL CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
+static BOOL CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
+
 //******************************************************************************
 //******************************************************************************
 static VOID *CreateDevData()
 {
-  PHMDEVCOMDATA pData;
-  pData = new HMDEVCOMDATA();
-  if(NULL!=pData)
-  {
-    memset(pData,0,sizeof(HMDEVCOMDATA));
-    pData->ulMagic = MAGIC_COM;
-    pData->CommCfg.dwSize   = sizeof(COMMCONFIG);
-    pData->CommCfg.wVersion = 1;
-    pData->CommCfg.dwProviderSubType = PST_RS232;
-    pData->CommCfg.dcb.DCBlength = sizeof(DCB);
-    pData->CommCfg.dcb.BaudRate  = CBR_1200;
-    pData->CommCfg.dcb.ByteSize = 8;
-    pData->CommCfg.dcb.Parity   = NOPARITY;
-    pData->CommCfg.dcb.StopBits = ONESTOPBIT;
-    pData->dwInBuffer  = 16;
-    pData->dwOutBuffer = 16;
-  }
-  return pData;
+    PHMDEVCOMDATA pData;
+
+    pData = new HMDEVCOMDATA();
+    if(NULL!=pData)
+    {
+        memset(pData,0,sizeof(HMDEVCOMDATA));
+        pData->ulMagic = MAGIC_COM;
+        pData->CommCfg.dwSize   = sizeof(COMMCONFIG);
+        pData->CommCfg.wVersion = 1;
+        pData->CommCfg.dwProviderSubType = PST_RS232;
+        pData->CommCfg.dcb.DCBlength = sizeof(DCB);
+        pData->CommCfg.dcb.BaudRate  = CBR_1200;
+        pData->CommCfg.dcb.ByteSize = 8;
+        pData->CommCfg.dcb.Parity   = NOPARITY;
+        pData->CommCfg.dcb.StopBits = ONESTOPBIT;
+        pData->dwInBuffer  = 16;
+        pData->dwOutBuffer = 16;
+    }
+    return pData;
 }
 //******************************************************************************
@@ -88,29 +90,28 @@
 HMDeviceCommClass::HMDeviceCommClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
 {
-  VOID *pData;
-  dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n"));
-  pData = CreateDevData();
-  if(pData!= NULL)
-    HMDeviceRegisterEx("COM1", this, pData);
-  
-  // add symbolic links to the "real name" of the device
-  {
+    VOID *pData;
+
+    dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n"));
+    pData = CreateDevData();
+    if(pData!= NULL)
+        HMDeviceRegisterEx("COM1", this, pData);
+
+    // add symbolic links to the "real name" of the device
     // @@@PH what's the long device name: SerialPortx ?
     // HandleNamesAddSymbolicLink("\\Device\\ParallelPort3", "COM3");
     // Note: \\.\COMx: is invalid (NT4SP6)
-    
+
     PSZ pszCOM = strdup("\\\\.\\COMx");
-    for (char ch = '1'; ch <= '9'; ch++)
+    for (char ch = '1'; ch < '9'; ch++)
     {
-      pszCOM[7] = ch;
-      HandleNamesAddSymbolicLink(pszCOM, pszCOM+4);
+        pszCOM[7] = ch;
+        HandleNamesAddSymbolicLink(pszCOM, pszCOM+4);
     }
     free(pszCOM);
-  
+
     // add "AUX" device
     HandleNamesAddSymbolicLink("AUX",        "COM1");
     HandleNamesAddSymbolicLink("AUX:",       "COM1");
     HandleNamesAddSymbolicLink("\\\\.\\AUX", "COM1");
-  }
 }
 
@@ -131,5 +132,5 @@
 {
     dprintf2(("HMDeviceCommClass::FindDevice %s %s", lpClassDevName, lpDeviceName));
-  
+
     //first 3 letters 'COM'?
     if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) {
@@ -163,88 +164,100 @@
  DWORD ret = ERROR_SUCCESS;
 
-  dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
-
-  if(strlen(lpFileName) > 5) {
-      lpFileName += 4; //skip prefix
-  }
-
-  pHMHandleData->hHMHandle = 0;
-
-  strcpy(comname, lpFileName);
-  comname[4] = 0;   //get rid of : (if present) (eg COM1:)
-
-  //AH: TODO parse Win32 security handles
-  ULONG oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
-  pHMHandleData->hHMHandle = OSLibDosOpen(comname,
-                                          OSLIB_ACCESS_READWRITE |
-                                          OSLIB_ACCESS_SHAREDENYREAD |
-                                          OSLIB_ACCESS_SHAREDENYWRITE);
-  ::SetErrorMode(oldmode);
-  if (pHMHandleData->hHMHandle != 0)
-  {
-    ULONG ulLen;
-    APIRET rc;
-    pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
-    // Init The handle instance with the default default device config
-    memcpy( pHMHandleData->lpHandlerData,
-            pHMHandleData->lpDeviceData,
-            sizeof(HMDEVCOMDATA));
-
-    ulLen = sizeof(DCBINFO);
-
-    rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
-                           IOCTL_ASYNC,
-                           ASYNC_GETDCBINFO,
-                           0,0,0,
-                           &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
-    dprintf(("DCB Of %s :\n"
-             " WriteTimeout           : %d\n"
-             " ReadTimeout            : %d\n"
-             " CtlHandshake           : 0x%x\n"
-             " FlowReplace            : 0x%x\n"
-             " Timeout                : 0x%x\n"
-             " Error replacement Char : 0x%x\n"
-             " Break replacement Char : 0x%x\n"
-             " XON Char               : 0x%x\n"
-             " XOFF Char              : 0x%x\n",
-             comname,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
-             ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
-
-    if(rc)
+    dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
+
+    if(strlen(lpFileName) > 5) {
+        lpFileName += 4; //skip prefix
+    }
+
+    pHMHandleData->hHMHandle = 0;
+
+    strcpy(comname, lpFileName);
+    comname[4] = 0;   //get rid of : (if present) (eg COM1:)
+
+    //AH: TODO parse Win32 security handles
+    ULONG oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
+    pHMHandleData->hHMHandle = OSLibDosOpen(comname,
+                                            OSLIB_ACCESS_READWRITE |
+                                            OSLIB_ACCESS_SHAREDENYREAD |
+                                            OSLIB_ACCESS_SHAREDENYWRITE);
+    ::SetErrorMode(oldmode);
+    if (pHMHandleData->hHMHandle != 0)
     {
-      OSLibDosClose(pHMHandleData->hHMHandle);
-      delete pHMHandleData->lpHandlerData;
-      return rc;
-    }
-    rc = SetBaud(pHMHandleData,9600);
-    dprintf(("Init Baud to 9600 rc = %d",rc));
-    rc = SetLine(pHMHandleData,8,0,0);
-    dprintf(("Set Line to 8/N/1 rc = %d",rc));
-
-    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 
-    {
-        PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
-        DWORD         dwThreadId;
-
-    }
-    return ERROR_SUCCESS;
-  }
-  else
-    return ERROR_ACCESS_DENIED;
-
+        ULONG ulLen;
+        APIRET rc;
+        pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
+        // Init The handle instance with the default default device config
+        memcpy( pHMHandleData->lpHandlerData,
+                pHMHandleData->lpDeviceData,
+                sizeof(HMDEVCOMDATA));
+
+        ulLen = sizeof(DCBINFO);
+
+        rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
+                               IOCTL_ASYNC,
+                               ASYNC_GETDCBINFO,
+                               0,0,0,
+                               &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
+        dprintf(("DCB Of %s :\n"
+                 " WriteTimeout           : %d\n"
+                 " ReadTimeout            : %d\n"
+                 " CtlHandshake           : 0x%x\n"
+                 " FlowReplace            : 0x%x\n"
+                 " Timeout                : 0x%x\n"
+                 " Error replacement Char : 0x%x\n"
+                 " Break replacement Char : 0x%x\n"
+                 " XON Char               : 0x%x\n"
+                 " XOFF Char              : 0x%x\n",
+                 comname,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
+                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
+
+        if(rc)
+        {
+            OSLibDosClose(pHMHandleData->hHMHandle);
+            delete pHMHandleData->lpHandlerData;
+            return rc;
+        }
+        rc = SetBaud(pHMHandleData,9600);
+        dprintf(("Init Baud to 9600 rc = %d",rc));
+        rc = SetLine(pHMHandleData,8,0,0);
+        dprintf(("Set Line to 8/N/1 rc = %d",rc));
+
+        if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
+        {
+            PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
+            int           comnr;
+
+            comnr = comname[3] - '1';
+
+            if(handler[comnr] == NULL) {
+                try {
+                    handler[comnr] = new OverlappedIOHandler(CommReadIOHandler, CommWriteIOHandler, CommPollIOHandler);
+                }
+                catch(...)
+                {
+                    ret = ERROR_NOT_ENOUGH_MEMORY;
+                    goto fail;
+                }
+            }
+            pDevData->iohandler = handler[comnr];
+        }
+        return ERROR_SUCCESS;
+    }
+    else
+        return ERROR_ACCESS_DENIED;
 
 fail:
 
-  delete pHMHandleData->lpHandlerData;
-  OSLibDosClose(pHMHandleData->hHMHandle);
-  return ret;
+    delete pHMHandleData->lpHandlerData;
+    OSLibDosClose(pHMHandleData->hHMHandle);
+    return ret;
 }
 /*****************************************************************************
@@ -262,9 +275,8 @@
 DWORD HMDeviceCommClass::GetFileType(PHMHANDLEDATA pHMHandleData)
 {
-  dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n",
-           lpHMDeviceName,
-           pHMHandleData));
-
-  return FILE_TYPE_CHAR;
+    dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n",
+             lpHMDeviceName, pHMHandleData));
+
+    return FILE_TYPE_CHAR;
 }
 //******************************************************************************
@@ -272,13 +284,35 @@
 BOOL HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
 {
-  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
-  dprintf(("HMComm: Serial communication port close request"));
-
-  if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 
-  {
-      DebugInt3();
-  }
-  delete pHMHandleData->lpHandlerData;
-  return OSLibDosClose(pHMHandleData->hHMHandle);
+    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
+    dprintf(("HMComm: Serial communication port close request"));
+
+    if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
+    {
+        DebugInt3();
+    }
+    delete pHMHandleData->lpHandlerData;
+    return OSLibDosClose(pHMHandleData->hHMHandle);
+}
+//******************************************************************************
+//Overlapped read handler
+//******************************************************************************
+BOOL CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
+{
+    return FALSE;
+}
+//******************************************************************************
+//Overlapped write handler
+//******************************************************************************
+BOOL CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
+{
+    return FALSE;
+}
+//******************************************************************************
+//Overlapped WaitCommEvent handler
+//******************************************************************************
+BOOL CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
+{
+    *lpdwTimeOut = TIMEOUT_COMM;
+    return FALSE;
 }
 /*****************************************************************************
@@ -304,46 +338,55 @@
                                   LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
 {
-  dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
-           lpHMDeviceName,
-           pHMHandleData->hHMHandle,
-           lpBuffer,
-           nNumberOfBytesToWrite,
-           lpNumberOfBytesWritten,
-           lpOverlapped));
-
-  BOOL  ret;
-  ULONG ulBytesWritten;
-
-  if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
-    dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
-    ::SetLastError(ERROR_INVALID_PARAMETER);
-    return FALSE;
-  }
-  if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
-    dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
-  }
-  if(lpCompletionRoutine) {
-      dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
-  }
-
-//testestestest
-  dprintf2(("Bytes to write:"));
-  for(int i=0;i<nNumberOfBytesToWrite;i++) {
-          dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
-  }
-//testestestset
-
-  ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
-                      &ulBytesWritten);
-
-  if(lpNumberOfBytesWritten) {
+    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
+    BOOL  ret;
+    ULONG ulBytesWritten;
+
+    dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
+             lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite,
+             lpNumberOfBytesWritten, lpOverlapped));
+
+
+    if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
+    {
+        ::SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
+        dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
+        ::SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
+        dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
+    }
+    if(lpCompletionRoutine) {
+        dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
+    }
+
+    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
+        return pDevData->iohandler->WriteFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToWrite,
+                                              lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData);
+    }
+
+    //testestestest
+    dprintf2(("Bytes to write:"));
+    for(int i=0;i<nNumberOfBytesToWrite;i++) {
+        dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
+    }
+    //testestestset
+
+    ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
+                        &ulBytesWritten);
+
+    if(lpNumberOfBytesWritten) {
        *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
        dprintf2(("KERNEL32:HMDeviceCommClass::WriteFile %d byte(s) written", *lpNumberOfBytesWritten));
-  }
-  if(ret == FALSE) {
+    }
+    if(ret == FALSE) {
        dprintf(("!ERROR!: WriteFile failed with rc %d", GetLastError()));
-  }
-
-  return ret;
+    }
+
+    return ret;
 }
 /*****************************************************************************
@@ -370,58 +413,65 @@
                                  LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
 {
-  dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
-           lpHMDeviceName,
-           pHMHandleData->hHMHandle,
-           lpBuffer,
-           nNumberOfBytesToRead,
-           lpNumberOfBytesRead,
-           lpOverlapped));
-
-  BOOL  ret;
-  ULONG ulBytesRead;
-
-  if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
-    dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
-    ::SetLastError(ERROR_INVALID_PARAMETER);
-    return FALSE;
-  }
-  if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
-    dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
-  }
-
-  if(lpCompletionRoutine) {
-      dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
-  }
-
-  RXQUEUE qInfo;
-  ULONG ulLen = sizeof(qInfo);
-  ULONG rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
-                        IOCTL_ASYNC,
-                        ASYNC_GETINQUECOUNT,
-                        0,0,0,
-                        &qInfo,ulLen,&ulLen);
-  dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc));
-
-  ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
-                     &ulBytesRead);
-
-  if(lpNumberOfBytesRead) {
-       *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
-       dprintf2(("KERNEL32:HMDeviceCommClass::ReadFile %d bytes read", *lpNumberOfBytesRead));
-  }
-  if(ret == FALSE) {
-       dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError()));
-  }
-  else {
-//testestestest
-      dprintf2(("%d Bytes read:", ulBytesRead));
-      for(int i=0;i<ulBytesRead;i++) {
-          dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
-      }
-//testestestset
-  }
-  return ret;
-}
-
+    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
+    BOOL  ret;
+    ULONG ulBytesRead;
+
+    dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
+             lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead,
+             lpNumberOfBytesRead, lpOverlapped));
+
+    if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
+    {
+        ::SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
+        dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
+        ::SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
+        dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
+    }
+
+    if(lpCompletionRoutine) {
+        dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
+    }
+
+    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
+        return pDevData->iohandler->ReadFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToRead,
+                                             lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData);
+    }
+
+    RXQUEUE qInfo;
+    ULONG ulLen = sizeof(qInfo);
+    ULONG rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
+                                IOCTL_ASYNC,
+                                ASYNC_GETINQUECOUNT,
+                                0,0,0,
+                                &qInfo,ulLen,&ulLen);
+    dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc));
+
+    ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
+                       &ulBytesRead);
+
+    if(lpNumberOfBytesRead) {
+        *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
+        dprintf2(("KERNEL32:HMDeviceCommClass::ReadFile %d bytes read", *lpNumberOfBytesRead));
+    }
+    if(ret == FALSE) {
+        dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError()));
+    }
+    else {
+        //testestestest
+        dprintf2(("%d Bytes read:", ulBytesRead));
+        for(int i=0;i<ulBytesRead;i++) {
+            dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
+        }
+        //testestestset
+    }
+    return ret;
+}
 /*****************************************************************************
  * Name      : DWORD HMDeviceHandler::SetupComm
@@ -439,18 +489,18 @@
                                    DWORD dwOutQueue)
 {
-  dprintf(("HMDeviceCommClass::SetupComm "));
-  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
-  if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
-  {
-      ::SetLastError(ERROR_INVALID_HANDLE);
-      return FALSE;
-  }
-  pDevData->dwInBuffer  = dwInQueue;
-  pDevData->dwOutBuffer = dwOutQueue;
-
-  return(TRUE);
-}
-//******************************************************************************
-#define TIMEOUT_COMM 50
+    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
+
+    dprintf(("HMDeviceCommClass::SetupComm "));
+    if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
+    {
+        ::SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+    pDevData->dwInBuffer  = dwInQueue;
+    pDevData->dwOutBuffer = dwOutQueue;
+
+    return(TRUE);
+}
+//******************************************************************************
 //******************************************************************************
 BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
@@ -458,75 +508,64 @@
                                        LPOVERLAPPED lpo)
 {
-  APIRET rc;
-  ULONG ulLen;
-  USHORT COMEvt;
-  DWORD dwEvent,dwMask;
-
-  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
-
-  dprintf(("HMDeviceCommClass::WaitCommEvent %x %x %x", pHMHandleData->hHMHandle, lpfdwEvtMask, lpo));
-
-  if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) {
-      dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo"));
-      ::SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
-  }
-
-  ulLen = sizeof(CHAR);
-
-  dwEvent = 0;
-  rc = 0;
-  ulLen = sizeof(COMEvt);
-  dwMask = pDevData->dwEventMask;
-  while( (0==rc) &&
-        !(dwEvent & dwMask) &&
-        (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
-  {
-    rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
-                          IOCTL_ASYNC,
-                          ASYNC_GETCOMMEVENT,
-                          0,0,0,
-                          &COMEvt,ulLen,&ulLen);
-    if(!rc)
+    APIRET rc;
+    ULONG ulLen;
+    USHORT COMEvt;
+    DWORD dwEvent,dwMask;
+
+    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
+
+    dprintf(("HMDeviceCommClass::WaitCommEvent %x %x %x", pHMHandleData->hHMHandle, lpfdwEvtMask, lpo));
+
+    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) {
+        dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo"));
+        ::SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    ulLen = sizeof(CHAR);
+
+    dwEvent = 0;
+    rc = 0;
+    ulLen = sizeof(COMEvt);
+    dwMask = pDevData->dwEventMask;
+    while( (0==rc) &&
+           !(dwEvent & dwMask) &&
+           (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
     {
-        dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
-        //dwEvent |= (COMEvt&0x0002)? 0:0;
-        dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
-        dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
-        dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
-        //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
-        dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
-        dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
-        dwEvent |= (COMEvt&0x0100)? EV_RING:0;
-        if((dwEvent & dwMask)) break;
-    }
-    else break;
-
-    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 
-    {
-        memcpy(&pDevData->overlapped, lpo, sizeof(pDevData->overlapped));
-        pDevData->overlapped.Internal     = 0;
-        pDevData->overlapped.InternalHigh = 0;
-        pDevData->overlapped.Offset       = 0;
-        pDevData->overlapped.OffsetHigh   = 0;
-        //We're also supposed to write the result to the address supplied
-        //by this call
-        pDevData->lpfdwEvtMask            = lpfdwEvtMask;
-        //Set app event semaphore to non-signalled state
-        ::ResetEvent(lpo->hEvent);
-
-        ::SetLastError(ERROR_IO_PENDING);
-        return FALSE;
-    }
-    DosSleep(TIMEOUT_COMM);
-  }
-  if(dwMask == pDevData->dwEventMask) {
-       *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0;
-       dprintf(("WaitCommEvent returned %x", *lpfdwEvtMask));
-  }
-  else  *lpfdwEvtMask = 0;
-
-  ::SetLastError(rc);
-  return (rc==0);
+        rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
+                              IOCTL_ASYNC,
+                              ASYNC_GETCOMMEVENT,
+                              0,0,0,
+                              &COMEvt,ulLen,&ulLen);
+        if(!rc)
+        {
+            dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
+            //dwEvent |= (COMEvt&0x0002)? 0:0;
+            dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
+            dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
+            dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
+            //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
+            dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
+            dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
+            dwEvent |= (COMEvt&0x0100)? EV_RING:0;
+            if((dwEvent & dwMask)) break;
+        }
+        else break;
+
+        if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
+        {
+            return pDevData->iohandler->WaitForEvent(pHMHandleData->hWin32Handle, lpfdwEvtMask,
+                                                     lpo, NULL, (DWORD)pDevData);
+        }
+        DosSleep(TIMEOUT_COMM);
+    }
+    if(dwMask == pDevData->dwEventMask) {
+        *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0;
+        dprintf(("WaitCommEvent returned %x", *lpfdwEvtMask));
+    }
+    else  *lpfdwEvtMask = 0;
+
+    ::SetLastError(rc);
+    return (rc==0);
 }
 /*****************************************************************************
@@ -550,10 +589,5 @@
     }
 
-    //signal serial thread to cancel pending IO operation
-    pDevData->fCancelIo = TRUE;
-//    ::SetEvent(pDevData->hEventSem);
-
-    ::SetLastError(ERROR_SUCCESS);
-    return(TRUE);
+    return pDevData->iohandler->CancelIo(pHMHandleData->hWin32Handle);
 }
 /*****************************************************************************
@@ -572,5 +606,5 @@
  *****************************************************************************/
 BOOL HMDeviceCommClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
-                                            LPOVERLAPPED  lpoOverlapped,
+                                            LPOVERLAPPED  lpOverlapped,
                                             LPDWORD       lpcbTransfer,
                                             BOOL          fWait)
@@ -578,47 +612,26 @@
   PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
 
-  dprintf(("KERNEL32-WARNING: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) partly implemented",
-            pHMHandleData->hHMHandle,
-            lpoOverlapped,
-            lpcbTransfer,
-            fWait));
-
-  if(pDevData == NULL || !(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
-      ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
-      return FALSE;
-  }
-  if(!lpoOverlapped) {
-      ::SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
-  }
-  if(lpoOverlapped->hEvent != pDevData->overlapped.hEvent) {
-      dprintf(("!WARNING!: GetOverlappedResult called for unknown operation"));
-      ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
-      return FALSE;
-  }
-  if(pDevData->overlapped.Internal) {
-      lpoOverlapped->Internal       = pDevData->overlapped.Internal;
-      pDevData->overlapped.Internal = 0; //not entirely safe
-      pDevData->dwLastError         = 0;
-      ::SetLastError(pDevData->dwLastError);
-      return lpoOverlapped->Internal;
-  }
-  if(fWait) {
-      ::WaitForSingleObject(pDevData->overlapped.hEvent, INFINITE);
-      ::ResetEvent(pDevData->overlapped.hEvent);
-      lpoOverlapped->Internal       = pDevData->overlapped.Internal;
-      pDevData->overlapped.Internal = 0; //not entirely safe
-      ::SetLastError(ERROR_SUCCESS);
-      return lpoOverlapped->Internal;
-  }
-  else {
-      ::SetLastError(ERROR_IO_PENDING);
-      return FALSE;
-  }
-}
-//******************************************************************************
-//******************************************************************************
-BOOL HMDeviceCommClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
-                                           LPCOMMPROP lpcmmp)
+    dprintf(("KERNEL32-WARNING: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) partly implemented",
+             pHMHandleData->hHMHandle, lpOverlapped, lpcbTransfer, fWait));
+
+    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
+        dprintf(("!WARNING!: GetOverlappedResult called for a handle that wasn't opened with FILE_FLAG_OVERLAPPED"));
+        return TRUE; //NT4, SP6 doesn't fail
+    }
+
+    if(pDevData == NULL) {
+        ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
+        return FALSE;
+    }
+    if(!lpOverlapped) {
+        ::SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    return pDevData->iohandler->GetOverlappedResult(pHMHandleData->hWin32Handle, lpOverlapped, lpcbTransfer, fWait);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL HMDeviceCommClass::GetCommProperties(PHMHANDLEDATA pHMHandleData,
+                                          LPCOMMPROP lpcmmp)
 {
   EXTBAUDGET BaudInfo;
@@ -719,5 +732,5 @@
   }
   if(rc) {
-      dprintf(("!WARNING! OSLibDosDevIOCtl failed with rc %d", rc)); 
+      dprintf(("!WARNING! OSLibDosDevIOCtl failed with rc %d", rc));
   }
   return (rc == ERROR_SUCCESS);
@@ -980,5 +993,5 @@
   }
   if( (0==pDevData->CommTOuts.WriteTotalTimeoutMultiplier) &&
-      (0==pDevData->CommTOuts.WriteTotalTimeoutConstant)) 
+      (0==pDevData->CommTOuts.WriteTotalTimeoutConstant))
   {//no timeout used for writing
     os2dcb.fbTimeOut |= 1; //write infinite timeout
@@ -1423,4 +1436,15 @@
 //******************************************************************************
 //******************************************************************************
-
-
+void HMDeviceCommClass::CloseOverlappedIOHandlers()
+{
+    for(int i=0;i<MAX_COMPORTS;i++) {
+        if(handler[i]) {
+            delete handler[i];
+            handler[i] = NULL;
+        }
+    }
+}
+//******************************************************************************
+//******************************************************************************
+OverlappedIOHandler *HMDeviceCommClass::handler[MAX_COMPORTS] = {NULL};
+
Index: trunk/src/kernel32/hmcomm.h
===================================================================
--- trunk/src/kernel32/hmcomm.h	(revision 7560)
+++ trunk/src/kernel32/hmcomm.h	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: hmcomm.h,v 1.12 2001-12-05 14:15:59 sandervl Exp $ */
+/* $Id: hmcomm.h,v 1.13 2001-12-07 11:28:10 sandervl Exp $ */
 
 /*
@@ -13,5 +13,12 @@
 #define _HM_COMM_H_
 
-#define MAGIC_COM 0x12abcd34
+#include <handlemanager.h>
+#include "hmdevice.h"
+#include "overlappedio.h"
+
+#define MAX_COMPORTS        8
+#define MAGIC_COM           0x12abcd34
+
+#define TIMEOUT_COMM        50
 
 typedef struct
@@ -84,16 +91,14 @@
 typedef struct _HMDEVCOMDATA
 {
-  ULONG ulMagic;
+  ULONG                 ulMagic;
   // Win32 Device Control Block
-  COMMCONFIG   CommCfg;
-  COMMTIMEOUTS CommTOuts;
-  DWORD dwInBuffer, dwOutBuffer;
-  DWORD dwEventMask;
-  OVERLAPPED overlapped;
-  DWORD *lpfdwEvtMask;
-  BOOL fCancelIo;
-  DWORD dwLastError;
+  COMMCONFIG            CommCfg;
+  COMMTIMEOUTS          CommTOuts;
+  DWORD                 dwInBuffer;
+  DWORD                 dwOutBuffer;
+  DWORD                 dwEventMask;
+  OverlappedIOHandler  *iohandler;
   //OS/2 Device Control Block
-  DCBINFO dcbOS2;
+  DCBINFO               dcbOS2;
 } HMDEVCOMDATA, *PHMDEVCOMDATA;
 
@@ -115,4 +120,6 @@
 } EXTBAUDSET, *PEXTBAUDSET;
 #pragma pack()
+
+
 
 class HMDeviceCommClass : public HMDeviceHandler
@@ -209,5 +216,8 @@
                                    BOOL          arg4);
 
+  static void CloseOverlappedIOHandlers();
+
   private:
+
   APIRET SetLine( PHMHANDLEDATA pHMHandleData,
                   UCHAR ucSize,UCHAR Parity, UCHAR Stop);
@@ -222,4 +232,7 @@
   APIRET SetBaud( PHMHANDLEDATA pHMHandleData,
                   DWORD dwNewBaud);
+
+
+    static OverlappedIOHandler *handler[MAX_COMPORTS];
 };
 
Index: trunk/src/kernel32/hmparport.cpp
===================================================================
--- trunk/src/kernel32/hmparport.cpp	(revision 7560)
+++ trunk/src/kernel32/hmparport.cpp	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: hmparport.cpp,v 1.17 2001-12-05 18:06:02 sandervl Exp $ */
+/* $Id: hmparport.cpp,v 1.18 2001-12-07 11:28:10 sandervl Exp $ */
 
 /*
@@ -48,46 +48,4 @@
 #define PRT_QUERDEVICEID                   0x0074
 
-
-#if 0
-#pragma pack(1)
-typedef struct _DCBINFO
-{
-  USHORT   usWriteTimeout;         /*  Time period used for Write Timeout processing. */
-  USHORT   usReadTimeout;          /*  Time period used for Read Timeout processing. */
-  BYTE     fbCtlHndShake;          /*  HandShake Control flag. */
-  BYTE     fbFlowReplace;          /*  Flow Control flag. */
-  BYTE     fbTimeOut;              /*  Timeout flag. */
-  BYTE     bErrorReplacementChar;  /*  Error Replacement Character. */
-  BYTE     bBreakReplacementChar;  /*  Break Replacement Character. */
-  BYTE     bXONChar;               /*  Character XON. */
-  BYTE     bXOFFChar;              /*  Character XOFF. */
-} DCBINFO;
-typedef DCBINFO *PDCBINFO;
-
-
-typedef struct _RXQUEUE
-{
-  USHORT   cch;  /*  Number of characters in the queue. */
-  USHORT   cb;   /*  Size of receive/transmit queue. */
-} RXQUEUE;
-
-typedef RXQUEUE *PRXQUEUE;
-
-
-typedef struct _MODEMSTATUS
-{
-  BYTE   fbModemOn;   /*  Modem Control Signals ON Mask. */
-  BYTE   fbModemOff;  /*  Modem Control Signals OFF Mask. */
-} MODEMSTATUS;
-
-typedef MODEMSTATUS *PMODEMSTATUS;
-
-
-#pragma pack()
-
-
-#endif
-
-
 // Hardwired parallel port configuration information.
 // @@@PH better query the Resource Manager
@@ -121,4 +79,6 @@
 } HMDEVPARPORTDATA, *PHMDEVPARPORTDATA;
 
+//******************************************************************************
+//******************************************************************************
 static VOID *CreateDevData()
 {
@@ -135,6 +95,6 @@
   return pData;
 }
-
-
+//******************************************************************************
+//******************************************************************************
 HMDeviceParPortClass::HMDeviceParPortClass(LPCSTR lpDeviceName) : 
   HMDeviceHandler(lpDeviceName)
@@ -231,5 +191,6 @@
   return FALSE;
 }
-
+//******************************************************************************
+//******************************************************************************
 DWORD HMDeviceParPortClass::CreateFile(LPCSTR lpFileName,
                                        PHMHANDLEDATA pHMHandleData,
@@ -298,6 +259,26 @@
 }
 
-
-                      /* this is a handler method for calls to CloseHandle() */
+/*****************************************************************************
+ * Name      : DWORD HMDeviceParPortClass::GetFileType
+ * Purpose   : determine the handle type
+ * Parameters: PHMHANDLEDATA pHMHandleData
+ * Variables :
+ * Result    : API returncode
+ * Remark    :
+ * Status    :
+ *
+ * Author    : SvL
+ *****************************************************************************/
+
+DWORD HMDeviceParPortClass::GetFileType(PHMHANDLEDATA pHMHandleData)
+{
+    dprintf(("KERNEL32: HMDeviceParPortClass::GetFileType %s(%08x)\n",
+             lpHMDeviceName, pHMHandleData));
+
+    return FILE_TYPE_PIPE; //this is what NT4 returns
+}
+//******************************************************************************
+/* this is a handler method for calls to CloseHandle() */
+//******************************************************************************
 BOOL HMDeviceParPortClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
 {
@@ -426,136 +407,6 @@
   return ret;
 }
-
-BOOL HMDeviceParPortClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
-                                             LPCOMMPROP lpcmmp)
-{
-  dprintf(("HMDeviceParPortClass::GetCommProperties(%08xh, %08xh)\n",
-           pHMHandleData,
-           lpcmmp));
-  
-  APIRET rc;
-  ULONG ulLen;
-  int i;
-  
-#if 0
-  USHORT COMErr;
-  EXTBAUDGET BaudInfo;
-  ulLen = sizeof(EXTBAUDGET);
-  rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
-                    IOCTL_ASYNC,
-                    ASYNC_EXTGETBAUDRATE,
-                    0,0,0,
-                        &BaudInfo,ulLen,&ulLen);
-#endif
-  rc = NO_ERROR;
-  
-  memset(lpcmmp,0,sizeof(COMMPROP));
-  lpcmmp->wPacketLength  = sizeof(COMMPROP);
-  lpcmmp->wPacketVersion = 1; //???
-  lpcmmp->dwProvSubType =  PST_PARALLELPORT;
-  
-#if 0
-  lpcmmp->dwServiceMask  = SP_SERIALCOMM;
-  for(i=0;i<BaudTableSize && BaudInfo.ulMaxBaud <= BaudTable[i].dwBaudRate;i++);
-  lpcmmp->dwMaxBaud      = BaudTable[i].dwBaudFlag;
-  lpcmmp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK |
-                               PCF_RTSCTS | PCF_SETXCHAR |
-                               PCF_XONXOFF;
-  lpcmmp->dwSettableParams   = SP_BAUD | SP_DATABITS |
-                               SP_HANDSHAKEING | SP_PARITY |
-                               SP_PARITY_CHECK | SP_STOPBIT;
-  lpcmmp->dwSettableBaud = 0;
-  for(i=0;i<BaudTableSize;i++)
-  {
-    if ( (BaudTable[i].dwBaudRate>=BaudInfo.ulMinBaud) &&
-         (BaudTable[i].dwBaudRate<=BaudInfo.ulMaxBaud) )
-      lpcmmp->dwSettableBaud |= BaudTable[i].dwBaudFlag;
-  }
-  lpcmmp->dwSettableBaud |= BAUD_USER;
-  lpcmmp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
-  lpcmmp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
-                                PARITY_NONE | PARITY_ODD | PARITY_EVEN |
-    PARITY_MARK | PARITY_SPACE;
-#endif
-  
-  return(rc==0);
-}
-
-BOOL HMDeviceParPortClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
-                                          LPDWORD lpdwErrors,
-                                          LPCOMSTAT lpcst)
-{
-  dprintf(("HMDeviceParPortClass::ClearCommError(%08xh,%08xh,%08xh)\n",
-           pHMHandleData,
-           lpdwErrors,
-           lpcst));
-  
-  APIRET rc;
-  ULONG ulLen;
-  USHORT COMErr;
-
-  ulLen = sizeof(USHORT);
-  
-  *lpdwErrors = 0;
-  rc = NO_ERROR;
-  
-#if 0
-  // ParPort: CE_DNS, CE_OOP CE_PTO
-  
-  rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
-                    IOCTL_ASYNC,
-                    ASYNC_GETCOMMERROR,
-                    0,0,0,
-                    &COMErr,2,&ulLen);
-  *lpdwErrors |= (COMErr & 0x0001)?CE_OVERRUN:0;
-  *lpdwErrors |= (COMErr & 0x0002)?CE_RXOVER:0;
-  *lpdwErrors |= (COMErr & 0x0004)?CE_RXPARITY:0;
-  *lpdwErrors |= (COMErr & 0x0008)?CE_FRAME:0;
-
-  if(lpcst)
-  {
-    UCHAR ucStatus;
-    RXQUEUE qInfo;
-    ulLen = 1;
-    rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
-                      IOCTL_ASYNC,
-                      ASYNC_GETCOMMSTATUS,
-                      0,0,0,
-                      &ucStatus,ulLen,&ulLen);
-    if(!rc)
-    {
-      lpcst->fCtsHold  = ((ucStatus & 0x01)>0);
-      lpcst->fDsrHold  = ((ucStatus & 0x02)>0);
-      lpcst->fRlsdHold = FALSE;//(ucStatus & 0x04)>0);
-      lpcst->fXoffHold = ((ucStatus & 0x08)>0);
-      lpcst->fXoffSend = ((ucStatus & 0x10)>0);
-      lpcst->fEof      = ((ucStatus & 0x20)>0);// Is break = Eof ??
-      lpcst->fTxim     = ((ucStatus & 0x40)>0);
-
-      ulLen = sizeof(qInfo);
-      rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
-                        IOCTL_ASYNC,
-                        ASYNC_GETINQUECOUNT,
-                        0,0,0,
-                        &qInfo,ulLen,&ulLen);
-      if(!rc)
-      {
-        lpcst->cbInQue   = qInfo.cch;
-        rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
-                          IOCTL_ASYNC,
-                          ASYNC_GETOUTQUECOUNT,
-                          0,0,0,
-                          &qInfo,ulLen,&ulLen);
-        if(!rc)
-          lpcst->cbOutQue = qInfo.cch;
-      }
-    }
-  }
-#endif
-  
-  return(rc==NO_ERROR);
-}
-
-
+//******************************************************************************
+//******************************************************************************
 BOOL HMDeviceParPortClass::DeviceIoControl(PHMHANDLEDATA pHMHandleData, 
                                            DWORD dwIoControlCode,
@@ -719,97 +570,6 @@
     return FALSE;
 }
-
-
-BOOL HMDeviceParPortClass::SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
-                                                LPCOMMCONFIG lpCC,
-                                                DWORD dwSize)
-{
-  dprintf(("HMDeviceParPortClass::SetDefaultCommConfig(%08xh,%08xh,%08xh)\n",
-           pHMHandleData,
-           lpCC,
-           dwSize));
-  
-  PHMDEVPARPORTDATA pDevData = (PHMDEVPARPORTDATA)pHMHandleData->lpDeviceData;
-  if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_PARPORT) )
-  {
-    SetLastError(ERROR_INVALID_HANDLE);
-    return FALSE;
-  }
-  memset(&pDevData->CommCfg,0, sizeof(COMMCONFIG));
-  memcpy(&pDevData->CommCfg,lpCC,dwSize>sizeof(COMMCONFIG)?sizeof(COMMCONFIG):dwSize);
-
-  return(TRUE);
-}
-
-
-BOOL HMDeviceParPortClass::GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
-                                                LPCOMMCONFIG lpCC,
-                                                LPDWORD lpdwSize)
-{
-  dprintf(("HMDeviceParPortClass::GetDefaultCommConfig(%08xh,%08xh,%08xh)\n",
-           pHMHandleData,
-           lpCC,
-           lpdwSize));
-
-  
-  PHMDEVPARPORTDATA pDevData = (PHMDEVPARPORTDATA)pHMHandleData->lpDeviceData;
-
-  if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
-      *lpdwSize< sizeof(COMMCONFIG) )
-  {
-    SetLastError(ERROR_INSUFFICIENT_BUFFER);
-    *lpdwSize= sizeof(COMMCONFIG);
-    return FALSE;
-  }
-
-  if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_PARPORT) )
-  {
-    SetLastError(ERROR_INVALID_HANDLE);
-    return FALSE;
-  }
-
-  memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
-  *lpdwSize = sizeof(COMMCONFIG);
-  return(TRUE);
-}
-
-
-BOOL HMDeviceParPortClass::SetCommConfig( PHMHANDLEDATA pHMHandleData,
-                                         LPCOMMCONFIG lpCC,
-                                         DWORD dwSize )
-{
-  dprintf(("HMDeviceParPortClass::SetCommConfig not implemented"));
-
-  return(TRUE);
-}
-
-
-BOOL HMDeviceParPortClass::GetCommConfig( PHMHANDLEDATA pHMHandleData,
-                                         LPCOMMCONFIG lpCC,
-                                         LPDWORD lpdwSize )
-{
-  PHMDEVPARPORTDATA pDevData = (PHMDEVPARPORTDATA)pHMHandleData->lpHandlerData;
-
-  dprintf(("HMDeviceParPortClass::GetCommConfig(%08xh,%08xh,%08xh)\n",
-           pHMHandleData,
-           lpCC,
-           lpdwSize));
-
-  if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
-      *lpdwSize< sizeof(COMMCONFIG) )
-  {
-    SetLastError(ERROR_INSUFFICIENT_BUFFER);
-    *lpdwSize= sizeof(COMMCONFIG);
-    return FALSE;
-  }
-
-  if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_PARPORT) )
-  {
-    SetLastError(ERROR_INVALID_HANDLE);
-    return FALSE;
-  }
-
-  memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
-  *lpdwSize = sizeof(COMMCONFIG);
-  return(TRUE);
-}
+//******************************************************************************
+//******************************************************************************
+
+
Index: trunk/src/kernel32/hmparport.h
===================================================================
--- trunk/src/kernel32/hmparport.h	(revision 7560)
+++ trunk/src/kernel32/hmparport.h	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: hmparport.h,v 1.6 2001-12-05 14:16:05 sandervl Exp $ */
+/* $Id: hmparport.h,v 1.7 2001-12-07 11:28:10 sandervl Exp $ */
 
 /*
@@ -28,30 +28,10 @@
                              PHMHANDLEDATA pHMHandleDataTemplate);
 
+  /* this is a handler method for calls to GetFileType() */
+  virtual DWORD GetFileType (PHMHANDLEDATA pHMHandleData);
+
   /* this is the handler method for calls to CloseHandle() */
   virtual BOOL CloseHandle(PHMHANDLEDATA pHMHandleData);
 
-  virtual BOOL GetCommProperties( PHMHANDLEDATA pHMHandleData,
-                                 LPCOMMPROP lpcmmp);
-  
-  virtual BOOL ClearCommError( PHMHANDLEDATA pHMHandleData,
-                               LPDWORD lpdwErrors,
-                               LPCOMSTAT lpcst);
-  
-  virtual BOOL SetCommConfig( PHMHANDLEDATA pHMHandleData,
-                              LPCOMMCONFIG lpCC,
-                              DWORD dwSize );
-  
-  virtual BOOL GetCommConfig( PHMHANDLEDATA pHMHandleData,
-                              LPCOMMCONFIG lpCC,
-                              LPDWORD lpdwSize );
-  
-  virtual BOOL SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
-                                     LPCOMMCONFIG lpCC,
-                                     DWORD dwSize);
-  
-  virtual BOOL GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
-                                     LPCOMMCONFIG lpCC,
-                                     LPDWORD lpdwSize);
-  
   /* this is a handler method for calls to DeviceIoControl() */
   virtual BOOL   DeviceIoControl    (PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
Index: trunk/src/kernel32/initkernel32.cpp
===================================================================
--- trunk/src/kernel32/initkernel32.cpp	(revision 7560)
+++ trunk/src/kernel32/initkernel32.cpp	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: initkernel32.cpp,v 1.9 2001-11-24 13:55:57 sandervl Exp $
+/* $Id: initkernel32.cpp,v 1.10 2001-12-07 11:28:11 sandervl Exp $
  *
  * KERNEL32 DLL entry point
@@ -47,4 +47,5 @@
 #include "directory.h"
 #include "hmdevio.h"
+#include "hmcomm.h"
 #include <windllbase.h>
 #include "winexepe2lx.h"
@@ -215,4 +216,7 @@
 {
     dprintf(("kernel32 exit %d\n", ulReason));
+
+    HMDeviceCommClass::CloseOverlappedIOHandlers();
+
     //Flush and delete all open memory mapped files
     Win32MemMap::deleteAll();
Index: trunk/src/kernel32/overlappedio.cpp
===================================================================
--- trunk/src/kernel32/overlappedio.cpp	(revision 7560)
+++ trunk/src/kernel32/overlappedio.cpp	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: overlappedio.cpp,v 1.5 2001-12-06 15:57:52 sandervl Exp $ */
+/* $Id: overlappedio.cpp,v 1.6 2001-12-07 11:28:11 sandervl Exp $ */
 
 /*
@@ -25,6 +25,6 @@
 //******************************************************************************
 //******************************************************************************
-OverlappedIOHandler::OverlappedIOHandler(LPOVERLAPPED_HANDLER lpReadHandler, 
-                                         LPOVERLAPPED_HANDLER lpWriteHandler, 
+OverlappedIOHandler::OverlappedIOHandler(LPOVERLAPPED_HANDLER lpReadHandler,
+                                         LPOVERLAPPED_HANDLER lpWriteHandler,
                                          LPOVERLAPPED_HANDLER lpPollHandler) :
                    hThreadRead(0), hThreadWrite(0), hThreadPoll(0)
@@ -49,5 +49,5 @@
     hEventWrite  = ::CreateEventA(NULL, FALSE, FALSE, NULL);
 
-    //the exit event semaphore is manual reset, because signalling this event
+    //the exit event semaphore is manual reset, because this event
     //must be able to wake up multiple threads
     hEventExit   = ::CreateEventA(NULL, TRUE, FALSE, NULL);
@@ -58,5 +58,5 @@
         goto failed;
     }
-    
+
     DWORD dwThreadId;
     LPOVERLAPPED_THREAD_PARAM threadparam;
@@ -89,5 +89,5 @@
     }
 
-    if((lpPollHandler && !hThreadPoll) || !hThreadRead || (lpWriteHandler && !hThreadWrite)) 
+    if((lpPollHandler && !hThreadPoll) || !hThreadRead || (lpWriteHandler && !hThreadWrite))
     {
         DebugInt3();
@@ -97,9 +97,9 @@
     return;
 
-outofmem: 
+outofmem:
     errcode = OutOfMemory;
     //fall through
 failed:
-    //SvL: NOTE: We might not fail gracefully when threads have already been 
+    //SvL: NOTE: We might not fail gracefully when threads have already been
     //           created. (thread accessing memory that has been freed)
     //           Don't feel like wasting time to fix this as this should never
@@ -223,5 +223,5 @@
         case ASYNCIO_READ:
         case ASYNCIO_READWRITE:
-	    lpReadHandler(lpRequest, &dwResult, NULL);
+            lpReadHandler(lpRequest, &dwResult, NULL);
             lpOverlapped->Internal     = lpRequest->dwLastError;
             lpOverlapped->InternalHigh = dwResult;
@@ -235,5 +235,5 @@
 
         case ASYNCIO_WRITE:
-	    lpWriteHandler(lpRequest, &dwResult, NULL);
+            lpWriteHandler(lpRequest, &dwResult, NULL);
             lpOverlapped->Internal     = lpRequest->dwLastError;
             lpOverlapped->InternalHigh = dwResult;
@@ -247,5 +247,5 @@
 
         case ASYNCIO_POLL:
-            while(TRUE) 
+            while(TRUE)
             {
                 dwTimeOut = 0;
@@ -281,5 +281,6 @@
                                     LPOVERLAPPED  lpOverlapped,
                                     LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
-                                    DWORD         dwUserData)
+                                    DWORD         dwUserData,
+                                    DWORD         dwTimeOut)
 {
     LPASYNCIOREQUEST lpRequest, current;
@@ -290,5 +291,5 @@
         return FALSE;
     }
- 
+
     lpRequest = new ASYNCIOREQUEST;
     if(lpRequest == NULL) {
@@ -304,4 +305,5 @@
     lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     lpRequest->dwUserData          = dwUserData;
+    lpRequest->dwTimeOut           = dwTimeOut;
     lpRequest->next                = NULL;
 
@@ -322,5 +324,5 @@
     ::LeaveCriticalSection(&critsect);
 
-    lpOverlapped->Internal     = STATUS_PENDING;
+    lpOverlapped->Internal     = ERROR_IO_PENDING;
     lpOverlapped->InternalHigh = 0;
     lpOverlapped->Offset       = 0;
@@ -343,5 +345,6 @@
                                    LPOVERLAPPED  lpOverlapped,
                                    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
-                                   DWORD         dwUserData)
+                                   DWORD         dwUserData,
+                                   DWORD         dwTimeOut)
 {
     LPASYNCIOREQUEST lpRequest, current;
@@ -351,5 +354,5 @@
         return FALSE;
     }
- 
+
     lpRequest = new ASYNCIOREQUEST;
     if(lpRequest == NULL) {
@@ -365,4 +368,5 @@
     lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     lpRequest->dwUserData          = dwUserData;
+    lpRequest->dwTimeOut           = dwTimeOut;
     lpRequest->next                = NULL;
 
@@ -378,5 +382,5 @@
     ::LeaveCriticalSection(&critsect);
 
-    lpOverlapped->Internal     = STATUS_PENDING;
+    lpOverlapped->Internal     = ERROR_IO_PENDING;
     lpOverlapped->InternalHigh = 0;
     lpOverlapped->Offset       = 0;
@@ -396,5 +400,6 @@
                                        LPOVERLAPPED  lpOverlapped,
                                        LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
-                                       DWORD         dwUserData)
+                                       DWORD         dwUserData,
+                                       DWORD         dwTimeOut)
 {
     LPASYNCIOREQUEST lpRequest, current;
@@ -404,5 +409,5 @@
         return FALSE;
     }
- 
+
     lpRequest = new ASYNCIOREQUEST;
     if(lpRequest == NULL) {
@@ -418,4 +423,5 @@
     lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     lpRequest->dwUserData          = dwUserData;
+    lpRequest->dwTimeOut           = dwTimeOut;
     lpRequest->next                = NULL;
 
@@ -431,5 +437,5 @@
     ::LeaveCriticalSection(&critsect);
 
-    lpOverlapped->Internal     = STATUS_PENDING;
+    lpOverlapped->Internal     = ERROR_IO_PENDING;
     lpOverlapped->InternalHigh = 0;
     lpOverlapped->Offset       = 0;
@@ -449,5 +455,5 @@
     LPASYNCIOREQUEST lpRequest;
 
-    for(int i=ASYNC_INDEX_READ;i<NR_ASYNC_OPERATIONS;i++) 
+    for(int i=ASYNC_INDEX_READ;i<NR_ASYNC_OPERATIONS;i++)
     {
         while(TRUE) {
@@ -468,9 +474,9 @@
                                               LPOVERLAPPED  lpOverlapped,
                                               LPDWORD       lpcbTransfer,
-                                              DWORD         dwTimeout)
+                                              BOOL          fWait)
 {
     DWORD ret;
 
-    ret = ::WaitForSingleObject(lpOverlapped->hEvent, dwTimeout);
+    ret = ::WaitForSingleObject(lpOverlapped->hEvent, (fWait) ? INFINITE : 0);
 
     if(lpcbTransfer)
@@ -488,7 +494,7 @@
 
     ::EnterCriticalSection(&critsect);
-    if(pending[index]) 
+    if(pending[index])
     {
-        if(pending[index]->hHandle != hHandle) 
+        if(pending[index]->hHandle != hHandle)
         {
             lpRequest = pending[index];
Index: trunk/src/kernel32/overlappedio.h
===================================================================
--- trunk/src/kernel32/overlappedio.h	(revision 7560)
+++ trunk/src/kernel32/overlappedio.h	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: overlappedio.h,v 1.4 2001-12-06 15:57:52 sandervl Exp $ */
+/* $Id: overlappedio.h,v 1.5 2001-12-07 11:28:11 sandervl Exp $ */
 
 /*
@@ -13,13 +13,13 @@
 #define __OVERLAPPEDIO_H__
 
-#define NR_ASYNC_OPERATIONS	3
+#define NR_ASYNC_OPERATIONS 3
 #define ASYNC_INDEX_READ        0
 #define ASYNC_INDEX_WRITE       1
 #define ASYNC_INDEX_POLL        2
 
-#define ASYNCIO_READ		1
-#define ASYNCIO_WRITE		2
-#define ASYNCIO_READWRITE	4
-#define ASYNCIO_POLL		8
+#define ASYNCIO_READ        1
+#define ASYNCIO_WRITE       2
+#define ASYNCIO_READWRITE   4
+#define ASYNCIO_POLL        8
 
 //forward decl
@@ -35,5 +35,6 @@
   HANDLE              hHandle;
   LPCVOID             lpBuffer;
-  ULONG               nNumberOfBytes;
+  DWORD               nNumberOfBytes;
+  DWORD               dwTimeOut;
   LPOVERLAPPED        lpOverlapped;
   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;
@@ -44,5 +45,5 @@
 } ASYNCIOREQUEST, *LPASYNCIOREQUEST;
 
-typedef BOOL (* SYSTEM LPOVERLAPPED_HANDLER)(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
+typedef BOOL (* LPOVERLAPPED_HANDLER)(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
 
 enum OverlappedIOError {
@@ -53,6 +54,6 @@
 {
 public:
-     OverlappedIOHandler(LPOVERLAPPED_HANDLER lpReadHandler, 
-                         LPOVERLAPPED_HANDLER lpWriteHandler, 
+     OverlappedIOHandler(LPOVERLAPPED_HANDLER lpReadHandler,
+                         LPOVERLAPPED_HANDLER lpWriteHandler,
                          LPOVERLAPPED_HANDLER lpPollHandler = NULL);
     ~OverlappedIOHandler();
@@ -64,5 +65,6 @@
                       LPOVERLAPPED  lpOverlapped,
                       LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
-                      DWORD         dwUserData);
+                      DWORD         dwUserData,
+                      DWORD         dwTimeOut = INFINITE);
 
      BOOL   ReadFile(HANDLE        hHandle,
@@ -72,5 +74,6 @@
                      LPOVERLAPPED  lpOverlapped,
                      LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
-                     DWORD         dwUserData);
+                     DWORD         dwUserData,
+                     DWORD         dwTimeOut = INFINITE);
 
      BOOL   WaitForEvent(HANDLE        hHandle,
@@ -78,5 +81,6 @@
                          LPOVERLAPPED  lpOverlapped,
                          LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
-                         DWORD         dwUserData);
+                         DWORD         dwUserData,
+                         DWORD         dwTimeOut = INFINITE);
 
      BOOL   CancelIo(HANDLE hHandle);
@@ -85,5 +89,5 @@
                                 LPOVERLAPPED  lpoOverlapped,
                                 LPDWORD       lpcbTransfer,
-                                DWORD         dwTimeout);
+                                BOOL          fWait);
 
 protected:
Index: trunk/src/kernel32/wprocess.cpp
===================================================================
--- trunk/src/kernel32/wprocess.cpp	(revision 7560)
+++ trunk/src/kernel32/wprocess.cpp	(revision 7564)
@@ -1,3 +1,3 @@
-/* $Id: wprocess.cpp,v 1.139 2001-12-03 12:13:10 sandervl Exp $ */
+/* $Id: wprocess.cpp,v 1.140 2001-12-07 11:28:11 sandervl Exp $ */
 
 /*
@@ -37,4 +37,5 @@
 #include "oslibmisc.h"
 #include "oslibdebug.h"
+#include "hmcomm.h"
 
 #include "console.h"
@@ -424,4 +425,6 @@
     }
 
+    HMDeviceCommClass::CloseOverlappedIOHandlers();
+
     //Note: Needs to be done after deleting WinExe (destruction of exe + dll objects)
     //Flush and delete all open memory mapped files
