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

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

Parallel Port detection doesn't take OS/2 devices into account

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