Ignore:
Timestamp:
Dec 5, 2001, 3:16:38 PM (24 years ago)
Author:
sandervl
Message:

preliminary changes for new overlapped io framework

File:
1 edited

Legend:

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

    r7543 r7549  
    1 /* $Id: hmcomm.cpp,v 1.25 2001-12-04 16:11:25 sandervl Exp $ */
     1/* $Id: hmcomm.cpp,v 1.26 2001-12-05 14:15:59 sandervl Exp $ */
    22
    33/*
     
    6161#define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
    6262
    63 DWORD CALLBACK SerialCommThread(LPVOID lpThreadParam);
    64 
    6563//******************************************************************************
    6664//******************************************************************************
     
    157155//******************************************************************************
    158156//******************************************************************************
    159 DWORD HMDeviceCommClass::CreateFile(HANDLE hComm,
    160                                     LPCSTR lpFileName,
     157DWORD HMDeviceCommClass::CreateFile(LPCSTR lpFileName,
    161158                                    PHMHANDLEDATA pHMHandleData,
    162159                                    PVOID lpSecurityAttributes,
    163160                                    PHMHANDLEDATA pHMHandleDataTemplate)
    164161{
    165  char comname[6];
     162 char  comname[6];
     163 DWORD ret = ERROR_SUCCESS;
    166164
    167165  dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
     
    237235        DWORD         dwThreadId;
    238236
    239         pDevData->hEventSem = ::CreateEventA(NULL, TRUE, FALSE, NULL);
    240         pDevData->hThread   = ::CreateThread(NULL, 32*1024, SerialCommThread, (LPVOID)hComm, 0, &dwThreadId);
    241 
    242         if(!pDevData->hEventSem || !pDevData->hThread)
    243         {
    244             DebugInt3();
    245             if(pDevData->hEventSem) ::CloseHandle(pDevData->hEventSem);
    246             delete pHMHandleData->lpHandlerData;
    247             OSLibDosClose(pHMHandleData->hHMHandle);
    248             return ERROR_NOT_ENOUGH_MEMORY;
    249         }
    250237    }
    251238    return ERROR_SUCCESS;
     
    253240  else
    254241    return ERROR_ACCESS_DENIED;
     242
     243
     244fail:
     245
     246  delete pHMHandleData->lpHandlerData;
     247  OSLibDosClose(pHMHandleData->hHMHandle);
     248  return ret;
     249}
     250/*****************************************************************************
     251 * Name      : DWORD HMDeviceCommClass::GetFileType
     252 * Purpose   : determine the handle type
     253 * Parameters: PHMHANDLEDATA pHMHandleData
     254 * Variables :
     255 * Result    : API returncode
     256 * Remark    :
     257 * Status    :
     258 *
     259 * Author    : SvL
     260 *****************************************************************************/
     261
     262DWORD HMDeviceCommClass::GetFileType(PHMHANDLEDATA pHMHandleData)
     263{
     264  dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n",
     265           lpHMDeviceName,
     266           pHMHandleData));
     267
     268  return FILE_TYPE_CHAR;
    255269}
    256270//******************************************************************************
     
    263277  if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
    264278  {
    265       pDevData->fClosing = TRUE;
    266       dprintf(("signalling serial thread"));
    267       ::SetEvent(pDevData->hEventSem);
    268       ::ResetEvent(pDevData->hEventSem);
    269 
    270       //Wait for thread to clean up
    271       dprintf(("waiting for serial thread"));
    272       DWORD ret = ::WaitForSingleObject(pDevData->hEventSem, 200);
    273       dprintf(("waiting for serial thread done -> %x", ret));
    274       ::CloseHandle(pDevData->hEventSem);
     279      DebugInt3();
    275280  }
    276281  delete pHMHandleData->lpHandlerData;
     
    296301                                  DWORD         nNumberOfBytesToWrite,
    297302                                  LPDWORD       lpNumberOfBytesWritten,
    298                                   LPOVERLAPPED  lpOverlapped)
     303                                  LPOVERLAPPED  lpOverlapped,
     304                                  LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    299305{
    300306  dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
     
    318324  }
    319325//testestestest
    320   dprintf(("Bytes to write:"));
     326  dprintf2(("Bytes to write:"));
    321327  for(int i=0;i<nNumberOfBytesToWrite;i++) {
    322           dprintf(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
     328          dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
    323329  }
    324330//testestestset
     
    336342
    337343  return ret;
    338 }
    339 /*****************************************************************************
    340  * Name      : BOOL WriteFileEx
    341  * Purpose   : The WriteFileEx function writes data to a file. It is designed
    342  *             solely for asynchronous operation, unlike WriteFile, which is
    343  *             designed for both synchronous and asynchronous operation.
    344  *             WriteFileEx reports its completion status asynchronously,
    345  *             calling a specified completion routine when writing is completed
    346  *             and the calling thread is in an alertable wait state.
    347  * Parameters: HANDLE       hFile                handle of file to write
    348  *             LPVOID       lpBuffer             address of buffer
    349  *             DWORD        nNumberOfBytesToRead number of bytes to write
    350  *             LPOVERLAPPED lpOverlapped         address of offset
    351  *             LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
    352  * Variables :
    353  * Result    : TRUE / FALSE
    354  * Remark    :
    355  * Status    : UNTESTED STUB
    356  *
    357  * Author    : SvL
    358  *****************************************************************************/
    359 
    360 BOOL HMDeviceCommClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
    361                            LPVOID       lpBuffer,
    362                            DWORD        nNumberOfBytesToWrite,
    363                            LPOVERLAPPED lpOverlapped,
    364                            LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    365 {
    366   dprintf(("!ERROR!: WriteFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
    367            lpHMDeviceName,
    368            pHMHandleData->hHMHandle,
    369            lpBuffer,
    370            nNumberOfBytesToWrite,
    371            lpOverlapped,
    372            lpCompletionRoutine));
    373 
    374   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
    375       dprintf(("!WARNING!: Handle not created with FILE_FLAG_OVERLAPPED!"));
    376       ::SetLastError(ERROR_ACCESS_DENIED); //todo: right error?
    377       return FALSE;
    378   }
    379 
    380   ::SetLastError(ERROR_INVALID_FUNCTION);
    381   return FALSE;
    382344}
    383345/*****************************************************************************
     
    401363                                 DWORD         nNumberOfBytesToRead,
    402364                                 LPDWORD       lpNumberOfBytesRead,
    403                                  LPOVERLAPPED  lpOverlapped)
     365                                 LPOVERLAPPED  lpOverlapped,
     366                                 LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    404367{
    405368  dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
     
    444407  else {
    445408//testestestest
    446       dprintf(("Bytes read:"));
     409      dprintf2(("%d Bytes read:", ulBytesRead));
    447410      for(int i=0;i<ulBytesRead;i++) {
    448           dprintf(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
     411          dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
    449412      }
    450413//testestestset
     
    453416}
    454417
    455 /*****************************************************************************
    456  * Name      : BOOL ReadFileEx
    457  * Purpose   : The ReadFileEx function reads data from a file asynchronously.
    458  *             It is designed solely for asynchronous operation, unlike the
    459  *             ReadFile function, which is designed for both synchronous and
    460  *             asynchronous operation. ReadFileEx lets an application perform
    461  *             other processing during a file read operation.
    462  *             The ReadFileEx function reports its completion status asynchronously,
    463  *             calling a specified completion routine when reading is completed
    464  *             and the calling thread is in an alertable wait state.
    465  * Parameters: HANDLE       hFile                handle of file to read
    466  *             LPVOID       lpBuffer             address of buffer
    467  *             DWORD        nNumberOfBytesToRead number of bytes to read
    468  *             LPOVERLAPPED lpOverlapped         address of offset
    469  *             LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
    470  * Variables :
    471  * Result    : TRUE / FALSE
    472  * Remark    :
    473  * Status    : UNTESTED STUB
    474  *
    475  * Author    : SvL
    476  *****************************************************************************/
    477 BOOL HMDeviceCommClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
    478                                    LPVOID       lpBuffer,
    479                                    DWORD        nNumberOfBytesToRead,
    480                                    LPOVERLAPPED lpOverlapped,
    481                                    LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    482 {
    483   dprintf(("!ERROR!: ReadFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
    484            lpHMDeviceName,
    485            pHMHandleData->hHMHandle,
    486            lpBuffer,
    487            nNumberOfBytesToRead,
    488            lpOverlapped,
    489            lpCompletionRoutine));
    490 
    491   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
    492       dprintf(("!WARNING!: Handle not created with FILE_FLAG_OVERLAPPED!"));
    493       ::SetLastError(ERROR_ACCESS_DENIED); //todo: right error?
    494       return FALSE;
    495   }
    496 
    497   ::SetLastError(ERROR_INVALID_FUNCTION);
    498   return FALSE;
    499 }
    500418/*****************************************************************************
    501419 * Name      : DWORD HMDeviceHandler::SetupComm
     
    526444}
    527445//******************************************************************************
    528 #define TIMEOUT_COMM  50
    529 //******************************************************************************
    530 DWORD CALLBACK SerialCommThread(LPVOID lpThreadParam)
    531 {
    532   HANDLE        hComm = (HANDLE)lpThreadParam;
    533   PHMHANDLEDATA pHMHandleData;
    534   PHMDEVCOMDATA pDevData;
    535   DWORD         ret;
    536   APIRET        rc;
    537   ULONG         ulLen;
    538   USHORT        COMEvt;
    539   DWORD         dwEvent,dwMask;
    540 
    541   pHMHandleData = HMQueryHandleData(hComm);
    542   if(!pHMHandleData) {
    543       dprintf(("!ERROR!: Invalid handle -> aborting"));
    544       return 0;
    545   }
    546 
    547   pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
    548   if(!pDevData) {
    549       dprintf(("!ERROR! SerialCommThread !pDevData"));
    550       DebugInt3();
    551       return 0;
    552   }
    553   HANDLE hEvent   = pDevData->hEventSem;
    554   HANDLE hCommOS2 = pHMHandleData->hHMHandle;
    555   if(!hCommOS2 || !hEvent) {
    556       dprintf(("!ERROR! SerialCommThread !hCommOS2 || !hEvent"));
    557       DebugInt3();
    558       return 0;
    559   }
    560   dprintf(("SerialCommThread %x entered", hComm));
    561 
    562   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    563   while(TRUE)
    564   {
    565       //validate handle
    566       pHMHandleData = HMQueryHandleData(hComm);
    567       if(!pHMHandleData) {
    568           dprintf(("!ERROR!: Invalid handle -> aborting"));
    569           return 0;
    570       }
    571       if(pDevData->fClosing) {
    572           dprintf(("Cleaning up async comm thread"));
    573           SetEvent(hEvent); //signal to CloseHandle that we're done
    574           return 0;
    575       }
    576 
    577       //Wait for the app to call WaitCommEvent
    578       dprintf(("SerialCommThread: wait for WaitCommEvent"));
    579       ret = WaitForSingleObject(hEvent, INFINITE);
    580       ResetEvent(hEvent);
    581       dprintf(("SerialCommThread: wait for WaitCommEvent done %x", ret));
    582 
    583       //validate handle first
    584       pHMHandleData = HMQueryHandleData(hComm);
    585       if(!pHMHandleData) {
    586           dprintf(("!ERROR!: Invalid handle -> aborting"));
    587           return 0;
    588       }
    589 
    590       if(pDevData->fClosing) {
    591           dprintf(("Cleaning up async comm thread"));
    592           SetEvent(hEvent); //signal to CloseHandle that we're done
    593           return 0;
    594       }
    595 
    596       HANDLE hOverlappedEvent = pDevData->overlapped.hEvent;
    597       if(!hOverlappedEvent) {
    598           DebugInt3();
    599           return 0;
    600       }
    601 
    602       ulLen   = sizeof(CHAR);
    603       dwEvent = 0;
    604       rc      = 0;
    605       ulLen   = sizeof(COMEvt);
    606       dwMask  = pDevData->dwEventMask;
    607 
    608       while( (0==rc) &&
    609             !(dwEvent & dwMask) &&
    610             (dwMask == pDevData->dwEventMask) &&
    611             !(pDevData->fCancelIo) && !(pDevData->fClosing) ) // Exit if the Mask gets changed
    612       {
    613           rc = OSLibDosDevIOCtl(hCommOS2,
    614                                 IOCTL_ASYNC,
    615                                 ASYNC_GETCOMMEVENT,
    616                                 0,0,0,
    617                                 &COMEvt,ulLen,&ulLen);
    618           if(!rc)
    619           {
    620               dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
    621               //dwEvent |= (COMEvt&0x0002)? 0:0;
    622               dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
    623               dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
    624               dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
    625               //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
    626               dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
    627               dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
    628               dwEvent |= (COMEvt&0x0100)? EV_RING:0;
    629               if((dwEvent & dwMask)) break;
    630           }
    631           else break;
    632 
    633           //validate handle first
    634           pHMHandleData = HMQueryHandleData(hComm);
    635           if(!pHMHandleData) {
    636               dprintf(("!ERROR!: Invalid handle -> aborting"));
    637               return 0;
    638           }
    639 
    640           if(pDevData->fClosing) {
    641               dprintf(("Cleaning up async comm thread"));
    642               SetEvent(hEvent); //signal to CloseHandle that we're done
    643               return 0;
    644           }
    645 
    646           DosSleep(TIMEOUT_COMM);
    647       }
    648       if(pDevData->fClosing) {
    649           dprintf(("Cleaning up async comm thread"));
    650           SetEvent(hEvent); //signal to CloseHandle that we're done
    651           return 0;
    652       }
    653       else
    654       if(pDevData->fCancelIo) {
    655           pDevData->overlapped.Internal = 0;
    656           pDevData->dwLastError = ERROR_OPERATION_ABORTED;
    657           if(pDevData->lpfdwEvtMask) *pDevData->lpfdwEvtMask = 0;
    658           dprintf(("Overlapped: WaitCommEvent ERROR_OPERATION_ABORTED"));
    659 
    660           //signal to app that a comm event has occurred
    661           SetEvent(hOverlappedEvent);
    662       }
    663       else
    664       if((dwEvent & dwMask) && (dwMask == pDevData->dwEventMask)) {
    665           pDevData->overlapped.Internal |= (rc==0) ? (dwEvent & dwMask) : 0;
    666           pDevData->dwLastError = rc;
    667 
    668           //We're also supposed to write the result to the address supplied
    669           //by the call to WaitCommEvent
    670           if(pDevData->lpfdwEvtMask) *pDevData->lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0;
    671           dprintf(("Overlapped: WaitCommEvent returned %x", pDevData->overlapped.Internal));
    672 
    673           //signal to app that a comm event has occurred
    674           SetEvent(hOverlappedEvent);
    675       }
    676   }
    677   return 0;
    678 }
    679 //******************************************************************************
     446#define TIMEOUT_COMM 50
    680447//******************************************************************************
    681448BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
     
    741508        ::ResetEvent(lpo->hEvent);
    742509
    743         //signal async comm thread to start polling comm status
    744         ::SetEvent(pDevData->hEventSem);
    745510        ::SetLastError(ERROR_IO_PENDING);
    746511        return FALSE;
     
    779544    //signal serial thread to cancel pending IO operation
    780545    pDevData->fCancelIo = TRUE;
    781     ::SetEvent(pDevData->hEventSem);
     546//    ::SetEvent(pDevData->hEventSem);
    782547
    783548    ::SetLastError(ERROR_SUCCESS);
     
    1187952  memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
    1188953
    1189   fbTimeOut = 0x02;
     954  fbTimeOut = 0x02; //normal processing (wait until timout or buffer full)
    1190955  if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
    1191956  {
    1192957    if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
    1193958        (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
    1194       fbTimeOut = 0x05;
     959      fbTimeOut = 0x05; //no wait
    1195960    else
    1196       fbTimeOut = 0x04;
     961      fbTimeOut = 0x04; //wait for something
    1197962  }
    1198963  else
     
    1200965    DWORD dwTimeout;
    1201966    dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
    1202 #if 0
    1203967    if(dwTimeout)
    1204968      dwTimeout--; // 0=10 ms unit is 10ms or .01s
    1205 #endif
     969
    1206970    os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
    1207971    os2dcb.usReadTimeout  = 0x0000FFFF & dwTimeout;
    1208972  }
    1209   os2dcb.fbTimeOut = (os2dcb.fbTimeOut & 0xF9) | fbTimeOut;
     973  if( (0==pDevData->CommTOuts.WriteTotalTimeoutMultiplier) &&
     974      (0==pDevData->CommTOuts.WriteTotalTimeoutConstant))
     975  {//no timeout used for writing
     976    os2dcb.fbTimeOut |= 1; //write infinite timeout
     977  }
     978
     979  os2dcb.fbTimeOut = (os2dcb.fbTimeOut & 0xF8) | fbTimeOut;
    1210980
    1211981  dprintf((" New DCB:\n"
Note: See TracChangeset for help on using the changeset viewer.