Ignore:
Timestamp:
Dec 7, 2001, 12:28:11 PM (24 years ago)
Author:
sandervl
Message:

overlappedio, com & lpt updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/hmcomm.cpp

    r7550 r7564  
    1 /* $Id: hmcomm.cpp,v 1.27 2001-12-05 18:06:00 sandervl Exp $ */
     1/* $Id: hmcomm.cpp,v 1.28 2001-12-07 11:28:09 sandervl Exp $ */
    22
    33/*
     
    99 * 2001 Sander van Leeuwen <sandervl@xs4all.nl>
    1010 *
    11  * TODO: Overlapped IO only supports one request at a time
    12  * TODO: Overlapped IO not thread safe
    1311 *
    1412 */
     
    2119#include "handlenames.h"
    2220#include <heapstring.h>
    23 #include "hmdevice.h"
    2421#include "hmcomm.h"
    2522#include "oslibdos.h"
     
    6158#define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
    6259
     60static BOOL CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
     61static BOOL CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
     62static BOOL CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
     63
    6364//******************************************************************************
    6465//******************************************************************************
    6566static VOID *CreateDevData()
    6667{
    67   PHMDEVCOMDATA pData;
    68   pData = new HMDEVCOMDATA();
    69   if(NULL!=pData)
    70   {
    71     memset(pData,0,sizeof(HMDEVCOMDATA));
    72     pData->ulMagic = MAGIC_COM;
    73     pData->CommCfg.dwSize   = sizeof(COMMCONFIG);
    74     pData->CommCfg.wVersion = 1;
    75     pData->CommCfg.dwProviderSubType = PST_RS232;
    76     pData->CommCfg.dcb.DCBlength = sizeof(DCB);
    77     pData->CommCfg.dcb.BaudRate  = CBR_1200;
    78     pData->CommCfg.dcb.ByteSize = 8;
    79     pData->CommCfg.dcb.Parity   = NOPARITY;
    80     pData->CommCfg.dcb.StopBits = ONESTOPBIT;
    81     pData->dwInBuffer  = 16;
    82     pData->dwOutBuffer = 16;
    83   }
    84   return pData;
     68    PHMDEVCOMDATA pData;
     69
     70    pData = new HMDEVCOMDATA();
     71    if(NULL!=pData)
     72    {
     73        memset(pData,0,sizeof(HMDEVCOMDATA));
     74        pData->ulMagic = MAGIC_COM;
     75        pData->CommCfg.dwSize   = sizeof(COMMCONFIG);
     76        pData->CommCfg.wVersion = 1;
     77        pData->CommCfg.dwProviderSubType = PST_RS232;
     78        pData->CommCfg.dcb.DCBlength = sizeof(DCB);
     79        pData->CommCfg.dcb.BaudRate  = CBR_1200;
     80        pData->CommCfg.dcb.ByteSize = 8;
     81        pData->CommCfg.dcb.Parity   = NOPARITY;
     82        pData->CommCfg.dcb.StopBits = ONESTOPBIT;
     83        pData->dwInBuffer  = 16;
     84        pData->dwOutBuffer = 16;
     85    }
     86    return pData;
    8587}
    8688//******************************************************************************
     
    8890HMDeviceCommClass::HMDeviceCommClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
    8991{
    90   VOID *pData;
    91   dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n"));
    92   pData = CreateDevData();
    93   if(pData!= NULL)
    94     HMDeviceRegisterEx("COM1", this, pData);
    95  
    96   // add symbolic links to the "real name" of the device
    97   {
     92    VOID *pData;
     93
     94    dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n"));
     95    pData = CreateDevData();
     96    if(pData!= NULL)
     97        HMDeviceRegisterEx("COM1", this, pData);
     98
     99    // add symbolic links to the "real name" of the device
    98100    // @@@PH what's the long device name: SerialPortx ?
    99101    // HandleNamesAddSymbolicLink("\\Device\\ParallelPort3", "COM3");
    100102    // Note: \\.\COMx: is invalid (NT4SP6)
    101    
     103
    102104    PSZ pszCOM = strdup("\\\\.\\COMx");
    103     for (char ch = '1'; ch <= '9'; ch++)
     105    for (char ch = '1'; ch < '9'; ch++)
    104106    {
    105       pszCOM[7] = ch;
    106       HandleNamesAddSymbolicLink(pszCOM, pszCOM+4);
     107        pszCOM[7] = ch;
     108        HandleNamesAddSymbolicLink(pszCOM, pszCOM+4);
    107109    }
    108110    free(pszCOM);
    109  
     111
    110112    // add "AUX" device
    111113    HandleNamesAddSymbolicLink("AUX",        "COM1");
    112114    HandleNamesAddSymbolicLink("AUX:",       "COM1");
    113115    HandleNamesAddSymbolicLink("\\\\.\\AUX", "COM1");
    114   }
    115116}
    116117
     
    131132{
    132133    dprintf2(("HMDeviceCommClass::FindDevice %s %s", lpClassDevName, lpDeviceName));
    133  
     134
    134135    //first 3 letters 'COM'?
    135136    if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) {
     
    163164 DWORD ret = ERROR_SUCCESS;
    164165
    165   dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
    166 
    167   if(strlen(lpFileName) > 5) {
    168       lpFileName += 4; //skip prefix
    169   }
    170 
    171   pHMHandleData->hHMHandle = 0;
    172 
    173   strcpy(comname, lpFileName);
    174   comname[4] = 0;   //get rid of : (if present) (eg COM1:)
    175 
    176   //AH: TODO parse Win32 security handles
    177   ULONG oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
    178   pHMHandleData->hHMHandle = OSLibDosOpen(comname,
    179                                           OSLIB_ACCESS_READWRITE |
    180                                           OSLIB_ACCESS_SHAREDENYREAD |
    181                                           OSLIB_ACCESS_SHAREDENYWRITE);
    182   ::SetErrorMode(oldmode);
    183   if (pHMHandleData->hHMHandle != 0)
    184   {
    185     ULONG ulLen;
    186     APIRET rc;
    187     pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
    188     // Init The handle instance with the default default device config
    189     memcpy( pHMHandleData->lpHandlerData,
    190             pHMHandleData->lpDeviceData,
    191             sizeof(HMDEVCOMDATA));
    192 
    193     ulLen = sizeof(DCBINFO);
    194 
    195     rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
    196                            IOCTL_ASYNC,
    197                            ASYNC_GETDCBINFO,
    198                            0,0,0,
    199                            &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
    200     dprintf(("DCB Of %s :\n"
    201              " WriteTimeout           : %d\n"
    202              " ReadTimeout            : %d\n"
    203              " CtlHandshake           : 0x%x\n"
    204              " FlowReplace            : 0x%x\n"
    205              " Timeout                : 0x%x\n"
    206              " Error replacement Char : 0x%x\n"
    207              " Break replacement Char : 0x%x\n"
    208              " XON Char               : 0x%x\n"
    209              " XOFF Char              : 0x%x\n",
    210              comname,
    211              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
    212              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
    213              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
    214              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
    215              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
    216              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
    217              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
    218              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
    219              ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
    220 
    221     if(rc)
     166    dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
     167
     168    if(strlen(lpFileName) > 5) {
     169        lpFileName += 4; //skip prefix
     170    }
     171
     172    pHMHandleData->hHMHandle = 0;
     173
     174    strcpy(comname, lpFileName);
     175    comname[4] = 0;   //get rid of : (if present) (eg COM1:)
     176
     177    //AH: TODO parse Win32 security handles
     178    ULONG oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
     179    pHMHandleData->hHMHandle = OSLibDosOpen(comname,
     180                                            OSLIB_ACCESS_READWRITE |
     181                                            OSLIB_ACCESS_SHAREDENYREAD |
     182                                            OSLIB_ACCESS_SHAREDENYWRITE);
     183    ::SetErrorMode(oldmode);
     184    if (pHMHandleData->hHMHandle != 0)
    222185    {
    223       OSLibDosClose(pHMHandleData->hHMHandle);
    224       delete pHMHandleData->lpHandlerData;
    225       return rc;
    226     }
    227     rc = SetBaud(pHMHandleData,9600);
    228     dprintf(("Init Baud to 9600 rc = %d",rc));
    229     rc = SetLine(pHMHandleData,8,0,0);
    230     dprintf(("Set Line to 8/N/1 rc = %d",rc));
    231 
    232     if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
    233     {
    234         PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    235         DWORD         dwThreadId;
    236 
    237     }
    238     return ERROR_SUCCESS;
    239   }
    240   else
    241     return ERROR_ACCESS_DENIED;
    242 
     186        ULONG ulLen;
     187        APIRET rc;
     188        pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
     189        // Init The handle instance with the default default device config
     190        memcpy( pHMHandleData->lpHandlerData,
     191                pHMHandleData->lpDeviceData,
     192                sizeof(HMDEVCOMDATA));
     193
     194        ulLen = sizeof(DCBINFO);
     195
     196        rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
     197                               IOCTL_ASYNC,
     198                               ASYNC_GETDCBINFO,
     199                               0,0,0,
     200                               &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
     201        dprintf(("DCB Of %s :\n"
     202                 " WriteTimeout           : %d\n"
     203                 " ReadTimeout            : %d\n"
     204                 " CtlHandshake           : 0x%x\n"
     205                 " FlowReplace            : 0x%x\n"
     206                 " Timeout                : 0x%x\n"
     207                 " Error replacement Char : 0x%x\n"
     208                 " Break replacement Char : 0x%x\n"
     209                 " XON Char               : 0x%x\n"
     210                 " XOFF Char              : 0x%x\n",
     211                 comname,
     212                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
     213                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
     214                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
     215                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
     216                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
     217                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
     218                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
     219                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
     220                 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
     221
     222        if(rc)
     223        {
     224            OSLibDosClose(pHMHandleData->hHMHandle);
     225            delete pHMHandleData->lpHandlerData;
     226            return rc;
     227        }
     228        rc = SetBaud(pHMHandleData,9600);
     229        dprintf(("Init Baud to 9600 rc = %d",rc));
     230        rc = SetLine(pHMHandleData,8,0,0);
     231        dprintf(("Set Line to 8/N/1 rc = %d",rc));
     232
     233        if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
     234        {
     235            PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     236            int           comnr;
     237
     238            comnr = comname[3] - '1';
     239
     240            if(handler[comnr] == NULL) {
     241                try {
     242                    handler[comnr] = new OverlappedIOHandler(CommReadIOHandler, CommWriteIOHandler, CommPollIOHandler);
     243                }
     244                catch(...)
     245                {
     246                    ret = ERROR_NOT_ENOUGH_MEMORY;
     247                    goto fail;
     248                }
     249            }
     250            pDevData->iohandler = handler[comnr];
     251        }
     252        return ERROR_SUCCESS;
     253    }
     254    else
     255        return ERROR_ACCESS_DENIED;
    243256
    244257fail:
    245258
    246   delete pHMHandleData->lpHandlerData;
    247   OSLibDosClose(pHMHandleData->hHMHandle);
    248   return ret;
     259    delete pHMHandleData->lpHandlerData;
     260    OSLibDosClose(pHMHandleData->hHMHandle);
     261    return ret;
    249262}
    250263/*****************************************************************************
     
    262275DWORD HMDeviceCommClass::GetFileType(PHMHANDLEDATA pHMHandleData)
    263276{
    264   dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n",
    265            lpHMDeviceName,
    266            pHMHandleData));
    267 
    268   return FILE_TYPE_CHAR;
     277    dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n",
     278             lpHMDeviceName, pHMHandleData));
     279
     280    return FILE_TYPE_CHAR;
    269281}
    270282//******************************************************************************
     
    272284BOOL HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
    273285{
    274   PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    275   dprintf(("HMComm: Serial communication port close request"));
    276 
    277   if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
    278   {
    279       DebugInt3();
    280   }
    281   delete pHMHandleData->lpHandlerData;
    282   return OSLibDosClose(pHMHandleData->hHMHandle);
     286    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     287    dprintf(("HMComm: Serial communication port close request"));
     288
     289    if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
     290    {
     291        DebugInt3();
     292    }
     293    delete pHMHandleData->lpHandlerData;
     294    return OSLibDosClose(pHMHandleData->hHMHandle);
     295}
     296//******************************************************************************
     297//Overlapped read handler
     298//******************************************************************************
     299BOOL CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
     300{
     301    return FALSE;
     302}
     303//******************************************************************************
     304//Overlapped write handler
     305//******************************************************************************
     306BOOL CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
     307{
     308    return FALSE;
     309}
     310//******************************************************************************
     311//Overlapped WaitCommEvent handler
     312//******************************************************************************
     313BOOL CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
     314{
     315    *lpdwTimeOut = TIMEOUT_COMM;
     316    return FALSE;
    283317}
    284318/*****************************************************************************
     
    304338                                  LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    305339{
    306   dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
    307            lpHMDeviceName,
    308            pHMHandleData->hHMHandle,
    309            lpBuffer,
    310            nNumberOfBytesToWrite,
    311            lpNumberOfBytesWritten,
    312            lpOverlapped));
    313 
    314   BOOL  ret;
    315   ULONG ulBytesWritten;
    316 
    317   if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
    318     dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
    319     ::SetLastError(ERROR_INVALID_PARAMETER);
    320     return FALSE;
    321   }
    322   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
    323     dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
    324   }
    325   if(lpCompletionRoutine) {
    326       dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
    327   }
    328 
    329 //testestestest
    330   dprintf2(("Bytes to write:"));
    331   for(int i=0;i<nNumberOfBytesToWrite;i++) {
    332           dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
    333   }
    334 //testestestset
    335 
    336   ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
    337                       &ulBytesWritten);
    338 
    339   if(lpNumberOfBytesWritten) {
     340    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     341    BOOL  ret;
     342    ULONG ulBytesWritten;
     343
     344    dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
     345             lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite,
     346             lpNumberOfBytesWritten, lpOverlapped));
     347
     348
     349    if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
     350    {
     351        ::SetLastError(ERROR_INVALID_HANDLE);
     352        return FALSE;
     353    }
     354
     355    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
     356        dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
     357        ::SetLastError(ERROR_INVALID_PARAMETER);
     358        return FALSE;
     359    }
     360    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
     361        dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
     362    }
     363    if(lpCompletionRoutine) {
     364        dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
     365    }
     366
     367    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
     368        return pDevData->iohandler->WriteFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToWrite,
     369                                              lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData);
     370    }
     371
     372    //testestestest
     373    dprintf2(("Bytes to write:"));
     374    for(int i=0;i<nNumberOfBytesToWrite;i++) {
     375        dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
     376    }
     377    //testestestset
     378
     379    ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
     380                        &ulBytesWritten);
     381
     382    if(lpNumberOfBytesWritten) {
    340383       *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
    341384       dprintf2(("KERNEL32:HMDeviceCommClass::WriteFile %d byte(s) written", *lpNumberOfBytesWritten));
    342   }
    343   if(ret == FALSE) {
     385    }
     386    if(ret == FALSE) {
    344387       dprintf(("!ERROR!: WriteFile failed with rc %d", GetLastError()));
    345   }
    346 
    347   return ret;
     388    }
     389
     390    return ret;
    348391}
    349392/*****************************************************************************
     
    370413                                 LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    371414{
    372   dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
    373            lpHMDeviceName,
    374            pHMHandleData->hHMHandle,
    375            lpBuffer,
    376            nNumberOfBytesToRead,
    377            lpNumberOfBytesRead,
    378            lpOverlapped));
    379 
    380   BOOL  ret;
    381   ULONG ulBytesRead;
    382 
    383   if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
    384     dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
    385     ::SetLastError(ERROR_INVALID_PARAMETER);
    386     return FALSE;
    387   }
    388   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
    389     dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
    390   }
    391 
    392   if(lpCompletionRoutine) {
    393       dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
    394   }
    395 
    396   RXQUEUE qInfo;
    397   ULONG ulLen = sizeof(qInfo);
    398   ULONG rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
    399                         IOCTL_ASYNC,
    400                         ASYNC_GETINQUECOUNT,
    401                         0,0,0,
    402                         &qInfo,ulLen,&ulLen);
    403   dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc));
    404 
    405   ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
    406                      &ulBytesRead);
    407 
    408   if(lpNumberOfBytesRead) {
    409        *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
    410        dprintf2(("KERNEL32:HMDeviceCommClass::ReadFile %d bytes read", *lpNumberOfBytesRead));
    411   }
    412   if(ret == FALSE) {
    413        dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError()));
    414   }
    415   else {
    416 //testestestest
    417       dprintf2(("%d Bytes read:", ulBytesRead));
    418       for(int i=0;i<ulBytesRead;i++) {
    419           dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
    420       }
    421 //testestestset
    422   }
    423   return ret;
    424 }
    425 
     415    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     416    BOOL  ret;
     417    ULONG ulBytesRead;
     418
     419    dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
     420             lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead,
     421             lpNumberOfBytesRead, lpOverlapped));
     422
     423    if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
     424    {
     425        ::SetLastError(ERROR_INVALID_HANDLE);
     426        return FALSE;
     427    }
     428
     429    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
     430        dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
     431        ::SetLastError(ERROR_INVALID_PARAMETER);
     432        return FALSE;
     433    }
     434    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
     435        dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
     436    }
     437
     438    if(lpCompletionRoutine) {
     439        dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
     440    }
     441
     442    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
     443        return pDevData->iohandler->ReadFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToRead,
     444                                             lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData);
     445    }
     446
     447    RXQUEUE qInfo;
     448    ULONG ulLen = sizeof(qInfo);
     449    ULONG rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
     450                                IOCTL_ASYNC,
     451                                ASYNC_GETINQUECOUNT,
     452                                0,0,0,
     453                                &qInfo,ulLen,&ulLen);
     454    dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc));
     455
     456    ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
     457                       &ulBytesRead);
     458
     459    if(lpNumberOfBytesRead) {
     460        *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
     461        dprintf2(("KERNEL32:HMDeviceCommClass::ReadFile %d bytes read", *lpNumberOfBytesRead));
     462    }
     463    if(ret == FALSE) {
     464        dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError()));
     465    }
     466    else {
     467        //testestestest
     468        dprintf2(("%d Bytes read:", ulBytesRead));
     469        for(int i=0;i<ulBytesRead;i++) {
     470            dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
     471        }
     472        //testestestset
     473    }
     474    return ret;
     475}
    426476/*****************************************************************************
    427477 * Name      : DWORD HMDeviceHandler::SetupComm
     
    439489                                   DWORD dwOutQueue)
    440490{
    441   dprintf(("HMDeviceCommClass::SetupComm "));
    442   PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    443   if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
    444   {
    445       ::SetLastError(ERROR_INVALID_HANDLE);
    446       return FALSE;
    447   }
    448   pDevData->dwInBuffer  = dwInQueue;
    449   pDevData->dwOutBuffer = dwOutQueue;
    450 
    451   return(TRUE);
    452 }
    453 //******************************************************************************
    454 #define TIMEOUT_COMM 50
     491    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     492
     493    dprintf(("HMDeviceCommClass::SetupComm "));
     494    if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
     495    {
     496        ::SetLastError(ERROR_INVALID_HANDLE);
     497        return FALSE;
     498    }
     499    pDevData->dwInBuffer  = dwInQueue;
     500    pDevData->dwOutBuffer = dwOutQueue;
     501
     502    return(TRUE);
     503}
     504//******************************************************************************
    455505//******************************************************************************
    456506BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
     
    458508                                       LPOVERLAPPED lpo)
    459509{
    460   APIRET rc;
    461   ULONG ulLen;
    462   USHORT COMEvt;
    463   DWORD dwEvent,dwMask;
    464 
    465   PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    466 
    467   dprintf(("HMDeviceCommClass::WaitCommEvent %x %x %x", pHMHandleData->hHMHandle, lpfdwEvtMask, lpo));
    468 
    469   if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) {
    470       dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo"));
    471       ::SetLastError(ERROR_INVALID_PARAMETER);
    472       return FALSE;
    473   }
    474 
    475   ulLen = sizeof(CHAR);
    476 
    477   dwEvent = 0;
    478   rc = 0;
    479   ulLen = sizeof(COMEvt);
    480   dwMask = pDevData->dwEventMask;
    481   while( (0==rc) &&
    482         !(dwEvent & dwMask) &&
    483         (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
    484   {
    485     rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
    486                           IOCTL_ASYNC,
    487                           ASYNC_GETCOMMEVENT,
    488                           0,0,0,
    489                           &COMEvt,ulLen,&ulLen);
    490     if(!rc)
     510    APIRET rc;
     511    ULONG ulLen;
     512    USHORT COMEvt;
     513    DWORD dwEvent,dwMask;
     514
     515    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     516
     517    dprintf(("HMDeviceCommClass::WaitCommEvent %x %x %x", pHMHandleData->hHMHandle, lpfdwEvtMask, lpo));
     518
     519    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) {
     520        dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo"));
     521        ::SetLastError(ERROR_INVALID_PARAMETER);
     522        return FALSE;
     523    }
     524
     525    ulLen = sizeof(CHAR);
     526
     527    dwEvent = 0;
     528    rc = 0;
     529    ulLen = sizeof(COMEvt);
     530    dwMask = pDevData->dwEventMask;
     531    while( (0==rc) &&
     532           !(dwEvent & dwMask) &&
     533           (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
    491534    {
    492         dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
    493         //dwEvent |= (COMEvt&0x0002)? 0:0;
    494         dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
    495         dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
    496         dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
    497         //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
    498         dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
    499         dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
    500         dwEvent |= (COMEvt&0x0100)? EV_RING:0;
    501         if((dwEvent & dwMask)) break;
    502     }
    503     else break;
    504 
    505     if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
    506     {
    507         memcpy(&pDevData->overlapped, lpo, sizeof(pDevData->overlapped));
    508         pDevData->overlapped.Internal     = 0;
    509         pDevData->overlapped.InternalHigh = 0;
    510         pDevData->overlapped.Offset       = 0;
    511         pDevData->overlapped.OffsetHigh   = 0;
    512         //We're also supposed to write the result to the address supplied
    513         //by this call
    514         pDevData->lpfdwEvtMask            = lpfdwEvtMask;
    515         //Set app event semaphore to non-signalled state
    516         ::ResetEvent(lpo->hEvent);
    517 
    518         ::SetLastError(ERROR_IO_PENDING);
    519         return FALSE;
    520     }
    521     DosSleep(TIMEOUT_COMM);
    522   }
    523   if(dwMask == pDevData->dwEventMask) {
    524        *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0;
    525        dprintf(("WaitCommEvent returned %x", *lpfdwEvtMask));
    526   }
    527   else  *lpfdwEvtMask = 0;
    528 
    529   ::SetLastError(rc);
    530   return (rc==0);
     535        rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
     536                              IOCTL_ASYNC,
     537                              ASYNC_GETCOMMEVENT,
     538                              0,0,0,
     539                              &COMEvt,ulLen,&ulLen);
     540        if(!rc)
     541        {
     542            dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
     543            //dwEvent |= (COMEvt&0x0002)? 0:0;
     544            dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
     545            dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
     546            dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
     547            //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
     548            dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
     549            dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
     550            dwEvent |= (COMEvt&0x0100)? EV_RING:0;
     551            if((dwEvent & dwMask)) break;
     552        }
     553        else break;
     554
     555        if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
     556        {
     557            return pDevData->iohandler->WaitForEvent(pHMHandleData->hWin32Handle, lpfdwEvtMask,
     558                                                     lpo, NULL, (DWORD)pDevData);
     559        }
     560        DosSleep(TIMEOUT_COMM);
     561    }
     562    if(dwMask == pDevData->dwEventMask) {
     563        *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0;
     564        dprintf(("WaitCommEvent returned %x", *lpfdwEvtMask));
     565    }
     566    else  *lpfdwEvtMask = 0;
     567
     568    ::SetLastError(rc);
     569    return (rc==0);
    531570}
    532571/*****************************************************************************
     
    550589    }
    551590
    552     //signal serial thread to cancel pending IO operation
    553     pDevData->fCancelIo = TRUE;
    554 //    ::SetEvent(pDevData->hEventSem);
    555 
    556     ::SetLastError(ERROR_SUCCESS);
    557     return(TRUE);
     591    return pDevData->iohandler->CancelIo(pHMHandleData->hWin32Handle);
    558592}
    559593/*****************************************************************************
     
    572606 *****************************************************************************/
    573607BOOL HMDeviceCommClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
    574                                             LPOVERLAPPED  lpoOverlapped,
     608                                            LPOVERLAPPED  lpOverlapped,
    575609                                            LPDWORD       lpcbTransfer,
    576610                                            BOOL          fWait)
     
    578612  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    579613
    580   dprintf(("KERNEL32-WARNING: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) partly implemented",
    581             pHMHandleData->hHMHandle,
    582             lpoOverlapped,
    583             lpcbTransfer,
    584             fWait));
    585 
    586   if(pDevData == NULL || !(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
    587       ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
    588       return FALSE;
    589   }
    590   if(!lpoOverlapped) {
    591       ::SetLastError(ERROR_INVALID_PARAMETER);
    592       return FALSE;
    593   }
    594   if(lpoOverlapped->hEvent != pDevData->overlapped.hEvent) {
    595       dprintf(("!WARNING!: GetOverlappedResult called for unknown operation"));
    596       ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
    597       return FALSE;
    598   }
    599   if(pDevData->overlapped.Internal) {
    600       lpoOverlapped->Internal       = pDevData->overlapped.Internal;
    601       pDevData->overlapped.Internal = 0; //not entirely safe
    602       pDevData->dwLastError         = 0;
    603       ::SetLastError(pDevData->dwLastError);
    604       return lpoOverlapped->Internal;
    605   }
    606   if(fWait) {
    607       ::WaitForSingleObject(pDevData->overlapped.hEvent, INFINITE);
    608       ::ResetEvent(pDevData->overlapped.hEvent);
    609       lpoOverlapped->Internal       = pDevData->overlapped.Internal;
    610       pDevData->overlapped.Internal = 0; //not entirely safe
    611       ::SetLastError(ERROR_SUCCESS);
    612       return lpoOverlapped->Internal;
    613   }
    614   else {
    615       ::SetLastError(ERROR_IO_PENDING);
    616       return FALSE;
    617   }
    618 }
    619 //******************************************************************************
    620 //******************************************************************************
    621 BOOL HMDeviceCommClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
    622                                            LPCOMMPROP lpcmmp)
     614    dprintf(("KERNEL32-WARNING: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) partly implemented",
     615             pHMHandleData->hHMHandle, lpOverlapped, lpcbTransfer, fWait));
     616
     617    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
     618        dprintf(("!WARNING!: GetOverlappedResult called for a handle that wasn't opened with FILE_FLAG_OVERLAPPED"));
     619        return TRUE; //NT4, SP6 doesn't fail
     620    }
     621
     622    if(pDevData == NULL) {
     623        ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
     624        return FALSE;
     625    }
     626    if(!lpOverlapped) {
     627        ::SetLastError(ERROR_INVALID_PARAMETER);
     628        return FALSE;
     629    }
     630    return pDevData->iohandler->GetOverlappedResult(pHMHandleData->hWin32Handle, lpOverlapped, lpcbTransfer, fWait);
     631}
     632//******************************************************************************
     633//******************************************************************************
     634BOOL HMDeviceCommClass::GetCommProperties(PHMHANDLEDATA pHMHandleData,
     635                                          LPCOMMPROP lpcmmp)
    623636{
    624637  EXTBAUDGET BaudInfo;
     
    719732  }
    720733  if(rc) {
    721       dprintf(("!WARNING! OSLibDosDevIOCtl failed with rc %d", rc)); 
     734      dprintf(("!WARNING! OSLibDosDevIOCtl failed with rc %d", rc));
    722735  }
    723736  return (rc == ERROR_SUCCESS);
     
    980993  }
    981994  if( (0==pDevData->CommTOuts.WriteTotalTimeoutMultiplier) &&
    982       (0==pDevData->CommTOuts.WriteTotalTimeoutConstant)) 
     995      (0==pDevData->CommTOuts.WriteTotalTimeoutConstant))
    983996  {//no timeout used for writing
    984997    os2dcb.fbTimeOut |= 1; //write infinite timeout
     
    14231436//******************************************************************************
    14241437//******************************************************************************
    1425 
    1426 
     1438void HMDeviceCommClass::CloseOverlappedIOHandlers()
     1439{
     1440    for(int i=0;i<MAX_COMPORTS;i++) {
     1441        if(handler[i]) {
     1442            delete handler[i];
     1443            handler[i] = NULL;
     1444        }
     1445    }
     1446}
     1447//******************************************************************************
     1448//******************************************************************************
     1449OverlappedIOHandler *HMDeviceCommClass::handler[MAX_COMPORTS] = {NULL};
     1450
Note: See TracChangeset for help on using the changeset viewer.