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

Last change on this file since 5039 was 5039, checked in by sandervl, 25 years ago

MM: comm fix for palm hotsync & ibm com drivers

File size: 39.6 KB
Line 
1/* $Id: hmcomm.cpp,v 1.9 2001-01-29 23:42:25 sandervl 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 *
10 */
11
12
13
14#include <os2win.h>
15#include <string.h>
16#include <handlemanager.h>
17#include <heapstring.h>
18#include "hmdevice.h"
19#include "hmcomm.h"
20#include "oslibdos.h"
21
22#define DBG_LOCALLOG DBG_hmcomm
23#include "dbglocal.h"
24
25#define MAGIC_COM 0x12abcd34
26
27#define IOCTL_ASYNC 0x01
28#define ASYNC_GETDCBINFO 0x73
29#define ASYNC_SETDCBINFO 0x53
30#define ASYNC_SETLINECTRL 0x42
31#define ASYNC_GETCOMMEVENT 0x72
32#define ASYNC_EXTGETBAUDRATE 0x63
33#define ASYNC_EXTSETBAUDRATE 0x43
34#define ASYNC_GETCOMMERROR 0x6D
35#define ASYNC_GETCOMMSTATUS 0x65
36#define ASYNC_GETINQUECOUNT 0x68
37#define ASYNC_GETOUTQUECOUNT 0x69
38#define ASYNC_GETMODEMINPUT 0x67
39#define ASYNC_TRANSMITIMM 0x44
40#define ASYNC_SETBREAKON 0x4B
41#define ASYNC_SETBREAKOFF 0x45
42#define ASYNC_SETMODEMCTRL 0x46
43#define ASYNC_STARTTRANSMIT 0x48
44#define ASYNC_STOPTRANSMIT 0x47
45#define ASYNC_GETMODEMOUTPUT 0x66
46
47
48#pragma pack(1)
49typedef struct _DCBINFO
50{
51 USHORT usWriteTimeout; /* Time period used for Write Timeout processing. */
52 USHORT usReadTimeout; /* Time period used for Read Timeout processing. */
53 BYTE fbCtlHndShake; /* HandShake Control flag. */
54 BYTE fbFlowReplace; /* Flow Control flag. */
55 BYTE fbTimeOut; /* Timeout flag. */
56 BYTE bErrorReplacementChar; /* Error Replacement Character. */
57 BYTE bBreakReplacementChar; /* Break Replacement Character. */
58 BYTE bXONChar; /* Character XON. */
59 BYTE bXOFFChar; /* Character XOFF. */
60} DCBINFO;
61typedef DCBINFO *PDCBINFO;
62
63
64typedef struct _RXQUEUE
65{
66 USHORT cch; /* Number of characters in the queue. */
67 USHORT cb; /* Size of receive/transmit queue. */
68} RXQUEUE;
69
70typedef RXQUEUE *PRXQUEUE;
71
72
73typedef struct _MODEMSTATUS
74{
75 BYTE fbModemOn; /* Modem Control Signals ON Mask. */
76 BYTE fbModemOff; /* Modem Control Signals OFF Mask. */
77} MODEMSTATUS;
78
79typedef MODEMSTATUS *PMODEMSTATUS;
80
81
82#pragma pack()
83
84
85
86
87
88typedef struct _HMDEVCOMDATA
89{
90 ULONG ulMagic;
91 // Win32 Device Control Block
92 COMMCONFIG CommCfg;
93 COMMTIMEOUTS CommTOuts;
94 DWORD dwInBuffer, dwOutBuffer;
95 DWORD dwEventMask;
96 //OS/2 Device Control Block
97 DCBINFO dcbOS2;
98} HMDEVCOMDATA, *PHMDEVCOMDATA;
99
100VOID *CreateDevData()
101{
102 PHMDEVCOMDATA pData;
103 pData = new HMDEVCOMDATA();
104 if(NULL!=pData)
105 {
106 memset(pData,0,sizeof(HMDEVCOMDATA));
107 pData->ulMagic = MAGIC_COM;
108 pData->CommCfg.dwSize = sizeof(COMMCONFIG);
109 pData->CommCfg.wVersion = 1;
110 pData->CommCfg.dwProviderSubType = PST_RS232;
111 pData->CommCfg.dcb.DCBlength = sizeof(DCB);
112 pData->CommCfg.dcb.BaudRate = CBR_1200;
113 pData->CommCfg.dcb.ByteSize = 8;
114 pData->CommCfg.dcb.Parity = NOPARITY;
115 pData->CommCfg.dcb.StopBits = ONESTOPBIT;
116 pData->dwInBuffer = 16;
117 pData->dwOutBuffer = 16;
118 }
119 return pData;
120}
121
122HMDeviceCommClass::HMDeviceCommClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
123{
124 VOID *pData;
125 dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n"));
126 pData = CreateDevData();
127 if(pData!= NULL)
128 HMDeviceRegisterEx("COM1", this, pData);
129}
130
131/*****************************************************************************
132 * Name : HMDeviceCommClass::FindDevice
133 * Purpose : Checks if lpDeviceName belongs to this device class
134 * Parameters: LPCSTR lpClassDevName
135 * LPCSTR lpDeviceName
136 * int namelength
137 * Variables :
138 * Result : checks if name is COMx or COMx: (x=1..8)
139 * Remark :
140 * Status :
141 *
142 * Author : SvL
143 *****************************************************************************/
144BOOL HMDeviceCommClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
145{
146 if(namelength > 5)
147 return FALSE; //can't be com name
148
149 //first 3 letters 'COM'?
150 if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) {
151 return FALSE;
152 }
153
154 if(namelength == 5 && lpDeviceName[4] != ':') {
155 return FALSE;
156 }
157 switch(lpDeviceName[3]) {
158 case '1':
159 case '2':
160 case '3':
161 case '4':
162 case '5':
163 case '6':
164 case '7':
165 case '8':
166 return TRUE; //we support up to COM8
167 }
168 return FALSE;
169}
170
171DWORD HMDeviceCommClass::CreateFile(LPCSTR lpFileName,
172 PHMHANDLEDATA pHMHandleData,
173 PVOID lpSecurityAttributes,
174 PHMHANDLEDATA pHMHandleDataTemplate)
175{
176 char comname[6];
177
178 dprintf(("HMComm: Serial communication port %s open request\n", lpFileName));
179
180 if(strlen(lpFileName) > 5) {
181 return -1; //safety check (unnecessary..)
182 }
183 pHMHandleData->hHMHandle = 0;
184
185 strcpy(comname, lpFileName);
186 comname[4] = 0; //get rid of : (if present) (eg COM1:)
187
188 //AH: TODO parse Win32 security handles
189 OSLibDosDisableHardError(TRUE);
190 pHMHandleData->hHMHandle = OSLibDosOpen(comname,
191 OSLIB_ACCESS_READWRITE |
192 OSLIB_ACCESS_SHAREDENYREAD |
193 OSLIB_ACCESS_SHAREDENYWRITE);
194 OSLibDosDisableHardError(FALSE);
195 if (pHMHandleData->hHMHandle != 0)
196 {
197 ULONG ulLen;
198 APIRET rc;
199 pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
200 // Init The handle instance with the default default device config
201 memcpy( pHMHandleData->lpHandlerData,
202 pHMHandleData->lpDeviceData,
203 sizeof(HMDEVCOMDATA));
204
205 ulLen = sizeof(DCBINFO);
206
207 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
208 IOCTL_ASYNC,
209 ASYNC_GETDCBINFO,
210 0,0,0,
211 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
212 dprintf(("DCB Of %s :\n"
213 " WriteTimeout : %d\n"
214 " ReadTimeout : %d\n"
215 " CtlHandshake : 0x%x\n"
216 " FlowReplace : 0x%x\n"
217 " Timeout : 0x%x\n"
218 " Error replacement Char : 0x%x\n"
219 " Break replacement Char : 0x%x\n"
220 " XON Char : 0x%x\n"
221 " XOFF Char : 0x%x\n",
222 comname,
223 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
224 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
225 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
226 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
227 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
228 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
229 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
230 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
231 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
232
233 if(rc)
234 {
235 return -1;
236 }
237 rc = SetBaud(pHMHandleData,9600);
238 dprintf(("Init Baud to 9600 rc = %d",rc));
239 rc = SetLine(pHMHandleData,8,0,0);
240 dprintf(("Set Line to 8/N/1 rc = %d",rc));
241 return 0;
242 }
243 else
244 return -1;
245}
246
247
248 /* this is a handler method for calls to CloseHandle() */
249DWORD HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
250{
251 dprintf(("HMComm: Serial communication port close request\n"));
252 delete pHMHandleData->lpHandlerData;
253 return OSLibDosClose(pHMHandleData->hHMHandle);
254}
255
256/*****************************************************************************
257 * Name : DWORD HMDeviceHandler::SetupComm
258 * Purpose : set com port parameters (queue)
259 * Variables :
260 * Result :
261 * Remark :
262 * Status :
263 *
264 * Author : Achim Hasenmueller
265 *****************************************************************************/
266
267BOOL HMDeviceCommClass::SetupComm( PHMHANDLEDATA pHMHandleData,
268 DWORD dwInQueue,
269 DWORD dwOutQueue)
270{
271 dprintf(("HMDeviceCommClass::SetupComm "));
272 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
273 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
274 {
275 SetLastError(ERROR_INVALID_HANDLE);
276 return FALSE;
277 }
278 pDevData->dwInBuffer = dwInQueue;
279 pDevData->dwOutBuffer = dwOutQueue;
280
281 return(TRUE);
282}
283
284BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
285 LPDWORD lpfdwEvtMask,
286 LPOVERLAPPED lpo)
287{
288 APIRET rc;
289 ULONG ulLen;
290 USHORT COMEvt;
291 DWORD dwEvent,dwMask;
292
293 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
294
295 dprintf(("HMDeviceCommClass::WaitCommEvent"));
296 ulLen = sizeof(CHAR);
297
298 dwEvent = 0;
299 rc = 0;
300 ulLen = sizeof(COMEvt);
301 dwMask = pDevData->dwEventMask;
302 while( (0==rc) &&
303 !(dwEvent & dwMask) &&
304 (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
305 {
306 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
307 IOCTL_ASYNC,
308 ASYNC_GETCOMMEVENT,
309 0,0,0,
310 &COMEvt,ulLen,&ulLen);
311 if(!rc)
312 {
313 dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
314 //dwEvent |= (COMEvt&0x0002)? 0:0;
315 dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
316 dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
317 dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
318 //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
319 dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
320 dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
321 dwEvent |= (COMEvt&0x0100)? EV_RING:0;
322 }
323 DosSleep(100);
324 }
325 *lpfdwEvtMask = rc==0?dwEvent:0;
326 return(rc==0);
327}
328
329
330#pragma pack(1)
331typedef struct
332{
333 ULONG ulCurrBaud;
334 UCHAR ucCurrFrac;
335 ULONG ulMinBaud;
336 UCHAR ucMinFrac;
337 ULONG ulMaxBaud;
338 UCHAR ucMaxFrac;
339} EXTBAUDGET, *PEXTBAUDGET;
340
341typedef struct
342{
343 ULONG ulBaud;
344 UCHAR ucFrac;
345} EXTBAUDSET, *PEXTBAUDSET;
346#pragma pack()
347
348BAUDTABLEENTRY BaudTable[] =
349{
350 {75,BAUD_075},
351 {110,BAUD_110},
352 {134,BAUD_134_5},
353 {150,BAUD_150},
354 {300,BAUD_300},
355 {600,BAUD_600},
356 {1200,BAUD_1200},
357 {1800,BAUD_1800},
358 {2400,BAUD_2400},
359 {4800,BAUD_4800},
360 {7200,BAUD_7200},
361 {9600,BAUD_9600},
362 {14400,BAUD_14400},
363 {19200,BAUD_19200},
364 {38400,BAUD_38400},
365 {56000,BAUD_56K},
366 {57600,BAUD_57600},
367 {115200,BAUD_115200},
368 {128000,BAUD_128K}
369};
370
371#define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
372
373BOOL HMDeviceCommClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
374 LPCOMMPROP lpcmmp)
375{
376 EXTBAUDGET BaudInfo;
377 APIRET rc;
378 ULONG ulLen;
379 USHORT COMErr;
380 int i;
381 dprintf(("HMDeviceCommClass::GetCommProperties"));
382
383 ulLen = sizeof(EXTBAUDGET);
384 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
385 IOCTL_ASYNC,
386 ASYNC_EXTGETBAUDRATE,
387 0,0,0,
388 &BaudInfo,ulLen,&ulLen);
389 memset(lpcmmp,0,sizeof(COMMPROP));
390 lpcmmp->wPacketLength = sizeof(COMMPROP);
391 lpcmmp->wPacketVersion = 1; //???
392 lpcmmp->dwServiceMask = SP_SERIALCOMM;
393 for(i=0;i<BaudTableSize && BaudInfo.ulMaxBaud <= BaudTable[i].dwBaudRate;i++);
394 lpcmmp->dwMaxBaud = BaudTable[i].dwBaudFlag;
395 lpcmmp->dwProvSubType = PST_RS232;
396 lpcmmp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK |
397 PCF_RTSCTS | PCF_SETXCHAR |
398 PCF_XONXOFF;
399 lpcmmp->dwSettableParams = SP_BAUD | SP_DATABITS |
400 SP_HANDSHAKEING | SP_PARITY |
401 SP_PARITY_CHECK | SP_STOPBIT;
402 lpcmmp->dwSettableBaud = 0;
403 for(i=0;i<BaudTableSize;i++)
404 {
405 if ( (BaudTable[i].dwBaudRate>=BaudInfo.ulMinBaud) &&
406 (BaudTable[i].dwBaudRate<=BaudInfo.ulMaxBaud) )
407 lpcmmp->dwSettableBaud |= BaudTable[i].dwBaudFlag;
408 }
409 lpcmmp->dwSettableBaud |= BAUD_USER;
410 lpcmmp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
411 lpcmmp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
412 PARITY_NONE | PARITY_ODD | PARITY_EVEN |
413 PARITY_MARK | PARITY_SPACE;
414 return(rc==0);
415}
416
417BOOL HMDeviceCommClass::GetCommMask( PHMHANDLEDATA pHMHandleData,
418 LPDWORD lpfdwEvtMask)
419{
420 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
421
422 dprintf(("HMDeviceCommClass::GetCommMask"));
423
424 *lpfdwEvtMask = pDevData->dwEventMask;
425 return(TRUE);
426}
427
428BOOL HMDeviceCommClass::SetCommMask( PHMHANDLEDATA pHMHandleData,
429 DWORD fdwEvtMask)
430{
431 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
432 dprintf(("HMDeviceCommClass::SetCommMask"));
433
434 pDevData->dwEventMask = fdwEvtMask & ~(EV_RLSD|EV_RXFLAG); // Clear the 2 not supported Flags.
435 return(TRUE);
436}
437
438BOOL HMDeviceCommClass::PurgeComm( PHMHANDLEDATA pHMHandleData,
439 DWORD fdwAction)
440{
441 dprintf(("HMDeviceCommClass::PurgeComm (flags 0x%x) unimplemented stub!",fdwAction));
442 // ToDo: find a way to stop the current transmision didn't find
443 // any clue how to in Control Program Guide and reference
444
445 return(TRUE);
446}
447BOOL HMDeviceCommClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
448 LPDWORD lpdwErrors,
449 LPCOMSTAT lpcst)
450{
451 APIRET rc;
452 ULONG ulLen;
453 USHORT COMErr;
454
455 dprintf(("HMDeviceCommClass::ClearCommError"));
456 ulLen = sizeof(USHORT);
457
458 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
459 IOCTL_ASYNC,
460 ASYNC_GETCOMMERROR,
461 0,0,0,
462 &COMErr,2,&ulLen);
463 *lpdwErrors = 0;
464 *lpdwErrors |= (COMErr & 0x0001)?CE_OVERRUN:0;
465 *lpdwErrors |= (COMErr & 0x0002)?CE_RXOVER:0;
466 *lpdwErrors |= (COMErr & 0x0004)?CE_RXPARITY:0;
467 *lpdwErrors |= (COMErr & 0x0008)?CE_FRAME:0;
468
469 if(lpcst)
470 {
471 UCHAR ucStatus;
472 RXQUEUE qInfo;
473 ulLen = 1;
474 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
475 IOCTL_ASYNC,
476 ASYNC_GETCOMMSTATUS,
477 0,0,0,
478 &ucStatus,ulLen,&ulLen);
479 if(!rc)
480 {
481 lpcst->fCtsHold = ((ucStatus & 0x01)>0);
482 lpcst->fDsrHold = ((ucStatus & 0x02)>0);
483 lpcst->fRlsdHold = FALSE;//(ucStatus & 0x04)>0);
484 lpcst->fXoffHold = ((ucStatus & 0x08)>0);
485 lpcst->fXoffSend = ((ucStatus & 0x10)>0);
486 lpcst->fEof = ((ucStatus & 0x20)>0);// Is break = Eof ??
487 lpcst->fTxim = ((ucStatus & 0x40)>0);
488
489 ulLen = sizeof(qInfo);
490 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
491 IOCTL_ASYNC,
492 ASYNC_GETINQUECOUNT,
493 0,0,0,
494 &qInfo,ulLen,&ulLen);
495 if(!rc)
496 {
497 lpcst->cbInQue = qInfo.cch;
498 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
499 IOCTL_ASYNC,
500 ASYNC_GETOUTQUECOUNT,
501 0,0,0,
502 &qInfo,ulLen,&ulLen);
503 if(!rc)
504 lpcst->cbOutQue = qInfo.cch;
505 }
506 }
507 }
508
509 return(rc==0);
510}
511BOOL HMDeviceCommClass::SetCommState( PHMHANDLEDATA pHMHandleData,
512 LPDCB lpDCB)
513{
514 APIRET rc;
515 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
516 DCB *pCurDCB = &pDevData->CommCfg.dcb;
517 dprintf(("HMDeviceCommClass::SetCommState"));
518
519 rc = 0;
520 if(pCurDCB->BaudRate != lpDCB->BaudRate)
521 rc = SetBaud( pHMHandleData,
522 lpDCB->BaudRate);
523
524 if(!rc)
525 {
526 if( (pCurDCB->ByteSize != lpDCB->ByteSize) ||
527 (pCurDCB->Parity != lpDCB->Parity) ||
528 (pCurDCB->StopBits != lpDCB->StopBits))
529 rc = SetLine( pHMHandleData,
530 lpDCB->ByteSize,
531 lpDCB->Parity,
532 lpDCB->StopBits);
533 }
534
535 if(!rc)
536 {
537 if( (pCurDCB->fOutxCtsFlow != lpDCB->fOutxCtsFlow) ||
538 (pCurDCB->fOutxDsrFlow != lpDCB->fOutxDsrFlow) ||
539 (pCurDCB->fDtrControl != lpDCB->fDtrControl) ||
540 (pCurDCB->fDsrSensitivity != lpDCB->fDsrSensitivity) ||
541 (pCurDCB->fTXContinueOnXoff != lpDCB->fTXContinueOnXoff) ||
542 (pCurDCB->fOutX != lpDCB->fOutX) ||
543 (pCurDCB->fInX != lpDCB->fInX) ||
544 (pCurDCB->fErrorChar != lpDCB->fErrorChar) ||
545 (pCurDCB->fNull != lpDCB->fNull) ||
546 (pCurDCB->fRtsControl != lpDCB->fRtsControl) ||
547 (pCurDCB->fAbortOnError != lpDCB->fAbortOnError) ||
548 (pCurDCB->XonChar != lpDCB->XonChar) ||
549 (pCurDCB->XoffChar != lpDCB->XoffChar) ||
550 (pCurDCB->ErrorChar != lpDCB->ErrorChar))
551 SetOS2DCB( pHMHandleData,
552 lpDCB->fOutxCtsFlow, lpDCB->fOutxDsrFlow,
553 lpDCB->fDtrControl, lpDCB->fDsrSensitivity,
554 lpDCB->fTXContinueOnXoff, lpDCB->fOutX,
555 lpDCB->fInX, lpDCB->fErrorChar,
556 lpDCB->fNull, lpDCB->fRtsControl,
557 lpDCB->fAbortOnError, lpDCB->XonChar,
558 lpDCB->XoffChar,lpDCB->ErrorChar);
559 }
560
561 return(rc==0);
562}
563BOOL HMDeviceCommClass::GetCommState( PHMHANDLEDATA pHMHandleData,
564 LPDCB lpdcb)
565{
566 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
567
568 dprintf(("HMDeviceCommClass::GetCommState"));
569 memcpy(lpdcb,&pDevData->CommCfg.dcb,sizeof(DCB));
570
571 return(TRUE);
572}
573BOOL HMDeviceCommClass::GetCommModemStatus( PHMHANDLEDATA pHMHandleData,
574 LPDWORD lpModemStat )
575{
576 APIRET rc;
577 ULONG ulLen;
578 USHORT COMErr;
579 UCHAR ucStatus;
580
581 dprintf(("HMDeviceCommClass::TransmitCommChar partly implemented"));
582 ulLen = sizeof(CHAR);
583
584 ulLen = 1;
585 *lpModemStat = 0;
586
587 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
588 IOCTL_ASYNC,
589 ASYNC_GETMODEMINPUT,
590 0,0,0,
591 &ucStatus,ulLen,&ulLen);
592 if(!rc)
593 {
594 *lpModemStat |= (ucStatus & 0x10)? MS_CTS_ON:0;
595 *lpModemStat |= (ucStatus & 0x20)? MS_DSR_ON:0;
596 *lpModemStat |= (ucStatus & 0x40)? MS_RING_ON:0;
597 //*lpModemStat |= (ucStatus & 0x80)? MS_RSLD_ON:0;
598 }
599
600 return(rc==0);
601}
602
603BOOL HMDeviceCommClass::GetCommTimeouts( PHMHANDLEDATA pHMHandleData,
604 LPCOMMTIMEOUTS lpctmo)
605{
606 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
607
608 dprintf(("HMDeviceCommClass::GetCommTimeouts stub"));
609 memcpy( lpctmo,
610 &pDevData->CommTOuts,
611 sizeof(COMMTIMEOUTS));
612 return(TRUE);
613}
614BOOL HMDeviceCommClass::SetCommTimeouts( PHMHANDLEDATA pHMHandleData,
615 LPCOMMTIMEOUTS lpctmo)
616{
617 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
618 DCBINFO os2dcb;
619 ULONG ulLen;
620 APIRET rc;
621 UCHAR fbTimeOut;
622 dprintf(("HMDeviceCommClass::SetCommTimeouts\n"
623 " ReadIntervalTimeout : 0x%x\n"
624 " ReadTotalTimeoutMultiplier : %d\n"
625 " ReadTotalTimeoutConstant : %d\n"
626 " WriteTotalTimeoutMultiplier : %d\n"
627 " WriteTotalTimeoutConstant : %d\n",
628 lpctmo->ReadIntervalTimeout,
629 lpctmo->ReadTotalTimeoutMultiplier,
630 lpctmo->ReadTotalTimeoutConstant,
631 lpctmo->WriteTotalTimeoutMultiplier,
632 lpctmo->WriteTotalTimeoutConstant
633 ));
634
635 memcpy( &pDevData->CommTOuts,
636 lpctmo,
637 sizeof(COMMTIMEOUTS));
638
639 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
640
641 fbTimeOut = 0x02;
642 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
643 {
644 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
645 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
646 fbTimeOut = 0x05;
647 else
648 fbTimeOut = 0x04;
649 }
650 else
651 {
652 DWORD dwTimeout;
653 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
654#if 0
655 if(dwTimeout)
656 dwTimeout--; // 0=10 ms unit is 10ms or .01s
657#endif
658 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
659 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
660 }
661 os2dcb.fbTimeOut = (os2dcb.fbTimeOut & 0xF9) | fbTimeOut;
662
663 dprintf((" New DCB:\n"
664 " WriteTimeout : %d\n"
665 " ReadTimeout : %d\n"
666 " CtlHandshake : 0x%x\n"
667 " FlowReplace : 0x%x\n"
668 " Timeout : 0x%x\n"
669 " Error replacement Char : 0x%x\n"
670 " Break replacement Char : 0x%x\n"
671 " XON Char : 0x%x\n"
672 " XOFF Char : 0x%x\n",
673 os2dcb.usWriteTimeout,
674 os2dcb.usReadTimeout,
675 os2dcb.fbCtlHndShake,
676 os2dcb.fbFlowReplace,
677 os2dcb.fbTimeOut,
678 os2dcb.bErrorReplacementChar,
679 os2dcb.bBreakReplacementChar,
680 os2dcb.bXONChar,
681 os2dcb.bXOFFChar));
682
683 ulLen = sizeof(DCBINFO);
684 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
685 IOCTL_ASYNC,
686 ASYNC_SETDCBINFO,
687 &os2dcb,ulLen,&ulLen,
688 NULL,0,NULL);
689 dprintf(("IOCRL returned %d",rc));
690 return(0==rc);
691}
692BOOL HMDeviceCommClass::TransmitCommChar( PHMHANDLEDATA pHMHandleData,
693 CHAR cChar )
694{
695 APIRET rc;
696 ULONG ulLen;
697 USHORT COMErr;
698
699 dprintf(("HMDeviceCommClass::TransmitCommChar"));
700 ulLen = sizeof(CHAR);
701
702 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
703 IOCTL_ASYNC,
704 ASYNC_TRANSMITIMM,
705 &cChar,ulLen,&ulLen,
706 NULL,0,NULL);
707
708 return(rc==0);
709}
710
711/*****************************************************************************
712 * Name : BOOL HMDeviceCommClass::WriteFile
713 * Purpose : write data to handle / device
714 * Parameters: PHMHANDLEDATA pHMHandleData,
715 * LPCVOID lpBuffer,
716 * DWORD nNumberOfBytesToWrite,
717 * LPDWORD lpNumberOfBytesWritten,
718 * LPOVERLAPPED lpOverlapped
719 * Variables :
720 * Result : Boolean
721 * Remark :
722 * Status :
723 *
724 * Author : SvL
725 *****************************************************************************/
726
727BOOL HMDeviceCommClass::WriteFile(PHMHANDLEDATA pHMHandleData,
728 LPCVOID lpBuffer,
729 DWORD nNumberOfBytesToWrite,
730 LPDWORD lpNumberOfBytesWritten,
731 LPOVERLAPPED lpOverlapped)
732{
733 dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
734 lpHMDeviceName,
735 pHMHandleData->hHMHandle,
736 lpBuffer,
737 nNumberOfBytesToWrite,
738 lpNumberOfBytesWritten,
739 lpOverlapped));
740
741 BOOL ret;
742 ULONG ulBytesWritten;
743
744 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
745 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
746 SetLastError(ERROR_INVALID_PARAMETER);
747 return FALSE;
748 }
749 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
750 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
751 }
752
753 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
754 &ulBytesWritten);
755
756 if(lpNumberOfBytesWritten) {
757 *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
758 }
759 if(ret == FALSE) {
760 dprintf(("ERROR: WriteFile failed with rc %d", GetLastError()));
761 }
762
763 return ret;
764}
765
766/*****************************************************************************
767 * Name : BOOL WriteFileEx
768 * Purpose : The WriteFileEx function writes data to a file. It is designed
769 * solely for asynchronous operation, unlike WriteFile, which is
770 * designed for both synchronous and asynchronous operation.
771 * WriteFileEx reports its completion status asynchronously,
772 * calling a specified completion routine when writing is completed
773 * and the calling thread is in an alertable wait state.
774 * Parameters: HANDLE hFile handle of file to write
775 * LPVOID lpBuffer address of buffer
776 * DWORD nNumberOfBytesToRead number of bytes to write
777 * LPOVERLAPPED lpOverlapped address of offset
778 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
779 * Variables :
780 * Result : TRUE / FALSE
781 * Remark :
782 * Status : UNTESTED STUB
783 *
784 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
785 *****************************************************************************/
786
787BOOL HMDeviceCommClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
788 LPVOID lpBuffer,
789 DWORD nNumberOfBytesToWrite,
790 LPOVERLAPPED lpOverlapped,
791 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
792{
793 dprintf(("ERROR: WriteFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
794 lpHMDeviceName,
795 pHMHandleData->hHMHandle,
796 lpBuffer,
797 nNumberOfBytesToWrite,
798 lpOverlapped,
799 lpCompletionRoutine));
800
801 SetLastError(ERROR_INVALID_FUNCTION);
802 return FALSE;
803}
804
805/*****************************************************************************
806 * Name : BOOL HMDeviceCommClass::ReadFile
807 * Purpose : read data from handle / device
808 * Parameters: PHMHANDLEDATA pHMHandleData,
809 * LPCVOID lpBuffer,
810 * DWORD nNumberOfBytesToRead,
811 * LPDWORD lpNumberOfBytesRead,
812 * LPOVERLAPPED lpOverlapped
813 * Variables :
814 * Result : Boolean
815 * Remark :
816 * Status :
817 *
818 * Author : SvL
819 *****************************************************************************/
820
821BOOL HMDeviceCommClass::ReadFile(PHMHANDLEDATA pHMHandleData,
822 LPCVOID lpBuffer,
823 DWORD nNumberOfBytesToRead,
824 LPDWORD lpNumberOfBytesRead,
825 LPOVERLAPPED lpOverlapped)
826{
827 dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
828 lpHMDeviceName,
829 pHMHandleData->hHMHandle,
830 lpBuffer,
831 nNumberOfBytesToRead,
832 lpNumberOfBytesRead,
833 lpOverlapped));
834
835 BOOL ret;
836 ULONG ulBytesRead;
837
838 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
839 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
840 SetLastError(ERROR_INVALID_PARAMETER);
841 return FALSE;
842 }
843 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
844 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
845 }
846
847 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
848 &ulBytesRead);
849
850 if(lpNumberOfBytesRead) {
851 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
852 }
853 if(ret == FALSE) {
854 dprintf(("ERROR: ReadFile failed with rc %d", GetLastError()));
855 }
856 return ret;
857}
858
859/*****************************************************************************
860 * Name : BOOL ReadFileEx
861 * Purpose : The ReadFileEx function reads data from a file asynchronously.
862 * It is designed solely for asynchronous operation, unlike the
863 * ReadFile function, which is designed for both synchronous and
864 * asynchronous operation. ReadFileEx lets an application perform
865 * other processing during a file read operation.
866 * The ReadFileEx function reports its completion status asynchronously,
867 * calling a specified completion routine when reading is completed
868 * and the calling thread is in an alertable wait state.
869 * Parameters: HANDLE hFile handle of file to read
870 * LPVOID lpBuffer address of buffer
871 * DWORD nNumberOfBytesToRead number of bytes to read
872 * LPOVERLAPPED lpOverlapped address of offset
873 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
874 * Variables :
875 * Result : TRUE / FALSE
876 * Remark :
877 * Status : UNTESTED STUB
878 *
879 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
880 *****************************************************************************/
881BOOL HMDeviceCommClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
882 LPVOID lpBuffer,
883 DWORD nNumberOfBytesToRead,
884 LPOVERLAPPED lpOverlapped,
885 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
886{
887 dprintf(("ERROR: ReadFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
888 lpHMDeviceName,
889 pHMHandleData->hHMHandle,
890 lpBuffer,
891 nNumberOfBytesToRead,
892 lpOverlapped,
893 lpCompletionRoutine));
894
895 SetLastError(ERROR_INVALID_FUNCTION);
896 return FALSE;
897}
898
899BOOL HMDeviceCommClass::SetCommBreak( PHMHANDLEDATA pHMHandleData )
900{
901 APIRET rc;
902 ULONG ulLen;
903 USHORT COMErr;
904
905 dprintf(("HMDeviceCommClass::SetCommBreak"));
906 ulLen = sizeof(USHORT);
907
908 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
909 IOCTL_ASYNC,
910 ASYNC_SETBREAKON,
911 0,0,0,
912 &COMErr,2,&ulLen);
913
914 return(rc==0);
915}
916
917BOOL HMDeviceCommClass::ClearCommBreak( PHMHANDLEDATA pHMHandleData)
918{
919 APIRET rc;
920 ULONG ulLen;
921 USHORT COMErr;
922
923 dprintf(("HMDeviceCommClass::ClearCommBreak"));
924 ulLen = sizeof(USHORT);
925
926 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
927 IOCTL_ASYNC,
928 ASYNC_SETBREAKOFF,
929 0,0,0,
930 &COMErr,2,&ulLen);
931
932 return(rc==0);
933}
934
935BOOL HMDeviceCommClass::SetCommConfig( PHMHANDLEDATA pHMHandleData,
936 LPCOMMCONFIG lpCC,
937 DWORD dwSize )
938{
939 dprintf(("HMDeviceCommClass::SetCommConfig"));
940
941
942 return(TRUE);
943}
944
945BOOL HMDeviceCommClass::GetCommConfig( PHMHANDLEDATA pHMHandleData,
946 LPCOMMCONFIG lpCC,
947 LPDWORD lpdwSize )
948{
949 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
950
951 dprintf(("HMDeviceCommClass::GetCommConfig"));
952
953 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
954 *lpdwSize< sizeof(COMMCONFIG) )
955 {
956 SetLastError(ERROR_INSUFFICIENT_BUFFER);
957 *lpdwSize= sizeof(COMMCONFIG);
958 return FALSE;
959 }
960
961 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
962 {
963 SetLastError(ERROR_INVALID_HANDLE);
964 return FALSE;
965 }
966
967 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
968 *lpdwSize = sizeof(COMMCONFIG);
969 return(TRUE);
970
971
972 return(TRUE);
973}
974
975BOOL HMDeviceCommClass::EscapeCommFunction( PHMHANDLEDATA pHMHandleData,
976 UINT dwFunc )
977{
978 APIRET rc;
979 ULONG ulDLen,ulPLen;
980 USHORT COMErr;
981 MODEMSTATUS mdm;
982
983 dprintf(("HMDeviceCommClass::EscapeCommFunction"));
984
985 ulDLen = sizeof(USHORT);
986 ulPLen = sizeof(MODEMSTATUS);
987 switch(dwFunc)
988 {
989 case CLRDTR:
990 mdm.fbModemOn = 0x00;
991 mdm.fbModemOff = 0XFE;
992 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
993 IOCTL_ASYNC,
994 ASYNC_SETMODEMCTRL,
995 &mdm,ulPLen,&ulPLen,
996 &COMErr,ulDLen,&ulDLen);
997 dprintf(("CLRDTR rc = %d Comerror = 0x%x",rc,COMErr));
998 rc = COMErr;
999 if(rc==0)
1000 {
1001 BYTE bModem;
1002 ulDLen = sizeof(BYTE);
1003 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1004 IOCTL_ASYNC,
1005 ASYNC_GETMODEMOUTPUT,
1006 NULL,0,NULL,
1007 &bModem,ulDLen,&ulDLen);
1008 dprintf(("Check DTR rc = %d Flags = 0x%x",rc,bModem));
1009 rc = bModem & 0x01;
1010 }
1011 break;
1012 case CLRRTS:
1013 mdm.fbModemOn = 0x00;
1014 mdm.fbModemOff = 0XFD;
1015 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1016 IOCTL_ASYNC,
1017 ASYNC_SETMODEMCTRL,
1018 &mdm,ulPLen,&ulPLen,
1019 &COMErr,ulDLen,&ulDLen);
1020 break;
1021 case SETDTR:
1022 mdm.fbModemOn = 0x01;
1023 mdm.fbModemOff = 0XFF;
1024 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1025 IOCTL_ASYNC,
1026 ASYNC_SETMODEMCTRL,
1027 &mdm,ulPLen,&ulPLen,
1028 &COMErr,ulDLen,&ulDLen);
1029 break;
1030 case SETRTS:
1031 mdm.fbModemOn = 0x02;
1032 mdm.fbModemOff = 0XFF;
1033 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1034 IOCTL_ASYNC,
1035 ASYNC_SETMODEMCTRL,
1036 &mdm,ulPLen,&ulPLen,
1037 &COMErr,ulDLen,&ulDLen);
1038 break;
1039 case SETXOFF:
1040 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1041 IOCTL_ASYNC,
1042 ASYNC_STOPTRANSMIT,
1043 0,0,0,
1044 0,0,0);
1045 break;
1046 case SETXON:
1047 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1048 IOCTL_ASYNC,
1049 ASYNC_STARTTRANSMIT,
1050 0,0,0,
1051 0,0,0);
1052 break;
1053 default:
1054 SetLastError(ERROR_INVALID_PARAMETER);
1055 return(FALSE);
1056 }
1057
1058 return(rc==0);
1059}
1060
1061BOOL HMDeviceCommClass::SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
1062 LPCOMMCONFIG lpCC,
1063 DWORD dwSize)
1064{
1065 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
1066 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
1067 {
1068 SetLastError(ERROR_INVALID_HANDLE);
1069 return FALSE;
1070 }
1071 memset(&pDevData->CommCfg,0, sizeof(COMMCONFIG));
1072 memcpy(&pDevData->CommCfg,lpCC,dwSize>sizeof(COMMCONFIG)?sizeof(COMMCONFIG):dwSize);
1073
1074 return(TRUE);
1075}
1076BOOL HMDeviceCommClass::GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
1077 LPCOMMCONFIG lpCC,
1078 LPDWORD lpdwSize)
1079{
1080 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
1081
1082 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
1083 *lpdwSize< sizeof(COMMCONFIG) )
1084 {
1085 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1086 *lpdwSize= sizeof(COMMCONFIG);
1087 return FALSE;
1088 }
1089
1090 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
1091 {
1092 SetLastError(ERROR_INVALID_HANDLE);
1093 return FALSE;
1094 }
1095
1096 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
1097 *lpdwSize = sizeof(COMMCONFIG);
1098 return(TRUE);
1099}
1100APIRET HMDeviceCommClass::SetLine( PHMHANDLEDATA pHMHandleData,
1101 UCHAR ucSize,
1102 UCHAR ucParity,
1103 UCHAR ucStop)
1104{
1105 APIRET rc;
1106 ULONG ulLen;
1107 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1108 DCB *pCurDCB = &pDevData->CommCfg.dcb;
1109 struct
1110 {
1111 UCHAR ucSize;
1112 UCHAR ucParity;
1113 UCHAR ucStop;
1114 UCHAR ucPadding;
1115 }Param;
1116
1117 ulLen = 3;
1118 Param.ucSize = ucSize;
1119 Param.ucParity = ucParity;
1120 Param.ucStop = ucStop;
1121
1122 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1123 IOCTL_ASYNC,
1124 ASYNC_SETLINECTRL,
1125 &Param,ulLen,&ulLen,
1126 NULL,0,NULL);
1127
1128 if(0==rc)
1129 {
1130 pCurDCB->ByteSize = ucSize;
1131 pCurDCB->Parity = ucParity;
1132 pCurDCB->StopBits = ucStop;
1133 }
1134
1135 return rc;
1136}
1137
1138APIRET HMDeviceCommClass::SetOS2DCB( PHMHANDLEDATA pHMHandleData,
1139 BOOL fOutxCtsFlow, BOOL fOutxDsrFlow,
1140 UCHAR ucDtrControl, BOOL fDsrSensitivity,
1141 BOOL fTXContinueOnXoff, BOOL fOutX,
1142 BOOL fInX, BOOL fErrorChar,
1143 BOOL fNull, UCHAR ucRtsControl,
1144 BOOL fAbortOnError, BYTE XonChar,
1145 BYTE XoffChar,BYTE ErrorChar)
1146{
1147 APIRET rc;
1148 ULONG ulLen;
1149 DCBINFO os2dcb;
1150 UCHAR fbTimeOut;
1151 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
1152 DCB *pCurDCB = &pDevData->CommCfg.dcb;
1153
1154 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
1155 os2dcb.fbCtlHndShake = (ucDtrControl & 0x03) |
1156 (fOutxCtsFlow?0x08:0x00) |
1157 (fOutxDsrFlow?0x10:0x00) |
1158 // No DCD support in Win32 ?!
1159 (fDsrSensitivity?0x40:0x00);
1160 os2dcb.fbFlowReplace = (fOutX?0x01:0x00) |
1161 (fInX?0x02:0x00) |
1162 (fErrorChar?0x04:0x00)|
1163 (fNull?0x08:0x00)|
1164 (fTXContinueOnXoff?0x02:0x00)| // Not sure if thats the right flag to test
1165 (ucRtsControl<<6);
1166
1167 fbTimeOut = 0x02;
1168 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
1169 {
1170 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
1171 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
1172 fbTimeOut = 0x05;
1173 else
1174 fbTimeOut = 0x04;
1175 }
1176 else
1177 {
1178 DWORD dwTimeout;
1179 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
1180 if(dwTimeout)
1181 dwTimeout--; // 0=10 ms unit is 10ms or .01s
1182 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
1183 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
1184 }
1185 os2dcb.fbTimeOut = (os2dcb.fbTimeOut & 0xF9) | fbTimeOut;
1186 os2dcb.bErrorReplacementChar = ErrorChar;
1187 os2dcb.bXONChar = XonChar;
1188 os2dcb.bXOFFChar = XoffChar;
1189 ulLen = sizeof(DCBINFO);
1190 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1191 IOCTL_ASYNC,
1192 ASYNC_SETDCBINFO,
1193 &os2dcb,ulLen,&ulLen,
1194 NULL,0,NULL);
1195
1196 if(0==rc)
1197 {
1198 memcpy(&pDevData->dcbOS2,&os2dcb,sizeof(DCBINFO));
1199 pCurDCB->fOutxCtsFlow = fOutxCtsFlow;
1200 pCurDCB->fOutxDsrFlow = fOutxDsrFlow;
1201 pCurDCB->fDtrControl = ucDtrControl;
1202 pCurDCB->fDsrSensitivity = fDsrSensitivity;
1203 pCurDCB->fTXContinueOnXoff = fTXContinueOnXoff;
1204 pCurDCB->fOutX = fOutX;
1205 pCurDCB->fInX = fInX;
1206 pCurDCB->fErrorChar = fErrorChar;
1207 pCurDCB->fNull = fNull;
1208 pCurDCB->fRtsControl = ucRtsControl;
1209 pCurDCB->fAbortOnError = fAbortOnError;
1210 pCurDCB->XonChar = XonChar;
1211 pCurDCB->XoffChar = XoffChar;
1212 pCurDCB->ErrorChar = ErrorChar;
1213 }
1214
1215 return rc;
1216
1217}
1218
1219APIRET HMDeviceCommClass::SetBaud( PHMHANDLEDATA pHMHandleData,
1220 DWORD dwNewBaud)
1221{
1222 APIRET rc;
1223 ULONG ulLen;
1224 EXTBAUDSET SetBaud;
1225 EXTBAUDGET GetBaud;
1226 ulLen = sizeof(SetBaud);
1227 SetBaud.ulBaud = dwNewBaud;
1228 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1229 IOCTL_ASYNC,
1230 ASYNC_EXTSETBAUDRATE,
1231 &SetBaud,ulLen,&ulLen,
1232 NULL,0,NULL);
1233 if(0==rc)
1234 {
1235 ulLen = sizeof(GetBaud);
1236 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
1237 IOCTL_ASYNC,
1238 ASYNC_EXTGETBAUDRATE,
1239 NULL,0,NULL,
1240 &GetBaud,ulLen,&ulLen);
1241 if(0==rc)
1242 {
1243 if(dwNewBaud !=GetBaud.ulCurrBaud)
1244 rc = 1; // ToDo set a proper Errorhandling
1245 else
1246 {
1247 ((PHMDEVCOMDATA)pHMHandleData->lpDeviceData)->CommCfg.dcb.BaudRate = dwNewBaud;
1248 ((PHMDEVCOMDATA)pHMHandleData->lpDeviceData)->CommCfg.dcb.BaudRate = dwNewBaud;
1249 }
1250 }
1251 }
1252 return rc;
1253}
1254
1255
Note: See TracBrowser for help on using the repository browser.