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

Last change on this file since 7550 was 7550, checked in by sandervl, 24 years ago

overlapped io updates

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