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

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

Enabled parallel port hardware configuration table

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