source: trunk/src/kernel32/hmdevio.cpp@ 22018

Last change on this file since 22018 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 20.1 KB
Line 
1/* $Id: hmdevio.cpp,v 1.29 2002-12-20 10:38:56 sandervl Exp $ */
2
3/*
4 * Win32 Device IOCTL API functions for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_DOSPROFILE
13#define INCL_DOSDEVICES
14#define INCL_DOSDEVIOCTL
15#define INCL_GPI
16#define INCL_DOSFILEMGR /* File Manager values */
17#define INCL_DOSERRORS /* DOS Error values */
18#define INCL_DOSPROCESS /* DOS Process values */
19#define INCL_DOSMISC /* DOS Miscellanous values */
20#include <os2wrap.h> //Odin32 OS/2 api wrappers
21#include <string.h>
22#include <stdio.h>
23
24#include <win32type.h>
25#include <win32api.h>
26#include <misc.h>
27#include <win/winioctl.h>
28#include "hmdevio.h"
29#include "exceptutil.h"
30#include "oslibdos.h"
31
32#define DBG_LOCALLOG DBG_hmdevio
33#include "dbglocal.h"
34
35static WIN32DRV knownDriver[] =
36 { {0}
37 };
38
39static int nrKnownDrivers = 0;
40// = sizeof(knownDriver)/sizeof(WIN32DRV);
41
42//******************************************************************************
43//******************************************************************************
44void RegisterDevices()
45{
46 HMDeviceDriver *driver;
47 DWORD rc;
48
49 for(int i=0;i<nrKnownDrivers;i++)
50 {
51 driver = new HMDeviceDriver(knownDriver[i].szWin32Name,
52 knownDriver[i].szOS2Name,
53 knownDriver[i].fCreateFile,
54 knownDriver[i].devIOCtl);
55
56 rc = HMDeviceRegister(knownDriver[i].szWin32Name, driver);
57 if (rc != NO_ERROR) /* check for errors */
58 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n",
59 knownDriver[i].szWin32Name, rc));
60 }
61
62 //check registry for Odin driver plugin dlls
63 HKEY hkDrivers, hkDrvDll;
64
65 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
66 "System\\CurrentControlSet\\Services",
67 0, KEY_READ, &hkDrivers);
68
69 if(rc == 0) {
70 char szDllName[CCHMAXPATH];
71 char szKeyName[CCHMAXPATH];
72 char szDrvName[CCHMAXPATH];
73 DWORD dwType, dwSize;
74 int iSubKey = 0;
75
76 while(rc == 0) {
77 rc = RegEnumKeyA(hkDrivers, iSubKey++, szKeyName, sizeof(szKeyName));
78 if(rc) break;
79
80 rc = RegOpenKeyExA(hkDrivers, szKeyName,
81 0, KEY_READ, &hkDrvDll);
82 if(rc == 0) {
83 dwSize = sizeof(szDllName);
84 rc = RegQueryValueExA(hkDrvDll,
85 "DllName",
86 NULL,
87 &dwType,
88 (LPBYTE)szDllName,
89 &dwSize);
90
91 RegCloseKey(hkDrvDll);
92 if(rc == 0 && dwType == REG_SZ)
93 {
94 HINSTANCE hDrvDll = LoadLibraryA(szDllName);
95 if(hDrvDll)
96 {
97 sprintf(szDrvName, "\\\\.\\%s", szKeyName);
98 driver = new HMCustomDriver(hDrvDll, szDrvName, NULL);
99
100 rc = HMDeviceRegister(szDrvName, driver);
101 if (rc != NO_ERROR) /* check for errors */
102 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n", szDrvName, rc));
103
104 // @@@PH
105 // there should be an symbolic link:
106 // "\\.\drvname$" -> "drvname$"
107 }
108 }
109 rc = 0;
110 }
111 }
112 RegCloseKey(hkDrivers);
113 }
114
115 return;
116}
117//******************************************************************************
118//******************************************************************************
119BOOL WIN32API RegisterCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose,
120 PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead,
121 PFNDRVWRITE pfnDriverWrite, PFNDRVCANCELIO pfnDriverCancelIo,
122 PFNDRVGETOVERLAPPEDRESULT pfnDriverGetOverlappedResult,
123 LPCSTR lpDeviceName, LPVOID lpDriverData)
124{
125 HMCustomDriver *driver;
126 DWORD rc;
127
128 dprintf(("RegisterCustomDriver %s", lpDeviceName));
129 driver = new HMCustomDriver(pfnDriverOpen, pfnDriverClose, pfnDriverIOCtl, pfnDriverRead, pfnDriverWrite, pfnDriverCancelIo, pfnDriverGetOverlappedResult, lpDeviceName, lpDriverData);
130 if(driver == NULL) {
131 DebugInt3();
132 return FALSE;
133 }
134 rc = HMDeviceRegister((LPSTR)lpDeviceName, driver);
135 if (rc != NO_ERROR) { /* check for errors */
136 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n", lpDeviceName, rc));
137 return FALSE;
138 }
139 return TRUE;
140}
141//******************************************************************************
142//******************************************************************************
143HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName, LPSTR lpOS2DevName, BOOL fCreate,
144 WINIOCTL pDevIOCtl)
145 : HMDeviceHandler(lpDeviceName)
146{
147 this->fCreateFile = fCreateFile;
148 this->szOS2Name = lpOS2DevName;
149 this->devIOCtl = pDevIOCtl;
150}
151//******************************************************************************
152//******************************************************************************
153HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName)
154 : HMDeviceHandler(lpDeviceName)
155{
156}
157//******************************************************************************
158//******************************************************************************
159DWORD HMDeviceDriver::CreateFile (LPCSTR lpFileName,
160 PHMHANDLEDATA pHMHandleData,
161 PVOID lpSecurityAttributes,
162 PHMHANDLEDATA pHMHandleDataTemplate)
163{
164 APIRET rc;
165 HFILE hfFileHandle = 0L; /* Handle for file being manipulated */
166 ULONG ulAction = 0; /* Action taken by DosOpen */
167 ULONG sharetype = 0;
168
169 if(pHMHandleData->dwAccess & (GENERIC_READ | GENERIC_WRITE))
170 sharetype |= OPEN_ACCESS_READWRITE;
171 else
172 if(pHMHandleData->dwAccess & GENERIC_WRITE)
173 sharetype |= OPEN_ACCESS_WRITEONLY;
174
175 if(pHMHandleData->dwShare == 0)
176 sharetype |= OPEN_SHARE_DENYREADWRITE;
177 else
178 if(pHMHandleData->dwShare & (FILE_SHARE_READ | FILE_SHARE_WRITE))
179 sharetype |= OPEN_SHARE_DENYNONE;
180 else
181 if(pHMHandleData->dwShare & FILE_SHARE_WRITE)
182 sharetype |= OPEN_SHARE_DENYREAD;
183 else
184 if(pHMHandleData->dwShare & FILE_SHARE_READ)
185 sharetype |= OPEN_SHARE_DENYWRITE;
186
187 if(szOS2Name[0] == 0) {
188 pHMHandleData->hHMHandle = 0;
189 return (NO_ERROR);
190 }
191
192tryopen:
193 rc = DosOpen( szOS2Name, /* File path name */
194 &hfFileHandle, /* File handle */
195 &ulAction, /* Action taken */
196 0,
197 FILE_NORMAL,
198 FILE_OPEN,
199 sharetype,
200 0L); /* No extended attribute */
201
202 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
203 ULONG CurMaxFH;
204 LONG ReqCount = 32;
205
206 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
207 if(rc) {
208 dprintf(("DosSetRelMaxFH returned %d", rc));
209 return error2WinError(rc);
210 }
211 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
212 goto tryopen;
213 }
214
215 dprintf(("DosOpen %s returned %d\n", szOS2Name, rc));
216
217 if(rc == NO_ERROR)
218 {
219 pHMHandleData->hHMHandle = hfFileHandle;
220 return (NO_ERROR);
221 }
222 else
223 return(error2WinError(rc));
224}
225//******************************************************************************
226//******************************************************************************
227BOOL HMDeviceDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
228{
229 DWORD rc = 0;
230
231 if(pHMHandleData->hHMHandle) {
232 rc = DosClose(pHMHandleData->hHMHandle);
233 }
234 pHMHandleData->hHMHandle = 0;
235 return rc;
236}
237//******************************************************************************
238//******************************************************************************
239BOOL HMDeviceDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
240 LPVOID lpInBuffer, DWORD nInBufferSize,
241 LPVOID lpOutBuffer, DWORD nOutBufferSize,
242 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
243{
244 return devIOCtl(pHMHandleData->hHMHandle, dwIoControlCode, lpInBuffer, nInBufferSize,
245 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
246}
247//******************************************************************************
248//******************************************************************************
249HMCustomDriver::HMCustomDriver(HINSTANCE hInstance, LPCSTR lpDeviceName, LPVOID lpDriverData)
250 : HMDeviceDriver(lpDeviceName), hDrvDll(0), lpDriverData(NULL)
251{
252 hDrvDll = hInstance ;
253 pfnDriverOpen = (PFNDRVOPEN) GetProcAddress(hDrvDll, "DrvOpen");
254 pfnDriverClose = (PFNDRVCLOSE)GetProcAddress(hDrvDll, "DrvClose");
255 pfnDriverRead = (PFNDRVREAD) GetProcAddress(hDrvDll, "DrvRead");
256 pfnDriverWrite = (PFNDRVWRITE)GetProcAddress(hDrvDll, "DrvWrite");
257 pfnDriverIOCtl = (PFNDRVIOCTL)GetProcAddress(hDrvDll, "DrvIOCtl");
258}
259//******************************************************************************
260//******************************************************************************
261HMCustomDriver::HMCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose,
262 PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead,
263 PFNDRVWRITE pfnDriverWrite, PFNDRVCANCELIO pfnDriverCancelIo,
264 PFNDRVGETOVERLAPPEDRESULT pfnDriverGetOverlappedResult,
265 LPCSTR lpDeviceName, LPVOID lpDriverData)
266 : HMDeviceDriver(lpDeviceName), hDrvDll(0)
267{
268 if(!pfnDriverOpen || !pfnDriverClose) {
269 DebugInt3();
270 }
271 this->pfnDriverOpen = pfnDriverOpen;
272 this->pfnDriverClose = pfnDriverClose;
273 this->pfnDriverIOCtl = pfnDriverIOCtl;
274 this->pfnDriverRead = pfnDriverRead;
275 this->pfnDriverWrite = pfnDriverWrite;
276 this->pfnDriverCancelIo = pfnDriverCancelIo;
277 this->pfnDriverGetOverlappedResult = pfnDriverGetOverlappedResult;
278 this->lpDriverData = lpDriverData;
279}
280//******************************************************************************
281//******************************************************************************
282HMCustomDriver::~HMCustomDriver()
283{
284 if(hDrvDll) FreeLibrary(hDrvDll);
285}
286//******************************************************************************
287//******************************************************************************
288DWORD HMCustomDriver::CreateFile (LPCSTR lpFileName,
289 PHMHANDLEDATA pHMHandleData,
290 PVOID lpSecurityAttributes,
291 PHMHANDLEDATA pHMHandleDataTemplate)
292{
293 pHMHandleData->hHMHandle = pfnDriverOpen(lpDriverData, pHMHandleData->dwAccess, pHMHandleData->dwShare, pHMHandleData->dwFlags, (PVOID *)&pHMHandleData->dwUserData);
294 if(pHMHandleData->hHMHandle == INVALID_HANDLE_VALUE_W) {
295 return GetLastError();
296 }
297 return ERROR_SUCCESS_W;
298}
299//******************************************************************************
300//******************************************************************************
301BOOL HMCustomDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
302{
303 if(pHMHandleData->hHMHandle) {
304 pfnDriverClose(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, (LPVOID)pHMHandleData->dwUserData);
305 }
306 pHMHandleData->hHMHandle = 0;
307 return TRUE;
308}
309//******************************************************************************
310//******************************************************************************
311BOOL HMCustomDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
312 LPVOID lpInBuffer, DWORD nInBufferSize,
313 LPVOID lpOutBuffer, DWORD nOutBufferSize,
314 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
315{
316 BOOL ret;
317
318 if(pfnDriverIOCtl == NULL) {
319 dprintf(("HMCustomDriver::DeviceIoControl: pfnDriverIOCtl == NULL"));
320 ::SetLastError(ERROR_INVALID_FUNCTION_W);
321 return FALSE;
322 }
323
324 ret = pfnDriverIOCtl(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, dwIoControlCode, lpInBuffer, nInBufferSize,
325 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped, (LPVOID)pHMHandleData->dwUserData);
326 dprintf(("DeviceIoControl %x returned %d", dwIoControlCode, ret));
327 return ret;
328}
329/*****************************************************************************
330 * Name : BOOL HMCustomDriver::ReadFile
331 * Purpose : read data from handle / device
332 * Parameters: PHMHANDLEDATA pHMHandleData,
333 * LPCVOID lpBuffer,
334 * DWORD nNumberOfBytesToRead,
335 * LPDWORD lpNumberOfBytesRead,
336 * LPOVERLAPPED lpOverlapped
337 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
338 * Variables :
339 * Result : Boolean
340 * Remark :
341 * Status :
342 *
343 * Author : SvL
344 *****************************************************************************/
345
346BOOL HMCustomDriver::ReadFile(PHMHANDLEDATA pHMHandleData,
347 LPCVOID lpBuffer,
348 DWORD nNumberOfBytesToRead,
349 LPDWORD lpNumberOfBytesRead,
350 LPOVERLAPPED lpOverlapped,
351 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
352{
353 BOOL ret;
354
355 if(pfnDriverRead == NULL) {
356 dprintf(("HMCustomDriver::ReadFile: pfnDriverRead == NULL"));
357 ::SetLastError(ERROR_INVALID_FUNCTION_W);
358 return FALSE;
359 }
360 ret = pfnDriverRead(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, lpBuffer, nNumberOfBytesToRead,
361 lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine,
362 (LPVOID)pHMHandleData->dwUserData);
363 dprintf(("pfnDriverRead %x %x %x %x %x %x returned %x", pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead,
364 lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, ret));
365 return ret;
366}
367/*****************************************************************************
368 * Name : BOOL HMCustomDriver::WriteFile
369 * Purpose : write data to handle / device
370 * Parameters: PHMHANDLEDATA pHMHandleData,
371 * LPCVOID lpBuffer,
372 * DWORD nNumberOfBytesToWrite,
373 * LPDWORD lpNumberOfBytesWritten,
374 * LPOVERLAPPED lpOverlapped
375 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
376 * Variables :
377 * Result : Boolean
378 * Remark :
379 * Status :
380 *
381 * Author : SvL
382 *****************************************************************************/
383
384BOOL HMCustomDriver::WriteFile(PHMHANDLEDATA pHMHandleData,
385 LPCVOID lpBuffer,
386 DWORD nNumberOfBytesToWrite,
387 LPDWORD lpNumberOfBytesWritten,
388 LPOVERLAPPED lpOverlapped,
389 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
390{
391 BOOL ret;
392
393 if(pfnDriverWrite == NULL) {
394 dprintf(("HMCustomDriver::WriteFile: pfnDriverWrite == NULL"));
395 ::SetLastError(ERROR_INVALID_FUNCTION_W);
396 return FALSE;
397 }
398 ret = pfnDriverWrite(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, lpBuffer, nNumberOfBytesToWrite,
399 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine,
400 (LPVOID)pHMHandleData->dwUserData);
401 dprintf(("pfnDriverWrite %x %x %x %x %x %x returned %x", pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite,
402 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, ret));
403 return ret;
404}
405/*****************************************************************************
406 * Name : DWORD HMCustomDriver::CancelIo
407 * Purpose : cancel pending IO operation
408 * Variables :
409 * Result :
410 * Remark :
411 * Status :
412 *
413 * Author : SvL
414 *****************************************************************************/
415BOOL HMCustomDriver::CancelIo(PHMHANDLEDATA pHMHandleData)
416{
417 BOOL ret;
418
419 if(pfnDriverCancelIo == NULL) {
420 dprintf(("HMCustomDriver::CancelIo: pfnDriverCancelIo == NULL"));
421 ::SetLastError(ERROR_INVALID_FUNCTION_W);
422 return FALSE;
423 }
424 ret = pfnDriverCancelIo(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, (LPVOID)pHMHandleData->dwUserData);
425 dprintf(("pfnDriverCancelIo %x returned %x", pHMHandleData->hHMHandle, ret));
426 return ret;
427}
428/*****************************************************************************
429 * Name : DWORD HMCustomDriver::GetOverlappedResult
430 * Purpose : asynchronus I/O
431 * Parameters: PHMHANDLEDATA pHMHandleData
432 * LPOVERLAPPED arg2
433 * LPDWORD arg3
434 * BOOL arg4
435 * Variables :
436 * Result : API returncode
437 * Remark :
438 * Status :
439 *
440 * Author : SvL
441 *****************************************************************************/
442BOOL HMCustomDriver::GetOverlappedResult(PHMHANDLEDATA pHMHandleData,
443 LPOVERLAPPED lpOverlapped,
444 LPDWORD lpcbTransfer,
445 BOOL fWait)
446{
447 dprintf(("KERNEL32-HMCustomDriver: HMCustomDriver::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh)",
448 pHMHandleData->hHMHandle, lpOverlapped, lpcbTransfer, fWait));
449
450 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED_W)) {
451 dprintf(("!WARNING!: GetOverlappedResult called for a handle that wasn't opened with FILE_FLAG_OVERLAPPED"));
452 return TRUE; //NT4, SP6 doesn't fail
453 }
454 if(!lpOverlapped) {
455 ::SetLastError(ERROR_INVALID_PARAMETER);
456 return FALSE;
457 }
458 if(pfnDriverGetOverlappedResult == NULL) {
459 dprintf(("HMCustomDriver::GetOverlappedResult: pfnDriverGetOverlappedResult == NULL"));
460 ::SetLastError(ERROR_INVALID_FUNCTION_W);
461 return FALSE;
462 }
463 return pfnDriverGetOverlappedResult(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags,
464 lpOverlapped, lpcbTransfer, fWait, (LPVOID)pHMHandleData->dwUserData);
465}
466
467extern "C" {
468
469//******************************************************************************
470//******************************************************************************
471BOOL WIN32API QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
472{
473 QWORD time;
474 APIRET rc;
475#if 0
476 return FALSE;
477#else
478 rc = DosTmrQueryTime(&time);
479 if(rc) {
480 dprintf(("DosTmrQueryTime returned %d\n", rc));
481 return(FALSE);
482 }
483 lpPerformanceCount->u.LowPart = time.ulLo;
484 lpPerformanceCount->u.HighPart = time.ulHi;
485 dprintf2(("QueryPerformanceCounter returned 0x%X%X\n", lpPerformanceCount->u.HighPart, lpPerformanceCount->u.LowPart));
486 return(TRUE);
487#endif
488}
489//******************************************************************************
490//******************************************************************************
491BOOL WIN32API QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)
492{
493 APIRET rc;
494 ULONG freq;
495
496#if 0
497 return FALSE;
498#else
499 rc = DosTmrQueryFreq(&freq);
500 if(rc) {
501 dprintf(("DosTmrQueryFreq returned %d\n", rc));
502 return(FALSE);
503 }
504 lpFrequency->u.LowPart = freq;
505 lpFrequency->u.HighPart = 0;
506 dprintf2(("QueryPerformanceFrequency returned 0x%X%X\n", lpFrequency->u.HighPart, lpFrequency->u.LowPart));
507 return(TRUE);
508#endif
509}
510//******************************************************************************
511//******************************************************************************
512
513} // extern "C"
514
Note: See TracBrowser for help on using the repository browser.