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

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

parport support

File size: 14.6 KB
Line 
1/* $Id: hmparport.cpp,v 1.1 2001-11-08 14:49: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 <heapstring.h>
18#include "hmdevice.h"
19#include "hmparport.h"
20#include "oslibdos.h"
21
22#define DBG_LOCALLOG DBG_hmparport
23#include "dbglocal.h"
24
25
26#define MAGIC_PARPORT 0x4c505431
27
28#if 0
29
30#define IOCTL_ASYNC 0x01
31#define ASYNC_GETDCBINFO 0x73
32#define ASYNC_SETDCBINFO 0x53
33#define ASYNC_SETLINECTRL 0x42
34#define ASYNC_GETCOMMEVENT 0x72
35#define ASYNC_EXTGETBAUDRATE 0x63
36#define ASYNC_EXTSETBAUDRATE 0x43
37#define ASYNC_GETCOMMERROR 0x6D
38#define ASYNC_GETCOMMSTATUS 0x65
39#define ASYNC_GETINQUECOUNT 0x68
40#define ASYNC_GETOUTQUECOUNT 0x69
41#define ASYNC_GETMODEMINPUT 0x67
42#define ASYNC_TRANSMITIMM 0x44
43#define ASYNC_SETBREAKON 0x4B
44#define ASYNC_SETBREAKOFF 0x45
45#define ASYNC_SETMODEMCTRL 0x46
46#define ASYNC_STARTTRANSMIT 0x48
47#define ASYNC_STOPTRANSMIT 0x47
48#define ASYNC_GETMODEMOUTPUT 0x66
49
50
51#pragma pack(1)
52typedef struct _DCBINFO
53{
54 USHORT usWriteTimeout; /* Time period used for Write Timeout processing. */
55 USHORT usReadTimeout; /* Time period used for Read Timeout processing. */
56 BYTE fbCtlHndShake; /* HandShake Control flag. */
57 BYTE fbFlowReplace; /* Flow Control flag. */
58 BYTE fbTimeOut; /* Timeout flag. */
59 BYTE bErrorReplacementChar; /* Error Replacement Character. */
60 BYTE bBreakReplacementChar; /* Break Replacement Character. */
61 BYTE bXONChar; /* Character XON. */
62 BYTE bXOFFChar; /* Character XOFF. */
63} DCBINFO;
64typedef DCBINFO *PDCBINFO;
65
66
67typedef struct _RXQUEUE
68{
69 USHORT cch; /* Number of characters in the queue. */
70 USHORT cb; /* Size of receive/transmit queue. */
71} RXQUEUE;
72
73typedef RXQUEUE *PRXQUEUE;
74
75
76typedef struct _MODEMSTATUS
77{
78 BYTE fbModemOn; /* Modem Control Signals ON Mask. */
79 BYTE fbModemOff; /* Modem Control Signals OFF Mask. */
80} MODEMSTATUS;
81
82typedef MODEMSTATUS *PMODEMSTATUS;
83
84
85#pragma pack()
86
87
88#endif
89
90
91typedef struct _HMDEVPARPORTDATA
92{
93 ULONG ulMagic;
94 // Win32 Device Control Block
95 //OS/2 Device Control Block
96} HMDEVPARPORTDATA, *PHMDEVPARPORTDATA;
97
98static VOID *CreateDevData()
99{
100 PHMDEVPARPORTDATA pData;
101 pData = new HMDEVPARPORTDATA();
102 if(NULL!=pData)
103 {
104 memset(pData,0,sizeof(HMDEVPARPORTDATA));
105 pData->ulMagic = MAGIC_PARPORT;
106 }
107 return pData;
108}
109
110
111HMDeviceParPortClass::HMDeviceParPortClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName)
112{
113 VOID *pData;
114 dprintf(("HMDeviceParPortClass: Register LPT1 to LPT3 with Handle Manager\n"));
115
116 pData = CreateDevData();
117 if(pData!= NULL)
118 HMDeviceRegisterEx("LPT1", this, pData);
119}
120
121/*****************************************************************************
122 * Name : HMDeviceParPortClass::FindDevice
123 * Purpose : Checks if lpDeviceName belongs to this device class
124 * Parameters: LPCSTR lpClassDevName
125 * LPCSTR lpDeviceName
126 * int namelength
127 * Variables :
128 * Result : checks if name is COMx or COMx: (x=1..8)
129 * Remark :
130 * Status :
131 *
132 * Author : SvL
133 *****************************************************************************/
134BOOL HMDeviceParPortClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
135{
136 if(namelength > 5)
137 return FALSE; //can't be lpt name
138
139 //first 3 letters 'LPT'?
140 if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) {
141 return FALSE;
142 }
143
144 if(namelength == 5 && lpDeviceName[4] != ':') {
145 return FALSE;
146 }
147 switch(lpDeviceName[3]) {
148 case '1':
149 case '2':
150 case '3':
151 return TRUE; //we support up to LPT3
152 }
153 return FALSE;
154}
155
156DWORD HMDeviceParPortClass::CreateFile(LPCSTR lpFileName,
157 PHMHANDLEDATA pHMHandleData,
158 PVOID lpSecurityAttributes,
159 PHMHANDLEDATA pHMHandleDataTemplate)
160{
161 char comname[6];
162
163 dprintf(("HMDeviceParPortClass: Parallel port %s open request\n", lpFileName));
164
165 if(strlen(lpFileName) > 5) {
166 return -1; //safety check (unnecessary..)
167 }
168 pHMHandleData->hHMHandle = 0;
169
170 strcpy(comname, lpFileName);
171 comname[4] = 0; //get rid of : (if present) (eg LPT1:)
172
173 //AH: TODO parse Win32 security handles
174 ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
175 pHMHandleData->hHMHandle = OSLibDosOpen(comname,
176 OSLIB_ACCESS_READWRITE |
177 OSLIB_ACCESS_SHAREDENYREAD |
178 OSLIB_ACCESS_SHAREDENYWRITE);
179 SetErrorMode(oldmode);
180
181#if 0
182 if (pHMHandleData->hHMHandle != 0)
183 {
184 ULONG ulLen;
185 APIRET rc;
186 pHMHandleData->lpHandlerData = new HMDEVPARPORTDATA();
187 // Init The handle instance with the default default device config
188 memcpy( pHMHandleData->lpHandlerData,
189 pHMHandleData->lpDeviceData,
190 sizeof(HMDEVPARPORTDATA));
191
192 ulLen = sizeof(DCBINFO);
193
194 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle,
195 IOCTL_ASYNC,
196 ASYNC_GETDCBINFO,
197 0,0,0,
198 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen);
199 dprintf(("DCB Of %s :\n"
200 " WriteTimeout : %d\n"
201 " ReadTimeout : %d\n"
202 " CtlHandshake : 0x%x\n"
203 " FlowReplace : 0x%x\n"
204 " Timeout : 0x%x\n"
205 " Error replacement Char : 0x%x\n"
206 " Break replacement Char : 0x%x\n"
207 " XON Char : 0x%x\n"
208 " XOFF Char : 0x%x\n",
209 comname,
210 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout,
211 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout,
212 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake,
213 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace,
214 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut,
215 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar,
216 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar,
217 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar,
218 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar));
219
220 if(rc)
221 {
222 return -1;
223 }
224 rc = SetBaud(pHMHandleData,9600);
225 dprintf(("Init Baud to 9600 rc = %d",rc));
226 rc = SetLine(pHMHandleData,8,0,0);
227 dprintf(("Set Line to 8/N/1 rc = %d",rc));
228 return 0;
229 }
230 else
231 return -1;
232#endif
233
234 return NO_ERROR;
235}
236
237
238 /* this is a handler method for calls to CloseHandle() */
239BOOL HMDeviceParPortClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
240{
241 dprintf(("HMDeviceParPortClass: Parallel port close request\n"));
242 delete pHMHandleData->lpHandlerData;
243 return OSLibDosClose(pHMHandleData->hHMHandle);
244}
245
246
247/*****************************************************************************
248 * Name : BOOL HMDeviceParPortClass::WriteFile
249 * Purpose : write data to handle / device
250 * Parameters: PHMHANDLEDATA pHMHandleData,
251 * LPCVOID lpBuffer,
252 * DWORD nNumberOfBytesToWrite,
253 * LPDWORD lpNumberOfBytesWritten,
254 * LPOVERLAPPED lpOverlapped
255 * Variables :
256 * Result : Boolean
257 * Remark :
258 * Status :
259 *
260 * Author : SvL
261 *****************************************************************************/
262
263BOOL HMDeviceParPortClass::WriteFile(PHMHANDLEDATA pHMHandleData,
264 LPCVOID lpBuffer,
265 DWORD nNumberOfBytesToWrite,
266 LPDWORD lpNumberOfBytesWritten,
267 LPOVERLAPPED lpOverlapped)
268{
269 dprintf(("KERNEL32:HMDeviceParPortClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)",
270 lpHMDeviceName,
271 pHMHandleData->hHMHandle,
272 lpBuffer,
273 nNumberOfBytesToWrite,
274 lpNumberOfBytesWritten,
275 lpOverlapped));
276
277 BOOL ret;
278 ULONG ulBytesWritten;
279
280 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
281 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
282 SetLastError(ERROR_INVALID_PARAMETER);
283 return FALSE;
284 }
285 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
286 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
287 }
288
289 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite,
290 &ulBytesWritten);
291
292 if(lpNumberOfBytesWritten) {
293 *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0;
294 }
295 if(ret == FALSE) {
296 dprintf(("ERROR: WriteFile failed with rc %d", GetLastError()));
297 }
298
299 return ret;
300}
301
302/*****************************************************************************
303 * Name : BOOL WriteFileEx
304 * Purpose : The WriteFileEx function writes data to a file. It is designed
305 * solely for asynchronous operation, unlike WriteFile, which is
306 * designed for both synchronous and asynchronous operation.
307 * WriteFileEx reports its completion status asynchronously,
308 * calling a specified completion routine when writing is completed
309 * and the calling thread is in an alertable wait state.
310 * Parameters: HANDLE hFile handle of file to write
311 * LPVOID lpBuffer address of buffer
312 * DWORD nNumberOfBytesToRead number of bytes to write
313 * LPOVERLAPPED lpOverlapped address of offset
314 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
315 * Variables :
316 * Result : TRUE / FALSE
317 * Remark :
318 * Status : UNTESTED STUB
319 *
320 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
321 *****************************************************************************/
322
323BOOL HMDeviceParPortClass::WriteFileEx(PHMHANDLEDATA pHMHandleData,
324 LPVOID lpBuffer,
325 DWORD nNumberOfBytesToWrite,
326 LPOVERLAPPED lpOverlapped,
327 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
328{
329 dprintf(("ERROR: WriteFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
330 lpHMDeviceName,
331 pHMHandleData->hHMHandle,
332 lpBuffer,
333 nNumberOfBytesToWrite,
334 lpOverlapped,
335 lpCompletionRoutine));
336
337 SetLastError(ERROR_INVALID_FUNCTION);
338 return FALSE;
339}
340
341/*****************************************************************************
342 * Name : BOOL HMDeviceParPortClass::ReadFile
343 * Purpose : read data from handle / device
344 * Parameters: PHMHANDLEDATA pHMHandleData,
345 * LPCVOID lpBuffer,
346 * DWORD nNumberOfBytesToRead,
347 * LPDWORD lpNumberOfBytesRead,
348 * LPOVERLAPPED lpOverlapped
349 * Variables :
350 * Result : Boolean
351 * Remark :
352 * Status :
353 *
354 * Author : SvL
355 *****************************************************************************/
356
357BOOL HMDeviceParPortClass::ReadFile(PHMHANDLEDATA pHMHandleData,
358 LPCVOID lpBuffer,
359 DWORD nNumberOfBytesToRead,
360 LPDWORD lpNumberOfBytesRead,
361 LPOVERLAPPED lpOverlapped)
362{
363 dprintf(("KERNEL32:HMDeviceParPortClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
364 lpHMDeviceName,
365 pHMHandleData->hHMHandle,
366 lpBuffer,
367 nNumberOfBytesToRead,
368 lpNumberOfBytesRead,
369 lpOverlapped));
370
371 BOOL ret;
372 ULONG ulBytesRead;
373
374 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
375 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
376 SetLastError(ERROR_INVALID_PARAMETER);
377 return FALSE;
378 }
379 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
380 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
381 }
382
383 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead,
384 &ulBytesRead);
385
386 if(lpNumberOfBytesRead) {
387 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0;
388 }
389 if(ret == FALSE) {
390 dprintf(("ERROR: ReadFile failed with rc %d", GetLastError()));
391 }
392 return ret;
393}
394
395/*****************************************************************************
396 * Name : BOOL ReadFileEx
397 * Purpose : The ReadFileEx function reads data from a file asynchronously.
398 * It is designed solely for asynchronous operation, unlike the
399 * ReadFile function, which is designed for both synchronous and
400 * asynchronous operation. ReadFileEx lets an application perform
401 * other processing during a file read operation.
402 * The ReadFileEx function reports its completion status asynchronously,
403 * calling a specified completion routine when reading is completed
404 * and the calling thread is in an alertable wait state.
405 * Parameters: HANDLE hFile handle of file to read
406 * LPVOID lpBuffer address of buffer
407 * DWORD nNumberOfBytesToRead number of bytes to read
408 * LPOVERLAPPED lpOverlapped address of offset
409 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
410 * Variables :
411 * Result : TRUE / FALSE
412 * Remark :
413 * Status : UNTESTED STUB
414 *
415 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
416 *****************************************************************************/
417BOOL HMDeviceParPortClass::ReadFileEx(PHMHANDLEDATA pHMHandleData,
418 LPVOID lpBuffer,
419 DWORD nNumberOfBytesToRead,
420 LPOVERLAPPED lpOverlapped,
421 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
422{
423 dprintf(("ERROR: ReadFileEx %s (%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
424 lpHMDeviceName,
425 pHMHandleData->hHMHandle,
426 lpBuffer,
427 nNumberOfBytesToRead,
428 lpOverlapped,
429 lpCompletionRoutine));
430
431 SetLastError(ERROR_INVALID_FUNCTION);
432 return FALSE;
433}
434
Note: See TracBrowser for help on using the repository browser.