source: trunk/src/kernel32/hmparport.cpp@ 7300

Last change on this file since 7300 was 7300, checked in by phaller, 24 years ago

.

File size: 18.7 KB
Line 
1/* $Id: hmparport.cpp,v 1.2 2001-11-08 15:10:39 phaller Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 Parallel Port device access class
7 *
8 * 2001 Patrick Haller <patrick.haller@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 "hmparport.h"
20#include "oslibdos.h"
21
22#define DBG_LOCALLOG DBG_hmparport
23#include "dbglocal.h"
24
25
26#define MAGIC_PARPORT 0x4c505431
27
28#define IOCTL_PRINTER 0x0005
29#define PRT_QUERYJOBHANDLE 0x0021
30#define PRT_SETFRAMECTL 0x0042
31#define PRT_SETINFINITERETRY 0x0044
32#define PRT_INITPRINTER 0x0046
33#define PRT_ACTIVATEFONT 0x0048
34#define PRT_SETPRINTJOBTITLE 0x004D
35#define PRT_SETIRQTIMEOUT 0x004E
36#define PRT_SETCOMMMODE 0x0052
37#define PRT_SETDATAXFERMODE 0x0053
38#define PRT_GETFRAMECTL 0x0062
39#define PRT_GETINFINITERETRY 0x0064
40#define PRT_GETPRINTERSTATUS 0x0066
41#define PRT_QUERYACTIVEFONT 0x0069
42#define PRT_VERIFYFONT 0x006A
43#define PRT_QUERYIRQTIMEOUT 0x006E
44#define PRT_QUERYCOMMMODE 0x0072
45#define PRT_QUERYDATAXFERMODE 0x0073
46#define PRT_QUERDEVICEID 0x0074
47
48
49#if 0
50#pragma pack(1)
51typedef struct _DCBINFO
52{
53 USHORT usWriteTimeout; /* Time period used for Write Timeout processing. */
54 USHORT usReadTimeout; /* Time period used for Read Timeout processing. */
55 BYTE fbCtlHndShake; /* HandShake Control flag. */
56 BYTE fbFlowReplace; /* Flow Control flag. */
57 BYTE fbTimeOut; /* Timeout flag. */
58 BYTE bErrorReplacementChar; /* Error Replacement Character. */
59 BYTE bBreakReplacementChar; /* Break Replacement Character. */
60 BYTE bXONChar; /* Character XON. */
61 BYTE bXOFFChar; /* Character XOFF. */
62} DCBINFO;
63typedef DCBINFO *PDCBINFO;
64
65
66typedef struct _RXQUEUE
67{
68 USHORT cch; /* Number of characters in the queue. */
69 USHORT cb; /* Size of receive/transmit queue. */
70} RXQUEUE;
71
72typedef RXQUEUE *PRXQUEUE;
73
74
75typedef struct _MODEMSTATUS
76{
77 BYTE fbModemOn; /* Modem Control Signals ON Mask. */
78 BYTE fbModemOff; /* Modem Control Signals OFF Mask. */
79} MODEMSTATUS;
80
81typedef MODEMSTATUS *PMODEMSTATUS;
82
83
84#pragma pack()
85
86
87#endif
88
89
90typedef struct _HMDEVPARPORTDATA
91{
92 ULONG ulMagic;
93 // Win32 Device Control Block
94 //OS/2 Device Control Block
95} HMDEVPARPORTDATA, *PHMDEVPARPORTDATA;
96
97static VOID *CreateDevData()
98{
99 PHMDEVPARPORTDATA pData;
100 pData = new HMDEVPARPORTDATA();
101 if(NULL!=pData)
102 {
103 memset(pData,0,sizeof(HMDEVPARPORTDATA));
104 pData->ulMagic = MAGIC_PARPORT;
105 }
106 return pData;
107}
108
109
110HMDeviceParPortClass::HMDeviceParPortClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
111{
112 VOID *pData;
113 dprintf(("HMDeviceParPortClass: Register LPT1 to LPT3 with Handle Manager\n"));
114
115 pData = CreateDevData();
116 if(pData!= NULL)
117 HMDeviceRegisterEx("LPT1", this, pData);
118}
119
120/*****************************************************************************
121 * Name : HMDeviceParPortClass::FindDevice
122 * Purpose : Checks if lpDeviceName belongs to this device class
123 * Parameters: LPCSTR lpClassDevName
124 * LPCSTR lpDeviceName
125 * int namelength
126 * Variables :
127 * Result : checks if name is COMx or COMx: (x=1..8)
128 * Remark :
129 * Status :
130 *
131 * Author : SvL
132 *****************************************************************************/
133BOOL HMDeviceParPortClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
134{
135 if(namelength > 5)
136 return FALSE; //can't be lpt name
137
138 //first 3 letters 'LPT'?
139 if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) {
140 return FALSE;
141 }
142
143 if(namelength == 5 && lpDeviceName[4] != ':') {
144 return FALSE;
145 }
146 switch(lpDeviceName[3]) {
147 case '1':
148 case '2':
149 case '3':
150 return TRUE; //we support up to LPT3
151 }
152 return FALSE;
153}
154
155DWORD HMDeviceParPortClass::CreateFile(LPCSTR lpFileName,
156 PHMHANDLEDATA pHMHandleData,
157 PVOID lpSecurityAttributes,
158 PHMHANDLEDATA pHMHandleDataTemplate)
159{
160 char comname[6];
161
162 dprintf(("HMDeviceParPortClass: Parallel port %s open request\n", lpFileName));
163
164 if(strlen(lpFileName) > 5) {
165 return -1; //safety check (unnecessary..)
166 }
167 pHMHandleData->hHMHandle = 0;
168
169 strcpy(comname, lpFileName);
170 comname[4] = 0; //get rid of : (if present) (eg LPT1:)
171
172 //AH: TODO parse Win32 security handles
173 ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
174 pHMHandleData->hHMHandle = OSLibDosOpen(comname,
175 OSLIB_ACCESS_READWRITE |
176 OSLIB_ACCESS_SHAREDENYREAD |
177 OSLIB_ACCESS_SHAREDENYWRITE);
178 SetErrorMode(oldmode);
179
180#if 0
181 if (pHMHandleData->hHMHandle != 0)
182 {
183 ULONG ulLen;
184 APIRET rc;
185 pHMHandleData->lpHandlerData = new HMDEVPARPORTDATA();
186 // Init The handle instance with the default default device config
187 memcpy( pHMHandleData->lpHandlerData,
188 pHMHandleData->lpDeviceData,
189 sizeof(HMDEVPARPORTDATA));
190
191 ulLen = sizeof(DCBINFO);
192
193 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
194 IOCTL_ASYNC,
195 ASYNC_GETDCBINFO,
196 0,0,0,
197 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
198 dprintf(("DCB Of %s :\n"
199 " WriteTimeout : %d\n"
200 " ReadTimeout : %d\n"
201 " CtlHandshake : 0x%x\n"
202 " FlowReplace : 0x%x\n"
203 " Timeout : 0x%x\n"
204 " Error replacement Char : 0x%x\n"
205 " Break replacement Char : 0x%x\n"
206 " XON Char : 0x%x\n"
207 " XOFF Char : 0x%x\n",
208 comname,
209 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
210 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
211 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
212 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
213 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
214 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
215 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
216 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
217 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
218
219 if(rc)
220 {
221 return -1;
222 }
223 rc = SetBaud(pHMHandleData,9600);
224 dprintf(("Init Baud to 9600 rc = %d",rc));
225 rc = SetLine(pHMHandleData,8,0,0);
226 dprintf(("Set Line to 8/N/1 rc = %d",rc));
227 return 0;
228 }
229 else
230 return -1;
231#endif
232
233 return NO_ERROR;
234}
235
236
237 /* this is a handler method for calls to CloseHandle() */
238BOOL HMDeviceParPortClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
239{
240 dprintf(("HMDeviceParPortClass: Parallel port close request\n"));
241 delete pHMHandleData->lpHandlerData;
242 return OSLibDosClose(pHMHandleData->hHMHandle);
243}
244
245
246/*****************************************************************************
247 * Name : BOOL HMDeviceParPortClass::WriteFile
248 * Purpose : write data to handle / device
249 * Parameters: PHMHANDLEDATA pHMHandleData,
250 * LPCVOID lpBuffer,
251 * DWORD nNumberOfBytesToWrite,
252 * LPDWORD lpNumberOfBytesWritten,
253 * LPOVERLAPPED lpOverlapped
254 * Variables :
255 * Result : Boolean
256 * Remark :
257 * Status :
258 *
259 * Author : SvL
260 *****************************************************************************/
261
262BOOL HMDeviceParPortClass::WriteFile(PHMHANDLEDATA pHMHandleData,
263 LPCVOID lpBuffer,
264 DWORD nNumberOfBytesToWrite,
265 LPDWORD lpNumberOfBytesWritten,
266 LPOVERLAPPED lpOverlapped)
267{
268 dprintf(("KERNEL32:HMDeviceParPortClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
269 lpHMDeviceName,
270 pHMHandleData->hHMHandle,
271 lpBuffer,
272 nNumberOfBytesToWrite,
273 lpNumberOfBytesWritten,
274 lpOverlapped));
275
276 BOOL ret;
277 ULONG ulBytesWritten;
278
279 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
280 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
281 SetLastError(ERROR_INVALID_PARAMETER);
282 return FALSE;
283 }
284 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
285 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
286 }
287
288 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
289 &ulBytesWritten);
290
291 if(lpNumberOfBytesWritten) {
292 *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
293 }
294 if(ret == FALSE) {
295 dprintf(("ERROR: WriteFile failed with rc %d", GetLastError()));
296 }
297
298 return ret;
299}
300
301/*****************************************************************************
302 * Name : BOOL WriteFileEx
303 * Purpose : The WriteFileEx function writes data to a file. It is designed
304 * solely for asynchronous operation, unlike WriteFile, which is
305 * designed for both synchronous and asynchronous operation.
306 * WriteFileEx reports its completion status asynchronously,
307 * calling a specified completion routine when writing is completed
308 * and the calling thread is in an alertable wait state.
309 * Parameters: HANDLE hFile handle of file to write
310 * LPVOID lpBuffer address of buffer
311 * DWORD nNumberOfBytesToRead number of bytes to write
312 * LPOVERLAPPED lpOverlapped address of offset
313 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
314 * Variables :
315 * Result : TRUE / FALSE
316 * Remark :
317 * Status : UNTESTED STUB
318 *
319 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
320 *****************************************************************************/
321
322BOOL HMDeviceParPortClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
323 LPVOID lpBuffer,
324 DWORD nNumberOfBytesToWrite,
325 LPOVERLAPPED lpOverlapped,
326 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
327{
328 dprintf(("ERROR: WriteFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
329 lpHMDeviceName,
330 pHMHandleData->hHMHandle,
331 lpBuffer,
332 nNumberOfBytesToWrite,
333 lpOverlapped,
334 lpCompletionRoutine));
335
336 SetLastError(ERROR_INVALID_FUNCTION);
337 return FALSE;
338}
339
340/*****************************************************************************
341 * Name : BOOL HMDeviceParPortClass::ReadFile
342 * Purpose : read data from handle / device
343 * Parameters: PHMHANDLEDATA pHMHandleData,
344 * LPCVOID lpBuffer,
345 * DWORD nNumberOfBytesToRead,
346 * LPDWORD lpNumberOfBytesRead,
347 * LPOVERLAPPED lpOverlapped
348 * Variables :
349 * Result : Boolean
350 * Remark :
351 * Status :
352 *
353 * Author : SvL
354 *****************************************************************************/
355
356BOOL HMDeviceParPortClass::ReadFile(PHMHANDLEDATA pHMHandleData,
357 LPCVOID lpBuffer,
358 DWORD nNumberOfBytesToRead,
359 LPDWORD lpNumberOfBytesRead,
360 LPOVERLAPPED lpOverlapped)
361{
362 dprintf(("KERNEL32:HMDeviceParPortClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
363 lpHMDeviceName,
364 pHMHandleData->hHMHandle,
365 lpBuffer,
366 nNumberOfBytesToRead,
367 lpNumberOfBytesRead,
368 lpOverlapped));
369
370 BOOL ret;
371 ULONG ulBytesRead;
372
373 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
374 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
375 SetLastError(ERROR_INVALID_PARAMETER);
376 return FALSE;
377 }
378 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
379 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
380 }
381
382 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
383 &ulBytesRead);
384
385 if(lpNumberOfBytesRead) {
386 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
387 }
388 if(ret == FALSE) {
389 dprintf(("ERROR: ReadFile failed with rc %d", GetLastError()));
390 }
391 return ret;
392}
393
394/*****************************************************************************
395 * Name : BOOL ReadFileEx
396 * Purpose : The ReadFileEx function reads data from a file asynchronously.
397 * It is designed solely for asynchronous operation, unlike the
398 * ReadFile function, which is designed for both synchronous and
399 * asynchronous operation. ReadFileEx lets an application perform
400 * other processing during a file read operation.
401 * The ReadFileEx function reports its completion status asynchronously,
402 * calling a specified completion routine when reading is completed
403 * and the calling thread is in an alertable wait state.
404 * Parameters: HANDLE hFile handle of file to read
405 * LPVOID lpBuffer address of buffer
406 * DWORD nNumberOfBytesToRead number of bytes to read
407 * LPOVERLAPPED lpOverlapped address of offset
408 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
409 * Variables :
410 * Result : TRUE / FALSE
411 * Remark :
412 * Status : UNTESTED STUB
413 *
414 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
415 *****************************************************************************/
416BOOL HMDeviceParPortClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
417 LPVOID lpBuffer,
418 DWORD nNumberOfBytesToRead,
419 LPOVERLAPPED lpOverlapped,
420 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
421{
422 dprintf(("ERROR: ReadFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
423 lpHMDeviceName,
424 pHMHandleData->hHMHandle,
425 lpBuffer,
426 nNumberOfBytesToRead,
427 lpOverlapped,
428 lpCompletionRoutine));
429
430 SetLastError(ERROR_INVALID_FUNCTION);
431 return FALSE;
432}
433
434BOOL HMDeviceParPortClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
435 LPCOMMPROP lpcmmp)
436{
437 APIRET rc;
438 ULONG ulLen;
439 int i;
440 dprintf(("HMDeviceParPortClass::GetCommProperties"));
441
442#if 0
443 USHORT COMErr;
444 EXTBAUDGET BaudInfo;
445 ulLen = sizeof(EXTBAUDGET);
446 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
447 IOCTL_ASYNC,
448 ASYNC_EXTGETBAUDRATE,
449 0,0,0,
450 &BaudInfo,ulLen,&ulLen);
451#endif
452 rc = NO_ERROR;
453
454 memset(lpcmmp,0,sizeof(COMMPROP));
455 lpcmmp->wPacketLength = sizeof(COMMPROP);
456 lpcmmp->wPacketVersion = 1; //???
457 lpcmmp->dwProvSubType = PST_PARALLELPORT;
458
459#if 0
460 lpcmmp->dwServiceMask = SP_SERIALCOMM;
461 for(i=0;i<BaudTableSize && BaudInfo.ulMaxBaud <= BaudTable[i].dwBaudRate;i++);
462 lpcmmp->dwMaxBaud = BaudTable[i].dwBaudFlag;
463 lpcmmp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK |
464 PCF_RTSCTS | PCF_SETXCHAR |
465 PCF_XONXOFF;
466 lpcmmp->dwSettableParams = SP_BAUD | SP_DATABITS |
467 SP_HANDSHAKEING | SP_PARITY |
468 SP_PARITY_CHECK | SP_STOPBIT;
469 lpcmmp->dwSettableBaud = 0;
470 for(i=0;i<BaudTableSize;i++)
471 {
472 if ( (BaudTable[i].dwBaudRate>=BaudInfo.ulMinBaud) &&
473 (BaudTable[i].dwBaudRate<=BaudInfo.ulMaxBaud) )
474 lpcmmp->dwSettableBaud |= BaudTable[i].dwBaudFlag;
475 }
476 lpcmmp->dwSettableBaud |= BAUD_USER;
477 lpcmmp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
478 lpcmmp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
479 PARITY_NONE | PARITY_ODD | PARITY_EVEN |
480 PARITY_MARK | PARITY_SPACE;
481#endif
482
483 return(rc==0);
484}
485
486BOOL HMDeviceParPortClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
487 LPDWORD lpdwErrors,
488 LPCOMSTAT lpcst)
489{
490 APIRET rc;
491 ULONG ulLen;
492 USHORT COMErr;
493
494 dprintf(("HMDeviceParPortClass::ClearCommError"));
495 ulLen = sizeof(USHORT);
496
497 *lpdwErrors = 0;
498 rc = NO_ERROR;
499
500#if 0
501 // ParPort: CE_DNS, CE_OOP CE_PTO
502
503 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
504 IOCTL_ASYNC,
505 ASYNC_GETCOMMERROR,
506 0,0,0,
507 &COMErr,2,&ulLen);
508 *lpdwErrors |= (COMErr & 0x0001)?CE_OVERRUN:0;
509 *lpdwErrors |= (COMErr & 0x0002)?CE_RXOVER:0;
510 *lpdwErrors |= (COMErr & 0x0004)?CE_RXPARITY:0;
511 *lpdwErrors |= (COMErr & 0x0008)?CE_FRAME:0;
512
513 if(lpcst)
514 {
515 UCHAR ucStatus;
516 RXQUEUE qInfo;
517 ulLen = 1;
518 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
519 IOCTL_ASYNC,
520 ASYNC_GETCOMMSTATUS,
521 0,0,0,
522 &ucStatus,ulLen,&ulLen);
523 if(!rc)
524 {
525 lpcst->fCtsHold = ((ucStatus & 0x01)>0);
526 lpcst->fDsrHold = ((ucStatus & 0x02)>0);
527 lpcst->fRlsdHold = FALSE;//(ucStatus & 0x04)>0);
528 lpcst->fXoffHold = ((ucStatus & 0x08)>0);
529 lpcst->fXoffSend = ((ucStatus & 0x10)>0);
530 lpcst->fEof = ((ucStatus & 0x20)>0);// Is break = Eof ??
531 lpcst->fTxim = ((ucStatus & 0x40)>0);
532
533 ulLen = sizeof(qInfo);
534 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
535 IOCTL_ASYNC,
536 ASYNC_GETINQUECOUNT,
537 0,0,0,
538 &qInfo,ulLen,&ulLen);
539 if(!rc)
540 {
541 lpcst->cbInQue = qInfo.cch;
542 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
543 IOCTL_ASYNC,
544 ASYNC_GETOUTQUECOUNT,
545 0,0,0,
546 &qInfo,ulLen,&ulLen);
547 if(!rc)
548 lpcst->cbOutQue = qInfo.cch;
549 }
550 }
551 }
552#endif
553
554 return(rc==0);
555}
Note: See TracBrowser for help on using the repository browser.