Ignore:
Timestamp:
Nov 26, 2001, 3:54:03 PM (24 years ago)
Author:
sandervl
Message:

preliminary work on overlapped serial comm IO

File:
1 edited

Legend:

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

    r7301 r7457  
    1 /* $Id: hmcomm.cpp,v 1.13 2001-11-08 15:38:42 phaller Exp $ */
     1/* $Id: hmcomm.cpp,v 1.14 2001-11-26 14:53:59 sandervl Exp $ */
    22
    33/*
     
    77 *
    88 * 1999 Achim Hasenmueller <achimha@innotek.de>
     9 * 2001 Sander van Leeuwen <sandervl@xs4all.nl>
     10 *
     11 * TODO: Overlapped IO only supports one request at a time
    912 *
    1013 */
     
    2326#include "dbglocal.h"
    2427
    25 #define MAGIC_COM 0x12abcd34
    26 
    27 #define IOCTL_ASYNC          0x01
    28 #define ASYNC_GETDCBINFO     0x73
    29 #define ASYNC_SETDCBINFO     0x53
    30 #define ASYNC_SETLINECTRL    0x42
    31 #define ASYNC_GETCOMMEVENT   0x72
    32 #define ASYNC_EXTGETBAUDRATE 0x63
    33 #define ASYNC_EXTSETBAUDRATE 0x43
    34 #define ASYNC_GETCOMMERROR   0x6D
    35 #define ASYNC_GETCOMMSTATUS  0x65
    36 #define ASYNC_GETINQUECOUNT  0x68
    37 #define ASYNC_GETOUTQUECOUNT 0x69
    38 #define ASYNC_GETMODEMINPUT  0x67
    39 #define ASYNC_TRANSMITIMM    0x44
    40 #define ASYNC_SETBREAKON     0x4B
    41 #define ASYNC_SETBREAKOFF    0x45
    42 #define ASYNC_SETMODEMCTRL   0x46
    43 #define ASYNC_STARTTRANSMIT  0x48
    44 #define ASYNC_STOPTRANSMIT   0x47
    45 #define ASYNC_GETMODEMOUTPUT 0x66
    46 
    47 
    48 #pragma pack(1)
    49 typedef struct _DCBINFO
    50 {
    51   USHORT   usWriteTimeout;         /*  Time period used for Write Timeout processing. */
    52   USHORT   usReadTimeout;          /*  Time period used for Read Timeout processing. */
    53   BYTE     fbCtlHndShake;          /*  HandShake Control flag. */
    54   BYTE     fbFlowReplace;          /*  Flow Control flag. */
    55   BYTE     fbTimeOut;              /*  Timeout flag. */
    56   BYTE     bErrorReplacementChar;  /*  Error Replacement Character. */
    57   BYTE     bBreakReplacementChar;  /*  Break Replacement Character. */
    58   BYTE     bXONChar;               /*  Character XON. */
    59   BYTE     bXOFFChar;              /*  Character XOFF. */
    60 } DCBINFO;
    61 typedef DCBINFO *PDCBINFO;
    62 
    63 
    64 typedef struct _RXQUEUE
    65 {
    66   USHORT   cch;  /*  Number of characters in the queue. */
    67   USHORT   cb;   /*  Size of receive/transmit queue. */
    68 } RXQUEUE;
    69 
    70 typedef RXQUEUE *PRXQUEUE;
    71 
    72 
    73 typedef struct _MODEMSTATUS
    74 {
    75   BYTE   fbModemOn;   /*  Modem Control Signals ON Mask. */
    76   BYTE   fbModemOff;  /*  Modem Control Signals OFF Mask. */
    77 } MODEMSTATUS;
    78 
    79 typedef MODEMSTATUS *PMODEMSTATUS;
    80 
    81 
    82 #pragma pack()
    83 
    84 
    85 
    86 
    87 
    88 typedef struct _HMDEVCOMDATA
    89 {
    90   ULONG ulMagic;
    91   // Win32 Device Control Block
    92   COMMCONFIG   CommCfg;
    93   COMMTIMEOUTS CommTOuts;
    94   DWORD dwInBuffer, dwOutBuffer;
    95   DWORD dwEventMask;
    96   //OS/2 Device Control Block
    97   DCBINFO dcbOS2;
    98 } HMDEVCOMDATA, *PHMDEVCOMDATA;
    99 
     28
     29BAUDTABLEENTRY BaudTable[] =
     30{
     31  {75,BAUD_075},
     32  {110,BAUD_110},
     33  {134,BAUD_134_5},
     34  {150,BAUD_150},
     35  {300,BAUD_300},
     36  {600,BAUD_600},
     37  {1200,BAUD_1200},
     38  {1800,BAUD_1800},
     39  {2400,BAUD_2400},
     40  {4800,BAUD_4800},
     41  {7200,BAUD_7200},
     42  {9600,BAUD_9600},
     43  {14400,BAUD_14400},
     44  {19200,BAUD_19200},
     45  {38400,BAUD_38400},
     46  {56000,BAUD_56K},
     47  {57600,BAUD_57600},
     48  {115200,BAUD_115200},
     49  {128000,BAUD_128K}
     50};
     51
     52#define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
     53
     54DWORD CALLBACK SerialCommThread(LPVOID lpThreadParam);
     55
     56//******************************************************************************
     57//******************************************************************************
    10058static VOID *CreateDevData()
    10159{
     
    11977  return pData;
    12078}
    121 
     79//******************************************************************************
     80//******************************************************************************
    12281HMDeviceCommClass::HMDeviceCommClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
    12382{
     
    168127    return FALSE;
    169128}
    170 
    171 DWORD HMDeviceCommClass::CreateFile(LPCSTR lpFileName,
     129//******************************************************************************
     130//******************************************************************************
     131DWORD HMDeviceCommClass::CreateFile(HANDLE hComm,
     132                                    LPCSTR lpFileName,
    172133                                    PHMHANDLEDATA pHMHandleData,
    173134                                    PVOID lpSecurityAttributes,
     
    179140
    180141  if(strlen(lpFileName) > 5) {
    181     return -1;  //safety check (unnecessary..)
     142    return ERROR_INVALID_PARAMETER;  //safety check (unnecessary..)
    182143  }
    183144  pHMHandleData->hHMHandle = 0;
     
    233194    if(rc)
    234195    {
    235       return -1;
     196      delete pHMHandleData->lpHandlerData;
     197      return rc;
    236198    }
    237199    rc = SetBaud(pHMHandleData,9600);
     
    239201    rc = SetLine(pHMHandleData,8,0,0);
    240202    dprintf(("Set Line to 8/N/1 rc = %d",rc));
    241     return 0;
     203
     204    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
     205    {
     206        PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     207        DWORD         dwThreadId;
     208
     209        pDevData->hEventSem = ::CreateEventA(NULL, TRUE, FALSE, NULL);
     210        pDevData->hThread   = ::CreateThread(NULL, 32*1024, SerialCommThread, (LPVOID)hComm, 0, &dwThreadId);
     211
     212        if(!pDevData->hEventSem || !pDevData->hThread)
     213        {
     214            DebugInt3();
     215            if(pDevData->hEventSem) ::CloseHandle(pDevData->hEventSem);
     216            delete pHMHandleData->lpHandlerData;
     217            return ERROR_NOT_ENOUGH_MEMORY;
     218        }
     219    }
     220    return ERROR_SUCCESS;
    242221  }
    243222  else
    244     return  -1;
    245 }
    246 
    247 
    248                       /* this is a handler method for calls to CloseHandle() */
     223    return ERROR_ACCESS_DENIED;
     224}
     225//******************************************************************************
     226//******************************************************************************
    249227BOOL HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
    250228{
    251   dprintf(("HMComm: Serial communication port close request\n"));
     229  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     230  dprintf(("HMComm: Serial communication port close request"));
     231
     232  if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
     233  {
     234      pDevData->fClosing = TRUE;
     235      dprintf(("signalling serial thread"));
     236      ::SetEvent(pDevData->hEventSem);
     237      ::ResetEvent(pDevData->hEventSem);
     238
     239      //Wait for thread to clean up
     240      dprintf(("waiting for serial thread"));
     241      DWORD ret = ::WaitForSingleObject(pDevData->hEventSem, 200);
     242      dprintf(("waiting for serial thread done -> %x", ret));
     243      ::CloseHandle(pDevData->hEventSem);
     244  }
    252245  delete pHMHandleData->lpHandlerData;
    253246  return OSLibDosClose(pHMHandleData->hHMHandle);
    254247}
    255 
     248/*****************************************************************************
     249 * Name      : BOOL HMDeviceCommClass::WriteFile
     250 * Purpose   : write data to handle / device
     251 * Parameters: PHMHANDLEDATA pHMHandleData,
     252 *             LPCVOID       lpBuffer,
     253 *             DWORD         nNumberOfBytesToWrite,
     254 *             LPDWORD       lpNumberOfBytesWritten,
     255 *             LPOVERLAPPED  lpOverlapped
     256 * Variables :
     257 * Result    : Boolean
     258 * Remark    :
     259 * Status    :
     260 *
     261 * Author    : SvL
     262 *****************************************************************************/
     263BOOL HMDeviceCommClass::WriteFile(PHMHANDLEDATA pHMHandleData,
     264                                  LPCVOID       lpBuffer,
     265                                  DWORD         nNumberOfBytesToWrite,
     266                                  LPDWORD       lpNumberOfBytesWritten,
     267                                  LPOVERLAPPED  lpOverlapped)
     268{
     269  dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
     270           lpHMDeviceName,
     271           pHMHandleData->hHMHandle,
     272           lpBuffer,
     273           nNumberOfBytesToWrite,
     274           lpNumberOfBytesWritten,
     275           lpOverlapped));
     276
     277  BOOL  ret;
     278  ULONG ulBytesWritten;
     279
     280  if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
     281    dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
     282    SetLastError(ERROR_INVALID_PARAMETER);
     283    return FALSE;
     284  }
     285  if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
     286    dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
     287  }
     288
     289  ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
     290                      &ulBytesWritten);
     291
     292  if(lpNumberOfBytesWritten) {
     293       *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
     294  }
     295  if(ret == FALSE) {
     296       dprintf(("!ERROR!: WriteFile failed with rc %d", GetLastError()));
     297  }
     298
     299  return ret;
     300}
     301/*****************************************************************************
     302 * Name      : BOOL WriteFileEx
     303 * Purpose   : The WriteFileEx function writes data to a file. It is designed
     304 *             solely for asynchronous operation, unlike WriteFile, which is
     305 *             designed for both synchronous and asynchronous operation.
     306 *             WriteFileEx reports its completion status asynchronously,
     307 *             calling a specified completion routine when writing is completed
     308 *             and the calling thread is in an alertable wait state.
     309 * Parameters: HANDLE       hFile                handle of file to write
     310 *             LPVOID       lpBuffer             address of buffer
     311 *             DWORD        nNumberOfBytesToRead number of bytes to write
     312 *             LPOVERLAPPED lpOverlapped         address of offset
     313 *             LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
     314 * Variables :
     315 * Result    : TRUE / FALSE
     316 * Remark    :
     317 * Status    : UNTESTED STUB
     318 *
     319 * Author    : SvL
     320 *****************************************************************************/
     321
     322BOOL HMDeviceCommClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
     323                           LPVOID       lpBuffer,
     324                           DWORD        nNumberOfBytesToWrite,
     325                           LPOVERLAPPED lpOverlapped,
     326                           LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
     327{
     328  dprintf(("!ERROR!: WriteFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
     329           lpHMDeviceName,
     330           pHMHandleData->hHMHandle,
     331           lpBuffer,
     332           nNumberOfBytesToWrite,
     333           lpOverlapped,
     334           lpCompletionRoutine));
     335
     336  if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
     337      dprintf(("!WARNING!: Handle not created with FILE_FLAG_OVERLAPPED!"));
     338      SetLastError(ERROR_ACCESS_DENIED); //todo: right error?
     339      return FALSE;
     340  }
     341
     342  SetLastError(ERROR_INVALID_FUNCTION);
     343  return FALSE;
     344}
     345/*****************************************************************************
     346 * Name      : BOOL HMDeviceCommClass::ReadFile
     347 * Purpose   : read data from handle / device
     348 * Parameters: PHMHANDLEDATA pHMHandleData,
     349 *             LPCVOID       lpBuffer,
     350 *             DWORD         nNumberOfBytesToRead,
     351 *             LPDWORD       lpNumberOfBytesRead,
     352 *             LPOVERLAPPED  lpOverlapped
     353 * Variables :
     354 * Result    : Boolean
     355 * Remark    :
     356 * Status    :
     357 *
     358 * Author    : SvL
     359 *****************************************************************************/
     360
     361BOOL HMDeviceCommClass::ReadFile(PHMHANDLEDATA pHMHandleData,
     362                                 LPCVOID       lpBuffer,
     363                                 DWORD         nNumberOfBytesToRead,
     364                                 LPDWORD       lpNumberOfBytesRead,
     365                                 LPOVERLAPPED  lpOverlapped)
     366{
     367  dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
     368           lpHMDeviceName,
     369           pHMHandleData->hHMHandle,
     370           lpBuffer,
     371           nNumberOfBytesToRead,
     372           lpNumberOfBytesRead,
     373           lpOverlapped));
     374
     375  BOOL  ret;
     376  ULONG ulBytesRead;
     377
     378  if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
     379    dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
     380    SetLastError(ERROR_INVALID_PARAMETER);
     381    return FALSE;
     382  }
     383  if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
     384    dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
     385  }
     386
     387  ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
     388                     &ulBytesRead);
     389
     390  if(lpNumberOfBytesRead) {
     391       *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
     392  }
     393  if(ret == FALSE) {
     394       dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError()));
     395  }
     396  return ret;
     397}
     398
     399/*****************************************************************************
     400 * Name      : BOOL ReadFileEx
     401 * Purpose   : The ReadFileEx function reads data from a file asynchronously.
     402 *             It is designed solely for asynchronous operation, unlike the
     403 *             ReadFile function, which is designed for both synchronous and
     404 *             asynchronous operation. ReadFileEx lets an application perform
     405 *             other processing during a file read operation.
     406 *             The ReadFileEx function reports its completion status asynchronously,
     407 *             calling a specified completion routine when reading is completed
     408 *             and the calling thread is in an alertable wait state.
     409 * Parameters: HANDLE       hFile                handle of file to read
     410 *             LPVOID       lpBuffer             address of buffer
     411 *             DWORD        nNumberOfBytesToRead number of bytes to read
     412 *             LPOVERLAPPED lpOverlapped         address of offset
     413 *             LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
     414 * Variables :
     415 * Result    : TRUE / FALSE
     416 * Remark    :
     417 * Status    : UNTESTED STUB
     418 *
     419 * Author    : SvL
     420 *****************************************************************************/
     421BOOL HMDeviceCommClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
     422                                   LPVOID       lpBuffer,
     423                                   DWORD        nNumberOfBytesToRead,
     424                                   LPOVERLAPPED lpOverlapped,
     425                                   LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
     426{
     427  dprintf(("!ERROR!: ReadFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
     428           lpHMDeviceName,
     429           pHMHandleData->hHMHandle,
     430           lpBuffer,
     431           nNumberOfBytesToRead,
     432           lpOverlapped,
     433           lpCompletionRoutine));
     434
     435  if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
     436      dprintf(("!WARNING!: Handle not created with FILE_FLAG_OVERLAPPED!"));
     437      SetLastError(ERROR_ACCESS_DENIED); //todo: right error?
     438      return FALSE;
     439  }
     440
     441  SetLastError(ERROR_INVALID_FUNCTION);
     442  return FALSE;
     443}
    256444/*****************************************************************************
    257445 * Name      : DWORD HMDeviceHandler::SetupComm
     
    273461  if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
    274462  {
    275     SetLastError(ERROR_INVALID_HANDLE);
    276     return FALSE;
     463      SetLastError(ERROR_INVALID_HANDLE);
     464      return FALSE;
    277465  }
    278466  pDevData->dwInBuffer  = dwInQueue;
     
    281469  return(TRUE);
    282470}
    283 
     471//******************************************************************************
     472#define TIMEOUT_COMM  50
     473//******************************************************************************
     474DWORD CALLBACK SerialCommThread(LPVOID lpThreadParam)
     475{
     476  HANDLE        hComm = (HANDLE)lpThreadParam;
     477  PHMHANDLEDATA pHMHandleData;
     478  PHMDEVCOMDATA pDevData;
     479  DWORD         ret;
     480  APIRET        rc;
     481  ULONG         ulLen;
     482  USHORT        COMEvt;
     483  DWORD         dwEvent,dwMask;
     484
     485  dprintf(("SerialCommThread %x entered", hComm));
     486  pHMHandleData = HMQueryHandleData(hComm);
     487  if(!pHMHandleData) {
     488      dprintf(("!ERROR!: Invalid handle -> aborting"));
     489      return 0;
     490  }
     491
     492  pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     493  if(!pDevData) {
     494      DebugInt3();
     495      return 0;
     496  }
     497  HANDLE hEvent   = pDevData->hEventSem;
     498  HANDLE hCommOS2 = pHMHandleData->hHMHandle;
     499  if(!hCommOS2 || !hEvent) {
     500      DebugInt3();
     501      return 0;
     502  }
     503
     504  while(TRUE)
     505  {
     506      //validate handle
     507      pHMHandleData = HMQueryHandleData(hComm);
     508      if(!pHMHandleData) {
     509          dprintf(("!ERROR!: Invalid handle -> aborting"));
     510          return 0;
     511      }
     512      if(pDevData->fClosing) {
     513          dprintf(("Cleaning up async comm thread"));
     514          SetEvent(hEvent); //signal to CloseHandle that we're done
     515          return 0;
     516      }
     517
     518      //Wait for the app to call WaitCommEvent
     519      dprintf(("SerialCommThread: wait for WaitCommEvent"));
     520      ret = WaitForSingleObject(hEvent, INFINITE);
     521      ResetEvent(hEvent);
     522      dprintf(("SerialCommThread: wait for WaitCommEvent done %x", ret));
     523
     524      //validate handle first
     525      pHMHandleData = HMQueryHandleData(hComm);
     526      if(!pHMHandleData) {
     527          dprintf(("!ERROR!: Invalid handle -> aborting"));
     528          return 0;
     529      }
     530
     531      if(pDevData->fClosing) {
     532          dprintf(("Cleaning up async comm thread"));
     533          SetEvent(hEvent); //signal to CloseHandle that we're done
     534          return 0;
     535      }
     536
     537      HANDLE hOverlappedEvent = pDevData->overlapped.hEvent;
     538      if(!hOverlappedEvent) {
     539          DebugInt3();
     540          return 0;
     541      }
     542
     543      ulLen   = sizeof(CHAR);
     544      dwEvent = 0;
     545      rc      = 0;
     546      ulLen   = sizeof(COMEvt);
     547      dwMask  = pDevData->dwEventMask;
     548
     549      while( (0==rc) &&
     550            !(dwEvent & dwMask) &&
     551            (dwMask == pDevData->dwEventMask) &&
     552            !(pDevData->fCancelIo) && !(pDevData->fClosing) ) // Exit if the Mask gets changed
     553      {
     554          rc = OSLibDosDevIOCtl(hCommOS2,
     555                                IOCTL_ASYNC,
     556                                ASYNC_GETCOMMEVENT,
     557                                0,0,0,
     558                                &COMEvt,ulLen,&ulLen);
     559          if(!rc)
     560          {
     561              dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
     562              //dwEvent |= (COMEvt&0x0002)? 0:0;
     563              dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
     564              dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
     565              dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
     566              //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
     567              dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
     568              dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
     569              dwEvent |= (COMEvt&0x0100)? EV_RING:0;
     570              if((dwEvent & dwMask)) break;
     571          }
     572          else break;
     573
     574          DosSleep(TIMEOUT_COMM);
     575      }
     576      if((dwEvent & dwMask) && (dwMask == pDevData->dwEventMask)) {
     577          pDevData->overlapped.Internal |= (rc==0) ? (dwEvent & dwMask) : 0;
     578          pDevData->dwLastError = rc;
     579          dprintf(("Overlapped: WaitCommEvent returned %x", pDevData->overlapped.Internal));
     580
     581          //signal to app that a comm event has occurred
     582          SetEvent(hOverlappedEvent);
     583      }
     584  }
     585  return 0;
     586}
     587//******************************************************************************
     588//******************************************************************************
    284589BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
    285590                                       LPDWORD lpfdwEvtMask,
     
    293598  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    294599
    295   dprintf(("HMDeviceCommClass::WaitCommEvent"));
     600  dprintf2(("HMDeviceCommClass::WaitCommEvent %x", pHMHandleData->hHMHandle));
     601
     602  if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) {
     603      dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo"));
     604      SetLastError(ERROR_INVALID_PARAMETER);
     605      return FALSE;
     606  }
     607
    296608  ulLen = sizeof(CHAR);
    297609
     
    304616        (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
    305617  {
    306     rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
    307                       IOCTL_ASYNC,
    308                       ASYNC_GETCOMMEVENT,
    309                       0,0,0,
    310                       &COMEvt,ulLen,&ulLen);
     618    rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
     619                          IOCTL_ASYNC,
     620                          ASYNC_GETCOMMEVENT,
     621                          0,0,0,
     622                          &COMEvt,ulLen,&ulLen);
    311623    if(!rc)
    312624    {
    313       dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
    314       //dwEvent |= (COMEvt&0x0002)? 0:0;
    315       dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
    316       dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
    317       dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
    318       //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
    319       dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
    320       dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
    321       dwEvent |= (COMEvt&0x0100)? EV_RING:0;
     625        dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
     626        //dwEvent |= (COMEvt&0x0002)? 0:0;
     627        dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
     628        dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
     629        dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
     630        //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
     631        dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
     632        dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
     633        dwEvent |= (COMEvt&0x0100)? EV_RING:0;
     634        if((dwEvent & dwMask)) break;
    322635    }
    323     DosSleep(100);
    324   }
    325   *lpfdwEvtMask = rc==0?dwEvent:0;
    326   return(rc==0);
    327 }
    328 
    329 
    330 #pragma pack(1)
    331 typedef struct
    332 {
    333   ULONG ulCurrBaud;
    334   UCHAR ucCurrFrac;
    335   ULONG ulMinBaud;
    336   UCHAR ucMinFrac;
    337   ULONG ulMaxBaud;
    338   UCHAR ucMaxFrac;
    339 } EXTBAUDGET, *PEXTBAUDGET;
    340 
    341 typedef struct
    342 {
    343   ULONG ulBaud;
    344   UCHAR ucFrac;
    345 } EXTBAUDSET, *PEXTBAUDSET;
    346 #pragma pack()
    347 
    348 BAUDTABLEENTRY BaudTable[] =
    349 {
    350   {75,BAUD_075},
    351   {110,BAUD_110},
    352   {134,BAUD_134_5},
    353   {150,BAUD_150},
    354   {300,BAUD_300},
    355   {600,BAUD_600},
    356   {1200,BAUD_1200},
    357   {1800,BAUD_1800},
    358   {2400,BAUD_2400},
    359   {4800,BAUD_4800},
    360   {7200,BAUD_7200},
    361   {9600,BAUD_9600},
    362   {14400,BAUD_14400},
    363   {19200,BAUD_19200},
    364   {38400,BAUD_38400},
    365   {56000,BAUD_56K},
    366   {57600,BAUD_57600},
    367   {115200,BAUD_115200},
    368   {128000,BAUD_128K}
    369 };
    370 
    371 #define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
    372 
     636    else break;
     637
     638    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
     639    {
     640        memcpy(&pDevData->overlapped, lpo, sizeof(pDevData->overlapped));
     641        pDevData->overlapped.Internal     = 0;
     642        pDevData->overlapped.InternalHigh = 0;
     643        pDevData->overlapped.Offset       = 0;
     644        pDevData->overlapped.OffsetHigh   = 0;
     645        //signal async comm thread to start polling comm status
     646        ::SetEvent(pDevData->hEventSem);
     647        SetLastError(ERROR_IO_PENDING);
     648        return FALSE;
     649    }
     650    DosSleep(TIMEOUT_COMM);
     651  }
     652  if(dwMask == pDevData->dwEventMask) {
     653       *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0;
     654       dprintf(("WaitCommEvent returned %x", *lpfdwEvtMask));
     655  }
     656  else  *lpfdwEvtMask = 0;
     657
     658  return (rc==0);
     659}
     660/*****************************************************************************
     661 * Name      : DWORD HMDeviceCommClass::CancelIo
     662 * Purpose   : cancel pending IO operation
     663 * Variables :
     664 * Result    :
     665 * Remark    :
     666 * Status    :
     667 *
     668 * Author    : SvL
     669 *****************************************************************************/
     670BOOL HMDeviceCommClass::CancelIo(PHMHANDLEDATA pHMHandleData)
     671{
     672    PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     673
     674    dprintf(("HMDeviceCommClass::CancelIo"));
     675    if(pDevData == NULL || !(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
     676        SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
     677        return FALSE;
     678    }
     679
     680    //signal serial thread to cancel pending IO operation
     681    pDevData->fCancelIo = TRUE;
     682    ::SetEvent(pDevData->hEventSem);
     683
     684    SetLastError(ERROR_SUCCESS);
     685    return(TRUE);
     686}
     687/*****************************************************************************
     688 * Name      : DWORD HMDeviceFileClass::GetOverlappedResult
     689 * Purpose   : asynchronus I/O
     690 * Parameters: PHMHANDLEDATA pHMHandleData
     691 *             LPOVERLAPPED  arg2
     692 *             LPDWORD       arg3
     693 *             BOOL          arg4
     694 * Variables :
     695 * Result    : API returncode
     696 * Remark    :
     697 * Status    :
     698 *
     699 * Author    : SvL
     700 *****************************************************************************/
     701BOOL HMDeviceCommClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
     702                                            LPOVERLAPPED  lpoOverlapped,
     703                                            LPDWORD       lpcbTransfer,
     704                                            BOOL          fWait)
     705{
     706  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
     707
     708  dprintf(("KERNEL32-WARNING: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) STUB!!",
     709            pHMHandleData->hHMHandle,
     710            lpoOverlapped,
     711            lpcbTransfer,
     712            fWait));
     713
     714  if(pDevData == NULL || !(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
     715      SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
     716      return FALSE;
     717  }
     718  if(!lpoOverlapped) {
     719      SetLastError(ERROR_INVALID_PARAMETER);
     720      return FALSE;
     721  }
     722  if(lpoOverlapped->hEvent != pDevData->overlapped.hEvent) {
     723      dprintf(("!WARNING!: GetOverlappedResult called for unknown operation"));
     724      SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
     725      return FALSE;
     726  }
     727  if(pDevData->overlapped.Internal) {
     728      lpoOverlapped->Internal       = pDevData->overlapped.Internal;
     729      pDevData->overlapped.Internal = 0; //not entirely safe
     730      pDevData->dwLastError         = 0;
     731      SetLastError(pDevData->dwLastError);
     732      return lpoOverlapped->Internal;
     733  }
     734  if(fWait) {
     735      ::WaitForSingleObject(pDevData->overlapped.hEvent, INFINITE);
     736      ::ResetEvent(pDevData->overlapped.hEvent);
     737      lpoOverlapped->Internal       = pDevData->overlapped.Internal;
     738      pDevData->overlapped.Internal = 0; //not entirely safe
     739      SetLastError(ERROR_SUCCESS);
     740      return lpoOverlapped->Internal;
     741  }
     742  else {
     743      SetLastError(ERROR_IO_PENDING);
     744      return FALSE;
     745  }
     746}
     747//******************************************************************************
     748//******************************************************************************
    373749BOOL HMDeviceCommClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
    374750                                           LPCOMMPROP lpcmmp)
     
    414790  return(rc==0);
    415791}
    416 
     792//******************************************************************************
     793//******************************************************************************
    417794BOOL HMDeviceCommClass::GetCommMask( PHMHANDLEDATA pHMHandleData,
    418795                                     LPDWORD lpfdwEvtMask)
     
    425802  return(TRUE);
    426803}
    427 
     804//******************************************************************************
     805//******************************************************************************
    428806BOOL HMDeviceCommClass::SetCommMask( PHMHANDLEDATA pHMHandleData,
    429807                                     DWORD fdwEvtMask)
    430808{
    431809  PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    432   dprintf(("HMDeviceCommClass::SetCommMask"));
     810  dprintf(("HMDeviceCommClass::SetCommMask %x", fdwEvtMask));
     811
     812  if(fdwEvtMask & (EV_RLSD|EV_RXFLAG)) {
     813      dprintf(("!WARNING! SetCommMask: unsupported flags EV_RLSD and/or EV_RXFLAG!!"));
     814  }
    433815
    434816  pDevData->dwEventMask = fdwEvtMask & ~(EV_RLSD|EV_RXFLAG); // Clear the 2 not supported Flags.
    435817  return(TRUE);
    436818}
    437 
     819//******************************************************************************
     820//******************************************************************************
    438821BOOL HMDeviceCommClass::PurgeComm( PHMHANDLEDATA pHMHandleData,
    439822                                   DWORD fdwAction)
     
    445828  return(TRUE);
    446829}
     830//******************************************************************************
     831//******************************************************************************
    447832BOOL HMDeviceCommClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
    448833                                        LPDWORD lpdwErrors,
     
    509894  return(rc==0);
    510895}
     896//******************************************************************************
     897//******************************************************************************
    511898BOOL HMDeviceCommClass::SetCommState( PHMHANDLEDATA pHMHandleData,
    512899                                      LPDCB lpDCB)
     
    561948  return(rc==0);
    562949}
     950//******************************************************************************
     951//******************************************************************************
    563952BOOL HMDeviceCommClass::GetCommState( PHMHANDLEDATA pHMHandleData,
    564953                                      LPDCB lpdcb)
     
    571960  return(TRUE);
    572961}
     962//******************************************************************************
     963//******************************************************************************
    573964BOOL HMDeviceCommClass::GetCommModemStatus( PHMHANDLEDATA pHMHandleData,
    574965                                          LPDWORD lpModemStat )
     
    579970  UCHAR ucStatus;
    580971
    581   dprintf(("HMDeviceCommClass::TransmitCommChar partly implemented"));
     972  dprintf(("HMDeviceCommClass::GetCommModemStatus %x", lpModemStat));
    582973  ulLen = sizeof(CHAR);
    583974
     
    600991  return(rc==0);
    601992}
    602 
     993//******************************************************************************
     994//******************************************************************************
    603995BOOL HMDeviceCommClass::GetCommTimeouts( PHMHANDLEDATA pHMHandleData,
    604996                                         LPCOMMTIMEOUTS lpctmo)
     
    6121004  return(TRUE);
    6131005}
     1006//******************************************************************************
     1007//******************************************************************************
    6141008BOOL HMDeviceCommClass::SetCommTimeouts( PHMHANDLEDATA pHMHandleData,
    6151009                                         LPCOMMTIMEOUTS lpctmo)
     
    6901084  return(0==rc);
    6911085}
     1086//******************************************************************************
     1087//******************************************************************************
    6921088BOOL HMDeviceCommClass::TransmitCommChar( PHMHANDLEDATA pHMHandleData,
    6931089                                          CHAR cChar )
     
    7081104  return(rc==0);
    7091105}
    710 
    711 /*****************************************************************************
    712  * Name      : BOOL HMDeviceCommClass::WriteFile
    713  * Purpose   : write data to handle / device
    714  * Parameters: PHMHANDLEDATA pHMHandleData,
    715  *             LPCVOID       lpBuffer,
    716  *             DWORD         nNumberOfBytesToWrite,
    717  *             LPDWORD       lpNumberOfBytesWritten,
    718  *             LPOVERLAPPED  lpOverlapped
    719  * Variables :
    720  * Result    : Boolean
    721  * Remark    :
    722  * Status    :
    723  *
    724  * Author    : SvL
    725  *****************************************************************************/
    726 
    727 BOOL HMDeviceCommClass::WriteFile(PHMHANDLEDATA pHMHandleData,
    728                                   LPCVOID       lpBuffer,
    729                                   DWORD         nNumberOfBytesToWrite,
    730                                   LPDWORD       lpNumberOfBytesWritten,
    731                                   LPOVERLAPPED  lpOverlapped)
    732 {
    733   dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
    734            lpHMDeviceName,
    735            pHMHandleData->hHMHandle,
    736            lpBuffer,
    737            nNumberOfBytesToWrite,
    738            lpNumberOfBytesWritten,
    739            lpOverlapped));
    740 
    741   BOOL  ret;
    742   ULONG ulBytesWritten;
    743 
    744   if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
    745     dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
    746     SetLastError(ERROR_INVALID_PARAMETER);
    747     return FALSE;
    748   }
    749   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
    750     dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
    751   }
    752 
    753   ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
    754                       &ulBytesWritten);
    755 
    756   if(lpNumberOfBytesWritten) {
    757        *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
    758   }
    759   if(ret == FALSE) {
    760        dprintf(("ERROR: WriteFile failed with rc %d", GetLastError()));
    761   }
    762 
    763   return ret;
    764 }
    765 
    766 /*****************************************************************************
    767  * Name      : BOOL WriteFileEx
    768  * Purpose   : The WriteFileEx function writes data to a file. It is designed
    769  *             solely for asynchronous operation, unlike WriteFile, which is
    770  *             designed for both synchronous and asynchronous operation.
    771  *             WriteFileEx reports its completion status asynchronously,
    772  *             calling a specified completion routine when writing is completed
    773  *             and the calling thread is in an alertable wait state.
    774  * Parameters: HANDLE       hFile                handle of file to write
    775  *             LPVOID       lpBuffer             address of buffer
    776  *             DWORD        nNumberOfBytesToRead number of bytes to write
    777  *             LPOVERLAPPED lpOverlapped         address of offset
    778  *             LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
    779  * Variables :
    780  * Result    : TRUE / FALSE
    781  * Remark    :
    782  * Status    : UNTESTED STUB
    783  *
    784  * Author    : Patrick Haller [Mon, 1998/06/15 08:00]
    785  *****************************************************************************/
    786 
    787 BOOL HMDeviceCommClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
    788                            LPVOID       lpBuffer,
    789                            DWORD        nNumberOfBytesToWrite,
    790                            LPOVERLAPPED lpOverlapped,
    791                            LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    792 {
    793   dprintf(("ERROR: WriteFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
    794            lpHMDeviceName,
    795            pHMHandleData->hHMHandle,
    796            lpBuffer,
    797            nNumberOfBytesToWrite,
    798            lpOverlapped,
    799            lpCompletionRoutine));
    800 
    801   SetLastError(ERROR_INVALID_FUNCTION);
    802   return FALSE;
    803 }
    804 
    805 /*****************************************************************************
    806  * Name      : BOOL HMDeviceCommClass::ReadFile
    807  * Purpose   : read data from handle / device
    808  * Parameters: PHMHANDLEDATA pHMHandleData,
    809  *             LPCVOID       lpBuffer,
    810  *             DWORD         nNumberOfBytesToRead,
    811  *             LPDWORD       lpNumberOfBytesRead,
    812  *             LPOVERLAPPED  lpOverlapped
    813  * Variables :
    814  * Result    : Boolean
    815  * Remark    :
    816  * Status    :
    817  *
    818  * Author    : SvL
    819  *****************************************************************************/
    820 
    821 BOOL HMDeviceCommClass::ReadFile(PHMHANDLEDATA pHMHandleData,
    822                                  LPCVOID       lpBuffer,
    823                                  DWORD         nNumberOfBytesToRead,
    824                                  LPDWORD       lpNumberOfBytesRead,
    825                                  LPOVERLAPPED  lpOverlapped)
    826 {
    827   dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
    828            lpHMDeviceName,
    829            pHMHandleData->hHMHandle,
    830            lpBuffer,
    831            nNumberOfBytesToRead,
    832            lpNumberOfBytesRead,
    833            lpOverlapped));
    834 
    835   BOOL  ret;
    836   ULONG ulBytesRead;
    837 
    838   if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
    839     dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
    840     SetLastError(ERROR_INVALID_PARAMETER);
    841     return FALSE;
    842   }
    843   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
    844     dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
    845   }
    846 
    847   ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
    848                      &ulBytesRead);
    849 
    850   if(lpNumberOfBytesRead) {
    851        *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
    852   }
    853   if(ret == FALSE) {
    854        dprintf(("ERROR: ReadFile failed with rc %d", GetLastError()));
    855   }
    856   return ret;
    857 }
    858 
    859 /*****************************************************************************
    860  * Name      : BOOL ReadFileEx
    861  * Purpose   : The ReadFileEx function reads data from a file asynchronously.
    862  *             It is designed solely for asynchronous operation, unlike the
    863  *             ReadFile function, which is designed for both synchronous and
    864  *             asynchronous operation. ReadFileEx lets an application perform
    865  *             other processing during a file read operation.
    866  *             The ReadFileEx function reports its completion status asynchronously,
    867  *             calling a specified completion routine when reading is completed
    868  *             and the calling thread is in an alertable wait state.
    869  * Parameters: HANDLE       hFile                handle of file to read
    870  *             LPVOID       lpBuffer             address of buffer
    871  *             DWORD        nNumberOfBytesToRead number of bytes to read
    872  *             LPOVERLAPPED lpOverlapped         address of offset
    873  *             LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
    874  * Variables :
    875  * Result    : TRUE / FALSE
    876  * Remark    :
    877  * Status    : UNTESTED STUB
    878  *
    879  * Author    : Patrick Haller [Mon, 1998/06/15 08:00]
    880  *****************************************************************************/
    881 BOOL HMDeviceCommClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
    882                            LPVOID       lpBuffer,
    883                            DWORD        nNumberOfBytesToRead,
    884                            LPOVERLAPPED lpOverlapped,
    885                            LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    886 {
    887   dprintf(("ERROR: ReadFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
    888            lpHMDeviceName,
    889            pHMHandleData->hHMHandle,
    890            lpBuffer,
    891            nNumberOfBytesToRead,
    892            lpOverlapped,
    893            lpCompletionRoutine));
    894 
    895   SetLastError(ERROR_INVALID_FUNCTION);
    896   return FALSE;
    897 }
    898 
     1106//******************************************************************************
     1107//******************************************************************************
    8991108BOOL HMDeviceCommClass::SetCommBreak( PHMHANDLEDATA pHMHandleData )
    9001109{
     
    9141123  return(rc==0);
    9151124}
    916 
     1125//******************************************************************************
     1126//******************************************************************************
    9171127BOOL HMDeviceCommClass::ClearCommBreak( PHMHANDLEDATA pHMHandleData)
    9181128{
     
    9321142  return(rc==0);
    9331143}
    934 
     1144//******************************************************************************
     1145//******************************************************************************
    9351146BOOL HMDeviceCommClass::SetCommConfig( PHMHANDLEDATA pHMHandleData,
    9361147                                       LPCOMMCONFIG lpCC,
    9371148                                       DWORD dwSize )
    9381149{
    939   dprintf(("HMDeviceCommClass::SetCommConfig"));
    940 
     1150  dprintf(("HMDeviceCommClass::SetCommConfig NOT IMPLEMENTED"));
    9411151
    9421152  return(TRUE);
    9431153}
    944 
     1154//******************************************************************************
     1155//******************************************************************************
    9451156BOOL HMDeviceCommClass::GetCommConfig( PHMHANDLEDATA pHMHandleData,
    9461157                                       LPCOMMCONFIG lpCC,
     
    9691180  return(TRUE);
    9701181}
    971 
     1182//******************************************************************************
     1183//******************************************************************************
    9721184BOOL HMDeviceCommClass::EscapeCommFunction( PHMHANDLEDATA pHMHandleData,
    9731185                                            UINT dwFunc )
     
    9781190  MODEMSTATUS mdm;
    9791191
    980   dprintf(("HMDeviceCommClass::EscapeCommFunction"));
     1192  dprintf(("HMDeviceCommClass::EscapeCommFunction %x", dwFunc));
    9811193
    9821194  ulDLen = sizeof(USHORT);
     
    10491261      break;
    10501262    default:
     1263      dprintf(("!ERROR!: EscapeCommFunction: unknown function"));
    10511264      SetLastError(ERROR_INVALID_PARAMETER);
    10521265      return(FALSE);
     
    10551268  return(rc==0);
    10561269}
    1057 
     1270//******************************************************************************
     1271//******************************************************************************
    10581272BOOL HMDeviceCommClass::SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
    10591273                                              LPCOMMCONFIG lpCC,
     
    10711285  return(TRUE);
    10721286}
     1287//******************************************************************************
     1288//******************************************************************************
    10731289BOOL HMDeviceCommClass::GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
    10741290                                              LPCOMMCONFIG lpCC,
     
    10951311  return(TRUE);
    10961312}
     1313//******************************************************************************
     1314//******************************************************************************
    10971315APIRET HMDeviceCommClass::SetLine( PHMHANDLEDATA pHMHandleData,
    10981316                                   UCHAR ucSize,
     
    11321350  return rc;
    11331351}
    1134 
     1352//******************************************************************************
     1353//******************************************************************************
    11351354APIRET HMDeviceCommClass::SetOS2DCB( PHMHANDLEDATA pHMHandleData,
    11361355                                     BOOL fOutxCtsFlow, BOOL fOutxDsrFlow,
     
    12131432
    12141433}
    1215 
     1434//******************************************************************************
     1435//******************************************************************************
    12161436APIRET HMDeviceCommClass::SetBaud( PHMHANDLEDATA pHMHandleData,
    12171437                                   DWORD dwNewBaud)
     
    12491469  return rc;
    12501470}
    1251 
    1252 
     1471//******************************************************************************
     1472//******************************************************************************
     1473
     1474
Note: See TracChangeset for help on using the changeset viewer.