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

Last change on this file since 6035 was 6035, checked in by achimha, 24 years ago

remove VPC fake driver

File size: 16.3 KB
Line 
1/* $Id: hmdevio.cpp,v 1.13 2001-06-17 11:16:42 achimha 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 "cio.h"
30#include "map.h"
31#include "exceptutil.h"
32
33#define DBG_LOCALLOG DBG_hmdevio
34#include "dbglocal.h"
35
36static BOOL fX86Init = FALSE;
37//SvL: Used in iccio.asm (how can you put these in the .asm data segment without messing things up?)
38ULONG ioentry = 0;
39USHORT gdt = 0;
40char devname[] = "/dev/fastio$";
41
42static BOOL GpdDevIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
43static BOOL MAPMEMIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
44static BOOL FXMEMMAPIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
45
46static WIN32DRV knownDriver[] =
47 {{"\\\\.\\GpdDev", "", TRUE, 666, GpdDevIOCtl},
48 { "\\\\.\\MAPMEM", "PMAP$", FALSE, 0, MAPMEMIOCtl},
49 { "FXMEMMAP.VXD", "PMAP$", FALSE, 0, FXMEMMAPIOCtl}
50 };
51
52static int nrKnownDrivers = sizeof(knownDriver)/sizeof(WIN32DRV);
53
54//******************************************************************************
55//******************************************************************************
56void RegisterDevices()
57{
58 HMDeviceDriver *driver;
59 DWORD rc;
60
61 for(int i=0;i<nrKnownDrivers;i++)
62 {
63 driver = new HMDeviceDriver(knownDriver[i].szWin32Name,
64 knownDriver[i].szOS2Name,
65 knownDriver[i].fCreateFile,
66 knownDriver[i].devIOCtl);
67
68 rc = HMDeviceRegister(knownDriver[i].szWin32Name, driver);
69 if (rc != NO_ERROR) /* check for errors */
70 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n",
71 knownDriver[i].szWin32Name, rc));
72 }
73
74 //check registry for Odin driver plugin dlls
75 HKEY hkDrivers, hkDrvDll;
76
77 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
78 "System\\CurrentControlSet\\Services",
79 0, KEY_READ, &hkDrivers);
80
81 if(rc == 0) {
82 char szDllName[CCHMAXPATH];
83 char szKeyName[CCHMAXPATH];
84 char szDrvName[CCHMAXPATH];
85 DWORD dwType, dwSize;
86 int iSubKey = 0;
87
88 while(rc == 0) {
89 rc = RegEnumKeyA(hkDrivers, iSubKey++, szKeyName, sizeof(szKeyName));
90 if(rc) break;
91
92 rc = RegOpenKeyExA(hkDrivers, szKeyName,
93 0, KEY_READ, &hkDrvDll);
94 if(rc == 0) {
95 dwSize = sizeof(szDllName);
96 rc = RegQueryValueExA(hkDrvDll,
97 "DllName",
98 NULL,
99 &dwType,
100 (LPBYTE)szDllName,
101 &dwSize);
102
103 RegCloseKey(hkDrvDll);
104 if(rc == 0 && dwType == REG_SZ)
105 {
106 HINSTANCE hDrvDll = LoadLibraryA(szDllName);
107 if(hDrvDll) {
108 sprintf(szDrvName, "\\\\.\\%s", szKeyName);
109 driver = new HMCustomDriver(hDrvDll, szDrvName);
110
111 rc = HMDeviceRegister(szDrvName, driver);
112 if (rc != NO_ERROR) /* check for errors */
113 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n", szDrvName, rc));
114 }
115 }
116 rc = 0;
117 }
118 }
119 RegCloseKey(hkDrivers);
120 }
121
122 return;
123}
124//******************************************************************************
125//******************************************************************************
126HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName, LPSTR lpOS2DevName, BOOL fCreate,
127 WINIOCTL pDevIOCtl)
128 : HMDeviceKernelObjectClass(lpDeviceName)
129{
130 this->fCreateFile = fCreateFile;
131 this->szOS2Name = lpOS2DevName;
132 this->devIOCtl = pDevIOCtl;
133}
134//******************************************************************************
135//******************************************************************************
136HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName)
137 : HMDeviceKernelObjectClass(lpDeviceName)
138{
139}
140//******************************************************************************
141//******************************************************************************
142DWORD HMDeviceDriver::CreateFile (LPCSTR lpFileName,
143 PHMHANDLEDATA pHMHandleData,
144 PVOID lpSecurityAttributes,
145 PHMHANDLEDATA pHMHandleDataTemplate)
146{
147 APIRET rc;
148 HFILE hfFileHandle = 0L; /* Handle for file being manipulated */
149 ULONG ulAction = 0; /* Action taken by DosOpen */
150 ULONG sharetype = 0;
151
152 if(pHMHandleData->dwAccess & (GENERIC_READ | GENERIC_WRITE))
153 sharetype |= OPEN_ACCESS_READWRITE;
154 else
155 if(pHMHandleData->dwAccess & GENERIC_WRITE)
156 sharetype |= OPEN_ACCESS_WRITEONLY;
157
158 if(pHMHandleData->dwShare == 0)
159 sharetype |= OPEN_SHARE_DENYREADWRITE;
160 else
161 if(pHMHandleData->dwShare & (FILE_SHARE_READ | FILE_SHARE_WRITE))
162 sharetype |= OPEN_SHARE_DENYNONE;
163 else
164 if(pHMHandleData->dwShare & FILE_SHARE_WRITE)
165 sharetype |= OPEN_SHARE_DENYREAD;
166 else
167 if(pHMHandleData->dwShare & FILE_SHARE_READ)
168 sharetype |= OPEN_SHARE_DENYWRITE;
169
170 if(szOS2Name[0] == 0) {
171 pHMHandleData->hHMHandle = 0;
172 return (NO_ERROR);
173 }
174
175tryopen:
176 rc = DosOpen( szOS2Name, /* File path name */
177 &hfFileHandle, /* File handle */
178 &ulAction, /* Action taken */
179 0,
180 FILE_NORMAL,
181 FILE_OPEN,
182 sharetype,
183 0L); /* No extended attribute */
184
185 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
186 ULONG CurMaxFH;
187 LONG ReqCount = 32;
188
189 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
190 if(rc) {
191 dprintf(("DosSetRelMaxFH returned %d", rc));
192 return rc;
193 }
194 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
195 goto tryopen;
196 }
197
198 dprintf(("DosOpen %s returned %d\n", szOS2Name, rc));
199
200 if(rc == NO_ERROR) {
201 pHMHandleData->hHMHandle = hfFileHandle;
202 return (NO_ERROR);
203 }
204 else return(rc);
205}
206//******************************************************************************
207//******************************************************************************
208BOOL HMDeviceDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
209{
210 DWORD rc = 0;
211
212 if(pHMHandleData->hHMHandle) {
213 rc = DosClose(pHMHandleData->hHMHandle);
214 }
215 pHMHandleData->hHMHandle = 0;
216 return rc;
217}
218//******************************************************************************
219//******************************************************************************
220BOOL HMDeviceDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
221 LPVOID lpInBuffer, DWORD nInBufferSize,
222 LPVOID lpOutBuffer, DWORD nOutBufferSize,
223 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
224{
225 return devIOCtl(pHMHandleData->hHMHandle, dwIoControlCode, lpInBuffer, nInBufferSize,
226 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
227}
228//******************************************************************************
229//******************************************************************************
230static BOOL GpdDevIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
231{
232 ULONG port, val = 0;
233
234 if(fX86Init == FALSE) {
235 if(io_init() == 0)
236 fX86Init = TRUE;
237 else return(FALSE);
238 }
239
240 *lpBytesReturned = 0;
241
242 port = ((GENPORT_WRITE_INPUT *)lpInBuffer)->PortNumber;
243
244 switch((dwIoControlCode >> 2) & 0xFFF) {
245 case IOCTL_GPD_READ_PORT_UCHAR:
246 if(nOutBufferSize < sizeof(char))
247 return(FALSE);
248
249 val = c_inb(port);
250 *(char *)lpOutBuffer = val;
251 *lpBytesReturned = sizeof(char);
252 break;
253 case IOCTL_GPD_READ_PORT_USHORT:
254 if(nOutBufferSize < sizeof(USHORT))
255 return(FALSE);
256
257 val = c_inw(port);
258 *(USHORT *)lpOutBuffer = val;
259 *lpBytesReturned = sizeof(USHORT);
260 break;
261 case IOCTL_GPD_READ_PORT_ULONG:
262 if(nOutBufferSize < sizeof(ULONG))
263 return(FALSE);
264
265 val = c_inl(port);
266 *(ULONG *)lpOutBuffer = val;
267 *lpBytesReturned = sizeof(ULONG);
268 break;
269 case IOCTL_GPD_WRITE_PORT_UCHAR:
270 val = ((GENPORT_WRITE_INPUT *)lpInBuffer)->CharData;
271 c_outb(port, val);
272 break;
273 case IOCTL_GPD_WRITE_PORT_USHORT:
274 val = ((GENPORT_WRITE_INPUT *)lpInBuffer)->ShortData;
275 c_outw(port, val);
276 break;
277 case IOCTL_GPD_WRITE_PORT_ULONG:
278 val = ((GENPORT_WRITE_INPUT *)lpInBuffer)->LongData;
279 c_outl(port, val);
280 break;
281 default:
282 dprintf(("GpdDevIOCtl unknown func %X\n", (dwIoControlCode >> 2) & 0xFFF));
283 return(FALSE);
284 }
285
286 return(TRUE);
287}
288//******************************************************************************
289//******************************************************************************
290static BOOL MAPMEMIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
291{
292 PHYSICAL_MEMORY_INFO *meminfo = (PHYSICAL_MEMORY_INFO *)lpInBuffer;
293 struct map_ioctl memmap;
294
295 *lpBytesReturned = 0;
296
297 switch((dwIoControlCode >> 2) & 0xFFF) {
298 case IOCTL_MAPMEM_MAP_USER_PHYSICAL_MEMORY:
299 if(nInBufferSize != sizeof(PHYSICAL_MEMORY_INFO))
300 return(FALSE);
301
302 memmap.a.phys = meminfo->BusAddress.u.LowPart;
303 memmap.size = meminfo->Length;
304 dprintf(("DeviceIoControl map phys address %X length %X\n", memmap.a.phys, memmap.size));
305 if(mpioctl((HFILE)hDevice, IOCTL_MAP, &memmap) == -1) {
306 dprintf(("mpioctl failed!\n"));
307 return(FALSE);
308 }
309
310 dprintf(("DeviceIoControl map virt address = %X\n", memmap.a.user));
311 *(ULONG *)lpOutBuffer = (ULONG)memmap.a.user;
312 break;
313 case IOCTL_MAPMEM_UNMAP_USER_PHYSICAL_MEMORY:
314 dprintf(("Unmap mapping %X\n", *(ULONG *)lpInBuffer));
315 memmap.a.phys = *(ULONG *)lpInBuffer;
316 memmap.size = 0;
317 if(mpioctl((HFILE)hDevice, IOCTL_MAP, &memmap) == -1)
318 return(FALSE);
319 break;
320 default:
321 dprintf(("MAPMEMIOCtl unknown func %X\n", (dwIoControlCode >> 2) & 0xFFF));
322 return(FALSE);
323 }
324
325 return(TRUE);
326}
327//******************************************************************************
328//******************************************************************************
329static BOOL FXMEMMAPIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
330{
331 struct map_ioctl memmap;
332 MAPDEVREQUEST *vxdmem = (MAPDEVREQUEST *)lpInBuffer;
333
334 switch(dwIoControlCode) {
335 case 1:
336 break;
337 case 2:
338 memmap.a.phys = (DWORD)vxdmem->mdr_PhysicalAddress;
339 memmap.size = vxdmem->mdr_SizeInBytes;
340 dprintf(("DeviceIoControl map phys address %X length %X\n", memmap.a.phys, memmap.size));
341 if(mpioctl((HFILE)hDevice, IOCTL_MAP, &memmap) == -1) {
342 dprintf(("mpioctl failed!\n"));
343 return(FALSE);
344 }
345
346 dprintf(("DeviceIoControl map virt address = %X\n", memmap.a.user));
347 vxdmem->mdr_LinearAddress = (PVOID)memmap.a.user;
348 break;
349 default:
350 dprintf(("FXMEMMAPIOCtl unknown func %X\n", (dwIoControlCode >> 2) & 0xFFF));
351 return(FALSE);
352 }
353
354 return(TRUE);
355}
356//******************************************************************************
357//******************************************************************************
358HMCustomDriver::HMCustomDriver(HINSTANCE hInstance, LPCSTR lpDeviceName)
359 : HMDeviceDriver(lpDeviceName)
360{
361 hDrvDll = hInstance ;
362 *(ULONG *)&driverOpen = (ULONG)GetProcAddress(hDrvDll, "DrvOpen");
363 *(ULONG *)&driverClose = (ULONG)GetProcAddress(hDrvDll, "DrvClose");
364 *(ULONG *)&driverIOCtl = (ULONG)GetProcAddress(hDrvDll, "DrvIOCtl");
365}
366//******************************************************************************
367//******************************************************************************
368HMCustomDriver::~HMCustomDriver()
369{
370 FreeLibrary(hDrvDll);
371}
372//******************************************************************************
373//******************************************************************************
374DWORD HMCustomDriver::CreateFile (LPCSTR lpFileName,
375 PHMHANDLEDATA pHMHandleData,
376 PVOID lpSecurityAttributes,
377 PHMHANDLEDATA pHMHandleDataTemplate)
378{
379 pHMHandleData->hHMHandle = driverOpen(pHMHandleData->dwAccess, pHMHandleData->dwShare);
380 if(pHMHandleData->hHMHandle == 0) {
381 return 2;
382 }
383 return 0;
384}
385//******************************************************************************
386//******************************************************************************
387BOOL HMCustomDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
388{
389 if(pHMHandleData->hHMHandle) {
390 driverClose(pHMHandleData->hHMHandle);
391 }
392 pHMHandleData->hHMHandle = 0;
393 return TRUE;
394}
395//******************************************************************************
396//******************************************************************************
397BOOL HMCustomDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
398 LPVOID lpInBuffer, DWORD nInBufferSize,
399 LPVOID lpOutBuffer, DWORD nOutBufferSize,
400 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
401{
402 return driverIOCtl(pHMHandleData->hHMHandle, dwIoControlCode, lpInBuffer, nInBufferSize,
403 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
404}
405//******************************************************************************
406//******************************************************************************
407BOOL WIN32API QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
408{
409 QWORD time;
410 APIRET rc;
411
412 rc = DosTmrQueryTime(&time);
413 if(rc) {
414 dprintf(("DosTmrQueryTime returned %d\n", rc));
415 return(FALSE);
416 }
417 lpPerformanceCount->u.LowPart = time.ulLo;
418 lpPerformanceCount->u.HighPart = time.ulHi;
419 return(TRUE);
420}
421//******************************************************************************
422//******************************************************************************
423BOOL WIN32API QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)
424{
425 APIRET rc;
426 ULONG freq;
427
428 rc = DosTmrQueryFreq(&freq);
429 if(rc) {
430 dprintf(("DosTmrQueryFreq returned %d\n", rc));
431 return(FALSE);
432 }
433 lpFrequency->u.LowPart = freq;
434 lpFrequency->u.HighPart = 0;
435 dprintf2(("QueryPerformanceFrequency returned 0x%X%X\n", lpFrequency->u.HighPart, lpFrequency->u.LowPart));
436 return(TRUE);
437}
438//******************************************************************************
439//******************************************************************************
Note: See TracBrowser for help on using the repository browser.