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

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

.

File size: 29.2 KB
Line 
1/* $Id: hmparport.cpp,v 1.7 2001-11-23 18:58:24 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 "handlenames.h"
18#include <heapstring.h>
19#include <winioctl.h>
20#include "hmdevice.h"
21#include "hmparport.h"
22#include "oslibdos.h"
23
24#define DBG_LOCALLOG DBG_hmparport
25#include "dbglocal.h"
26
27
28#define MAGIC_PARPORT 0x4c505431
29
30#define IOCTL_PRINTER 0x0005
31#define PRT_QUERYJOBHANDLE 0x0021
32#define PRT_SETFRAMECTL 0x0042
33#define PRT_SETINFINITERETRY 0x0044
34#define PRT_INITPRINTER 0x0046
35#define PRT_ACTIVATEFONT 0x0048
36#define PRT_SETPRINTJOBTITLE 0x004D
37#define PRT_SETIRQTIMEOUT 0x004E
38#define PRT_SETCOMMMODE 0x0052
39#define PRT_SETDATAXFERMODE 0x0053
40#define PRT_GETFRAMECTL 0x0062
41#define PRT_GETINFINITERETRY 0x0064
42#define PRT_GETPRINTERSTATUS 0x0066
43#define PRT_QUERYACTIVEFONT 0x0069
44#define PRT_VERIFYFONT 0x006A
45#define PRT_QUERYIRQTIMEOUT 0x006E
46#define PRT_QUERYCOMMMODE 0x0072
47#define PRT_QUERYDATAXFERMODE 0x0073
48#define PRT_QUERDEVICEID 0x0074
49
50
51#if 0
52#pragma pack(1)
53typedef struct _DCBINFO
54{
55 USHORT usWriteTimeout; /* Time period used for Write Timeout processing. */
56 USHORT usReadTimeout; /* Time period used for Read Timeout processing. */
57 BYTE fbCtlHndShake; /* HandShake Control flag. */
58 BYTE fbFlowReplace; /* Flow Control flag. */
59 BYTE fbTimeOut; /* Timeout flag. */
60 BYTE bErrorReplacementChar; /* Error Replacement Character. */
61 BYTE bBreakReplacementChar; /* Break Replacement Character. */
62 BYTE bXONChar; /* Character XON. */
63 BYTE bXOFFChar; /* Character XOFF. */
64} DCBINFO;
65typedef DCBINFO *PDCBINFO;
66
67
68typedef struct _RXQUEUE
69{
70 USHORT cch; /* Number of characters in the queue. */
71 USHORT cb; /* Size of receive/transmit queue. */
72} RXQUEUE;
73
74typedef RXQUEUE *PRXQUEUE;
75
76
77typedef struct _MODEMSTATUS
78{
79 BYTE fbModemOn; /* Modem Control Signals ON Mask. */
80 BYTE fbModemOff; /* Modem Control Signals OFF Mask. */
81} MODEMSTATUS;
82
83typedef MODEMSTATUS *PMODEMSTATUS;
84
85
86#pragma pack()
87
88
89#endif
90
91
92#if 0
93
94typedef struct _PARALLEL_PNP_INFORMATION {
95 PHYSICAL_ADDRESS OriginalEcpController;
96 PUCHAR EcpController;
97 ULONG SpanOfEcpController;
98 ULONG PortNumber;
99 ULONG HardwareCapabilities;
100 PPARALLEL_SET_CHIP_MODE TrySetChipMode;
101 PPARALLEL_CLEAR_CHIP_MODE ClearChipMode;
102 ULONG FifoDepth;
103 ULONG FifoWidth;
104 PHYSICAL_ADDRESS EppControllerPhysicalAddress;
105 ULONG SpanOfEppController;
106 ULONG Ieee1284_3DeviceCount;
107 PPARALLEL_TRY_SELECT_ROUTINE TrySelectDevice;
108 PPARALLEL_DESELECT_ROUTINE DeselectDevice;
109 PVOID Context;
110 ULONG CurrentMode;
111 PWSTR PortName;
112} PARALLEL_PNP_INFORMATION, *PPARALLEL_PNP_INFORMATION;
113#endif
114
115
116
117typedef struct _HMDEVPARPORTDATA
118{
119 ULONG ulMagic;
120 // Win32 Device Control Block
121 COMMCONFIG CommCfg;
122 //OS/2 Device Control Block
123} HMDEVPARPORTDATA, *PHMDEVPARPORTDATA;
124
125static VOID *CreateDevData()
126{
127 PHMDEVPARPORTDATA pData;
128 pData = new HMDEVPARPORTDATA();
129 if(NULL!=pData)
130 {
131 memset(pData,0,sizeof(HMDEVPARPORTDATA));
132 pData->ulMagic = MAGIC_PARPORT;
133 pData->CommCfg.dwSize = sizeof(COMMCONFIG);
134 pData->CommCfg.wVersion = 1;
135 pData->CommCfg.dwProviderSubType = PST_PARALLELPORT;
136 }
137 return pData;
138}
139
140
141HMDeviceParPortClass::HMDeviceParPortClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
142{
143 dprintf(("HMDeviceParPortClass::HMDevParPortClass(%s)\n",
144 lpDeviceName));
145
146 VOID *pData;
147 dprintf(("HMDeviceParPortClass: Register LPT1 to LPT3 with Handle Manager\n"));
148
149 pData = CreateDevData();
150 if(pData!= NULL)
151 HMDeviceRegisterEx("LPT1", this, pData);
152
153 // add symbolic links to the "real name" of the device
154 HandleNamesAddSymbolicLink("\\Device\\ParallelPort1", "LPT1");
155 HandleNamesAddSymbolicLink("\\Device\\ParallelPort2", "LPT2");
156 HandleNamesAddSymbolicLink("\\Device\\ParallelPort3", "LPT3");
157}
158
159/*****************************************************************************
160 * Name : HMDeviceParPortClass::FindDevice
161 * Purpose : Checks if lpDeviceName belongs to this device class
162 * Parameters: LPCSTR lpClassDevName
163 * LPCSTR lpDeviceName
164 * int namelength
165 * Variables :
166 * Result : checks if name is COMx or COMx: (x=1..8)
167 * Remark :
168 * Status :
169 *
170 * Author : SvL
171 *****************************************************************************/
172BOOL HMDeviceParPortClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
173{
174 dprintf(("HMDeviceParPortClass::FindDevice(%s,%s)\n",
175 lpClassDevName,
176 lpDeviceName));
177
178 if(namelength > 5)
179 return FALSE; //can't be lpt name
180
181 //first 3 letters 'LPT'?
182 if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) {
183 return FALSE;
184 }
185
186 if(namelength == 5 && lpDeviceName[4] != ':') {
187 return FALSE;
188 }
189 switch(lpDeviceName[3]) {
190 case '1':
191 case '2':
192 case '3':
193 return TRUE; //we support up to LPT3
194 }
195 return FALSE;
196}
197
198DWORD HMDeviceParPortClass::CreateFile(LPCSTR lpFileName,
199 PHMHANDLEDATA pHMHandleData,
200 PVOID lpSecurityAttributes,
201 PHMHANDLEDATA pHMHandleDataTemplate)
202{
203 dprintf(("HMDeviceParPortClass::CreateFile(%s,%08xh,%08xh,%08xh)\n",
204 lpFileName,
205 pHMHandleData,
206 lpSecurityAttributes,
207 pHMHandleDataTemplate));
208
209 char comname[6];
210
211 dprintf(("HMDeviceParPortClass: Parallel port %s open request\n", lpFileName));
212
213 if(strlen(lpFileName) > 5) {
214 return -1; //safety check (unnecessary..)
215 }
216 pHMHandleData->hHMHandle = 0;
217
218 strcpy(comname, lpFileName);
219 comname[4] = 0; //get rid of : (if present) (eg LPT1:)
220
221 //AH: TODO parse Win32 security handles
222 ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
223 pHMHandleData->hHMHandle = OSLibDosOpen(comname,
224 OSLIB_ACCESS_READWRITE |
225 OSLIB_ACCESS_SHAREDENYREAD |
226 OSLIB_ACCESS_SHAREDENYWRITE);
227 SetErrorMode(oldmode);
228
229#if 0
230 if (pHMHandleData->hHMHandle != 0)
231 {
232 ULONG ulLen;
233 APIRET rc;
234 pHMHandleData->lpHandlerData = new HMDEVPARPORTDATA();
235 // Init The handle instance with the default default device config
236 memcpy( pHMHandleData->lpHandlerData,
237 pHMHandleData->lpDeviceData,
238 sizeof(HMDEVPARPORTDATA));
239
240 ulLen = sizeof(DCBINFO);
241
242 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
243 IOCTL_ASYNC,
244 ASYNC_GETDCBINFO,
245 0,0,0,
246 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
247 dprintf(("DCB Of %s :\n"
248 " WriteTimeout : %d\n"
249 " ReadTimeout : %d\n"
250 " CtlHandshake : 0x%x\n"
251 " FlowReplace : 0x%x\n"
252 " Timeout : 0x%x\n"
253 " Error replacement Char : 0x%x\n"
254 " Break replacement Char : 0x%x\n"
255 " XON Char : 0x%x\n"
256 " XOFF Char : 0x%x\n",
257 comname,
258 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
259 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
260 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
261 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
262 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
263 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
264 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
265 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
266 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
267
268 if(rc)
269 {
270 return -1;
271 }
272 rc = SetBaud(pHMHandleData,9600);
273 dprintf(("Init Baud to 9600 rc = %d",rc));
274 rc = SetLine(pHMHandleData,8,0,0);
275 dprintf(("Set Line to 8/N/1 rc = %d",rc));
276 return 0;
277 }
278 else
279 return -1;
280#endif
281
282 return NO_ERROR;
283}
284
285
286 /* this is a handler method for calls to CloseHandle() */
287BOOL HMDeviceParPortClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
288{
289 dprintf(("HMDeviceParPortClass: Parallel port close request(%08xh)\n",
290 pHMHandleData));
291 delete pHMHandleData->lpHandlerData;
292 return OSLibDosClose(pHMHandleData->hHMHandle);
293}
294
295
296/*****************************************************************************
297 * Name : BOOL HMDeviceParPortClass::WriteFile
298 * Purpose : write data to handle / device
299 * Parameters: PHMHANDLEDATA pHMHandleData,
300 * LPCVOID lpBuffer,
301 * DWORD nNumberOfBytesToWrite,
302 * LPDWORD lpNumberOfBytesWritten,
303 * LPOVERLAPPED lpOverlapped
304 * Variables :
305 * Result : Boolean
306 * Remark :
307 * Status :
308 *
309 * Author : SvL
310 *****************************************************************************/
311
312BOOL HMDeviceParPortClass::WriteFile(PHMHANDLEDATA pHMHandleData,
313 LPCVOID lpBuffer,
314 DWORD nNumberOfBytesToWrite,
315 LPDWORD lpNumberOfBytesWritten,
316 LPOVERLAPPED lpOverlapped)
317{
318 dprintf(("KERNEL32:HMDeviceParPortClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
319 lpHMDeviceName,
320 pHMHandleData->hHMHandle,
321 lpBuffer,
322 nNumberOfBytesToWrite,
323 lpNumberOfBytesWritten,
324 lpOverlapped));
325
326 BOOL ret;
327 ULONG ulBytesWritten;
328
329 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
330 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
331 SetLastError(ERROR_INVALID_PARAMETER);
332 return FALSE;
333 }
334 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
335 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
336 }
337
338 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
339 &ulBytesWritten);
340
341 if(lpNumberOfBytesWritten) {
342 *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
343 }
344 if(ret == FALSE) {
345 dprintf(("ERROR: WriteFile failed with rc %d", GetLastError()));
346 }
347
348 return ret;
349}
350
351/*****************************************************************************
352 * Name : BOOL WriteFileEx
353 * Purpose : The WriteFileEx function writes data to a file. It is designed
354 * solely for asynchronous operation, unlike WriteFile, which is
355 * designed for both synchronous and asynchronous operation.
356 * WriteFileEx reports its completion status asynchronously,
357 * calling a specified completion routine when writing is completed
358 * and the calling thread is in an alertable wait state.
359 * Parameters: HANDLE hFile handle of file to write
360 * LPVOID lpBuffer address of buffer
361 * DWORD nNumberOfBytesToRead number of bytes to write
362 * LPOVERLAPPED lpOverlapped address of offset
363 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
364 * Variables :
365 * Result : TRUE / FALSE
366 * Remark :
367 * Status : UNTESTED STUB
368 *
369 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
370 *****************************************************************************/
371
372BOOL HMDeviceParPortClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
373 LPVOID lpBuffer,
374 DWORD nNumberOfBytesToWrite,
375 LPOVERLAPPED lpOverlapped,
376 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
377{
378 dprintf(("ERROR: WriteFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
379 lpHMDeviceName,
380 pHMHandleData->hHMHandle,
381 lpBuffer,
382 nNumberOfBytesToWrite,
383 lpOverlapped,
384 lpCompletionRoutine));
385
386 SetLastError(ERROR_INVALID_FUNCTION);
387 return FALSE;
388}
389
390/*****************************************************************************
391 * Name : BOOL HMDeviceParPortClass::ReadFile
392 * Purpose : read data from handle / device
393 * Parameters: PHMHANDLEDATA pHMHandleData,
394 * LPCVOID lpBuffer,
395 * DWORD nNumberOfBytesToRead,
396 * LPDWORD lpNumberOfBytesRead,
397 * LPOVERLAPPED lpOverlapped
398 * Variables :
399 * Result : Boolean
400 * Remark :
401 * Status :
402 *
403 * Author : SvL
404 *****************************************************************************/
405
406BOOL HMDeviceParPortClass::ReadFile(PHMHANDLEDATA pHMHandleData,
407 LPCVOID lpBuffer,
408 DWORD nNumberOfBytesToRead,
409 LPDWORD lpNumberOfBytesRead,
410 LPOVERLAPPED lpOverlapped)
411{
412 dprintf(("KERNEL32:HMDeviceParPortClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
413 lpHMDeviceName,
414 pHMHandleData->hHMHandle,
415 lpBuffer,
416 nNumberOfBytesToRead,
417 lpNumberOfBytesRead,
418 lpOverlapped));
419
420 BOOL ret;
421 ULONG ulBytesRead;
422
423 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
424 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
425 SetLastError(ERROR_INVALID_PARAMETER);
426 return FALSE;
427 }
428 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
429 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
430 }
431
432 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
433 &ulBytesRead);
434
435 if(lpNumberOfBytesRead) {
436 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
437 }
438 if(ret == FALSE) {
439 dprintf(("ERROR: ReadFile failed with rc %d", GetLastError()));
440 }
441 return ret;
442}
443
444/*****************************************************************************
445 * Name : BOOL ReadFileEx
446 * Purpose : The ReadFileEx function reads data from a file asynchronously.
447 * It is designed solely for asynchronous operation, unlike the
448 * ReadFile function, which is designed for both synchronous and
449 * asynchronous operation. ReadFileEx lets an application perform
450 * other processing during a file read operation.
451 * The ReadFileEx function reports its completion status asynchronously,
452 * calling a specified completion routine when reading is completed
453 * and the calling thread is in an alertable wait state.
454 * Parameters: HANDLE hFile handle of file to read
455 * LPVOID lpBuffer address of buffer
456 * DWORD nNumberOfBytesToRead number of bytes to read
457 * LPOVERLAPPED lpOverlapped address of offset
458 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
459 * Variables :
460 * Result : TRUE / FALSE
461 * Remark :
462 * Status : UNTESTED STUB
463 *
464 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
465 *****************************************************************************/
466BOOL HMDeviceParPortClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
467 LPVOID lpBuffer,
468 DWORD nNumberOfBytesToRead,
469 LPOVERLAPPED lpOverlapped,
470 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
471{
472 dprintf(("ERROR: ReadFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
473 lpHMDeviceName,
474 pHMHandleData->hHMHandle,
475 lpBuffer,
476 nNumberOfBytesToRead,
477 lpOverlapped,
478 lpCompletionRoutine));
479
480 SetLastError(ERROR_INVALID_FUNCTION);
481 return FALSE;
482}
483
484BOOL HMDeviceParPortClass::GetCommProperties( PHMHANDLEDATA pHMHandleData,
485 LPCOMMPROP lpcmmp)
486{
487 dprintf(("HMDeviceParPortClass::GetCommProperties(%08xh, %08xh)\n",
488 pHMHandleData,
489 lpcmmp));
490
491 APIRET rc;
492 ULONG ulLen;
493 int i;
494
495#if 0
496 USHORT COMErr;
497 EXTBAUDGET BaudInfo;
498 ulLen = sizeof(EXTBAUDGET);
499 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
500 IOCTL_ASYNC,
501 ASYNC_EXTGETBAUDRATE,
502 0,0,0,
503 &BaudInfo,ulLen,&ulLen);
504#endif
505 rc = NO_ERROR;
506
507 memset(lpcmmp,0,sizeof(COMMPROP));
508 lpcmmp->wPacketLength = sizeof(COMMPROP);
509 lpcmmp->wPacketVersion = 1; //???
510 lpcmmp->dwProvSubType = PST_PARALLELPORT;
511
512#if 0
513 lpcmmp->dwServiceMask = SP_SERIALCOMM;
514 for(i=0;i<BaudTableSize && BaudInfo.ulMaxBaud <= BaudTable[i].dwBaudRate;i++);
515 lpcmmp->dwMaxBaud = BaudTable[i].dwBaudFlag;
516 lpcmmp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK |
517 PCF_RTSCTS | PCF_SETXCHAR |
518 PCF_XONXOFF;
519 lpcmmp->dwSettableParams = SP_BAUD | SP_DATABITS |
520 SP_HANDSHAKEING | SP_PARITY |
521 SP_PARITY_CHECK | SP_STOPBIT;
522 lpcmmp->dwSettableBaud = 0;
523 for(i=0;i<BaudTableSize;i++)
524 {
525 if ( (BaudTable[i].dwBaudRate>=BaudInfo.ulMinBaud) &&
526 (BaudTable[i].dwBaudRate<=BaudInfo.ulMaxBaud) )
527 lpcmmp->dwSettableBaud |= BaudTable[i].dwBaudFlag;
528 }
529 lpcmmp->dwSettableBaud |= BAUD_USER;
530 lpcmmp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
531 lpcmmp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
532 PARITY_NONE | PARITY_ODD | PARITY_EVEN |
533 PARITY_MARK | PARITY_SPACE;
534#endif
535
536 return(rc==0);
537}
538
539BOOL HMDeviceParPortClass::ClearCommError( PHMHANDLEDATA pHMHandleData,
540 LPDWORD lpdwErrors,
541 LPCOMSTAT lpcst)
542{
543 dprintf(("HMDeviceParPortClass::ClearCommError(%08xh,%08xh,%08xh)\n",
544 pHMHandleData,
545 lpdwErrors,
546 lpcst));
547
548 APIRET rc;
549 ULONG ulLen;
550 USHORT COMErr;
551
552 ulLen = sizeof(USHORT);
553
554 *lpdwErrors = 0;
555 rc = NO_ERROR;
556
557#if 0
558 // ParPort: CE_DNS, CE_OOP CE_PTO
559
560 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
561 IOCTL_ASYNC,
562 ASYNC_GETCOMMERROR,
563 0,0,0,
564 &COMErr,2,&ulLen);
565 *lpdwErrors |= (COMErr & 0x0001)?CE_OVERRUN:0;
566 *lpdwErrors |= (COMErr & 0x0002)?CE_RXOVER:0;
567 *lpdwErrors |= (COMErr & 0x0004)?CE_RXPARITY:0;
568 *lpdwErrors |= (COMErr & 0x0008)?CE_FRAME:0;
569
570 if(lpcst)
571 {
572 UCHAR ucStatus;
573 RXQUEUE qInfo;
574 ulLen = 1;
575 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
576 IOCTL_ASYNC,
577 ASYNC_GETCOMMSTATUS,
578 0,0,0,
579 &ucStatus,ulLen,&ulLen);
580 if(!rc)
581 {
582 lpcst->fCtsHold = ((ucStatus & 0x01)>0);
583 lpcst->fDsrHold = ((ucStatus & 0x02)>0);
584 lpcst->fRlsdHold = FALSE;//(ucStatus & 0x04)>0);
585 lpcst->fXoffHold = ((ucStatus & 0x08)>0);
586 lpcst->fXoffSend = ((ucStatus & 0x10)>0);
587 lpcst->fEof = ((ucStatus & 0x20)>0);// Is break = Eof ??
588 lpcst->fTxim = ((ucStatus & 0x40)>0);
589
590 ulLen = sizeof(qInfo);
591 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
592 IOCTL_ASYNC,
593 ASYNC_GETINQUECOUNT,
594 0,0,0,
595 &qInfo,ulLen,&ulLen);
596 if(!rc)
597 {
598 lpcst->cbInQue = qInfo.cch;
599 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
600 IOCTL_ASYNC,
601 ASYNC_GETOUTQUECOUNT,
602 0,0,0,
603 &qInfo,ulLen,&ulLen);
604 if(!rc)
605 lpcst->cbOutQue = qInfo.cch;
606 }
607 }
608 }
609#endif
610
611 return(rc==0);
612}
613
614
615BOOL HMDeviceParPortClass::DeviceIoControl(PHMHANDLEDATA pHMHandleData,
616 DWORD dwIoControlCode,
617 LPVOID lpInBuffer,
618 DWORD nInBufferSize,
619 LPVOID lpOutBuffer,
620 DWORD nOutBufferSize,
621 LPDWORD lpBytesReturned,
622 LPOVERLAPPED lpOverlapped)
623{
624#ifdef DEBUG
625 char *msg = NULL;
626
627 switch(dwIoControlCode)
628 {
629 case IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO:
630 msg = "IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO";
631 break;
632
633 case IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO:
634 msg = "IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO";
635 break;
636 }
637
638 if(msg) {
639 dprintf(("HMDeviceParPortClass::DeviceIoControl %s %x %d %x %d %x %x", msg, lpInBuffer, nInBufferSize,
640 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped));
641 }
642#endif
643
644 switch(dwIoControlCode)
645 {
646 case IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO:
647 {
648 PPARALLEL_PORT_INFORMATION pPPI = (PPARALLEL_PORT_INFORMATION)lpOutBuffer;
649
650 if(nOutBufferSize < sizeof(PARALLEL_PORT_INFORMATION) || !pPPI)
651 {
652 SetLastError(ERROR_INSUFFICIENT_BUFFER);
653 return FALSE;
654 }
655
656 if(lpBytesReturned)
657 *lpBytesReturned = sizeof(PARALLEL_PORT_INFORMATION);
658
659 // fill in the data values
660
661 // Specifies the bus relative base I/O address of the parallel port registers.
662 pPPI->OriginalController.LowPart = 0; // @@@PH
663 pPPI->OriginalController.HighPart = 0; // @@@PH
664
665 // Pointer to the system-mapped base I/O location of the parallel port registers.
666 pPPI->Controller = 0; // @@@PH
667
668 // Specifies the size, in bytes, of the I/O space, allocated to the parallel port.
669 pPPI->SpanOfController = 0; // @@@PH
670
671 // Pointer to a callback routine that a kernel-mode driver can use to try to allocate the parallel port.
672 pPPI->TryAllocatePort = NULL;
673
674 // Pointer to a callback routine that a kernel-mode driver can use to free the parallel port.
675 pPPI->FreePort = NULL;
676
677 // Pointer to a callback routine that a kernel-mode driver can use to determine the number of requests on the work queue of the parallel port.
678 pPPI->QueryNumWaiters = NULL;
679
680 // Pointer to the device extension of parallel port.
681 pPPI->Context = NULL;
682
683 return TRUE;
684 }
685
686
687 case IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO:
688 {
689 PPARALLEL_PNP_INFORMATION pPPI = (PPARALLEL_PNP_INFORMATION)lpOutBuffer;
690
691 if(nOutBufferSize < sizeof(PARALLEL_PNP_INFORMATION) || !pPPI)
692 {
693 SetLastError(ERROR_INSUFFICIENT_BUFFER);
694 return FALSE;
695 }
696
697 if(lpBytesReturned)
698 *lpBytesReturned = sizeof(PARALLEL_PNP_INFORMATION);
699
700 // fill in the data values
701
702 // Specifies the base physical address that the system-supplied function driver for parallel ports uses to control the ECP operation of the parallel port.
703 pPPI->OriginalEcpController.LowPart = 0;
704 pPPI->OriginalEcpController.HighPart = 0;
705
706 // Pointer to the I/O port resource that is used to control the port in ECP mode.
707 pPPI->EcpController = 0;
708
709 // Specifies the size, in bytes, of the I/O port resource.
710 pPPI->SpanOfEcpController = 0;
711
712 // Not used.
713 pPPI->PortNumber = 0;
714
715 // Specifies the hardware capabilities of the parallel port. The following capabilities can be set using a bitwise OR of the following constants:
716 pPPI->HardwareCapabilities = 0;
717 // PPT_1284_3_PRESENT
718 // PPT_BYTE_PRESENT
719 // PPT_ECP_PRESENT
720 // PPT_EPP_32_PRESENT
721 // PPT_EPP_PRESENT
722 // PT_NO_HARDWARE_PRESENT
723
724 // Pointer to a callback routine that a kernel-mode driver can use to change the operating mode of the parallel port.
725 pPPI->TrySetChipMode = 0;
726
727 // Pointer to a callback routine that a kernel-mode driver can use to clear the operating mode of the parallel port.
728 pPPI->ClearChipMode = 0;
729
730 // Specifies the size, in words, of the hardware first in/first out (FIFO) buffer. The FIFO word size, in bits, is the value of FifoWidth.
731 pPPI->FifoDepth = 0;
732
733 // Specifies the FIFO word size, in bits, which is the number of bits handled in parallel.
734 pPPI->FifoWidth = 0;
735
736 // Not used.
737 pPPI->EppControllerPhysicalAddress.LowPart = 0;
738 pPPI->EppControllerPhysicalAddress.HighPart = 0;
739
740 // Not used.
741 pPPI->SpanOfEppController = 0;
742
743 // Specifies the number of daisy-chain devices currently attached to a parallel port. In Microsoftÿ Windowsÿ XP, from zero to two devices can be simultaneously connected to a
744 // parallel port. In Windows 2000, from zero to four devices can be simultaneously connected to a parallel port.
745 pPPI->Ieee1284_3DeviceCount = 0;
746
747 // Pointer to a callback routine that a kernel-mode driver can use to try to select an IEEE 1284.3 device.
748 pPPI->TrySelectDevice = 0;
749
750 // Pointer to a callback routine that a kernel-mode driver can use to deselect an IEEE 1284.3 device.
751 pPPI->DeselectDevice = 0;
752
753 // Pointer to the device extension of a parallel port's function device object (FDO).
754 pPPI->Context = 0;
755
756 // The current operating mode of the parallel port.
757 pPPI->CurrentMode = 0;
758
759 // The symbolic link name of the parallel port.
760 pPPI->PortName = 0;
761
762 return TRUE;
763 }
764 }
765 dprintf(("HMDeviceParPortClass::DeviceIoControl: unimplemented dwIoControlCode=%08lx\n", dwIoControlCode));
766 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
767 return FALSE;
768}
769
770
771BOOL HMDeviceParPortClass::SetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
772 LPCOMMCONFIG lpCC,
773 DWORD dwSize)
774{
775 dprintf(("HMDeviceParPortClass::SetDefaultCommConfig(%08xh,%08xh,%08xh)\n",
776 pHMHandleData,
777 lpCC,
778 dwSize));
779
780 PHMDEVPARPORTDATA pDevData = (PHMDEVPARPORTDATA)pHMHandleData->lpDeviceData;
781 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_PARPORT) )
782 {
783 SetLastError(ERROR_INVALID_HANDLE);
784 return FALSE;
785 }
786 memset(&pDevData->CommCfg,0, sizeof(COMMCONFIG));
787 memcpy(&pDevData->CommCfg,lpCC,dwSize>sizeof(COMMCONFIG)?sizeof(COMMCONFIG):dwSize);
788
789 return(TRUE);
790}
791
792
793BOOL HMDeviceParPortClass::GetDefaultCommConfig( PHMHANDLEDATA pHMHandleData,
794 LPCOMMCONFIG lpCC,
795 LPDWORD lpdwSize)
796{
797 dprintf(("HMDeviceParPortClass::GetDefaultCommConfig(%08xh,%08xh,%08xh)\n",
798 pHMHandleData,
799 lpCC,
800 lpdwSize));
801
802
803 PHMDEVPARPORTDATA pDevData = (PHMDEVPARPORTDATA)pHMHandleData->lpDeviceData;
804
805 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
806 *lpdwSize< sizeof(COMMCONFIG) )
807 {
808 SetLastError(ERROR_INSUFFICIENT_BUFFER);
809 *lpdwSize= sizeof(COMMCONFIG);
810 return FALSE;
811 }
812
813 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_PARPORT) )
814 {
815 SetLastError(ERROR_INVALID_HANDLE);
816 return FALSE;
817 }
818
819 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
820 *lpdwSize = sizeof(COMMCONFIG);
821 return(TRUE);
822}
823
824
825BOOL HMDeviceParPortClass::SetCommConfig( PHMHANDLEDATA pHMHandleData,
826 LPCOMMCONFIG lpCC,
827 DWORD dwSize )
828{
829 dprintf(("HMDeviceParPortClass::SetCommConfig not implemented"));
830
831 return(TRUE);
832}
833
834
835BOOL HMDeviceParPortClass::GetCommConfig( PHMHANDLEDATA pHMHandleData,
836 LPCOMMCONFIG lpCC,
837 LPDWORD lpdwSize )
838{
839 PHMDEVPARPORTDATA pDevData = (PHMDEVPARPORTDATA)pHMHandleData->lpHandlerData;
840
841 dprintf(("HMDeviceParPortClass::GetCommConfig(%08xh,%08xh,%08xh)\n",
842 pHMHandleData,
843 lpCC,
844 lpdwSize));
845
846 if( O32_IsBadWritePtr(lpCC,sizeof(COMMCONFIG)) ||
847 *lpdwSize< sizeof(COMMCONFIG) )
848 {
849 SetLastError(ERROR_INSUFFICIENT_BUFFER);
850 *lpdwSize= sizeof(COMMCONFIG);
851 return FALSE;
852 }
853
854 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_PARPORT) )
855 {
856 SetLastError(ERROR_INVALID_HANDLE);
857 return FALSE;
858 }
859
860 memcpy(lpCC,&pDevData->CommCfg,sizeof(COMMCONFIG));
861 *lpdwSize = sizeof(COMMCONFIG);
862 return(TRUE);
863}
Note: See TracBrowser for help on using the repository browser.