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

Last change on this file since 8404 was 8404, checked in by sandervl, 23 years ago

PF: parallel port updates (hw config)

File size: 24.6 KB
Line 
1/* $Id: hmparport.cpp,v 1.19 2002-05-13 12:12:42 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#include "rmioctl.h"
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// Hardwired parallel port configuration information.
51// for the cases where real thing will fail
52typedef struct tagParallelPortConfiguration
53{
54 ULONG ulNumber;
55 ULONG ulPortBase;
56 ULONG ulPortSpan;
57 ULONG ulEcpPortBase;
58 ULONG ulEcpPortSpan;
59} PARALLELPORTCONFIGURATION, *PPARALLELPORTCONFIGURATION;
60
61#define MAX_PARALLEL_PORTS_CONFIGURATION 3
62static PARALLELPORTCONFIGURATION arrParallelPorts[MAX_PARALLEL_PORTS_CONFIGURATION] =
63{
64 {1, 0x378, 8, 0x778, 3},
65 {2, 0x278, 8, 0x678, 3},
66 {3, 0x3bc, 8, 0x000, 0}
67};
68
69
70typedef struct _HMDEVPARPORTDATA
71{
72 ULONG ulMagic;
73
74 // Win32 Device Control Block
75 COMMCONFIG CommCfg;
76
77 // hardware configuration block
78 PPARALLELPORTCONFIGURATION pHardwareConfiguration;
79} HMDEVPARPORTDATA, *PHMDEVPARPORTDATA;
80
81//******************************************************************************
82//******************************************************************************
83static VOID *CreateDevData()
84{
85 HFILE hfFileHandle = 0L;
86 UCHAR uchParms[2] = {0, RM_COMMAND_PHYS};
87 ULONG ulParmLen = 0;
88 UCHAR uchDataArea[MAX_ENUM_SIZE] = {0};
89 UCHAR uchDataArea2[MAX_RM_NODE_SIZE] = {0};
90 ULONG ulDataLen = 0;
91 int rc,portCount = 0;
92
93 PRM_ENUMNODES_DATA enumData;
94 PNODEENTRY pNode;
95 RM_GETNODE_PARM inputData;
96 PRM_GETNODE_DATA poutputData;
97 PHMDEVPARPORTDATA pData;
98
99 hfFileHandle = OSLibDosOpen("RESMGR$",
100 OSLIB_ACCESS_READWRITE |
101 OSLIB_ACCESS_SHAREDENYNONE);
102
103 if (!hfFileHandle) {
104 dprintf(("HMDeviceParPortClass: Failed to open Resource Manager device %d\n", GetLastError()));
105 }
106 else
107 {
108 dprintf(("HMDeviceParPortClass: Succesfully opened Resource Manager"));
109
110 ulParmLen = sizeof(uchParms); /* Length of input parameters */
111 ulDataLen = sizeof(uchDataArea); /* Length of data */
112
113 rc = OSLibDosDevIOCtl(hfFileHandle, /* Handle to device */
114 CAT_RM,FUNC_RM_ENUM_NODES, uchParms, sizeof(uchParms),
115 &ulParmLen,
116 uchDataArea,
117 sizeof(uchDataArea),
118 &ulDataLen);
119
120 if (rc)
121 {
122 dprintf(("HMDeviceParPortClass: Failed to get resource list (IOCTL)"));
123 goto resourceLoopEnd;
124 }
125
126 enumData = (PRM_ENUMNODES_DATA)uchDataArea;
127
128 inputData.RMHandle = enumData->NodeEntry[0].RMHandle;
129 inputData.Linaddr = (ULONG)&uchDataArea2[0];
130
131 for (int i=0;i<enumData->NumEntries;i++)
132 {
133 ulParmLen = sizeof(inputData); /* Length of input parameters */
134 ulDataLen = sizeof(uchDataArea2); /* Length of data */
135
136 rc = OSLibDosDevIOCtl(hfFileHandle, /* Handle to device */
137 CAT_RM,FUNC_RM_GET_NODEINFO,
138 &inputData, /* Input/Output parameter list */
139 sizeof(inputData), /* Maximum output parameter size */
140 &ulParmLen, /* Input: size of parameter list */
141 /* Output: size of parameters returned */
142 uchDataArea2, /* Input/Output data area */
143 sizeof(uchDataArea2), /* Maximum output data size */
144 &ulDataLen); /* Input: size of input data area */
145 /* Output: size of data returned */
146 if (rc)
147 {
148 dprintf(("HMDeviceParPortClass: Failed to get resource node (IOCTL)"));
149 break;
150 }
151 inputData.RMHandle = enumData->NodeEntry[i].RMHandle;
152 poutputData = (PRM_GETNODE_DATA) uchDataArea2;
153 // @@PF Ports always follow numbering i.e. LPT0,LPT1, etc so
154 // no sorting needed
155 if ( (poutputData->RMNode.pAdapterNode->AdaptDescriptName) &&
156 (lstrncmpiA(poutputData->RMNode.pAdapterNode->AdaptDescriptName,"PARALLEL",8) == 0) &&
157 (poutputData->RMNode.pResourceList->Resource[0].ResourceType == RS_TYPE_IO) )
158 {
159 if (!portCount) memset(arrParallelPorts,0,sizeof(arrParallelPorts));
160 arrParallelPorts[portCount].ulNumber = portCount;
161 arrParallelPorts[portCount].ulPortBase = poutputData->RMNode.pResourceList->Resource[0].IOResource.BaseIOPort;
162 arrParallelPorts[portCount].ulPortSpan = 8;
163 // @@PF Hack, but what to do no ECP info from Resource Manager!
164 if (arrParallelPorts[portCount].ulPortBase == 0x378)
165 {
166 arrParallelPorts[portCount].ulEcpPortBase = 0x778;
167 arrParallelPorts[portCount].ulEcpPortSpan = 3;
168 }
169 else
170 if (arrParallelPorts[portCount].ulPortBase == 0x278)
171 {
172 arrParallelPorts[portCount].ulEcpPortBase = 0x678;
173 arrParallelPorts[portCount].ulEcpPortSpan = 3;
174 }
175 else
176 arrParallelPorts[portCount].ulEcpPortBase = 0;
177
178 arrParallelPorts[portCount].ulEcpPortSpan = 0;
179 dprintf(("HMDeviceParPortClass: Found and registered LPT%d with Base I/O: 0x%x",portCount,arrParallelPorts[portCount].ulPortBase));
180 portCount ++ ;
181 }
182 }
183 }
184resourceLoopEnd:
185 OSLibDosClose(hfFileHandle);
186
187 pData = new HMDEVPARPORTDATA();
188 if(NULL!=pData)
189 {
190 memset(pData,0,sizeof(HMDEVPARPORTDATA));
191 pData->ulMagic = MAGIC_PARPORT;
192 pData->CommCfg.dwSize = sizeof(COMMCONFIG);
193 pData->CommCfg.wVersion = 1;
194 pData->CommCfg.dwProviderSubType = PST_PARALLELPORT;
195 }
196
197 return pData;
198}
199//******************************************************************************
200//******************************************************************************
201HMDeviceParPortClass::HMDeviceParPortClass(LPCSTR lpDeviceName) :
202 HMDeviceHandler(lpDeviceName)
203{
204 dprintf(("HMDeviceParPortClass::HMDevParPortClass(%s)\n",
205 lpDeviceName));
206
207#ifndef DEVINFO_PRINTER
208#define DEVINFO_PRINTER 0
209#endif
210
211 // first, we determine the number of parallel port devices available
212
213 // PH 2001-12-04 Note:
214 // This call will not return any information about redirected LPT ports.
215 // We have a specific application requiring exactly this behaviour as it
216 // cannot talk to redirected LPTs anyway.
217 // For any change in this behaviour, we'd require a configuration switch.
218 bNumberOfParallelPorts = 0;
219 DWORD rc = OSLibDosDevConfig(&bNumberOfParallelPorts,
220 DEVINFO_PRINTER);
221 dprintf(("HMDeviceParPortClass: Parallel ports reported: %d\n",
222 bNumberOfParallelPorts));
223 if (0 == bNumberOfParallelPorts)
224 return;
225
226 VOID *pData;
227 dprintf(("HMDeviceParPortClass: Registering LPTs with Handle Manager\n"));
228
229 pData = CreateDevData();
230 if(pData!= NULL)
231 HMDeviceRegisterEx("LPT1", this, pData);
232
233 // add symbolic links to the "real name" of the device
234 if (bNumberOfParallelPorts > 0)
235 {
236 // Note: \\.\LPTx: is invalid (NT4SP6)
237 PSZ pszLPT = strdup("\\\\.\\LPTx");
238 PSZ pszLPT2 = strdup("\\Device\\ParallelPort0");
239 for (char ch = '1'; ch <= '1' + (bNumberOfParallelPorts - 1); ch++)
240 {
241 pszLPT[7] = ch;
242 pszLPT2[20] = ch - 1; // \DeviceParallelPort0 -> LPT1
243 HandleNamesAddSymbolicLink(pszLPT, pszLPT+4);
244 HandleNamesAddSymbolicLink(pszLPT2, pszLPT+4);
245 }
246 free(pszLPT);
247 free(pszLPT2);
248
249 // add "PRN" device
250 HandleNamesAddSymbolicLink("PRN", "LPT1");
251 HandleNamesAddSymbolicLink("PRN:", "LPT1");
252 HandleNamesAddSymbolicLink("\\\\.\\PRN", "LPT1");
253 }
254}
255
256/*****************************************************************************
257 * Name : HMDeviceParPortClass::FindDevice
258 * Purpose : Checks if lpDeviceName belongs to this device class
259 * Parameters: LPCSTR lpClassDevName
260 * LPCSTR lpDeviceName
261 * int namelength
262 * Variables :
263 * Result : checks if name is COMx or COMx: (x=1..8)
264 * Remark :
265 * Status :
266 *
267 * Author : SvL
268 *****************************************************************************/
269BOOL HMDeviceParPortClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
270{
271 // Don't accept any name if no parallel ports have been detected
272 if (bNumberOfParallelPorts == 0)
273 return FALSE;
274
275 // can be both, "LPT1" and "LPT1:"
276 if(namelength > 5)
277 return FALSE; //can't be lpt name
278
279 //first 3 letters 'LPT'?
280 if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0)
281 return FALSE;
282
283 if(namelength == 5 && lpDeviceName[4] != ':')
284 return FALSE;
285
286 // can support up tp LPT9
287 if ( (lpDeviceName[3] >= '1') &&
288 (lpDeviceName[3] <= '1' + bNumberOfParallelPorts) )
289 {
290 return TRUE;
291 }
292
293 return FALSE;
294}
295//******************************************************************************
296//******************************************************************************
297DWORD HMDeviceParPortClass::CreateFile(LPCSTR lpFileName,
298 PHMHANDLEDATA pHMHandleData,
299 PVOID lpSecurityAttributes,
300 PHMHANDLEDATA pHMHandleDataTemplate)
301{
302 dprintf(("HMDeviceParPortClass::CreateFile(%s,%08xh,%08xh,%08xh)\n",
303 lpFileName,
304 pHMHandleData,
305 lpSecurityAttributes,
306 pHMHandleDataTemplate));
307
308 char lptname[6];
309
310 dprintf(("HMDeviceParPortClass: Parallel port %s open request\n", lpFileName));
311
312 // Don't accept any name if no parallel ports have been detected
313 if (bNumberOfParallelPorts == 0)
314 {
315 return ERROR_DEV_NOT_EXIST;
316 }
317
318 strcpy(lptname, lpFileName);
319 lptname[4] = 0; //get rid of : (if present) (eg LPT1:)
320
321 //AH: TODO parse Win32 security handles
322 ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
323 pHMHandleData->hHMHandle = OSLibDosOpen(lptname,
324 OSLIB_ACCESS_READWRITE |
325 OSLIB_ACCESS_SHAREDENYREAD |
326 OSLIB_ACCESS_SHAREDENYWRITE);
327 SetErrorMode(oldmode);
328
329 // check if handle could be opened properly
330 if (0 == pHMHandleData->hHMHandle)
331 {
332 return ERROR_ACCESS_DENIED; // signal failure
333 }
334 else
335 {
336 ULONG ulLen;
337 APIRET rc;
338 pHMHandleData->lpHandlerData = new HMDEVPARPORTDATA();
339
340 // Init The handle instance with the default default device config
341 memcpy( pHMHandleData->lpHandlerData,
342 pHMHandleData->lpDeviceData,
343 sizeof(HMDEVPARPORTDATA));
344
345 // determine which port was opened
346 ULONG ulPortNo = lptname[3] - '1';
347
348 // safety check (device no 0..8 -> LPT1..9)
349 if (ulPortNo > MAX_PARALLEL_PORTS_CONFIGURATION)
350 {
351 HMDeviceParPortClass::CloseHandle(pHMHandleData);
352 return ERROR_DEV_NOT_EXIST;
353 }
354
355 // and save the hardware information
356 PHMDEVPARPORTDATA pPPD = (PHMDEVPARPORTDATA)pHMHandleData->lpHandlerData;
357 pPPD->pHardwareConfiguration = &arrParallelPorts[ulPortNo];
358
359 return NO_ERROR;
360 }
361}
362
363/*****************************************************************************
364 * Name : DWORD HMDeviceParPortClass::GetFileType
365 * Purpose : determine the handle type
366 * Parameters: PHMHANDLEDATA pHMHandleData
367 * Variables :
368 * Result : API returncode
369 * Remark :
370 * Status :
371 *
372 * Author : SvL
373 *****************************************************************************/
374
375DWORD HMDeviceParPortClass::GetFileType(PHMHANDLEDATA pHMHandleData)
376{
377 dprintf(("KERNEL32: HMDeviceParPortClass::GetFileType %s(%08x)\n",
378 lpHMDeviceName, pHMHandleData));
379
380 return FILE_TYPE_PIPE; //this is what NT4 returns
381}
382//******************************************************************************
383/* this is a handler method for calls to CloseHandle() */
384//******************************************************************************
385BOOL HMDeviceParPortClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
386{
387 dprintf(("HMDeviceParPortClass: Parallel port close request(%08xh)\n",
388 pHMHandleData));
389
390 delete pHMHandleData->lpHandlerData;
391 return OSLibDosClose(pHMHandleData->hHMHandle);
392}
393
394
395/*****************************************************************************
396 * Name : BOOL HMDeviceParPortClass::WriteFile
397 * Purpose : write data to handle / device
398 * Parameters: PHMHANDLEDATA pHMHandleData,
399 * LPCVOID lpBuffer,
400 * DWORD nNumberOfBytesToWrite,
401 * LPDWORD lpNumberOfBytesWritten,
402 * LPOVERLAPPED lpOverlapped
403 * Variables :
404 * Result : Boolean
405 * Remark :
406 * Status :
407 *
408 * Author : SvL
409 *****************************************************************************/
410
411BOOL HMDeviceParPortClass::WriteFile(PHMHANDLEDATA pHMHandleData,
412 LPCVOID lpBuffer,
413 DWORD nNumberOfBytesToWrite,
414 LPDWORD lpNumberOfBytesWritten,
415 LPOVERLAPPED lpOverlapped,
416 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
417{
418 dprintf(("KERNEL32:HMDeviceParPortClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
419 lpHMDeviceName,
420 pHMHandleData->hHMHandle,
421 lpBuffer,
422 nNumberOfBytesToWrite,
423 lpNumberOfBytesWritten,
424 lpOverlapped));
425
426 BOOL ret;
427 ULONG ulBytesWritten;
428
429 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
430 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
431 SetLastError(ERROR_INVALID_PARAMETER);
432 return FALSE;
433 }
434 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
435 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
436 }
437 if(lpCompletionRoutine) {
438 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
439 }
440
441 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
442 &ulBytesWritten);
443
444 if(lpNumberOfBytesWritten) {
445 *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
446 }
447 if(ret == FALSE) {
448 dprintf(("ERROR: WriteFile failed with rc %d", GetLastError()));
449 }
450
451 return ret;
452}
453
454/*****************************************************************************
455 * Name : BOOL HMDeviceParPortClass::ReadFile
456 * Purpose : read data from handle / device
457 * Parameters: PHMHANDLEDATA pHMHandleData,
458 * LPCVOID lpBuffer,
459 * DWORD nNumberOfBytesToRead,
460 * LPDWORD lpNumberOfBytesRead,
461 * LPOVERLAPPED lpOverlapped
462 * Variables :
463 * Result : Boolean
464 * Remark :
465 * Status :
466 *
467 * Author : SvL
468 *****************************************************************************/
469
470BOOL HMDeviceParPortClass::ReadFile(PHMHANDLEDATA pHMHandleData,
471 LPCVOID lpBuffer,
472 DWORD nNumberOfBytesToRead,
473 LPDWORD lpNumberOfBytesRead,
474 LPOVERLAPPED lpOverlapped,
475 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
476{
477 dprintf(("KERNEL32:HMDeviceParPortClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
478 lpHMDeviceName,
479 pHMHandleData->hHMHandle,
480 lpBuffer,
481 nNumberOfBytesToRead,
482 lpNumberOfBytesRead,
483 lpOverlapped));
484
485 BOOL ret;
486 ULONG ulBytesRead;
487
488 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
489 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
490 SetLastError(ERROR_INVALID_PARAMETER);
491 return FALSE;
492 }
493 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
494 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
495 }
496 if(lpCompletionRoutine) {
497 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
498 }
499
500 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
501 &ulBytesRead);
502
503 if(lpNumberOfBytesRead) {
504 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
505 }
506 if(ret == FALSE) {
507 dprintf(("ERROR: ReadFile failed with rc %d", GetLastError()));
508 }
509 return ret;
510}
511//******************************************************************************
512//******************************************************************************
513BOOL HMDeviceParPortClass::DeviceIoControl(PHMHANDLEDATA pHMHandleData,
514 DWORD dwIoControlCode,
515 LPVOID lpInBuffer,
516 DWORD nInBufferSize,
517 LPVOID lpOutBuffer,
518 DWORD nOutBufferSize,
519 LPDWORD lpBytesReturned,
520 LPOVERLAPPED lpOverlapped)
521{
522#ifdef DEBUG
523 char *msg = NULL;
524
525 switch(dwIoControlCode)
526 {
527 case IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO:
528 msg = "IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO";
529 break;
530
531 case IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO:
532 msg = "IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO";
533 break;
534 }
535
536 if(msg) {
537 dprintf(("HMDeviceParPortClass::DeviceIoControl %s %x %d %x %d %x %x", msg, lpInBuffer, nInBufferSize,
538 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped));
539 }
540#endif
541
542 switch(dwIoControlCode)
543 {
544 case IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO:
545 {
546 PPARALLEL_PORT_INFORMATION pPPI = (PPARALLEL_PORT_INFORMATION)lpOutBuffer;
547
548 if(nOutBufferSize < sizeof(PARALLEL_PORT_INFORMATION) || !pPPI)
549 {
550 SetLastError(ERROR_INSUFFICIENT_BUFFER);
551 return FALSE;
552 }
553
554 if(lpBytesReturned)
555 *lpBytesReturned = sizeof(PARALLEL_PORT_INFORMATION);
556
557 // fill in the data values
558 PHMDEVPARPORTDATA pPPD = (PHMDEVPARPORTDATA)pHMHandleData->lpHandlerData;
559
560 // @@@PH
561 // Specifies the bus relative base I/O address of the parallel port registers.
562 pPPI->OriginalController.LowPart = pPPD->pHardwareConfiguration->ulPortBase;
563 pPPI->OriginalController.HighPart = 0;
564
565 // Pointer to the system-mapped base I/O location of the parallel port registers.
566 pPPI->Controller = NULL;
567
568 // Specifies the size, in bytes, of the I/O space, allocated to the parallel port.
569 pPPI->SpanOfController = pPPD->pHardwareConfiguration->ulPortSpan;
570
571 // Pointer to a callback routine that a kernel-mode driver can use to try to allocate the parallel port.
572 pPPI->TryAllocatePort = NULL;
573
574 // Pointer to a callback routine that a kernel-mode driver can use to free the parallel port.
575 pPPI->FreePort = NULL;
576
577 // 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.
578 pPPI->QueryNumWaiters = NULL;
579
580 // Pointer to the device extension of parallel port.
581 pPPI->Context = NULL;
582
583 return TRUE;
584 }
585
586
587 case IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO:
588 {
589 PPARALLEL_PNP_INFORMATION pPPI = (PPARALLEL_PNP_INFORMATION)lpOutBuffer;
590
591 if(nOutBufferSize < sizeof(PARALLEL_PNP_INFORMATION) || !pPPI)
592 {
593 SetLastError(ERROR_INSUFFICIENT_BUFFER);
594 return FALSE;
595 }
596
597 if(lpBytesReturned)
598 *lpBytesReturned = sizeof(PARALLEL_PNP_INFORMATION);
599
600 // fill in the data values
601 PHMDEVPARPORTDATA pPPD = (PHMDEVPARPORTDATA)pHMHandleData->lpHandlerData;
602
603 // @@@PH
604 // Specifies the base physical address that the system-supplied
605 // function driver for parallel ports uses to control the ECP
606 // operation of the parallel port.
607 pPPI->OriginalEcpController.LowPart = pPPD->pHardwareConfiguration->ulEcpPortBase;
608 pPPI->OriginalEcpController.HighPart = 0;
609
610 // Pointer to the I/O port resource that is used to control the
611 // port in ECP mode.
612 pPPI->EcpController = NULL;
613
614 // Specifies the size, in bytes, of the I/O port resource.
615 pPPI->SpanOfEcpController = pPPD->pHardwareConfiguration->ulEcpPortSpan;
616
617 // Not used.
618 pPPI->PortNumber = 0;
619
620 // Specifies the hardware capabilities of the parallel port. The following capabilities can be set using a bitwise OR of the following constants:
621 pPPI->HardwareCapabilities = 0;
622 // PPT_1284_3_PRESENT
623 // PPT_BYTE_PRESENT
624 // PPT_ECP_PRESENT
625 // PPT_EPP_32_PRESENT
626 // PPT_EPP_PRESENT
627 // PT_NO_HARDWARE_PRESENT
628
629 // Pointer to a callback routine that a kernel-mode driver can use to change the operating mode of the parallel port.
630 pPPI->TrySetChipMode = 0;
631
632 // Pointer to a callback routine that a kernel-mode driver can use to clear the operating mode of the parallel port.
633 pPPI->ClearChipMode = 0;
634
635 // 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.
636 pPPI->FifoDepth = 0;
637
638 // Specifies the FIFO word size, in bits, which is the number of bits handled in parallel.
639 pPPI->FifoWidth = 0;
640
641 // Not used.
642 pPPI->EppControllerPhysicalAddress.LowPart = 0;
643 pPPI->EppControllerPhysicalAddress.HighPart = 0;
644
645 // Not used.
646 pPPI->SpanOfEppController = 0;
647
648 // 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
649 // parallel port. In Windows 2000, from zero to four devices can be simultaneously connected to a parallel port.
650 pPPI->Ieee1284_3DeviceCount = 0;
651
652 // Pointer to a callback routine that a kernel-mode driver can use to try to select an IEEE 1284.3 device.
653 pPPI->TrySelectDevice = 0;
654
655 // Pointer to a callback routine that a kernel-mode driver can use to deselect an IEEE 1284.3 device.
656 pPPI->DeselectDevice = 0;
657
658 // Pointer to the device extension of a parallel port's function device object (FDO).
659 pPPI->Context = 0;
660
661 // The current operating mode of the parallel port.
662 pPPI->CurrentMode = 0;
663
664 // The symbolic link name of the parallel port.
665 pPPI->PortName = 0;
666
667 return TRUE;
668 }
669 }
670 dprintf(("HMDeviceParPortClass::DeviceIoControl: unimplemented dwIoControlCode=%08lx\n", dwIoControlCode));
671 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
672 return FALSE;
673}
674//******************************************************************************
675//******************************************************************************
676
677
Note: See TracBrowser for help on using the repository browser.