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

Last change on this file since 5757 was 5757, checked in by sandervl, 24 years ago

added virtualpc driver emulation

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