source: trunk/src/kernel32/hmdevio.cpp

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

Merge branch gcc-kmk to trunk.

File size: 20.1 KB
RevLine 
[9533]1/* $Id: hmdevio.cpp,v 1.29 2002-12-20 10:38:56 sandervl Exp $ */
[1713]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 */
[4300]20#include <os2wrap.h> //Odin32 OS/2 api wrappers
[1713]21#include <string.h>
[5905]22#include <stdio.h>
[1713]23
24#include <win32type.h>
[5757]25#include <win32api.h>
[1713]26#include <misc.h>
[21916]27#include <win/winioctl.h>
[1713]28#include "hmdevio.h"
29#include "exceptutil.h"
[7474]30#include "oslibdos.h"
[1713]31
[4300]32#define DBG_LOCALLOG DBG_hmdevio
[2802]33#include "dbglocal.h"
34
[1713]35static WIN32DRV knownDriver[] =
[9533]36 { {0}
[5757]37 };
[1713]38
[9533]39static int nrKnownDrivers = 0;
40// = sizeof(knownDriver)/sizeof(WIN32DRV);
[1713]41
42//******************************************************************************
43//******************************************************************************
44void RegisterDevices()
45{
46 HMDeviceDriver *driver;
47 DWORD rc;
48
[21916]49 for(int i=0;i<nrKnownDrivers;i++)
[1713]50 {
[8840]51 driver = new HMDeviceDriver(knownDriver[i].szWin32Name,
[1713]52 knownDriver[i].szOS2Name,
53 knownDriver[i].fCreateFile,
54 knownDriver[i].devIOCtl);
55
[8840]56 rc = HMDeviceRegister(knownDriver[i].szWin32Name, driver);
[4300]57 if (rc != NO_ERROR) /* check for errors */
58 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n",
59 knownDriver[i].szWin32Name, rc));
[1713]60 }
[5905]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);
[7474]95 if(hDrvDll)
96 {
[5905]97 sprintf(szDrvName, "\\\\.\\%s", szKeyName);
[7763]98 driver = new HMCustomDriver(hDrvDll, szDrvName, NULL);
[5905]99
100 rc = HMDeviceRegister(szDrvName, driver);
101 if (rc != NO_ERROR) /* check for errors */
[7474]102 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n", szDrvName, rc));
[21916]103
[7474]104 // @@@PH
105 // there should be an symbolic link:
106 // "\\.\drvname$" -> "drvname$"
[5905]107 }
108 }
109 rc = 0;
110 }
[21916]111 }
[5905]112 RegCloseKey(hkDrivers);
113 }
114
[1713]115 return;
116}
117//******************************************************************************
118//******************************************************************************
[21916]119BOOL WIN32API RegisterCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose,
[7572]120 PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead,
[7630]121 PFNDRVWRITE pfnDriverWrite, PFNDRVCANCELIO pfnDriverCancelIo,
122 PFNDRVGETOVERLAPPEDRESULT pfnDriverGetOverlappedResult,
[7763]123 LPCSTR lpDeviceName, LPVOID lpDriverData)
[7245]124{
[8840]125 HMCustomDriver *driver;
126 DWORD rc;
[8325]127
128 dprintf(("RegisterCustomDriver %s", lpDeviceName));
[7763]129 driver = new HMCustomDriver(pfnDriverOpen, pfnDriverClose, pfnDriverIOCtl, pfnDriverRead, pfnDriverWrite, pfnDriverCancelIo, pfnDriverGetOverlappedResult, lpDeviceName, lpDriverData);
[7245]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//******************************************************************************
[21916]143HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName, LPSTR lpOS2DevName, BOOL fCreate,
[1713]144 WINIOCTL pDevIOCtl)
[8840]145 : HMDeviceHandler(lpDeviceName)
[1713]146{
147 this->fCreateFile = fCreateFile;
148 this->szOS2Name = lpOS2DevName;
149 this->devIOCtl = pDevIOCtl;
150}
151//******************************************************************************
152//******************************************************************************
[5905]153HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName)
[8840]154 : HMDeviceHandler(lpDeviceName)
[5905]155{
156}
157//******************************************************************************
158//******************************************************************************
[7549]159DWORD HMDeviceDriver::CreateFile (LPCSTR lpFileName,
[1713]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
[2952]187 if(szOS2Name[0] == 0) {
[4300]188 pHMHandleData->hHMHandle = 0;
189 return (NO_ERROR);
[2952]190 }
191
[3005]192tryopen:
[4300]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 */
[1713]201
[3005]202 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
203 ULONG CurMaxFH;
204 LONG ReqCount = 32;
205
[4300]206 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
207 if(rc) {
208 dprintf(("DosSetRelMaxFH returned %d", rc));
[7474]209 return error2WinError(rc);
[4300]210 }
211 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
212 goto tryopen;
[3005]213 }
214
[1713]215 dprintf(("DosOpen %s returned %d\n", szOS2Name, rc));
216
[21916]217 if(rc == NO_ERROR)
[7474]218 {
219 pHMHandleData->hHMHandle = hfFileHandle;
220 return (NO_ERROR);
[1713]221 }
[21916]222 else
[7474]223 return(error2WinError(rc));
[1713]224}
225//******************************************************************************
226//******************************************************************************
[5587]227BOOL HMDeviceDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
[1713]228{
[4431]229 DWORD rc = 0;
230
231 if(pHMHandleData->hHMHandle) {
232 rc = DosClose(pHMHandleData->hHMHandle);
233 }
234 pHMHandleData->hHMHandle = 0;
235 return rc;
[1713]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//******************************************************************************
[7763]249HMCustomDriver::HMCustomDriver(HINSTANCE hInstance, LPCSTR lpDeviceName, LPVOID lpDriverData)
250 : HMDeviceDriver(lpDeviceName), hDrvDll(0), lpDriverData(NULL)
[5905]251{
252 hDrvDll = hInstance ;
[7572]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");
[5905]258}
259//******************************************************************************
260//******************************************************************************
[21916]261HMCustomDriver::HMCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose,
[7572]262 PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead,
[7630]263 PFNDRVWRITE pfnDriverWrite, PFNDRVCANCELIO pfnDriverCancelIo,
264 PFNDRVGETOVERLAPPEDRESULT pfnDriverGetOverlappedResult,
[7763]265 LPCSTR lpDeviceName, LPVOID lpDriverData)
[7245]266 : HMDeviceDriver(lpDeviceName), hDrvDll(0)
267{
[7572]268 if(!pfnDriverOpen || !pfnDriverClose) {
269 DebugInt3();
270 }
[7630]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;
[7763]278 this->lpDriverData = lpDriverData;
[7245]279}
280//******************************************************************************
281//******************************************************************************
[5905]282HMCustomDriver::~HMCustomDriver()
283{
[7245]284 if(hDrvDll) FreeLibrary(hDrvDll);
[5905]285}
286//******************************************************************************
287//******************************************************************************
[7549]288DWORD HMCustomDriver::CreateFile (LPCSTR lpFileName,
[5905]289 PHMHANDLEDATA pHMHandleData,
290 PVOID lpSecurityAttributes,
291 PHMHANDLEDATA pHMHandleDataTemplate)
292{
[7763]293 pHMHandleData->hHMHandle = pfnDriverOpen(lpDriverData, pHMHandleData->dwAccess, pHMHandleData->dwShare, pHMHandleData->dwFlags, (PVOID *)&pHMHandleData->dwUserData);
[7590]294 if(pHMHandleData->hHMHandle == INVALID_HANDLE_VALUE_W) {
[7591]295 return GetLastError();
[5905]296 }
[7572]297 return ERROR_SUCCESS_W;
[5905]298}
299//******************************************************************************
300//******************************************************************************
301BOOL HMCustomDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
302{
303 if(pHMHandleData->hHMHandle) {
[7763]304 pfnDriverClose(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, (LPVOID)pHMHandleData->dwUserData);
[5905]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{
[6086]316 BOOL ret;
317
[7572]318 if(pfnDriverIOCtl == NULL) {
319 dprintf(("HMCustomDriver::DeviceIoControl: pfnDriverIOCtl == NULL"));
320 ::SetLastError(ERROR_INVALID_FUNCTION_W);
321 return FALSE;
322 }
323
[7763]324 ret = pfnDriverIOCtl(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, dwIoControlCode, lpInBuffer, nInBufferSize,
325 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped, (LPVOID)pHMHandleData->dwUserData);
[6086]326 dprintf(("DeviceIoControl %x returned %d", dwIoControlCode, ret));
327 return ret;
[5905]328}
[7572]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 }
[7763]360 ret = pfnDriverRead(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, lpBuffer, nNumberOfBytesToRead,
[7756]361 lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine,
[7763]362 (LPVOID)pHMHandleData->dwUserData);
[7572]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 }
[7763]398 ret = pfnDriverWrite(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, lpBuffer, nNumberOfBytesToWrite,
[7756]399 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine,
[7763]400 (LPVOID)pHMHandleData->dwUserData);
[7572]401 dprintf(("pfnDriverWrite %x %x %x %x %x %x returned %x", pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite,
402 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, ret));
403 return ret;
404}
[7630]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 }
[7763]424 ret = pfnDriverCancelIo(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags, (LPVOID)pHMHandleData->dwUserData);
[7630]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 }
[21916]463 return pfnDriverGetOverlappedResult(lpDriverData, pHMHandleData->hHMHandle, pHMHandleData->dwFlags,
[7763]464 lpOverlapped, lpcbTransfer, fWait, (LPVOID)pHMHandleData->dwUserData);
[7630]465}
[21916]466
467extern "C" {
468
[5905]469//******************************************************************************
470//******************************************************************************
[1713]471BOOL WIN32API QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
472{
[8840]473 QWORD time;
474 APIRET rc;
[21302]475#if 0
476 return FALSE;
477#else
[8840]478 rc = DosTmrQueryTime(&time);
479 if(rc) {
[4300]480 dprintf(("DosTmrQueryTime returned %d\n", rc));
481 return(FALSE);
[8840]482 }
483 lpPerformanceCount->u.LowPart = time.ulLo;
484 lpPerformanceCount->u.HighPart = time.ulHi;
[21302]485 dprintf2(("QueryPerformanceCounter returned 0x%X%X\n", lpPerformanceCount->u.HighPart, lpPerformanceCount->u.LowPart));
[8840]486 return(TRUE);
[21302]487#endif
[1713]488}
489//******************************************************************************
490//******************************************************************************
491BOOL WIN32API QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)
492{
[8840]493 APIRET rc;
494 ULONG freq;
[1713]495
[21302]496#if 0
497 return FALSE;
498#else
[8840]499 rc = DosTmrQueryFreq(&freq);
500 if(rc) {
[4300]501 dprintf(("DosTmrQueryFreq returned %d\n", rc));
502 return(FALSE);
[8840]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);
[21302]508#endif
[1713]509}
510//******************************************************************************
511//******************************************************************************
[21916]512
513} // extern "C"
514
Note: See TracBrowser for help on using the repository browser.