source: trunk/src/kernel32/hmcomm.cpp@ 21302

Last change on this file since 21302 was 21302, checked in by ydario, 16 years ago

Kernel32 updates.

File size: 60.4 KB
Line 
1/* $Id: hmcomm.cpp,v 1.41 2004-01-30 22:16:59 bird Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 COM device access class
7 *
8 * 1999 Achim Hasenmueller <achimha@innotek.de>
9 * 2001 Sander van Leeuwen <sandervl@xs4all.nl>
10 *
11 *
12 */
13
14
15
16#include <os2win.h>
17#include <string.h>
18#include <stdio.h>
19#include <handlemanager.h>
20#include "handlenames.h"
21#include <heapstring.h>
22#include "hmcomm.h"
23#include "oslibdos.h"
24
25#define DBG_LOCALLOG DBG_hmcomm
26#include "dbglocal.h"
27
28//#define TESTING_COMM
29#ifdef TESTING_COMM
30#undef dprintf
31#define dprintf(a) WriteLog a
32#undef dprintf2
33#define dprintf2(a) WriteLog a
34#endif
35
36BAUDTABLEENTRY BaudTable[] =
37{
38 {75,BAUD_075},
39 {110,BAUD_110},
40 {134,BAUD_134_5},
41 {150,BAUD_150},
42 {300,BAUD_300},
43 {600,BAUD_600},
44 {1200,BAUD_1200},
45 {1800,BAUD_1800},
46 {2400,BAUD_2400},
47 {4800,BAUD_4800},
48 {7200,BAUD_7200},
49 {9600,BAUD_9600},
50 {14400,BAUD_14400},
51 {19200,BAUD_19200},
52 {38400,BAUD_38400},
53 {56000,BAUD_56K},
54 {57600,BAUD_57600},
55 {115200,BAUD_115200},
56 {128000,BAUD_128K}
57};
58
59#define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
60
61static DWORD CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
62static DWORD CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
63static DWORD CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut);
64#ifdef DEBUG_LOGGING
65static char *DebugCommEvent(DWORD dwEvents);
66static char *DebugModemStatus(DWORD dwModemStatus);
67#ifdef DEBUG_COMOUTPUT
68static FILE *comlog = NULL;
69#endif
70#endif
71//******************************************************************************
72//******************************************************************************
73static VOID *CreateDevData()
74{
75 PHMDEVCOMDATA pData;
76
77 pData = new HMDEVCOMDATA();
78 if(NULL!=pData)
79 {
80 memset(pData,0,sizeof(HMDEVCOMDATA));
81 pData->ulMagic = MAGIC_COM;
82 pData->CommCfg.dwSize = sizeof(COMMCONFIG);
83 pData->CommCfg.wVersion = 1;
84 pData->CommCfg.dwProviderSubType = PST_RS232;
85 pData->CommCfg.dcb.DCBlength = sizeof(DCB);
86 pData->CommCfg.dcb.BaudRate = CBR_1200;
87 pData->CommCfg.dcb.ByteSize = 8;
88 pData->CommCfg.dcb.Parity = NOPARITY;
89 pData->CommCfg.dcb.StopBits = ONESTOPBIT;
90 pData->dwInBuffer = 16;
91 pData->dwOutBuffer = 16;
92 }
93 return pData;
94}
95//******************************************************************************
96//******************************************************************************
97HMDeviceCommClass::HMDeviceCommClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
98{
99 VOID *pData;
100
101 dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n"));
102 pData = CreateDevData();
103 if(pData!= NULL)
104 HMDeviceRegisterEx("COM1", this, pData);
105
106 // add symbolic links to the "real name" of the device
107 // @@@PH what's the long device name: SerialPortx ?
108 // HandleNamesAddSymbolicLink("\\Device\\ParallelPort3", "COM3");
109 // Note: \\.\COMx: is invalid (NT4SP6)
110
111 PSZ pszCOM = strdup("\\\\.\\COMx");
112 for (char ch = '1'; ch < '9'; ch++)
113 {
114 pszCOM[7] = ch;
115 HandleNamesAddSymbolicLink(pszCOM, pszCOM+4);
116 }
117 free(pszCOM);
118
119 // add "AUX" device
120 HandleNamesAddSymbolicLink("AUX", "COM1");
121 HandleNamesAddSymbolicLink("AUX:", "COM1");
122 HandleNamesAddSymbolicLink("\\\\.\\AUX", "COM1");
123#ifdef DEBUG_COMOUTPUT
124 comlog = fopen("comlog", "w");
125#endif
126}
127
128/*****************************************************************************
129 * Name : HMDeviceCommClass::FindDevice
130 * Purpose : Checks if lpDeviceName belongs to this device class
131 * Parameters: LPCSTR lpClassDevName
132 * LPCSTR lpDeviceName
133 * int namelength
134 * Variables :
135 * Result : checks if name is COMx or COMx: (x=1..8)
136 * Remark :
137 * Status :
138 *
139 * Author : SvL
140 *****************************************************************************/
141BOOL HMDeviceCommClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
142{
143 dprintf2(("HMDeviceCommClass::FindDevice %s %s", lpClassDevName, lpDeviceName));
144
145 //first 3 letters 'COM'?
146 if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) {
147 return FALSE;
148 }
149
150 if(namelength > 5 || (namelength == 5 && lpDeviceName[4] != ':')) {
151 return FALSE;
152 }
153 switch(lpDeviceName[3]) {
154 case '1':
155 case '2':
156 case '3':
157 case '4':
158 case '5':
159 case '6':
160 case '7':
161 case '8':
162 return TRUE; //we support up to COM8
163 }
164 return FALSE;
165}
166//******************************************************************************
167//******************************************************************************
168DWORD HMDeviceCommClass::CreateFile(LPCSTR lpFileName,
169 PHMHANDLEDATA pHMHandleData,
170 PVOID lpSecurityAttributes,
171 PHMHANDLEDATA pHMHandleDataTemplate)
172{
173 char comname[6];
174 DWORD ret = ERROR_SUCCESS;
175
176 dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
177
178 if(strlen(lpFileName) > 5) {
179 lpFileName += 4; //skip prefix
180 }
181
182 pHMHandleData->hHMHandle = 0;
183
184 strcpy(comname, lpFileName);
185 comname[4] = 0; //get rid of : (if present) (eg COM1:)
186
187 //AH: TODO parse Win32 security handles
188 ULONG oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
189 pHMHandleData->hHMHandle = OSLibDosOpen(comname,
190 OSLIB_ACCESS_READWRITE |
191 OSLIB_ACCESS_SHAREDENYREAD |
192 OSLIB_ACCESS_SHAREDENYWRITE);
193 ::SetErrorMode(oldmode);
194 if (pHMHandleData->hHMHandle != 0)
195 {
196 ULONG ulLen;
197 APIRET rc;
198 pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
199 // Init The handle instance with the default default device config
200 memcpy( pHMHandleData->lpHandlerData,
201 pHMHandleData->lpDeviceData,
202 sizeof(HMDEVCOMDATA));
203
204 ulLen = sizeof(DCBINFO);
205
206 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
207 IOCTL_ASYNC,
208 ASYNC_GETDCBINFO,
209 0,0,0,
210 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
211 dprintf(("DCB Of %s :\n"
212 " WriteTimeout : %d\n"
213 " ReadTimeout : %d\n"
214 " CtlHandshake : 0x%x\n"
215 " FlowReplace : 0x%x\n"
216 " Timeout : 0x%x\n"
217 " Error replacement Char : 0x%x\n"
218 " Break replacement Char : 0x%x\n"
219 " XON Char : 0x%x\n"
220 " XOFF Char : 0x%x\n",
221 comname,
222 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
223 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
224 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
225 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
226 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
227 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
228 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
229 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
230 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
231
232 if(rc)
233 {
234 OSLibDosClose(pHMHandleData->hHMHandle);
235 delete pHMHandleData->lpHandlerData;
236 return rc;
237 }
238
239 rc = SetBaud(pHMHandleData,9600);
240 dprintf(("Init Baud to 9600 rc = %d",rc));
241 rc = SetLine(pHMHandleData,8,0,0);
242 dprintf(("Set Line to 8/N/1 rc = %d",rc));
243
244 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
245 {
246 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
247 int comnr;
248
249 comnr = comname[3] - '1';
250
251 if(handler[comnr] == NULL)
252 {
253 try {
254 handler[comnr] = new OverlappedIOHandler(CommReadIOHandler, CommWriteIOHandler, CommPollIOHandler, ASYNC_TYPE_FULLDUPLEX);
255 }
256 catch(...)
257 {
258 ret = ERROR_NOT_ENOUGH_MEMORY;
259 goto fail;
260 }
261 if(handler[comnr] == NULL) {
262 ret = ERROR_NOT_ENOUGH_MEMORY;
263 goto fail;
264 }
265 handler[comnr]->AddRef();
266 }
267 pDevData->iohandler = handler[comnr];
268 }
269 return ERROR_SUCCESS;
270 }
271 else
272 return ERROR_ACCESS_DENIED;
273
274fail:
275
276 delete pHMHandleData->lpHandlerData;
277 OSLibDosClose(pHMHandleData->hHMHandle);
278 return ret;
279}
280/*****************************************************************************
281 * Name : DWORD HMDeviceCommClass::GetFileType
282 * Purpose : determine the handle type
283 * Parameters: PHMHANDLEDATA pHMHandleData
284 * Variables :
285 * Result : API returncode
286 * Remark :
287 * Status :
288 *
289 * Author : SvL
290 *****************************************************************************/
291DWORD HMDeviceCommClass::GetFileType(PHMHANDLEDATA pHMHandleData)
292{
293 dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n",
294 lpHMDeviceName, pHMHandleData));
295
296 return FILE_TYPE_CHAR;
297}
298//******************************************************************************
299//******************************************************************************
300BOOL HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
301{
302 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
303 dprintf(("HMComm: Serial communication port close request"));
304
305 delete pHMHandleData->lpHandlerData;
306 return OSLibDosClose(pHMHandleData->hHMHandle);
307}
308//******************************************************************************
309//Overlapped read handler
310//******************************************************************************
311DWORD CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
312{
313 PHMHANDLEDATA pHMHandleData;
314 BOOL ret;
315 ULONG ulBytesRead, len;
316
317 pHMHandleData = HMQueryHandleData(lpRequest->hHandle);
318 if(pHMHandleData == NULL) {
319 dprintf(("!ERROR!: CommReadIOHandler handle %x not valid", lpRequest->hHandle));
320 DebugInt3();
321 return ERROR_INVALID_HANDLE;
322 }
323
324#ifdef DEBUG
325 RXQUEUE qInfo;
326 ULONG ulLen = sizeof(qInfo);
327 ULONG rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
328 IOCTL_ASYNC,
329 ASYNC_GETINQUECOUNT,
330 0,0,0,
331 &qInfo,ulLen,&ulLen);
332 dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc));
333#endif
334
335 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpRequest->lpBuffer, lpRequest->nNumberOfBytes, &ulBytesRead);
336
337 *lpdwResult = (ret) ? ulBytesRead : 0;
338 dprintf(("KERNEL32: CommReadIOHandler %d bytes read", *lpdwResult));
339
340 if(ret == FALSE) {
341 dprintf(("!ERROR!: CommReadIOHandler failed with rc %d", GetLastError()));
342 }
343 else {
344#ifdef DEBUG
345 if(ulBytesRead < qInfo.cch) {
346 dprintf(("WARNING: Not all data removed from queue!!"));
347 }
348 dprintf2(("%d Bytes read:", ulBytesRead));
349 for(int i=0;i<min(ulBytesRead, 16);i++) {
350 dprintf2(("%x %c", ((char *)lpRequest->lpBuffer)[i], ((char *)lpRequest->lpBuffer)[i]));
351 }
352#endif
353 }
354 return GetLastError();
355}
356//******************************************************************************
357//Overlapped write handler
358//******************************************************************************
359DWORD CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
360{
361 PHMHANDLEDATA pHMHandleData;
362 BOOL ret;
363 ULONG ulBytesWritten;
364
365 pHMHandleData = HMQueryHandleData(lpRequest->hHandle);
366 if(pHMHandleData == NULL) {
367 dprintf(("!ERROR!: CommWriteIOHandler handle %x not valid", lpRequest->hHandle));
368 DebugInt3();
369 return ERROR_INVALID_HANDLE;
370 }
371
372#ifdef DEBUG
373 dprintf2(("Bytes to write:"));
374 for(int i=0;i<min(lpRequest->nNumberOfBytes, 16);i++) {
375 dprintf2(("%x %c", ((char *)lpRequest->lpBuffer)[i], ((char *)lpRequest->lpBuffer)[i]));
376 }
377#endif
378
379 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpRequest->lpBuffer, lpRequest->nNumberOfBytes,
380 &ulBytesWritten);
381
382 *lpdwResult = (ret) ? ulBytesWritten : 0;
383 dprintf2(("KERNEL32:CommWriteIOHandler %d byte(s) written", *lpdwResult));
384
385 if(ulBytesWritten != lpRequest->nNumberOfBytes) {
386 dprintf(("WARNING: ulBytesWritten (%d) != lpRequest->nNumberOfBytes (%d)", ulBytesWritten, lpRequest->nNumberOfBytes));
387 }
388 if(ret == FALSE) {
389 dprintf(("!ERROR!: CommWriteIOHandler failed with rc %d", GetLastError()));
390 }
391 return GetLastError();
392}
393//******************************************************************************
394//Overlapped WaitCommEvent handler
395//******************************************************************************
396DWORD CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut)
397{
398 APIRET rc;
399 ULONG ulLen;
400 USHORT COMEvt;
401 DWORD dwEvent,dwMask;
402 PHMHANDLEDATA pHMHandleData;
403 PHMDEVCOMDATA pDevData;
404
405 pHMHandleData = HMQueryHandleData(lpRequest->hHandle);
406 if(pHMHandleData == NULL || pHMHandleData->lpHandlerData == NULL) {
407 dprintf(("!ERROR!: CommWriteIOHandler handle %x not valid", lpRequest->hHandle));
408 DebugInt3();
409 return ERROR_INVALID_HANDLE;
410 }
411
412 pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
413
414//// dprintf(("CommPollIOHandler %x %x", pHMHandleData->hHMHandle, lpRequest->dwEventMask));
415
416 *lpdwTimeOut = TIMEOUT_COMM;
417
418 ulLen = sizeof(CHAR);
419 dwEvent = 0;
420 rc = 0;
421 ulLen = sizeof(COMEvt);
422 dwMask = lpRequest->dwEventMask;
423
424 if(lpRequest->dwEventMask != pDevData->dwEventMask) {
425 dprintf(("!WARNING!: CommPollIOHandler: operation aborted (event mask changed)"));
426 return ERROR_OPERATION_ABORTED; // Exit if the Mask gets changed
427 }
428 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
429 IOCTL_ASYNC,
430 ASYNC_GETCOMMEVENT,
431 0,0,0,
432 &COMEvt,ulLen,&ulLen);
433 if(!rc)
434 {
435#ifdef DEBUG
436 if(COMEvt) dprintf(("ASYNC_GETCOMMEVENT %x", COMEvt));
437#endif
438 dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
439 //dwEvent |= (COMEvt&0x0002)? 0:0;
440 dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
441 dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
442 dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
443 dwEvent |= (COMEvt&0x0020)? EV_RLSD:0;
444 dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
445 dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
446 dwEvent |= (COMEvt&0x0100)? EV_RING:0;
447
448#ifdef DEBUG
449 if(dwEvent & EV_ERR) {
450 ULONG COMErr = 0;
451
452 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
453 IOCTL_ASYNC,
454 ASYNC_GETCOMMERROR,
455 0,0,0,
456 &COMErr,2,&ulLen);
457
458 dprintf(("!!!!!!!----> ERROR OCCURRED (EV_ERR) reason %x <-----!!!!!", COMErr));
459
460 }
461#endif
462 if((dwEvent & EV_RXCHAR) && (dwMask & EV_RXCHAR))
463 {
464 //check if there's really data in the in queue
465 RXQUEUE qInfo;
466 ULONG ulLen = sizeof(qInfo);
467 ULONG rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
468 IOCTL_ASYNC,
469 ASYNC_GETINQUECOUNT,
470 0,0,0,
471 &qInfo,ulLen,&ulLen);
472 if(qInfo.cch == 0) {
473 dprintf(("!WARNING!: CommPollIOHandler -> EV_RXCHAR but no DATA"));
474 dwEvent &= ~EV_RXCHAR;
475 }
476 }
477 if((dwEvent & dwMask)) {
478 dprintf(("CommPollIOHandler: event(s) %s %x occured", DebugCommEvent((dwEvent & dwMask)), (dwEvent & dwMask)));
479 *lpdwResult = (dwEvent & dwMask);
480 return ERROR_SUCCESS;
481 }
482 }
483 else {
484 dprintf(("!ERROR!: CommPollIOHandler: OSLibDosDevIOCtl failed with rc %d", rc));
485 *lpdwResult = 0;
486 return ERROR_OPERATION_ABORTED;
487 }
488 return ERROR_IO_PENDING;
489}
490/*****************************************************************************
491 * Name : BOOL HMDeviceCommClass::WriteFile
492 * Purpose : write data to handle / device
493 * Parameters: PHMHANDLEDATA pHMHandleData,
494 * LPCVOID lpBuffer,
495 * DWORD nNumberOfBytesToWrite,
496 * LPDWORD lpNumberOfBytesWritten,
497 * LPOVERLAPPED lpOverlapped
498 * Variables :
499 * Result : Boolean
500 * Remark :
501 * Status :
502 *
503 * Author : SvL
504 *****************************************************************************/
505BOOL HMDeviceCommClass::WriteFile(PHMHANDLEDATA pHMHandleData,
506 LPCVOID lpBuffer,
507 DWORD nNumberOfBytesToWrite,
508 LPDWORD lpNumberOfBytesWritten,
509 LPOVERLAPPED lpOverlapped,
510 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
511{
512 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
513 BOOL ret;
514 ULONG ulBytesWritten;
515
516 dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
517 lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite,
518 lpNumberOfBytesWritten, lpOverlapped));
519
520
521 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
522 {
523 ::SetLastError(ERROR_INVALID_HANDLE);
524 return FALSE;
525 }
526
527 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
528 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
529 ::SetLastError(ERROR_INVALID_PARAMETER);
530 return FALSE;
531 }
532 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
533 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
534 }
535 if(lpCompletionRoutine) {
536 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
537 }
538
539#ifdef DEBUG
540 dprintf2(("WriteFile: bytes to write:"));
541 for(int i=0;i<min(nNumberOfBytesToWrite, 16);i++) {
542 dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
543 }
544#endif
545
546 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
547 return pDevData->iohandler->WriteFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToWrite,
548 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData);
549 }
550
551 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
552 &ulBytesWritten);
553
554 if(lpNumberOfBytesWritten) {
555 *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
556 dprintf2(("KERNEL32:HMDeviceCommClass::WriteFile %d byte(s) written", *lpNumberOfBytesWritten));
557 }
558 if(ret == FALSE) {
559 dprintf(("!ERROR!: WriteFile failed with rc %d", GetLastError()));
560 }
561
562 return ret;
563}
564/*****************************************************************************
565 * Name : BOOL HMDeviceCommClass::ReadFile
566 * Purpose : read data from handle / device
567 * Parameters: PHMHANDLEDATA pHMHandleData,
568 * LPCVOID lpBuffer,
569 * DWORD nNumberOfBytesToRead,
570 * LPDWORD lpNumberOfBytesRead,
571 * LPOVERLAPPED lpOverlapped
572 * Variables :
573 * Result : Boolean
574 * Remark :
575 * Status :
576 *
577 * Author : SvL
578 *****************************************************************************/
579
580BOOL HMDeviceCommClass::ReadFile(PHMHANDLEDATA pHMHandleData,
581 LPCVOID lpBuffer,
582 DWORD nNumberOfBytesToRead,
583 LPDWORD lpNumberOfBytesRead,
584 LPOVERLAPPED lpOverlapped,
585 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
586{
587 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
588 BOOL ret;
589 ULONG ulBytesRead;
590
591 dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
592 lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead,
593 lpNumberOfBytesRead, lpOverlapped));
594
595 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
596 {
597 ::SetLastError(ERROR_INVALID_HANDLE);
598 return FALSE;
599 }
600
601 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
602 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
603 ::SetLastError(ERROR_INVALID_PARAMETER);
604 return FALSE;
605 }
606 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
607 dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
608 }
609
610 if(lpCompletionRoutine) {
611 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
612 }
613
614 RXQUEUE qInfo;
615 ULONG ulLen = sizeof(qInfo);
616 ULONG rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, IOCTL_ASYNC, ASYNC_GETINQUECOUNT, 0,0,0, &qInfo,ulLen,&ulLen);
617 dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc));
618
619 if(!qInfo.cch && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
620 return pDevData->iohandler->ReadFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToRead,
621 lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData);
622 }
623
624 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
625 &ulBytesRead);
626
627 if(lpNumberOfBytesRead) {
628 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
629 dprintf2(("KERNEL32:HMDeviceCommClass::ReadFile %d bytes read", *lpNumberOfBytesRead));
630 if(qInfo.cch > ulBytesRead) {
631 dprintf(("Warning: more bytes available!!"));
632 }
633 }
634 if(ret == FALSE) {
635 dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError()));
636 }
637#ifdef DEBUG
638 else {
639 int i;
640 dprintf2(("%d Bytes read:", ulBytesRead));
641#ifdef DEBUG_COMOUTPUT
642 char *tmp = (char *)malloc(ulBytesRead+1);
643 memcpy(tmp, lpBuffer, ulBytesRead);
644 tmp[ulBytesRead] = 0;
645 dprintf2(("RF: %s", tmp));
646 WORD sel = RestoreOS2FS();
647 for(i=0;i<ulBytesRead;i++) {
648 fprintf(comlog, "%c", tmp[i]);
649 }
650 SetFS(sel);
651 free(tmp);
652#endif
653 for(i=0;i<ulBytesRead;i++) {
654 dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i]));
655 }
656 }
657#endif
658
659 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
660 //reset overlapped semaphore to non-signalled
661 ::ResetEvent(lpOverlapped->hEvent);
662
663 //set event to make sure next GetOverlappedResult doesn't block
664 ::SetEvent(lpOverlapped->hEvent);
665
666 lpOverlapped->Internal = GetLastError();
667 lpOverlapped->InternalHigh = ulBytesRead;
668 }
669 return ret;
670}
671/*****************************************************************************
672 * Name : DWORD HMDeviceHandler::SetupComm
673 * Purpose : set com port parameters (queue)
674 * Variables :
675 * Result :
676 * Remark :
677 * Status :
678 *
679 * Author : Achim Hasenmueller
680 *****************************************************************************/
681
682BOOL HMDeviceCommClass::SetupComm( PHMHANDLEDATA pHMHandleData,
683 DWORD dwInQueue,
684 DWORD dwOutQueue)
685{
686 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
687
688 dprintf(("HMDeviceCommClass::SetupComm "));
689 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
690 {
691 ::SetLastError(ERROR_INVALID_HANDLE);
692 return FALSE;
693 }
694 pDevData->dwInBuffer = dwInQueue;
695 pDevData->dwOutBuffer = dwOutQueue;
696
697 return(TRUE);
698}
699//******************************************************************************
700//******************************************************************************
701BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
702 LPDWORD lpfdwEvtMask,
703 LPOVERLAPPED lpo)
704{
705 APIRET rc;
706 ULONG ulLen;
707 USHORT COMEvt;
708 DWORD dwEvent,dwMask;
709
710 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
711
712 dprintf(("HMDeviceCommClass::WaitCommEvent %x %x %x", pHMHandleData->hHMHandle, lpfdwEvtMask, lpo));
713
714 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) {
715 dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo"));
716 ::SetLastError(ERROR_INVALID_PARAMETER);
717 return FALSE;
718 }
719
720 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)
721 {
722 return pDevData->iohandler->WaitForEvent(pHMHandleData->hWin32Handle, pDevData->dwEventMask, lpfdwEvtMask,
723 lpo, NULL, (DWORD)pDevData);
724 }
725
726 ulLen = sizeof(CHAR);
727
728 dwEvent = 0;
729 rc = 0;
730 ulLen = sizeof(COMEvt);
731 dwMask = pDevData->dwEventMask;
732 while( (0==rc) &&
733 !(dwEvent & dwMask) &&
734 (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
735 {
736 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
737 IOCTL_ASYNC,
738 ASYNC_GETCOMMEVENT,
739 0,0,0,
740 &COMEvt,ulLen,&ulLen);
741 if(!rc)
742 {
743 dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
744 //dwEvent |= (COMEvt&0x0002)? 0:0;
745 dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
746 dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
747 dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
748 dwEvent |= (COMEvt&0x0020)? EV_RLSD:0;
749 dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
750 dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
751 dwEvent |= (COMEvt&0x0100)? EV_RING:0;
752 if((dwEvent & dwMask)) break;
753 }
754 else break;
755
756 DosSleep(TIMEOUT_COMM);
757 }
758 if(dwMask == pDevData->dwEventMask) {
759 *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0;
760 dprintf(("WaitCommEvent returned %s %x", DebugCommEvent(*lpfdwEvtMask), *lpfdwEvtMask));
761 }
762 else *lpfdwEvtMask = 0;
763
764 ::SetLastError(rc);
765 return (rc==0);
766}
767/*****************************************************************************
768 * Name : DWORD HMDeviceCommClass::CancelIo
769 * Purpose : cancel pending IO operation
770 * Variables :
771 * Result :
772 * Remark :
773 * Status :
774 *
775 * Author : SvL
776 *****************************************************************************/
777BOOL HMDeviceCommClass::CancelIo(PHMHANDLEDATA pHMHandleData)
778{
779 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
780
781 dprintf(("HMDeviceCommClass::CancelIo"));
782 if(pDevData == NULL || !(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
783 ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
784 return FALSE;
785 }
786
787 return pDevData->iohandler->CancelIo(pHMHandleData->hWin32Handle);
788}
789/*****************************************************************************
790 * Name : DWORD HMDeviceFileClass::GetOverlappedResult
791 * Purpose : asynchronus I/O
792 * Parameters: PHMHANDLEDATA pHMHandleData
793 * LPOVERLAPPED arg2
794 * LPDWORD arg3
795 * BOOL arg4
796 * Variables :
797 * Result : API returncode
798 * Remark :
799 * Status :
800 *
801 * Author : SvL
802 *****************************************************************************/
803BOOL HMDeviceCommClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
804 LPOVERLAPPED lpOverlapped,
805 LPDWORD lpcbTransfer,
806 BOOL fWait)
807{
808 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
809
810 dprintf(("KERNEL32-HMDeviceCommClass: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh)",
811 pHMHandleData->hHMHandle, lpOverlapped, lpcbTransfer, fWait));
812
813 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) {
814 dprintf(("!WARNING!: GetOverlappedResult called for a handle that wasn't opened with FILE_FLAG_OVERLAPPED"));
815 return TRUE; //NT4, SP6 doesn't fail
816 }
817
818 if(pDevData == NULL) {
819 ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error?
820 return FALSE;
821 }
822 if(!lpOverlapped) {
823 ::SetLastError(ERROR_INVALID_PARAMETER);
824 return FALSE;
825 }
826 return pDevData->iohandler->GetOverlappedResult(pHMHandleData->hWin32Handle, lpOverlapped, lpcbTransfer, fWait);
827}
828//******************************************************************************
829//******************************************************************************
830BOOL HMDeviceCommClass::GetCommProperties(PHMHANDLEDATA pHMHandleData,
831 LPCOMMPROP lpcmmp)
832{
833 EXTBAUDGET BaudInfo;
834 APIRET rc;
835 ULONG ulLen;
836 USHORT COMErr;
837 int i;
838 dprintf(("HMDeviceCommClass::GetCommProperties"));
839
840 ulLen = sizeof(EXTBAUDGET);
841 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
842 IOCTL_ASYNC,
843 ASYNC_EXTGETBAUDRATE,
844 0,0,0,
845 &BaudInfo,ulLen,&ulLen);
846 memset(lpcmmp,0,sizeof(COMMPROP));
847 lpcmmp->wPacketLength = sizeof(COMMPROP);
848 lpcmmp->wPacketVersion = 1; //???
849 lpcmmp->dwServiceMask = SP_SERIALCOMM;
850 for(i=0;i<BaudTableSize && BaudInfo.ulMaxBaud <= BaudTable[i].dwBaudRate;i++);
851 lpcmmp->dwMaxBaud = BaudTable[i].dwBaudFlag;
852 lpcmmp->dwProvSubType = PST_RS232;
853 lpcmmp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK |
854 PCF_RTSCTS | PCF_SETXCHAR |
855 PCF_XONXOFF;
856 lpcmmp->dwSettableParams = SP_BAUD | SP_DATABITS |
857 SP_HANDSHAKEING | SP_PARITY |
858 SP_PARITY_CHECK | SP_STOPBIT;
859 lpcmmp->dwSettableBaud = 0;
860 for(i=0;i<BaudTableSize;i++)
861 {
862 if ( (BaudTable[i].dwBaudRate>=BaudInfo.ulMinBaud) &&
863 (BaudTable[i].dwBaudRate<=BaudInfo.ulMaxBaud) )
864 lpcmmp->dwSettableBaud |= BaudTable[i].dwBaudFlag;
865 }
866 lpcmmp->dwSettableBaud |= BAUD_USER;
867 lpcmmp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
868 lpcmmp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
869 PARITY_NONE | PARITY_ODD | PARITY_EVEN |
870 PARITY_MARK | PARITY_SPACE;
871 return(rc==0);
872}
873//******************************************************************************
874//******************************************************************************
875BOOL HMDeviceCommClass::GetCommMask( PHMHANDLEDATA pHMHandleData,
876 LPDWORD lpfdwEvtMask)
877{
878 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
879
880 dprintf(("HMDeviceCommClass::GetCommMask"));
881
882 *lpfdwEvtMask = pDevData->dwEventMask;
883 return(TRUE);
884}
885//******************************************************************************
886//******************************************************************************
887BOOL HMDeviceCommClass::SetCommMask( PHMHANDLEDATA pHMHandleData,
888 DWORD fdwEvtMask)
889{
890 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
891 dprintf(("HMDeviceCommClass::SetCommMask %x", fdwEvtMask));
892
893 if(fdwEvtMask & (EV_RXFLAG)) {
894 dprintf(("!WARNING! SetCommMask: unsupported flag EV_RXFLAG!!"));
895 }
896
897 pDevData->dwEventMask = fdwEvtMask & ~(EV_RXFLAG); // Clear the not supported Flag.
898 return(TRUE);
899}
900//******************************************************************************
901//******************************************************************************
902BOOL HMDeviceCommClass::PurgeComm( PHMHANDLEDATA pHMHandleData,
903 DWORD fdwAction)
904{
905 ULONG ulParLen, ulDataLen, rc = ERROR_SUCCESS;
906 BYTE par = 0;
907 WORD data = 0;
908
909 dprintf(("HMDeviceCommClass::PurgeComm (flags 0x%x) partly implemented",fdwAction));
910 // ToDo: find a way to stop the current transmision didn't find
911 // any clue how to in Control Program Guide and reference
912
913 ulParLen = sizeof(par);
914 ulDataLen = sizeof(data);
915 if(fdwAction & PURGE_TXCLEAR) {
916 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
917 IOCTL_GENERAL,
918 DEV_FLUSHOUTPUT,
919 &par,ulParLen,&ulParLen,
920 &data,ulDataLen,&ulDataLen);
921 }
922 if(fdwAction & PURGE_RXCLEAR) {
923 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
924 IOCTL_GENERAL,
925 DEV_FLUSHINPUT,
926 &par,ulParLen,&ulParLen,
927 &data,ulDataLen,&ulDataLen);
928 }
929 if(rc) {
930 dprintf(("!WARNING! OSLibDosDevIOCtl failed with rc %d", rc));
931 }
932 return (rc == ERROR_SUCCESS);
933}
934//******************************************************************************
935//******************************************************************************
936BOOL HMDeviceCommClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
937 LPDWORD lpdwErrors,
938 LPCOMSTAT lpcst)
939{
940 APIRET rc;
941 ULONG ulLen, dwError = 0;
942 USHORT COMErr;
943
944 if(lpdwErrors == NULL)
945 lpdwErrors = &dwError;
946
947 dprintf(("HMDeviceCommClass::ClearCommError"));
948 ulLen = sizeof(USHORT);
949
950 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
951 IOCTL_ASYNC,
952 ASYNC_GETCOMMERROR,
953 0,0,0,
954 &COMErr,2,&ulLen);
955 *lpdwErrors = 0;
956 *lpdwErrors |= (COMErr & 0x0001)?CE_OVERRUN:0;
957 *lpdwErrors |= (COMErr & 0x0002)?CE_RXOVER:0;
958 *lpdwErrors |= (COMErr & 0x0004)?CE_RXPARITY:0;
959 *lpdwErrors |= (COMErr & 0x0008)?CE_FRAME:0;
960
961 dprintf(("Error %x", *lpdwErrors));
962 if(lpcst)
963 {
964 UCHAR ucStatus;
965 RXQUEUE qInfo;
966 ulLen = 1;
967 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
968 IOCTL_ASYNC,
969 ASYNC_GETCOMMSTATUS,
970 0,0,0,
971 &ucStatus,ulLen,&ulLen);
972 if(!rc)
973 {
974 lpcst->fCtsHold = ((ucStatus & 0x01)>0);
975 lpcst->fDsrHold = ((ucStatus & 0x02)>0);
976 lpcst->fRlsdHold = FALSE;//(ucStatus & 0x04)>0);
977 lpcst->fXoffHold = ((ucStatus & 0x08)>0);
978 lpcst->fXoffSend = ((ucStatus & 0x10)>0);
979 lpcst->fEof = ((ucStatus & 0x20)>0);// Is break = Eof ??
980 lpcst->fTxim = ((ucStatus & 0x40)>0);
981
982 ulLen = sizeof(qInfo);
983 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
984 IOCTL_ASYNC,
985 ASYNC_GETINQUECOUNT,
986 0,0,0,
987 &qInfo,ulLen,&ulLen);
988 if(!rc)
989 {
990 lpcst->cbInQue = qInfo.cch;
991 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
992 IOCTL_ASYNC,
993 ASYNC_GETOUTQUECOUNT,
994 0,0,0,
995 &qInfo,ulLen,&ulLen);
996 if(!rc)
997 lpcst->cbOutQue = qInfo.cch;
998 }
999 }
1000 }
1001
1002 return(rc==0);
1003}
1004//******************************************************************************
1005//******************************************************************************
1006BOOL HMDeviceCommClass::SetCommState( PHMHANDLEDATA pHMHandleData,
1007 LPDCB lpDCB)
1008{
1009 APIRET rc;
1010 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1011 DCB *pCurDCB = &pDevData->CommCfg.dcb;
1012 dprintf(("HMDeviceCommClass::SetCommState"));
1013
1014 rc = 0;
1015 if(pCurDCB->BaudRate != lpDCB->BaudRate) {
1016 dprintf(("SetCommState: change baud rate from %d to %d", pCurDCB->BaudRate, lpDCB->BaudRate));
1017 rc = SetBaud( pHMHandleData,
1018 lpDCB->BaudRate);
1019 }
1020
1021 if(!rc)
1022 {
1023 if( (pCurDCB->ByteSize != lpDCB->ByteSize) ||
1024 (pCurDCB->Parity != lpDCB->Parity) ||
1025 (pCurDCB->StopBits != lpDCB->StopBits))
1026 {
1027 dprintf(("SetCommState: change line %d %d %d", lpDCB->ByteSize, lpDCB->Parity, lpDCB->StopBits));
1028 rc = SetLine( pHMHandleData,
1029 lpDCB->ByteSize,
1030 lpDCB->Parity,
1031 lpDCB->StopBits);
1032 }
1033 }
1034
1035 if(!rc)
1036 {
1037 if( (pCurDCB->fOutxCtsFlow != lpDCB->fOutxCtsFlow) ||
1038 (pCurDCB->fOutxDsrFlow != lpDCB->fOutxDsrFlow) ||
1039 (pCurDCB->fDtrControl != lpDCB->fDtrControl) ||
1040 (pCurDCB->fDsrSensitivity != lpDCB->fDsrSensitivity) ||
1041 (pCurDCB->fTXContinueOnXoff != lpDCB->fTXContinueOnXoff) ||
1042 (pCurDCB->fOutX != lpDCB->fOutX) ||
1043 (pCurDCB->fInX != lpDCB->fInX) ||
1044 (pCurDCB->fErrorChar != lpDCB->fErrorChar) ||
1045 (pCurDCB->fNull != lpDCB->fNull) ||
1046 (pCurDCB->fRtsControl != lpDCB->fRtsControl) ||
1047 (pCurDCB->fAbortOnError != lpDCB->fAbortOnError) ||
1048 (pCurDCB->XonChar != lpDCB->XonChar) ||
1049 (pCurDCB->XoffChar != lpDCB->XoffChar) ||
1050 (pCurDCB->ErrorChar != lpDCB->ErrorChar))
1051 {
1052 dprintf(("SetCommState: change flags cts %d dsr %d dtr %d dsr %d tx %d out %d in %d ferror %d null %d rts %d abort %d xon %d xoff %d error %d", lpDCB->fOutxCtsFlow, lpDCB->fOutxDsrFlow,lpDCB->fDtrControl,lpDCB->fDsrSensitivity,lpDCB->fDsrSensitivity,lpDCB->fTXContinueOnXoff,lpDCB->fOutX, lpDCB->fInX,lpDCB->fErrorChar,lpDCB->fNull,lpDCB->fRtsControl,lpDCB->fAbortOnError,lpDCB->XonChar,lpDCB->XoffChar,lpDCB->ErrorChar));
1053 SetOS2DCB( pHMHandleData,
1054 lpDCB->fOutxCtsFlow, lpDCB->fOutxDsrFlow,
1055 lpDCB->fDtrControl, lpDCB->fDsrSensitivity,
1056 lpDCB->fTXContinueOnXoff, lpDCB->fOutX,
1057 lpDCB->fInX, lpDCB->fErrorChar,
1058 lpDCB->fNull, lpDCB->fRtsControl,
1059 lpDCB->fAbortOnError, lpDCB->XonChar,
1060 lpDCB->XoffChar,lpDCB->ErrorChar);
1061 }
1062 }
1063
1064 return(rc==0);
1065}
1066//******************************************************************************
1067//******************************************************************************
1068BOOL HMDeviceCommClass::GetCommState( PHMHANDLEDATA pHMHandleData,
1069 LPDCB lpdcb)
1070{
1071 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1072
1073 dprintf(("HMDeviceCommClass::GetCommState %x", lpdcb));
1074
1075 if(lpdcb == NULL) {
1076 ::SetLastError(ERROR_INVALID_PARAMETER);
1077 return FALSE;
1078 }
1079
1080 memcpy(lpdcb,&pDevData->CommCfg.dcb,sizeof(DCB));
1081 return(TRUE);
1082}
1083//******************************************************************************
1084//******************************************************************************
1085BOOL HMDeviceCommClass::GetCommModemStatus( PHMHANDLEDATA pHMHandleData,
1086 LPDWORD lpModemStat )
1087{
1088 APIRET rc;
1089 ULONG ulLen;
1090 USHORT COMErr;
1091 UCHAR ucStatus;
1092
1093 dprintf(("HMDeviceCommClass::GetCommModemStatus %x", lpModemStat));
1094 if(lpModemStat == NULL) {
1095 ::SetLastError(ERROR_INVALID_PARAMETER);
1096 return FALSE;
1097 }
1098
1099 ulLen = sizeof(CHAR);
1100
1101 ulLen = 1;
1102 *lpModemStat = 0;
1103
1104 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1105 IOCTL_ASYNC,
1106 ASYNC_GETMODEMINPUT,
1107 0,0,0,
1108 &ucStatus,ulLen,&ulLen);
1109 if(!rc)
1110 {
1111 *lpModemStat |= (ucStatus & 0x10)? MS_CTS_ON:0;
1112 *lpModemStat |= (ucStatus & 0x20)? MS_DSR_ON:0;
1113 *lpModemStat |= (ucStatus & 0x40)? MS_RING_ON:0;
1114 *lpModemStat |= (ucStatus & 0x80)? MS_RLSD_ON:0;
1115 }
1116
1117 dprintf2(("HMDeviceCommClass::GetCommModemStatus -> %s %x rc=%d", DebugModemStatus(*lpModemStat), *lpModemStat, rc));
1118 return(rc==0);
1119}
1120//******************************************************************************
1121//******************************************************************************
1122BOOL HMDeviceCommClass::GetCommTimeouts( PHMHANDLEDATA pHMHandleData,
1123 LPCOMMTIMEOUTS lpctmo)
1124{
1125 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1126
1127 dprintf(("HMDeviceCommClass::GetCommTimeouts %x stub", lpctmo));
1128
1129 if(lpctmo == NULL) {
1130 ::SetLastError(ERROR_INVALID_PARAMETER);
1131 return FALSE;
1132 }
1133
1134 memcpy( lpctmo,
1135 &pDevData->CommTOuts,
1136 sizeof(COMMTIMEOUTS));
1137 return(TRUE);
1138}
1139//******************************************************************************
1140//******************************************************************************
1141BOOL HMDeviceCommClass::SetCommTimeouts( PHMHANDLEDATA pHMHandleData,
1142 LPCOMMTIMEOUTS lpctmo)
1143{
1144 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1145 DCBINFO os2dcb;
1146 ULONG ulLen;
1147 APIRET rc;
1148 UCHAR fbTimeOut;
1149
1150 if(lpctmo == NULL) {
1151 dprintf(("!WARNING! HMDeviceCommClass::SetCommTimeouts %x -> invalid parameter", lpctmo));
1152 ::SetLastError(ERROR_INVALID_PARAMETER);
1153 return FALSE;
1154 }
1155
1156 dprintf(("HMDeviceCommClass::SetCommTimeouts\n"
1157 " ReadIntervalTimeout : 0x%x\n"
1158 " ReadTotalTimeoutMultiplier : %d\n"
1159 " ReadTotalTimeoutConstant : %d\n"
1160 " WriteTotalTimeoutMultiplier : %d\n"
1161 " WriteTotalTimeoutConstant : %d\n",
1162 lpctmo->ReadIntervalTimeout,
1163 lpctmo->ReadTotalTimeoutMultiplier,
1164 lpctmo->ReadTotalTimeoutConstant,
1165 lpctmo->WriteTotalTimeoutMultiplier,
1166 lpctmo->WriteTotalTimeoutConstant
1167 ));
1168
1169 memcpy( &pDevData->CommTOuts,
1170 lpctmo,
1171 sizeof(COMMTIMEOUTS));
1172
1173 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
1174
1175 fbTimeOut = 0x02; //normal processing (wait until timout or buffer full)
1176 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
1177 {
1178 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
1179 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
1180 fbTimeOut = 0x05; //no wait
1181 else
1182 fbTimeOut = 0x04; //wait for something
1183 }
1184 else
1185 {
1186 DWORD dwTimeout;
1187 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
1188 if(dwTimeout)
1189 dwTimeout--; // 0=10 ms unit is 10ms or .01s
1190
1191 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
1192 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
1193 }
1194 if( (0==pDevData->CommTOuts.WriteTotalTimeoutMultiplier) &&
1195 (0==pDevData->CommTOuts.WriteTotalTimeoutConstant))
1196 {//no timeout used for writing
1197 os2dcb.fbTimeOut |= 1; //write infinite timeout
1198 }
1199
1200 os2dcb.fbTimeOut = (os2dcb.fbTimeOut & 0xF8) | fbTimeOut;
1201
1202 dprintf((" New DCB:\n"
1203 " WriteTimeout : %d\n"
1204 " ReadTimeout : %d\n"
1205 " CtlHandshake : 0x%x\n"
1206 " FlowReplace : 0x%x\n"
1207 " Timeout : 0x%x\n"
1208 " Error replacement Char : 0x%x\n"
1209 " Break replacement Char : 0x%x\n"
1210 " XON Char : 0x%x\n"
1211 " XOFF Char : 0x%x\n",
1212 os2dcb.usWriteTimeout,
1213 os2dcb.usReadTimeout,
1214 os2dcb.fbCtlHndShake,
1215 os2dcb.fbFlowReplace,
1216 os2dcb.fbTimeOut,
1217 os2dcb.bErrorReplacementChar,
1218 os2dcb.bBreakReplacementChar,
1219 os2dcb.bXONChar,
1220 os2dcb.bXOFFChar));
1221
1222 ulLen = sizeof(DCBINFO);
1223 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1224 IOCTL_ASYNC,
1225 ASYNC_SETDCBINFO,
1226 &os2dcb,ulLen,&ulLen,
1227 NULL,0,NULL);
1228 dprintf(("IOCRL returned %d",rc));
1229 return(0==rc);
1230}
1231//******************************************************************************
1232//******************************************************************************
1233BOOL HMDeviceCommClass::TransmitCommChar( PHMHANDLEDATA pHMHandleData,
1234 CHAR cChar )
1235{
1236 APIRET rc;
1237 ULONG ulLen;
1238 USHORT COMErr;
1239
1240 dprintf(("HMDeviceCommClass::TransmitCommChar"));
1241 ulLen = sizeof(CHAR);
1242
1243 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1244 IOCTL_ASYNC,
1245 ASYNC_TRANSMITIMM,
1246 &cChar,ulLen,&ulLen,
1247 NULL,0,NULL);
1248
1249 return(rc==0);
1250}
1251//******************************************************************************
1252//******************************************************************************
1253BOOL HMDeviceCommClass::SetCommBreak( PHMHANDLEDATA pHMHandleData )
1254{
1255 APIRET rc;
1256 ULONG ulLen;
1257 USHORT COMErr;
1258
1259 dprintf(("HMDeviceCommClass::SetCommBreak"));
1260 ulLen = sizeof(USHORT);
1261
1262 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1263 IOCTL_ASYNC,
1264 ASYNC_SETBREAKON,
1265 0,0,0,
1266 &COMErr,2,&ulLen);
1267
1268 return(rc==0);
1269}
1270//******************************************************************************
1271//******************************************************************************
1272BOOL HMDeviceCommClass::ClearCommBreak( PHMHANDLEDATA pHMHandleData)
1273{
1274 APIRET rc;
1275 ULONG ulLen;
1276 USHORT COMErr;
1277
1278 dprintf(("HMDeviceCommClass::ClearCommBreak"));
1279 ulLen = sizeof(USHORT);
1280
1281 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1282 IOCTL_ASYNC,
1283 ASYNC_SETBREAKOFF,
1284 0,0,0,
1285 &COMErr,2,&ulLen);
1286
1287 return(rc==0);
1288}
1289//******************************************************************************
1290//******************************************************************************
1291BOOL HMDeviceCommClass::SetCommConfig( PHMHANDLEDATA pHMHandleData,
1292 LPCOMMCONFIG lpCC,
1293 DWORD dwSize )
1294{
1295 dprintf(("HMDeviceCommClass::SetCommConfig NOT IMPLEMENTED"));
1296
1297 return(TRUE);
1298}
1299//******************************************************************************
1300//******************************************************************************
1301BOOL HMDeviceCommClass::GetCommConfig( PHMHANDLEDATA pHMHandleData,
1302 LPCOMMCONFIG lpCC,
1303 LPDWORD lpdwSize )
1304{
1305 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1306
1307 dprintf(("HMDeviceCommClass::GetCommConfig"));
1308
1309 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
1310 *lpdwSize< sizeof(COMMCONFIG) )
1311 {
1312 ::SetLastError(ERROR_INSUFFICIENT_BUFFER);
1313 *lpdwSize= sizeof(COMMCONFIG);
1314 return FALSE;
1315 }
1316
1317 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
1318 {
1319 ::SetLastError(ERROR_INVALID_HANDLE);
1320 return FALSE;
1321 }
1322
1323 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
1324 *lpdwSize = sizeof(COMMCONFIG);
1325 return(TRUE);
1326}
1327//******************************************************************************
1328//******************************************************************************
1329BOOL HMDeviceCommClass::EscapeCommFunction( PHMHANDLEDATA pHMHandleData,
1330 UINT dwFunc )
1331{
1332 APIRET rc;
1333 ULONG ulDLen,ulPLen;
1334 USHORT COMErr;
1335 MODEMSTATUS mdm;
1336
1337 dprintf(("HMDeviceCommClass::EscapeCommFunction %x", dwFunc));
1338
1339 ulDLen = sizeof(USHORT);
1340 ulPLen = sizeof(MODEMSTATUS);
1341 switch(dwFunc)
1342 {
1343 case CLRDTR:
1344 mdm.fbModemOn = 0x00;
1345 mdm.fbModemOff = 0XFE;
1346 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1347 IOCTL_ASYNC,
1348 ASYNC_SETMODEMCTRL,
1349 &mdm,ulPLen,&ulPLen,
1350 &COMErr,ulDLen,&ulDLen);
1351 dprintf(("CLRDTR rc = %d Comerror = 0x%x",rc,COMErr));
1352 rc = COMErr;
1353 if(rc==0)
1354 {
1355 BYTE bModem;
1356 ulDLen = sizeof(BYTE);
1357 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1358 IOCTL_ASYNC,
1359 ASYNC_GETMODEMOUTPUT,
1360 NULL,0,NULL,
1361 &bModem,ulDLen,&ulDLen);
1362 dprintf(("Check DTR rc = %d Flags = 0x%x",rc,bModem));
1363 rc = bModem & 0x01;
1364 }
1365 break;
1366 case CLRRTS:
1367 mdm.fbModemOn = 0x00;
1368 mdm.fbModemOff = 0XFD;
1369 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1370 IOCTL_ASYNC,
1371 ASYNC_SETMODEMCTRL,
1372 &mdm,ulPLen,&ulPLen,
1373 &COMErr,ulDLen,&ulDLen);
1374 dprintf(("CLRRTS: rc = %d, Comm error %x", rc, COMErr));
1375 break;
1376 case SETDTR:
1377 mdm.fbModemOn = 0x01;
1378 mdm.fbModemOff = 0XFF;
1379 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1380 IOCTL_ASYNC,
1381 ASYNC_SETMODEMCTRL,
1382 &mdm,ulPLen,&ulPLen,
1383 &COMErr,ulDLen,&ulDLen);
1384 dprintf(("SETDTR: rc = %d, Comm error %x", rc, COMErr));
1385 break;
1386 case SETRTS:
1387 mdm.fbModemOn = 0x02;
1388 mdm.fbModemOff = 0XFF;
1389 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1390 IOCTL_ASYNC,
1391 ASYNC_SETMODEMCTRL,
1392 &mdm,ulPLen,&ulPLen,
1393 &COMErr,ulDLen,&ulDLen);
1394 dprintf(("SETRTS: rc = %d, Comm error %x", rc, COMErr));
1395 break;
1396 case SETXOFF:
1397 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1398 IOCTL_ASYNC,
1399 ASYNC_STOPTRANSMIT,
1400 0,0,0,
1401 0,0,0);
1402 dprintf(("SETXOFF: rc = %d", rc));
1403 break;
1404 case SETXON:
1405 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1406 IOCTL_ASYNC,
1407 ASYNC_STARTTRANSMIT,
1408 0,0,0,
1409 0,0,0);
1410 dprintf(("SETXON: rc = %d", rc));
1411 break;
1412 default:
1413 dprintf(("!ERROR!: EscapeCommFunction: unknown function"));
1414 ::SetLastError(ERROR_INVALID_PARAMETER);
1415 return(FALSE);
1416 }
1417
1418 return(rc==0);
1419}
1420//******************************************************************************
1421//******************************************************************************
1422BOOL HMDeviceCommClass::SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
1423 LPCOMMCONFIG lpCC,
1424 DWORD dwSize)
1425{
1426 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
1427 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
1428 {
1429 ::SetLastError(ERROR_INVALID_HANDLE);
1430 return FALSE;
1431 }
1432
1433 dprintf(("SetDefaultCommConfig %x %d", lpCC, dwSize));
1434 memset(&pDevData->CommCfg,0, sizeof(COMMCONFIG));
1435 memcpy(&pDevData->CommCfg,lpCC,dwSize>sizeof(COMMCONFIG)?sizeof(COMMCONFIG):dwSize);
1436
1437 return(TRUE);
1438}
1439//******************************************************************************
1440//******************************************************************************
1441BOOL HMDeviceCommClass::GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
1442 LPCOMMCONFIG lpCC,
1443 LPDWORD lpdwSize)
1444{
1445 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
1446
1447 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
1448 *lpdwSize< sizeof(COMMCONFIG) )
1449 {
1450 ::SetLastError(ERROR_INSUFFICIENT_BUFFER);
1451 *lpdwSize= sizeof(COMMCONFIG);
1452 return FALSE;
1453 }
1454
1455 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
1456 {
1457 ::SetLastError(ERROR_INVALID_HANDLE);
1458 return FALSE;
1459 }
1460 dprintf(("GetDefaultCommConfig %x %x", lpCC, lpdwSize));
1461
1462 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
1463 *lpdwSize = sizeof(COMMCONFIG);
1464 return(TRUE);
1465}
1466//******************************************************************************
1467//******************************************************************************
1468APIRET HMDeviceCommClass::SetLine( PHMHANDLEDATA pHMHandleData,
1469 UCHAR ucSize,
1470 UCHAR ucParity,
1471 UCHAR ucStop)
1472{
1473 APIRET rc;
1474 ULONG ulLen;
1475 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1476 DCB *pCurDCB = &pDevData->CommCfg.dcb;
1477 struct
1478 {
1479 UCHAR ucSize;
1480 UCHAR ucParity;
1481 UCHAR ucStop;
1482 UCHAR ucPadding;
1483 }Param;
1484
1485 ulLen = 3;
1486 Param.ucSize = ucSize;
1487 Param.ucParity = ucParity;
1488 Param.ucStop = ucStop;
1489
1490 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1491 IOCTL_ASYNC,
1492 ASYNC_SETLINECTRL,
1493 &Param,ulLen,&ulLen,
1494 NULL,0,NULL);
1495
1496 if(0==rc)
1497 {
1498 pCurDCB->ByteSize = ucSize;
1499 pCurDCB->Parity = ucParity;
1500 pCurDCB->StopBits = ucStop;
1501 }
1502 else {
1503 dprintf(("!ERROR! SetLine: OSLibDosDevIOCtl failed with rc %d", rc));
1504 }
1505 return rc;
1506}
1507//******************************************************************************
1508//******************************************************************************
1509APIRET HMDeviceCommClass::SetOS2DCB( PHMHANDLEDATA pHMHandleData,
1510 BOOL fOutxCtsFlow, BOOL fOutxDsrFlow,
1511 UCHAR ucDtrControl, BOOL fDsrSensitivity,
1512 BOOL fTXContinueOnXoff, BOOL fOutX,
1513 BOOL fInX, BOOL fErrorChar,
1514 BOOL fNull, UCHAR ucRtsControl,
1515 BOOL fAbortOnError, BYTE XonChar,
1516 BYTE XoffChar,BYTE ErrorChar)
1517{
1518 APIRET rc;
1519 ULONG ulLen;
1520 DCBINFO os2dcb;
1521 UCHAR fbTimeOut;
1522 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1523 DCB *pCurDCB = &pDevData->CommCfg.dcb;
1524
1525 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
1526 os2dcb.fbCtlHndShake = (ucDtrControl & 0x03) |
1527 (fOutxCtsFlow?0x08:0x00) |
1528 (fOutxDsrFlow?0x10:0x00) |
1529 // No DCD support in Win32 ?!
1530 (fDsrSensitivity?0x40:0x00);
1531 os2dcb.fbFlowReplace = (fOutX?0x01:0x00) |
1532 (fInX?0x02:0x00) |
1533 (fErrorChar?0x04:0x00)|
1534 (fNull?0x08:0x00)|
1535 (fTXContinueOnXoff?0x02:0x00)| // Not sure if thats the right flag to test
1536 (ucRtsControl<<6);
1537
1538 fbTimeOut = 0x02;
1539 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
1540 {
1541 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
1542 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
1543 fbTimeOut = 0x05;
1544 else
1545 fbTimeOut = 0x04;
1546 }
1547 else
1548 {
1549 DWORD dwTimeout;
1550 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
1551 if(dwTimeout)
1552 dwTimeout--; // 0=10 ms unit is 10ms or .01s
1553 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
1554 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
1555 }
1556 os2dcb.fbTimeOut = (os2dcb.fbTimeOut & 0xF9) | fbTimeOut;
1557 os2dcb.bErrorReplacementChar = ErrorChar;
1558 os2dcb.bXONChar = XonChar;
1559 os2dcb.bXOFFChar = XoffChar;
1560 ulLen = sizeof(DCBINFO);
1561 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1562 IOCTL_ASYNC,
1563 ASYNC_SETDCBINFO,
1564 &os2dcb,ulLen,&ulLen,
1565 NULL,0,NULL);
1566
1567 if(0==rc)
1568 {
1569 memcpy(&pDevData->dcbOS2,&os2dcb,sizeof(DCBINFO));
1570 pCurDCB->fOutxCtsFlow = fOutxCtsFlow;
1571 pCurDCB->fOutxDsrFlow = fOutxDsrFlow;
1572 pCurDCB->fDtrControl = ucDtrControl;
1573 pCurDCB->fDsrSensitivity = fDsrSensitivity;
1574 pCurDCB->fTXContinueOnXoff = fTXContinueOnXoff;
1575 pCurDCB->fOutX = fOutX;
1576 pCurDCB->fInX = fInX;
1577 pCurDCB->fErrorChar = fErrorChar;
1578 pCurDCB->fNull = fNull;
1579 pCurDCB->fRtsControl = ucRtsControl;
1580 pCurDCB->fAbortOnError = fAbortOnError;
1581 pCurDCB->XonChar = XonChar;
1582 pCurDCB->XoffChar = XoffChar;
1583 pCurDCB->ErrorChar = ErrorChar;
1584
1585 dprintf(("OS/2 DCB:\n"
1586 " WriteTimeout : %d\n"
1587 " ReadTimeout : %d\n"
1588 " CtlHandshake : 0x%x\n"
1589 " FlowReplace : 0x%x\n"
1590 " Timeout : 0x%x\n"
1591 " Error replacement Char : 0x%x\n"
1592 " Break replacement Char : 0x%x\n"
1593 " XON Char : 0x%x\n"
1594 " XOFF Char : 0x%x\n",
1595 os2dcb.usWriteTimeout,
1596 os2dcb.usReadTimeout,
1597 os2dcb.fbCtlHndShake,
1598 os2dcb.fbFlowReplace,
1599 os2dcb.fbTimeOut,
1600 os2dcb.bErrorReplacementChar,
1601 os2dcb.bBreakReplacementChar,
1602 os2dcb.bXONChar,
1603 os2dcb.bXOFFChar));
1604
1605 }
1606
1607 return rc;
1608
1609}
1610//******************************************************************************
1611//******************************************************************************
1612APIRET HMDeviceCommClass::SetBaud( PHMHANDLEDATA pHMHandleData,
1613 DWORD dwNewBaud)
1614{
1615 APIRET rc;
1616 ULONG ulLen;
1617 EXTBAUDSET SetBaud;
1618 EXTBAUDGET GetBaud;
1619 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1620
1621 ulLen = sizeof(SetBaud);
1622 SetBaud.ulBaud = dwNewBaud;
1623 SetBaud.ucFrac = 0;
1624 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1625 IOCTL_ASYNC,
1626 ASYNC_EXTSETBAUDRATE,
1627 &SetBaud,ulLen,&ulLen,
1628 NULL,0,NULL);
1629 if(0==rc)
1630 {
1631 ulLen = sizeof(GetBaud);
1632 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1633 IOCTL_ASYNC,
1634 ASYNC_EXTGETBAUDRATE,
1635 NULL,0,NULL,
1636 &GetBaud,ulLen,&ulLen);
1637 if(0==rc)
1638 {
1639 if(dwNewBaud != GetBaud.ulCurrBaud) {
1640 dprintf(("!WARNING! dwNewBaud (%d) != GetBaud.ulCurrBaud (%d)", dwNewBaud, GetBaud.ulCurrBaud));
1641 rc = 1; // ToDo set a proper Errorhandling
1642 }
1643 else
1644 {
1645 pDevData->CommCfg.dcb.BaudRate = dwNewBaud;
1646 }
1647 }
1648 else {
1649 dprintf(("!WARNING! SetBaud: (get) OSLibDosDevIOCtl failed with rc %d", rc));
1650 }
1651 }
1652 else {
1653 dprintf(("!WARNING! SetBaud: (set) OSLibDosDevIOCtl failed with rc %d", rc));
1654 }
1655 return rc;
1656}
1657//******************************************************************************
1658//******************************************************************************
1659void HMDeviceCommClass::CloseOverlappedIOHandlers()
1660{
1661 for(int i=0;i<MAX_COMPORTS;i++) {
1662 if(handler[i]) {
1663 handler[i]->Release(TRUE);
1664 handler[i] = NULL;
1665 }
1666 }
1667}
1668#ifdef DEBUG_LOGGING
1669//******************************************************************************
1670//******************************************************************************
1671static char *DebugCommEvent(DWORD dwEvents)
1672{
1673 static char szCommEvents[128];
1674
1675 szCommEvents[0] = 0;
1676
1677 if(dwEvents & EV_RXCHAR) {
1678 strcat(szCommEvents, "EV_RXCHAR ");
1679 }
1680 if(dwEvents & EV_TXEMPTY) {
1681 strcat(szCommEvents, "EV_TXEMPTY ");
1682 }
1683 if(dwEvents & EV_CTS) {
1684 strcat(szCommEvents, "EV_CTS ");
1685 }
1686 if(dwEvents & EV_DSR) {
1687 strcat(szCommEvents, "EV_DSR ");
1688 }
1689 if(dwEvents & EV_RLSD) {
1690 strcat(szCommEvents, "EV_RLSD ");
1691 }
1692 if(dwEvents & EV_BREAK) {
1693 strcat(szCommEvents, "EV_BREAK ");
1694 }
1695 if(dwEvents & EV_ERR) {
1696 strcat(szCommEvents, "EV_ERR ");
1697 }
1698 if(dwEvents & EV_RING) {
1699 strcat(szCommEvents, "EV_RING ");
1700 }
1701 return szCommEvents;
1702}
1703//******************************************************************************
1704//******************************************************************************
1705static char *DebugModemStatus(DWORD dwModemStatus)
1706{
1707 static char szModemStatus[128];
1708
1709 szModemStatus[0] = 0;
1710
1711 if(dwModemStatus & MS_CTS_ON) {
1712 strcat(szModemStatus, "MS_CTS_ON ");
1713 }
1714 if(dwModemStatus & MS_DSR_ON) {
1715 strcat(szModemStatus, "MS_DSR_ON ");
1716 }
1717 if(dwModemStatus & MS_RING_ON) {
1718 strcat(szModemStatus, "MS_RING_ON ");
1719 }
1720 if(dwModemStatus & MS_RLSD_ON) {
1721 strcat(szModemStatus, "MS_RLSD_ON ");
1722 }
1723 return szModemStatus;
1724}
1725#endif
1726//******************************************************************************
1727//******************************************************************************
1728OverlappedIOHandler *HMDeviceCommClass::handler[MAX_COMPORTS] = {NULL};
1729
Note: See TracBrowser for help on using the repository browser.