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

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

device name fixes

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