Changeset 7549 for trunk/src/kernel32/hmcomm.cpp
- Timestamp:
- Dec 5, 2001, 3:16:38 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/hmcomm.cpp
r7543 r7549 1 /* $Id: hmcomm.cpp,v 1.2 5 2001-12-04 16:11:25sandervl Exp $ */1 /* $Id: hmcomm.cpp,v 1.26 2001-12-05 14:15:59 sandervl Exp $ */ 2 2 3 3 /* … … 61 61 #define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY)) 62 62 63 DWORD CALLBACK SerialCommThread(LPVOID lpThreadParam);64 65 63 //****************************************************************************** 66 64 //****************************************************************************** … … 157 155 //****************************************************************************** 158 156 //****************************************************************************** 159 DWORD HMDeviceCommClass::CreateFile(HANDLE hComm, 160 LPCSTR lpFileName, 157 DWORD HMDeviceCommClass::CreateFile(LPCSTR lpFileName, 161 158 PHMHANDLEDATA pHMHandleData, 162 159 PVOID lpSecurityAttributes, 163 160 PHMHANDLEDATA pHMHandleDataTemplate) 164 161 { 165 char comname[6]; 162 char comname[6]; 163 DWORD ret = ERROR_SUCCESS; 166 164 167 165 dprintf(("HMComm: Serial communication port %s open request\n", lpFileName)); … … 237 235 DWORD dwThreadId; 238 236 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 }250 237 } 251 238 return ERROR_SUCCESS; … … 253 240 else 254 241 return ERROR_ACCESS_DENIED; 242 243 244 fail: 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 262 DWORD HMDeviceCommClass::GetFileType(PHMHANDLEDATA pHMHandleData) 263 { 264 dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n", 265 lpHMDeviceName, 266 pHMHandleData)); 267 268 return FILE_TYPE_CHAR; 255 269 } 256 270 //****************************************************************************** … … 263 277 if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 264 278 { 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(); 275 280 } 276 281 delete pHMHandleData->lpHandlerData; … … 296 301 DWORD nNumberOfBytesToWrite, 297 302 LPDWORD lpNumberOfBytesWritten, 298 LPOVERLAPPED lpOverlapped) 303 LPOVERLAPPED lpOverlapped, 304 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 299 305 { 300 306 dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)", … … 318 324 } 319 325 //testestestest 320 dprintf (("Bytes to write:"));326 dprintf2(("Bytes to write:")); 321 327 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])); 323 329 } 324 330 //testestestset … … 336 342 337 343 return ret; 338 }339 /*****************************************************************************340 * Name : BOOL WriteFileEx341 * Purpose : The WriteFileEx function writes data to a file. It is designed342 * solely for asynchronous operation, unlike WriteFile, which is343 * designed for both synchronous and asynchronous operation.344 * WriteFileEx reports its completion status asynchronously,345 * calling a specified completion routine when writing is completed346 * and the calling thread is in an alertable wait state.347 * Parameters: HANDLE hFile handle of file to write348 * LPVOID lpBuffer address of buffer349 * DWORD nNumberOfBytesToRead number of bytes to write350 * LPOVERLAPPED lpOverlapped address of offset351 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine352 * Variables :353 * Result : TRUE / FALSE354 * Remark :355 * Status : UNTESTED STUB356 *357 * Author : SvL358 *****************************************************************************/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;382 344 } 383 345 /***************************************************************************** … … 401 363 DWORD nNumberOfBytesToRead, 402 364 LPDWORD lpNumberOfBytesRead, 403 LPOVERLAPPED lpOverlapped) 365 LPOVERLAPPED lpOverlapped, 366 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 404 367 { 405 368 dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)", … … 444 407 else { 445 408 //testestestest 446 dprintf (("Bytes read:"));409 dprintf2(("%d Bytes read:", ulBytesRead)); 447 410 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])); 449 412 } 450 413 //testestestset … … 453 416 } 454 417 455 /*****************************************************************************456 * Name : BOOL ReadFileEx457 * Purpose : The ReadFileEx function reads data from a file asynchronously.458 * It is designed solely for asynchronous operation, unlike the459 * ReadFile function, which is designed for both synchronous and460 * asynchronous operation. ReadFileEx lets an application perform461 * 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 completed464 * and the calling thread is in an alertable wait state.465 * Parameters: HANDLE hFile handle of file to read466 * LPVOID lpBuffer address of buffer467 * DWORD nNumberOfBytesToRead number of bytes to read468 * LPOVERLAPPED lpOverlapped address of offset469 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine470 * Variables :471 * Result : TRUE / FALSE472 * Remark :473 * Status : UNTESTED STUB474 *475 * Author : SvL476 *****************************************************************************/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 }500 418 /***************************************************************************** 501 419 * Name : DWORD HMDeviceHandler::SetupComm … … 526 444 } 527 445 //****************************************************************************** 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 680 447 //****************************************************************************** 681 448 BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData, … … 741 508 ::ResetEvent(lpo->hEvent); 742 509 743 //signal async comm thread to start polling comm status744 ::SetEvent(pDevData->hEventSem);745 510 ::SetLastError(ERROR_IO_PENDING); 746 511 return FALSE; … … 779 544 //signal serial thread to cancel pending IO operation 780 545 pDevData->fCancelIo = TRUE; 781 ::SetEvent(pDevData->hEventSem);546 // ::SetEvent(pDevData->hEventSem); 782 547 783 548 ::SetLastError(ERROR_SUCCESS); … … 1187 952 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO)); 1188 953 1189 fbTimeOut = 0x02; 954 fbTimeOut = 0x02; //normal processing (wait until timout or buffer full) 1190 955 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout) 1191 956 { 1192 957 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) && 1193 958 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant)) 1194 fbTimeOut = 0x05; 959 fbTimeOut = 0x05; //no wait 1195 960 else 1196 fbTimeOut = 0x04; 961 fbTimeOut = 0x04; //wait for something 1197 962 } 1198 963 else … … 1200 965 DWORD dwTimeout; 1201 966 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10; 1202 #if 01203 967 if(dwTimeout) 1204 968 dwTimeout--; // 0=10 ms unit is 10ms or .01s 1205 #endif 969 1206 970 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout; 1207 971 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout; 1208 972 } 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; 1210 980 1211 981 dprintf((" New DCB:\n"
Note:
See TracChangeset
for help on using the changeset viewer.