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

Last change on this file since 9533 was 9533, checked in by sandervl, 23 years ago

Removed obsolete code for Glide drivers and IOPL

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