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

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

Fixes in HandleManager and Device Handlers

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