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

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

Handlemanager fix (MN), changes for device name lookup, com bugfix (error check) + com class now called for COMx: names

File size: 28.9 KB
Line 
1/* $Id: hmcomm.cpp,v 1.6 2000-11-14 14:26:59 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
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
200 pHMHandleData->lpHandlerData = new HMDEVCOMDATA();
201 // Init The handle instance with the default default device config
202 memcpy( pHMHandleData->lpHandlerData,
203 pHMHandleData->lpDeviceData,
204 sizeof(HMDEVCOMDATA));
205
206 ulLen = sizeof(DCBINFO);
207
208 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
209 IOCTL_ASYNC,
210 ASYNC_GETDCBINFO,
211 0,0,0,
212 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
213
214 if(rc)
215 {
216 return -1;
217 }
218 return 0;
219 }
220 else
221 return -1;
222}
223
224
225 /* this is a handler method for calls to CloseHandle() */
226DWORD HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
227{
228 dprintf(("HMComm: Serial communication port close request\n"));
229 delete pHMHandleData->lpHandlerData;
230 return OSLibDosClose(pHMHandleData->hHMHandle);
231}
232
233/*****************************************************************************
234 * Name : DWORD HMDeviceHandler::SetupComm
235 * Purpose : set com port parameters (queue)
236 * Variables :
237 * Result :
238 * Remark :
239 * Status :
240 *
241 * Author : Achim Hasenmueller
242 *****************************************************************************/
243
244BOOL HMDeviceCommClass::SetupComm( PHMHANDLEDATA pHMHandleData,
245 DWORD dwInQueue,
246 DWORD dwOutQueue)
247{
248 dprintf(("HMDeviceCommClass::SetupComm "));
249 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
250 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
251 {
252 O32_SetLastError(ERROR_INVALID_HANDLE);
253 return FALSE;
254 }
255 pDevData->dwInBuffer = dwInQueue;
256 pDevData->dwOutBuffer = dwOutQueue;
257
258 return(TRUE);
259}
260
261BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData,
262 LPDWORD lpfdwEvtMask,
263 LPOVERLAPPED lpo)
264{
265 APIRET rc;
266 ULONG ulLen;
267 USHORT COMEvt;
268 DWORD dwEvent,dwMask;
269
270 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
271
272 dprintf(("HMDeviceCommClass::WaitCommEvent"));
273 ulLen = sizeof(CHAR);
274
275 dwEvent = 0;
276 rc = 0;
277 ulLen = sizeof(COMEvt);
278 dwMask = pDevData->dwEventMask;
279 while( (0==rc) &&
280 !(dwEvent & dwMask) &&
281 (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed
282 {
283 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
284 IOCTL_ASYNC,
285 ASYNC_GETCOMMEVENT,
286 0,0,0,
287 &COMEvt,ulLen,&ulLen);
288 if(!rc)
289 {
290 dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0;
291 //dwEvent |= (COMEvt&0x0002)? 0:0;
292 dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0;
293 dwEvent |= (COMEvt&0x0008)? EV_CTS:0;
294 dwEvent |= (COMEvt&0x0010)? EV_DSR:0;
295 //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD?
296 dwEvent |= (COMEvt&0x0040)? EV_BREAK:0;
297 dwEvent |= (COMEvt&0x0080)? EV_ERR:0;
298 dwEvent |= (COMEvt&0x0100)? EV_RING:0;
299 }
300 DosSleep(100);
301 }
302 *lpfdwEvtMask = rc==0?dwEvent:0;
303 return(rc==0);
304}
305
306
307#pragma pack(1)
308typedef struct
309{
310 ULONG ulCurrBaud;
311 UCHAR ucCurrFrac;
312 ULONG ulMinBaud;
313 UCHAR ucMinFrac;
314 ULONG ulMaxBaud;
315 UCHAR ucMaxFrac;
316} EXTBAUDGET, *PEXTBAUDGET;
317
318typedef struct
319{
320 ULONG ulBaud;
321 UCHAR ucFrac;
322} EXTBAUDSET, *PEXTBAUDSET;
323#pragma pack()
324
325BAUDTABLEENTRY BaudTable[] =
326{
327 {75,BAUD_075},
328 {110,BAUD_110},
329 {134,BAUD_134_5},
330 {150,BAUD_150},
331 {300,BAUD_300},
332 {600,BAUD_600},
333 {1200,BAUD_1200},
334 {1800,BAUD_1800},
335 {2400,BAUD_2400},
336 {4800,BAUD_4800},
337 {7200,BAUD_7200},
338 {9600,BAUD_9600},
339 {14400,BAUD_14400},
340 {19200,BAUD_19200},
341 {38400,BAUD_38400},
342 {56000,BAUD_56K},
343 {57600,BAUD_57600},
344 {115200,BAUD_115200},
345 {128000,BAUD_128K}
346};
347
348#define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY))
349
350BOOL HMDeviceCommClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
351 LPCOMMPROP lpcmmp)
352{
353 EXTBAUDGET BaudInfo;
354 APIRET rc;
355 ULONG ulLen;
356 USHORT COMErr;
357 int i;
358 dprintf(("HMDeviceCommClass::GetCommProperties"));
359
360 ulLen = sizeof(EXTBAUDGET);
361 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
362 IOCTL_ASYNC,
363 ASYNC_EXTGETBAUDRATE,
364 0,0,0,
365 &BaudInfo,ulLen,&ulLen);
366 memset(lpcmmp,0,sizeof(COMMPROP));
367 lpcmmp->wPacketLength = sizeof(COMMPROP);
368 lpcmmp->wPacketVersion = 1; //???
369 lpcmmp->dwServiceMask = SP_SERIALCOMM;
370 for(i=0;i<BaudTableSize && BaudInfo.ulMaxBaud <= BaudTable[i].dwBaudRate;i++);
371 lpcmmp->dwMaxBaud = BaudTable[i].dwBaudFlag;
372 lpcmmp->dwProvSubType = PST_RS232;
373 lpcmmp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK |
374 PCF_RTSCTS | PCF_SETXCHAR |
375 PCF_XONXOFF;
376 lpcmmp->dwSettableParams = SP_BAUD | SP_DATABITS |
377 SP_HANDSHAKEING | SP_PARITY |
378 SP_PARITY_CHECK | SP_STOPBIT;
379 lpcmmp->dwSettableBaud = 0;
380 for(i=0;i<BaudTableSize;i++)
381 {
382 if ( (BaudTable[i].dwBaudRate>=BaudInfo.ulMinBaud) &&
383 (BaudTable[i].dwBaudRate<=BaudInfo.ulMaxBaud) )
384 lpcmmp->dwSettableBaud |= BaudTable[i].dwBaudFlag;
385 }
386 lpcmmp->dwSettableBaud |= BAUD_USER;
387 lpcmmp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
388 lpcmmp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
389 PARITY_NONE | PARITY_ODD | PARITY_EVEN |
390 PARITY_MARK | PARITY_SPACE;
391 return(rc==0);
392}
393
394BOOL HMDeviceCommClass::GetCommMask( PHMHANDLEDATA pHMHandleData,
395 LPDWORD lpfdwEvtMask)
396{
397 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
398
399 dprintf(("HMDeviceCommClass::GetCommMask"));
400
401 *lpfdwEvtMask = pDevData->dwEventMask;
402 return(TRUE);
403}
404
405BOOL HMDeviceCommClass::SetCommMask( PHMHANDLEDATA pHMHandleData,
406 DWORD fdwEvtMask)
407{
408 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
409 dprintf(("HMDeviceCommClass::SetCommMask"));
410
411 pDevData->dwEventMask = fdwEvtMask & ~(EV_RLSD|EV_RXFLAG); // Clear the 2 not supported Flags.
412 return(TRUE);
413}
414
415BOOL HMDeviceCommClass::PurgeComm( PHMHANDLEDATA pHMHandleData,
416 DWORD fdwAction)
417{
418 dprintf(("HMDeviceCommClass::PurgeComm unimplemented stub!"));
419 // ToDo: find a way to stop the current transmision didn't find
420 // any clue how to in Control Program Guide and reference
421
422 return(TRUE);
423}
424BOOL HMDeviceCommClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
425 LPDWORD lpdwErrors,
426 LPCOMSTAT lpcst)
427{
428 APIRET rc;
429 ULONG ulLen;
430 USHORT COMErr;
431
432 dprintf(("HMDeviceCommClass::ClearCommError"));
433 ulLen = sizeof(USHORT);
434
435 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
436 IOCTL_ASYNC,
437 ASYNC_GETCOMMERROR,
438 0,0,0,
439 &COMErr,2,&ulLen);
440 *lpdwErrors = 0;
441 *lpdwErrors |= (COMErr & 0x0001)?CE_OVERRUN:0;
442 *lpdwErrors |= (COMErr & 0x0002)?CE_RXOVER:0;
443 *lpdwErrors |= (COMErr & 0x0004)?CE_RXPARITY:0;
444 *lpdwErrors |= (COMErr & 0x0008)?CE_FRAME:0;
445
446 if(lpcst)
447 {
448 UCHAR ucStatus;
449 RXQUEUE qInfo;
450 ulLen = 1;
451 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
452 IOCTL_ASYNC,
453 ASYNC_GETCOMMSTATUS,
454 0,0,0,
455 &ucStatus,ulLen,&ulLen);
456 if(!rc)
457 {
458 lpcst->fCtsHold = ((ucStatus & 0x01)>0);
459 lpcst->fDsrHold = ((ucStatus & 0x02)>0);
460 lpcst->fRlsdHold = FALSE;//(ucStatus & 0x04)>0);
461 lpcst->fXoffHold = ((ucStatus & 0x08)>0);
462 lpcst->fXoffSend = ((ucStatus & 0x10)>0);
463 lpcst->fEof = ((ucStatus & 0x20)>0);// Is break = Eof ??
464 lpcst->fTxim = ((ucStatus & 0x40)>0);
465
466 ulLen = sizeof(qInfo);
467 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
468 IOCTL_ASYNC,
469 ASYNC_GETINQUECOUNT,
470 0,0,0,
471 &qInfo,ulLen,&ulLen);
472 if(!rc)
473 {
474 lpcst->cbInQue = qInfo.cch;
475 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
476 IOCTL_ASYNC,
477 ASYNC_GETOUTQUECOUNT,
478 0,0,0,
479 &qInfo,ulLen,&ulLen);
480 if(!rc)
481 lpcst->cbOutQue = qInfo.cch;
482 }
483 }
484 }
485
486 return(rc==0);
487}
488BOOL HMDeviceCommClass::SetCommState( PHMHANDLEDATA pHMHandleData,
489 LPDCB lpDCB)
490{
491 APIRET rc;
492 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
493 DCB *pCurDCB = &pDevData->CommCfg.dcb;
494 dprintf(("HMDeviceCommClass::SetCommState"));
495
496 rc = 0;
497 if(pCurDCB->BaudRate != lpDCB->BaudRate)
498 rc = SetBaud( pHMHandleData,
499 lpDCB->BaudRate);
500
501 if(!rc)
502 {
503 if( (pCurDCB->ByteSize != lpDCB->ByteSize) ||
504 (pCurDCB->Parity != lpDCB->Parity) ||
505 (pCurDCB->StopBits != lpDCB->StopBits))
506 rc = SetLine( pHMHandleData,
507 lpDCB->ByteSize,
508 lpDCB->Parity,
509 lpDCB->StopBits);
510 }
511
512 if(!rc)
513 {
514 if( (pCurDCB->fOutxCtsFlow != lpDCB->fOutxCtsFlow) ||
515 (pCurDCB->fOutxDsrFlow != lpDCB->fOutxDsrFlow) ||
516 (pCurDCB->fDtrControl != lpDCB->fDtrControl) ||
517 (pCurDCB->fDsrSensitivity != lpDCB->fDsrSensitivity) ||
518 (pCurDCB->fTXContinueOnXoff != lpDCB->fTXContinueOnXoff) ||
519 (pCurDCB->fOutX != lpDCB->fOutX) ||
520 (pCurDCB->fInX != lpDCB->fInX) ||
521 (pCurDCB->fErrorChar != lpDCB->fErrorChar) ||
522 (pCurDCB->fNull != lpDCB->fNull) ||
523 (pCurDCB->fRtsControl != lpDCB->fRtsControl) ||
524 (pCurDCB->fAbortOnError != lpDCB->fAbortOnError) ||
525 (pCurDCB->XonChar != lpDCB->XonChar) ||
526 (pCurDCB->XoffChar != lpDCB->XoffChar) ||
527 (pCurDCB->ErrorChar != lpDCB->ErrorChar))
528 SetOS2DCB( pHMHandleData,
529 lpDCB->fOutxCtsFlow, lpDCB->fOutxDsrFlow,
530 lpDCB->fDtrControl, lpDCB->fDsrSensitivity,
531 lpDCB->fTXContinueOnXoff, lpDCB->fOutX,
532 lpDCB->fInX, lpDCB->fErrorChar,
533 lpDCB->fNull, lpDCB->fRtsControl,
534 lpDCB->fAbortOnError, lpDCB->XonChar,
535 lpDCB->XoffChar,lpDCB->ErrorChar);
536 }
537
538 return(rc==0);
539}
540BOOL HMDeviceCommClass::GetCommState( PHMHANDLEDATA pHMHandleData,
541 LPDCB lpdcb)
542{
543 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
544
545 dprintf(("HMDeviceCommClass::GetCommState"));
546 memcpy(lpdcb,&pDevData->CommCfg.dcb,sizeof(DCB));
547
548 return(TRUE);
549}
550BOOL HMDeviceCommClass::GetCommModemStatus( PHMHANDLEDATA pHMHandleData,
551 LPDWORD lpModemStat )
552{
553 APIRET rc;
554 ULONG ulLen;
555 USHORT COMErr;
556 UCHAR ucStatus;
557
558 dprintf(("HMDeviceCommClass::TransmitCommChar partly implemented"));
559 ulLen = sizeof(CHAR);
560
561 ulLen = 1;
562 *lpModemStat = 0;
563
564 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
565 IOCTL_ASYNC,
566 ASYNC_GETMODEMINPUT,
567 0,0,0,
568 &ucStatus,ulLen,&ulLen);
569 if(!rc)
570 {
571 *lpModemStat |= (ucStatus & 0x10)? MS_CTS_ON:0;
572 *lpModemStat |= (ucStatus & 0x20)? MS_DSR_ON:0;
573 *lpModemStat |= (ucStatus & 0x40)? MS_RING_ON:0;
574 //*lpModemStat |= (ucStatus & 0x80)? MS_RSLD_ON:0;
575 }
576
577 return(rc==0);
578}
579
580BOOL HMDeviceCommClass::GetCommTimeouts( PHMHANDLEDATA pHMHandleData,
581 LPCOMMTIMEOUTS lpctmo)
582{
583 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
584
585 dprintf(("HMDeviceCommClass::GetCommTimeouts stub"));
586 memcpy( lpctmo,
587 &pDevData->CommTOuts,
588 sizeof(COMMTIMEOUTS));
589 return(TRUE);
590}
591BOOL HMDeviceCommClass::SetCommTimeouts( PHMHANDLEDATA pHMHandleData,
592 LPCOMMTIMEOUTS lpctmo)
593{
594 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
595 DCBINFO os2dcb;
596 ULONG ulLen;
597 APIRET rc;
598
599 memcpy( &pDevData->CommTOuts,
600 lpctmo,
601 sizeof(COMMTIMEOUTS));
602
603 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
604
605 os2dcb.fbTimeOut = 0x01;
606 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
607 {
608 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
609 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
610 os2dcb.fbTimeOut = 0x03;
611 else
612 os2dcb.fbTimeOut = 0x02;
613 }
614 else
615 {
616 DWORD dwTimeout;
617 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
618 if(dwTimeout)
619 dwTimeout--; // 0=10 ms unit is 10ms or .01s
620 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
621 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
622 }
623 ulLen = sizeof(DCBINFO);
624 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
625 IOCTL_ASYNC,
626 ASYNC_SETDCBINFO,
627 &os2dcb,ulLen,&ulLen,
628 NULL,0,NULL);
629
630 return(0==rc);
631}
632BOOL HMDeviceCommClass::TransmitCommChar( PHMHANDLEDATA pHMHandleData,
633 CHAR cChar )
634{
635 APIRET rc;
636 ULONG ulLen;
637 USHORT COMErr;
638
639 dprintf(("HMDeviceCommClass::TransmitCommChar"));
640 ulLen = sizeof(CHAR);
641
642 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
643 IOCTL_ASYNC,
644 ASYNC_TRANSMITIMM,
645 &cChar,ulLen,&ulLen,
646 NULL,0,NULL);
647
648 return(rc==0);
649}
650
651BOOL HMDeviceCommClass::SetCommBreak( PHMHANDLEDATA pHMHandleData )
652{
653 APIRET rc;
654 ULONG ulLen;
655 USHORT COMErr;
656
657 dprintf(("HMDeviceCommClass::SetCommBreak"));
658 ulLen = sizeof(USHORT);
659
660 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
661 IOCTL_ASYNC,
662 ASYNC_SETBREAKON,
663 0,0,0,
664 &COMErr,2,&ulLen);
665
666 return(rc==0);
667}
668
669BOOL HMDeviceCommClass::ClearCommBreak( PHMHANDLEDATA pHMHandleData)
670{
671 APIRET rc;
672 ULONG ulLen;
673 USHORT COMErr;
674
675 dprintf(("HMDeviceCommClass::ClearCommBreak"));
676 ulLen = sizeof(USHORT);
677
678 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
679 IOCTL_ASYNC,
680 ASYNC_SETBREAKOFF,
681 0,0,0,
682 &COMErr,2,&ulLen);
683
684 return(rc==0);
685}
686
687BOOL HMDeviceCommClass::SetCommConfig( PHMHANDLEDATA pHMHandleData,
688 LPCOMMCONFIG lpCC,
689 DWORD dwSize )
690{
691 dprintf(("HMDeviceCommClass::SetCommConfig"));
692
693
694 return(TRUE);
695}
696
697BOOL HMDeviceCommClass::GetCommConfig( PHMHANDLEDATA pHMHandleData,
698 LPCOMMCONFIG lpCC,
699 LPDWORD lpdwSize )
700{
701 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
702
703 dprintf(("HMDeviceCommClass::GetCommConfig"));
704
705 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
706 *lpdwSize< sizeof(COMMCONFIG) )
707 {
708 O32_SetLastError(ERROR_INSUFFICIENT_BUFFER);
709 *lpdwSize= sizeof(COMMCONFIG);
710 return FALSE;
711 }
712
713 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
714 {
715 O32_SetLastError(ERROR_INVALID_HANDLE);
716 return FALSE;
717 }
718
719 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
720 *lpdwSize = sizeof(COMMCONFIG);
721 return(TRUE);
722
723
724 return(TRUE);
725}
726
727BOOL HMDeviceCommClass::EscapeCommFunction( PHMHANDLEDATA pHMHandleData,
728 UINT dwFunc )
729{
730 APIRET rc;
731 ULONG ulDLen,ulPLen;
732 USHORT COMErr;
733 MODEMSTATUS mdm;
734
735 dprintf(("HMDeviceCommClass::EscapeCommFunction"));
736
737 ulDLen = sizeof(USHORT);
738 ulPLen = sizeof(MODEMSTATUS);
739 switch(dwFunc)
740 {
741 case CLRDTR:
742 mdm.fbModemOn = 0x00;
743 mdm.fbModemOff = 0XFE;
744 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
745 IOCTL_ASYNC,
746 ASYNC_SETMODEMCTRL,
747 &mdm,ulPLen,&ulPLen,
748 &COMErr,ulDLen,&ulDLen);
749 break;
750 case CLRRTS:
751 mdm.fbModemOn = 0x00;
752 mdm.fbModemOff = 0XFD;
753 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
754 IOCTL_ASYNC,
755 ASYNC_SETMODEMCTRL,
756 &mdm,ulPLen,&ulPLen,
757 &COMErr,ulDLen,&ulDLen);
758 break;
759 case SETDTR:
760 mdm.fbModemOn = 0x01;
761 mdm.fbModemOff = 0XFF;
762 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
763 IOCTL_ASYNC,
764 ASYNC_SETMODEMCTRL,
765 &mdm,ulPLen,&ulPLen,
766 &COMErr,ulDLen,&ulDLen);
767 break;
768 case SETRTS:
769 mdm.fbModemOn = 0x02;
770 mdm.fbModemOff = 0XFF;
771 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
772 IOCTL_ASYNC,
773 ASYNC_SETMODEMCTRL,
774 &mdm,ulPLen,&ulPLen,
775 &COMErr,ulDLen,&ulDLen);
776 break;
777 case SETXOFF:
778 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
779 IOCTL_ASYNC,
780 ASYNC_STOPTRANSMIT,
781 0,0,0,
782 0,0,0);
783 break;
784 case SETXON:
785 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
786 IOCTL_ASYNC,
787 ASYNC_STARTTRANSMIT,
788 0,0,0,
789 0,0,0);
790 break;
791 default:
792 O32_SetLastError(ERROR_INVALID_PARAMETER);
793 return(FALSE);
794 }
795
796 return(rc==0);
797}
798
799BOOL HMDeviceCommClass::SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
800 LPCOMMCONFIG lpCC,
801 DWORD dwSize)
802{
803 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
804 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
805 {
806 O32_SetLastError(ERROR_INVALID_HANDLE);
807 return FALSE;
808 }
809 memset(&pDevData->CommCfg,0, sizeof(COMMCONFIG));
810 memcpy(&pDevData->CommCfg,lpCC,dwSize>sizeof(COMMCONFIG)?sizeof(COMMCONFIG):dwSize);
811
812 return(TRUE);
813}
814BOOL HMDeviceCommClass::GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
815 LPCOMMCONFIG lpCC,
816 LPDWORD lpdwSize)
817{
818 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpDeviceData;
819
820 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
821 *lpdwSize< sizeof(COMMCONFIG) )
822 {
823 O32_SetLastError(ERROR_INSUFFICIENT_BUFFER);
824 *lpdwSize= sizeof(COMMCONFIG);
825 return FALSE;
826 }
827
828 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )
829 {
830 O32_SetLastError(ERROR_INVALID_HANDLE);
831 return FALSE;
832 }
833
834 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
835 *lpdwSize = sizeof(COMMCONFIG);
836 return(TRUE);
837}
838APIRET HMDeviceCommClass::SetLine( PHMHANDLEDATA pHMHandleData,
839 UCHAR ucSize,
840 UCHAR ucParity,
841 UCHAR ucStop)
842{
843 APIRET rc;
844 ULONG ulLen;
845 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
846 DCB *pCurDCB = &pDevData->CommCfg.dcb;
847 struct
848 {
849 UCHAR ucSize;
850 UCHAR ucParity;
851 UCHAR ucStop;
852 UCHAR ucPadding;
853 }Param;
854
855 ulLen = 3;
856 Param.ucSize = ucSize;
857 Param.ucParity = ucParity;
858 Param.ucStop = ucStop;
859
860 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
861 IOCTL_ASYNC,
862 ASYNC_SETLINECTRL,
863 &Param,ulLen,&ulLen,
864 NULL,0,NULL);
865
866 if(0==rc)
867 {
868 pCurDCB->ByteSize = ucSize;
869 pCurDCB->Parity = ucParity;
870 pCurDCB->StopBits = ucStop;
871 }
872
873 return rc;
874}
875
876APIRET HMDeviceCommClass::SetOS2DCB( PHMHANDLEDATA pHMHandleData,
877 BOOL fOutxCtsFlow, BOOL fOutxDsrFlow,
878 UCHAR ucDtrControl, BOOL fDsrSensitivity,
879 BOOL fTXContinueOnXoff, BOOL fOutX,
880 BOOL fInX, BOOL fErrorChar,
881 BOOL fNull, UCHAR ucRtsControl,
882 BOOL fAbortOnError, BYTE XonChar,
883 BYTE XoffChar,BYTE ErrorChar)
884{
885 APIRET rc;
886 ULONG ulLen;
887 DCBINFO os2dcb;
888
889 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData;
890 DCB *pCurDCB = &pDevData->CommCfg.dcb;
891
892 memcpy(&os2dcb,&pDevData->dcbOS2,sizeof(DCBINFO));
893 os2dcb.fbCtlHndShake = (ucDtrControl & 0x03) |
894 (fOutxCtsFlow?0x08:0x00) |
895 (fOutxDsrFlow?0x10:0x00) |
896 // No DCD support in Win32 ?!
897 (fDsrSensitivity?0x40:0x00);
898 os2dcb.fbFlowReplace = (fOutX?0x01:0x00) |
899 (fInX?0x02:0x00) |
900 (fErrorChar?0x04:0x00)|
901 (fNull?0x08:0x00)|
902 (fTXContinueOnXoff?0x02:0x00)| // Not sure if thats the right flag to test
903 (ucRtsControl<<6);
904
905 os2dcb.fbTimeOut = 0x01;
906 if(MAXDWORD==pDevData->CommTOuts.ReadIntervalTimeout)
907 {
908 if( (0==pDevData->CommTOuts.ReadTotalTimeoutMultiplier) &&
909 (0==pDevData->CommTOuts.ReadTotalTimeoutConstant))
910 os2dcb.fbTimeOut = 0x03;
911 else
912 os2dcb.fbTimeOut = 0x02;
913 }
914 else
915 {
916 DWORD dwTimeout;
917 dwTimeout = pDevData->CommTOuts.ReadIntervalTimeout/10;
918 if(dwTimeout)
919 dwTimeout--; // 0=10 ms unit is 10ms or .01s
920 os2dcb.usWriteTimeout = 0x0000FFFF & dwTimeout;
921 os2dcb.usReadTimeout = 0x0000FFFF & dwTimeout;
922 }
923 os2dcb.bErrorReplacementChar = ErrorChar;
924 os2dcb.bXONChar = XonChar;
925 os2dcb.bXOFFChar = XoffChar;
926 ulLen = sizeof(DCBINFO);
927 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
928 IOCTL_ASYNC,
929 ASYNC_SETDCBINFO,
930 &os2dcb,ulLen,&ulLen,
931 NULL,0,NULL);
932
933 if(0==rc)
934 {
935 memcpy(&pDevData->dcbOS2,&os2dcb,sizeof(DCBINFO));
936 pCurDCB->fOutxCtsFlow = fOutxCtsFlow;
937 pCurDCB->fOutxDsrFlow = fOutxDsrFlow;
938 pCurDCB->fDtrControl = ucDtrControl;
939 pCurDCB->fDsrSensitivity = fDsrSensitivity;
940 pCurDCB->fTXContinueOnXoff = fTXContinueOnXoff;
941 pCurDCB->fOutX = fOutX;
942 pCurDCB->fInX = fInX;
943 pCurDCB->fErrorChar = fErrorChar;
944 pCurDCB->fNull = fNull;
945 pCurDCB->fRtsControl = ucRtsControl;
946 pCurDCB->fAbortOnError = fAbortOnError;
947 pCurDCB->XonChar = XonChar;
948 pCurDCB->XoffChar = XoffChar;
949 pCurDCB->ErrorChar = ErrorChar;
950 }
951
952 return rc;
953
954}
955
956APIRET HMDeviceCommClass::SetBaud( PHMHANDLEDATA pHMHandleData,
957 DWORD dwNewBaud)
958{
959 APIRET rc;
960 ULONG ulLen;
961 EXTBAUDSET SetBaud;
962 EXTBAUDGET GetBaud;
963 ulLen = sizeof(SetBaud);
964 SetBaud.ulBaud = dwNewBaud;
965 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
966 IOCTL_ASYNC,
967 ASYNC_EXTSETBAUDRATE,
968 &SetBaud,ulLen,&ulLen,
969 NULL,0,NULL);
970 if(0==rc)
971 {
972 ulLen = sizeof(GetBaud);
973 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
974 IOCTL_ASYNC,
975 ASYNC_EXTGETBAUDRATE,
976 NULL,0,NULL,
977 &GetBaud,ulLen,&ulLen);
978 if(0==rc)
979 {
980 if(dwNewBaud !=GetBaud.ulCurrBaud)
981 rc = 1; // ToDo set a proper Errorhandling
982 else
983 {
984 ((PHMDEVCOMDATA)pHMHandleData->lpDeviceData)->CommCfg.dcb.BaudRate = dwNewBaud;
985 ((PHMDEVCOMDATA)pHMHandleData->lpDeviceData)->CommCfg.dcb.BaudRate = dwNewBaud;
986 }
987 }
988 }
989 return rc;
990}
991
Note: See TracBrowser for help on using the repository browser.