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

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

update

File size: 22.0 KB
Line 
1/* $Id: hmdevio.cpp,v 1.22 2001-12-09 15:29:41 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 "cio.h"
30#include "map.h"
31#include "exceptutil.h"
32#include "oslibdos.h"
33
34#define DBG_LOCALLOG DBG_hmdevio
35#include "dbglocal.h"
36
37static BOOL fX86Init = FALSE;
38//SvL: Used in iccio.asm (how can you put these in the .asm data segment without messing things up?)
39ULONG ioentry = 0;
40USHORT gdt = 0;
41char devname[] = "/dev/fastio$";
42
43static BOOL GpdDevIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
44static BOOL MAPMEMIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
45static BOOL FXMEMMAPIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
46static BOOL VPCIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
47
48static WIN32DRV knownDriver[] =
49 {{"\\\\.\\GpdDev", "", TRUE, 666, GpdDevIOCtl},
50 { "\\\\.\\MAPMEM", "PMAP$", FALSE, 0, MAPMEMIOCtl},
51 { "FXMEMMAP.VXD", "PMAP$", FALSE, 0, FXMEMMAPIOCtl},
52 };
53
54static int nrKnownDrivers = sizeof(knownDriver)/sizeof(WIN32DRV);
55BOOL fVirtualPC = FALSE;
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
77 //check registry for Odin driver plugin dlls
78 HKEY hkDrivers, hkDrvDll;
79
80 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
81 "System\\CurrentControlSet\\Services",
82 0, KEY_READ, &hkDrivers);
83
84 if(rc == 0) {
85 char szDllName[CCHMAXPATH];
86 char szKeyName[CCHMAXPATH];
87 char szDrvName[CCHMAXPATH];
88 DWORD dwType, dwSize;
89 int iSubKey = 0;
90
91 while(rc == 0) {
92 rc = RegEnumKeyA(hkDrivers, iSubKey++, szKeyName, sizeof(szKeyName));
93 if(rc) break;
94
95 rc = RegOpenKeyExA(hkDrivers, szKeyName,
96 0, KEY_READ, &hkDrvDll);
97 if(rc == 0) {
98 dwSize = sizeof(szDllName);
99 rc = RegQueryValueExA(hkDrvDll,
100 "DllName",
101 NULL,
102 &dwType,
103 (LPBYTE)szDllName,
104 &dwSize);
105
106 RegCloseKey(hkDrvDll);
107 if(rc == 0 && dwType == REG_SZ)
108 {
109 HINSTANCE hDrvDll = LoadLibraryA(szDllName);
110 if(hDrvDll)
111 {
112 sprintf(szDrvName, "\\\\.\\%s", szKeyName);
113 driver = new HMCustomDriver(hDrvDll, szDrvName);
114
115 rc = HMDeviceRegister(szDrvName, driver);
116 if (rc != NO_ERROR) /* check for errors */
117 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n", szDrvName, rc));
118
119 // @@@PH
120 // there should be an symbolic link:
121 // "\\.\drvname$" -> "drvname$"
122 }
123 }
124 rc = 0;
125 }
126 }
127 RegCloseKey(hkDrivers);
128 }
129
130 return;
131}
132//******************************************************************************
133//******************************************************************************
134BOOL WIN32API RegisterCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose,
135 PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead,
136 PFNDRVWRITE pfnDriverWrite, LPCSTR lpDeviceName)
137{
138 HMDeviceDriver *driver;
139 DWORD rc;
140
141 driver = new HMCustomDriver(pfnDriverOpen, pfnDriverClose, pfnDriverIOCtl, pfnDriverRead, pfnDriverWrite, lpDeviceName);
142 if(driver == NULL) {
143 DebugInt3();
144 return FALSE;
145 }
146 rc = HMDeviceRegister((LPSTR)lpDeviceName, driver);
147 if (rc != NO_ERROR) { /* check for errors */
148 dprintf(("KERNEL32:RegisterDevices: registering %s failed with %u.\n", lpDeviceName, rc));
149 return FALSE;
150 }
151 return TRUE;
152}
153//******************************************************************************
154//******************************************************************************
155HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName, LPSTR lpOS2DevName, BOOL fCreate,
156 WINIOCTL pDevIOCtl)
157 : HMDeviceKernelObjectClass(lpDeviceName)
158{
159 this->fCreateFile = fCreateFile;
160 this->szOS2Name = lpOS2DevName;
161 this->devIOCtl = pDevIOCtl;
162}
163//******************************************************************************
164//******************************************************************************
165HMDeviceDriver::HMDeviceDriver(LPCSTR lpDeviceName)
166 : HMDeviceKernelObjectClass(lpDeviceName)
167{
168}
169//******************************************************************************
170//******************************************************************************
171DWORD HMDeviceDriver::CreateFile (LPCSTR lpFileName,
172 PHMHANDLEDATA pHMHandleData,
173 PVOID lpSecurityAttributes,
174 PHMHANDLEDATA pHMHandleDataTemplate)
175{
176 APIRET rc;
177 HFILE hfFileHandle = 0L; /* Handle for file being manipulated */
178 ULONG ulAction = 0; /* Action taken by DosOpen */
179 ULONG sharetype = 0;
180
181 if(pHMHandleData->dwAccess & (GENERIC_READ | GENERIC_WRITE))
182 sharetype |= OPEN_ACCESS_READWRITE;
183 else
184 if(pHMHandleData->dwAccess & GENERIC_WRITE)
185 sharetype |= OPEN_ACCESS_WRITEONLY;
186
187 if(pHMHandleData->dwShare == 0)
188 sharetype |= OPEN_SHARE_DENYREADWRITE;
189 else
190 if(pHMHandleData->dwShare & (FILE_SHARE_READ | FILE_SHARE_WRITE))
191 sharetype |= OPEN_SHARE_DENYNONE;
192 else
193 if(pHMHandleData->dwShare & FILE_SHARE_WRITE)
194 sharetype |= OPEN_SHARE_DENYREAD;
195 else
196 if(pHMHandleData->dwShare & FILE_SHARE_READ)
197 sharetype |= OPEN_SHARE_DENYWRITE;
198
199 if(szOS2Name[0] == 0) {
200 pHMHandleData->hHMHandle = 0;
201 return (NO_ERROR);
202 }
203
204tryopen:
205 rc = DosOpen( szOS2Name, /* File path name */
206 &hfFileHandle, /* File handle */
207 &ulAction, /* Action taken */
208 0,
209 FILE_NORMAL,
210 FILE_OPEN,
211 sharetype,
212 0L); /* No extended attribute */
213
214 if(rc == ERROR_TOO_MANY_OPEN_FILES) {
215 ULONG CurMaxFH;
216 LONG ReqCount = 32;
217
218 rc = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
219 if(rc) {
220 dprintf(("DosSetRelMaxFH returned %d", rc));
221 return error2WinError(rc);
222 }
223 dprintf(("DosOpen failed -> increased nr open files to %d", CurMaxFH));
224 goto tryopen;
225 }
226
227 dprintf(("DosOpen %s returned %d\n", szOS2Name, rc));
228
229 if(rc == NO_ERROR)
230 {
231 pHMHandleData->hHMHandle = hfFileHandle;
232 return (NO_ERROR);
233 }
234 else
235 return(error2WinError(rc));
236}
237//******************************************************************************
238//******************************************************************************
239BOOL HMDeviceDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
240{
241 DWORD rc = 0;
242
243 if(pHMHandleData->hHMHandle) {
244 rc = DosClose(pHMHandleData->hHMHandle);
245 }
246 pHMHandleData->hHMHandle = 0;
247 return rc;
248}
249//******************************************************************************
250//******************************************************************************
251BOOL HMDeviceDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
252 LPVOID lpInBuffer, DWORD nInBufferSize,
253 LPVOID lpOutBuffer, DWORD nOutBufferSize,
254 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
255{
256 return devIOCtl(pHMHandleData->hHMHandle, dwIoControlCode, lpInBuffer, nInBufferSize,
257 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
258}
259//******************************************************************************
260//******************************************************************************
261static BOOL GpdDevIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
262{
263 ULONG port, val = 0;
264
265 if(fX86Init == FALSE) {
266 if(io_init() == 0)
267 fX86Init = TRUE;
268 else return(FALSE);
269 }
270
271 *lpBytesReturned = 0;
272
273 port = ((GENPORT_WRITE_INPUT *)lpInBuffer)->PortNumber;
274
275 switch((dwIoControlCode >> 2) & 0xFFF) {
276 case IOCTL_GPD_READ_PORT_UCHAR:
277 if(nOutBufferSize < sizeof(char))
278 return(FALSE);
279
280 val = c_inb(port);
281 *(char *)lpOutBuffer = val;
282 *lpBytesReturned = sizeof(char);
283 break;
284 case IOCTL_GPD_READ_PORT_USHORT:
285 if(nOutBufferSize < sizeof(USHORT))
286 return(FALSE);
287
288 val = c_inw(port);
289 *(USHORT *)lpOutBuffer = val;
290 *lpBytesReturned = sizeof(USHORT);
291 break;
292 case IOCTL_GPD_READ_PORT_ULONG:
293 if(nOutBufferSize < sizeof(ULONG))
294 return(FALSE);
295
296 val = c_inl(port);
297 *(ULONG *)lpOutBuffer = val;
298 *lpBytesReturned = sizeof(ULONG);
299 break;
300 case IOCTL_GPD_WRITE_PORT_UCHAR:
301 val = ((GENPORT_WRITE_INPUT *)lpInBuffer)->CharData;
302 c_outb(port, val);
303 break;
304 case IOCTL_GPD_WRITE_PORT_USHORT:
305 val = ((GENPORT_WRITE_INPUT *)lpInBuffer)->ShortData;
306 c_outw(port, val);
307 break;
308 case IOCTL_GPD_WRITE_PORT_ULONG:
309 val = ((GENPORT_WRITE_INPUT *)lpInBuffer)->LongData;
310 c_outl(port, val);
311 break;
312 default:
313 dprintf(("GpdDevIOCtl unknown func %X\n", (dwIoControlCode >> 2) & 0xFFF));
314 return(FALSE);
315 }
316
317 return(TRUE);
318}
319//******************************************************************************
320//******************************************************************************
321static BOOL MAPMEMIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
322{
323 PHYSICAL_MEMORY_INFO *meminfo = (PHYSICAL_MEMORY_INFO *)lpInBuffer;
324 struct map_ioctl memmap;
325
326 *lpBytesReturned = 0;
327
328 switch((dwIoControlCode >> 2) & 0xFFF) {
329 case IOCTL_MAPMEM_MAP_USER_PHYSICAL_MEMORY:
330 if(nInBufferSize != sizeof(PHYSICAL_MEMORY_INFO))
331 return(FALSE);
332
333 memmap.a.phys = meminfo->BusAddress.u.LowPart;
334 memmap.size = meminfo->Length;
335 dprintf(("DeviceIoControl map phys address %X length %X\n", memmap.a.phys, memmap.size));
336 if(mpioctl((HFILE)hDevice, IOCTL_MAP, &memmap) == -1) {
337 dprintf(("mpioctl failed!\n"));
338 return(FALSE);
339 }
340
341 dprintf(("DeviceIoControl map virt address = %X\n", memmap.a.user));
342 *(ULONG *)lpOutBuffer = (ULONG)memmap.a.user;
343 break;
344 case IOCTL_MAPMEM_UNMAP_USER_PHYSICAL_MEMORY:
345 dprintf(("Unmap mapping %X\n", *(ULONG *)lpInBuffer));
346 memmap.a.phys = *(ULONG *)lpInBuffer;
347 memmap.size = 0;
348 if(mpioctl((HFILE)hDevice, IOCTL_MAP, &memmap) == -1)
349 return(FALSE);
350 break;
351 default:
352 dprintf(("MAPMEMIOCtl unknown func %X\n", (dwIoControlCode >> 2) & 0xFFF));
353 return(FALSE);
354 }
355
356 return(TRUE);
357}
358//******************************************************************************
359//******************************************************************************
360static BOOL FXMEMMAPIOCtl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
361{
362 struct map_ioctl memmap;
363 MAPDEVREQUEST *vxdmem = (MAPDEVREQUEST *)lpInBuffer;
364
365 switch(dwIoControlCode) {
366 case 1:
367 break;
368 case 2:
369 memmap.a.phys = (DWORD)vxdmem->mdr_PhysicalAddress;
370 memmap.size = vxdmem->mdr_SizeInBytes;
371 dprintf(("DeviceIoControl map phys address %X length %X\n", memmap.a.phys, memmap.size));
372 if(mpioctl((HFILE)hDevice, IOCTL_MAP, &memmap) == -1) {
373 dprintf(("mpioctl failed!\n"));
374 return(FALSE);
375 }
376
377 dprintf(("DeviceIoControl map virt address = %X\n", memmap.a.user));
378 vxdmem->mdr_LinearAddress = (PVOID)memmap.a.user;
379 break;
380 default:
381 dprintf(("FXMEMMAPIOCtl unknown func %X\n", (dwIoControlCode >> 2) & 0xFFF));
382 return(FALSE);
383 }
384
385 return(TRUE);
386}
387//******************************************************************************
388//******************************************************************************
389HMCustomDriver::HMCustomDriver(HINSTANCE hInstance, LPCSTR lpDeviceName)
390 : HMDeviceDriver(lpDeviceName), hDrvDll(0)
391{
392 hDrvDll = hInstance ;
393 pfnDriverOpen = (PFNDRVOPEN) GetProcAddress(hDrvDll, "DrvOpen");
394 pfnDriverClose = (PFNDRVCLOSE)GetProcAddress(hDrvDll, "DrvClose");
395 pfnDriverRead = (PFNDRVREAD) GetProcAddress(hDrvDll, "DrvRead");
396 pfnDriverWrite = (PFNDRVWRITE)GetProcAddress(hDrvDll, "DrvWrite");
397 pfnDriverIOCtl = (PFNDRVIOCTL)GetProcAddress(hDrvDll, "DrvIOCtl");
398}
399//******************************************************************************
400//******************************************************************************
401HMCustomDriver::HMCustomDriver(PFNDRVOPEN pfnDriverOpen, PFNDRVCLOSE pfnDriverClose,
402 PFNDRVIOCTL pfnDriverIOCtl, PFNDRVREAD pfnDriverRead,
403 PFNDRVWRITE pfnDriverWrite, LPCSTR lpDeviceName)
404 : HMDeviceDriver(lpDeviceName), hDrvDll(0)
405{
406 if(!pfnDriverOpen || !pfnDriverClose) {
407 DebugInt3();
408 }
409 this->pfnDriverOpen = pfnDriverOpen;
410 this->pfnDriverClose = pfnDriverClose;
411 this->pfnDriverIOCtl = pfnDriverIOCtl;
412 this->pfnDriverRead = pfnDriverRead;
413 this->pfnDriverWrite = pfnDriverWrite;
414}
415//******************************************************************************
416//******************************************************************************
417HMCustomDriver::~HMCustomDriver()
418{
419 if(hDrvDll) FreeLibrary(hDrvDll);
420}
421//******************************************************************************
422//******************************************************************************
423DWORD HMCustomDriver::CreateFile (LPCSTR lpFileName,
424 PHMHANDLEDATA pHMHandleData,
425 PVOID lpSecurityAttributes,
426 PHMHANDLEDATA pHMHandleDataTemplate)
427{
428 pHMHandleData->hHMHandle = pfnDriverOpen(pHMHandleData->dwAccess, pHMHandleData->dwShare);
429 if(pHMHandleData->hHMHandle == INVALID_HANDLE_VALUE_W) {
430 return GetLastError();
431 }
432 return ERROR_SUCCESS_W;
433}
434//******************************************************************************
435//******************************************************************************
436BOOL HMCustomDriver::CloseHandle(PHMHANDLEDATA pHMHandleData)
437{
438 if(pHMHandleData->hHMHandle) {
439 pfnDriverClose(pHMHandleData->hHMHandle);
440 }
441 pHMHandleData->hHMHandle = 0;
442 return TRUE;
443}
444//******************************************************************************
445//******************************************************************************
446BOOL HMCustomDriver::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
447 LPVOID lpInBuffer, DWORD nInBufferSize,
448 LPVOID lpOutBuffer, DWORD nOutBufferSize,
449 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
450{
451 BOOL ret;
452
453 if(pfnDriverIOCtl == NULL) {
454 dprintf(("HMCustomDriver::DeviceIoControl: pfnDriverIOCtl == NULL"));
455 ::SetLastError(ERROR_INVALID_FUNCTION_W);
456 return FALSE;
457 }
458
459 ret = pfnDriverIOCtl(pHMHandleData->hHMHandle, dwIoControlCode, lpInBuffer, nInBufferSize,
460 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
461 dprintf(("DeviceIoControl %x returned %d", dwIoControlCode, ret));
462 return ret;
463}
464/*****************************************************************************
465 * Name : BOOL HMCustomDriver::ReadFile
466 * Purpose : read data from handle / device
467 * Parameters: PHMHANDLEDATA pHMHandleData,
468 * LPCVOID lpBuffer,
469 * DWORD nNumberOfBytesToRead,
470 * LPDWORD lpNumberOfBytesRead,
471 * LPOVERLAPPED lpOverlapped
472 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
473 * Variables :
474 * Result : Boolean
475 * Remark :
476 * Status :
477 *
478 * Author : SvL
479 *****************************************************************************/
480
481BOOL HMCustomDriver::ReadFile(PHMHANDLEDATA pHMHandleData,
482 LPCVOID lpBuffer,
483 DWORD nNumberOfBytesToRead,
484 LPDWORD lpNumberOfBytesRead,
485 LPOVERLAPPED lpOverlapped,
486 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
487{
488 BOOL ret;
489
490 if(pfnDriverRead == NULL) {
491 dprintf(("HMCustomDriver::ReadFile: pfnDriverRead == NULL"));
492 ::SetLastError(ERROR_INVALID_FUNCTION_W);
493 return FALSE;
494 }
495 ret = pfnDriverRead(pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead,
496 lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine);
497 dprintf(("pfnDriverRead %x %x %x %x %x %x returned %x", pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead,
498 lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, ret));
499 return ret;
500}
501/*****************************************************************************
502 * Name : BOOL HMCustomDriver::WriteFile
503 * Purpose : write data to handle / device
504 * Parameters: PHMHANDLEDATA pHMHandleData,
505 * LPCVOID lpBuffer,
506 * DWORD nNumberOfBytesToWrite,
507 * LPDWORD lpNumberOfBytesWritten,
508 * LPOVERLAPPED lpOverlapped
509 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
510 * Variables :
511 * Result : Boolean
512 * Remark :
513 * Status :
514 *
515 * Author : SvL
516 *****************************************************************************/
517
518BOOL HMCustomDriver::WriteFile(PHMHANDLEDATA pHMHandleData,
519 LPCVOID lpBuffer,
520 DWORD nNumberOfBytesToWrite,
521 LPDWORD lpNumberOfBytesWritten,
522 LPOVERLAPPED lpOverlapped,
523 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
524{
525 BOOL ret;
526
527 if(pfnDriverWrite == NULL) {
528 dprintf(("HMCustomDriver::WriteFile: pfnDriverWrite == NULL"));
529 ::SetLastError(ERROR_INVALID_FUNCTION_W);
530 return FALSE;
531 }
532 ret = pfnDriverWrite(pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite,
533 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine);
534 dprintf(("pfnDriverWrite %x %x %x %x %x %x returned %x", pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite,
535 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, ret));
536 return ret;
537}
538//******************************************************************************
539//******************************************************************************
540BOOL WIN32API QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
541{
542 QWORD time;
543 APIRET rc;
544
545 rc = DosTmrQueryTime(&time);
546 if(rc) {
547 dprintf(("DosTmrQueryTime returned %d\n", rc));
548 return(FALSE);
549 }
550 lpPerformanceCount->u.LowPart = time.ulLo;
551 lpPerformanceCount->u.HighPart = time.ulHi;
552 return(TRUE);
553}
554//******************************************************************************
555//******************************************************************************
556BOOL WIN32API QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)
557{
558 APIRET rc;
559 ULONG freq;
560
561 rc = DosTmrQueryFreq(&freq);
562 if(rc) {
563 dprintf(("DosTmrQueryFreq returned %d\n", rc));
564 return(FALSE);
565 }
566 lpFrequency->u.LowPart = freq;
567 lpFrequency->u.HighPart = 0;
568 dprintf2(("QueryPerformanceFrequency returned 0x%X%X\n", lpFrequency->u.HighPart, lpFrequency->u.LowPart));
569 return(TRUE);
570}
571//******************************************************************************
572//******************************************************************************
Note: See TracBrowser for help on using the repository browser.