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

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

Added support for DosDevConfig, query number of available parallel ports

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