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

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

.

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