source: trunk/src/kernel32/hmcomm.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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