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

Last change on this file since 7457 was 7457, checked in by sandervl, 24 years ago

preliminary work on overlapped serial comm IO

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