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

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

.

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