]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/MAI/bios_emulator/scitech/src/pm/win32/pm.c
USB: This patch fix readl in ohci swap reg access.
[people/ms/u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / win32 / pm.c
CommitLineData
c7de829c
WD
1/****************************************************************************
2*
3* SciTech OS Portability Manager Library
4*
5* ========================================================================
6*
7* The contents of this file are subject to the SciTech MGL Public
8* License Version 1.0 (the "License"); you may not use this file
9* except in compliance with the License. You may obtain a copy of
10* the License at http://www.scitechsoft.com/mgl-license.txt
11*
12* Software distributed under the License is distributed on an
13* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14* implied. See the License for the specific language governing
15* rights and limitations under the License.
16*
17* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18*
19* The Initial Developer of the Original Code is SciTech Software, Inc.
20* All Rights Reserved.
21*
22* ========================================================================
23*
24* Language: ANSI C
25* Environment: Win32
26*
27* Description: Implementation for the OS Portability Manager Library, which
28* contains functions to implement OS specific services in a
29* generic, cross platform API. Porting the OS Portability
30* Manager library is the first step to porting any SciTech
31* products to a new platform.
32*
33****************************************************************************/
34
35#define WIN32_LEAN_AND_MEAN
36#define STRICT
37#include <windows.h>
38#include <mmsystem.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <direct.h>
43#include "pmapi.h"
44#include "drvlib/os/os.h"
45#include "pm_help.h"
46
47/*--------------------------- Global variables ----------------------------*/
48
49ibool _PM_haveWinNT; /* True if we are running on NT */
50static uint VESABuf_len = 1024; /* Length of the VESABuf buffer */
51static void *VESABuf_ptr = NULL;/* Near pointer to VESABuf */
52static uint VESABuf_rseg; /* Real mode segment of VESABuf */
53static uint VESABuf_roff; /* Real mode offset of VESABuf */
54HANDLE _PM_hDevice = NULL; /* Handle to Win32 VxD */
55static ibool inited = false; /* Flags if we are initialised */
56static void (PMAPIP fatalErrorCleanup)(void) = NULL;
57
58static char *szMachineNameKey = "System\\CurrentControlSet\\control\\ComputerName\\ComputerName";
59static char *szMachineNameKeyNT = "System\\CurrentControlSet\\control\\ComputerName\\ActiveComputerName";
60static char *szMachineName = "ComputerName";
61
62/*----------------------------- Implementation ----------------------------*/
63
64/* Macro to check for a valid, loaded version of PMHELP. We check this
65 * on demand when we need these services rather than when PM_init() is
66 * called because if we are running on DirectDraw we don't need PMHELP.VXD.
67 */
68
69#define CHECK_FOR_PMHELP() \
70{ \
71 if (_PM_hDevice == INVALID_HANDLE_VALUE) \
8bde7f77
WD
72 if (_PM_haveWinNT) \
73 PM_fatalError("Unable to connect to PMHELP.SYS or SDDHELP.SYS!"); \
74 else \
75 PM_fatalError("Unable to connect to PMHELP.VXD or SDDHELP.VXD!"); \
c7de829c
WD
76}
77
78/****************************************************************************
79REMARKS:
80Initialise the PM library and connect to our helper device driver. If we
81cannot connect to our helper device driver, we bail out with an error
82message. Our Windows 9x VxD is dynamically loadable, so it can be loaded
83after the system has started.
84****************************************************************************/
85void PMAPI PM_init(void)
86{
87 DWORD inBuf[1]; /* Buffer to receive data from VxD */
88 DWORD outBuf[1]; /* Buffer to receive data from VxD */
89 DWORD count; /* Count of bytes returned from VxD */
90 char cntPath[PM_MAX_PATH];
91 char *env;
92
93 /* Create a file handle for the static VxD if possible, otherwise
94 * dynamically load the PMHELP helper VxD. Note that if an old version
95 * of SDD is loaded, we use the PMHELP VxD instead.
96 */
97 if (!inited) {
8bde7f77
WD
98 /* Determine if we are running under Windows NT or not and
99 * set the global OS type variable.
100 */
101 _PM_haveWinNT = false;
102 if ((GetVersion() & 0x80000000UL) == 0)
103 _PM_haveWinNT = true;
104 ___drv_os_type = (_PM_haveWinNT) ? _OS_WINNT : _OS_WIN95;
105
106 /* Now try to connect to SDDHELP.VXD or SDDHELP.SYS */
107 _PM_hDevice = CreateFile(SDDHELP_MODULE_PATH, 0,0,0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);
108 if (_PM_hDevice != INVALID_HANDLE_VALUE) {
109 if (!DeviceIoControl(_PM_hDevice, PMHELP_GETVER32, NULL, 0,
110 outBuf, sizeof(outBuf), &count, NULL) || outBuf[0] < PMHELP_VERSION) {
111 /* Old version of SDDHELP loaded, so use PMHELP instead */
112 CloseHandle(_PM_hDevice);
113 _PM_hDevice = INVALID_HANDLE_VALUE;
114 }
115 }
116 if (_PM_hDevice == INVALID_HANDLE_VALUE) {
117 /* First try to see if there is a currently loaded PMHELP driver.
118 * This is usually the case when we are running under Windows NT/2K.
119 */
120 _PM_hDevice = CreateFile(PMHELP_MODULE_PATH, 0,0,0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);
121 if (_PM_hDevice == INVALID_HANDLE_VALUE) {
122 /* The driver was not staticly loaded, so try creating a file handle
123 * to a dynamic version of the VxD if possible. Note that on WinNT/2K we
124 * cannot support dynamically loading the drivers.
125 */
126 _PM_hDevice = CreateFile(PMHELP_VXD_PATH, 0,0,0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);
127 }
128 }
129 if (_PM_hDevice != INVALID_HANDLE_VALUE) {
130 /* Call the driver to determine the version number */
131 if (!DeviceIoControl(_PM_hDevice, PMHELP_GETVER32, inBuf, sizeof(inBuf),
132 outBuf, sizeof(outBuf), &count, NULL) || outBuf[0] < PMHELP_VERSION) {
133 if (_PM_haveWinNT)
134 PM_fatalError("Older version of PMHELP.SYS found!");
135 else
136 PM_fatalError("Older version of PMHELP.VXD found!");
137 }
138
139 /* Now set the current path inside the VxD so it knows what the
140 * current directory is for loading Nucleus drivers.
141 */
142 inBuf[0] = (ulong)PM_getCurrentPath(cntPath,sizeof(cntPath));
143 if (!DeviceIoControl(_PM_hDevice, PMHELP_SETCNTPATH32, inBuf, sizeof(inBuf), outBuf, sizeof(outBuf), &count, NULL))
144 PM_fatalError("Unable to set VxD current path!");
145
146 /* Now pass down the NUCLEUS_PATH environment variable to the device
147 * driver so it can use this value if it is found.
148 */
149 if ((env = getenv("NUCLEUS_PATH")) != NULL) {
150 inBuf[0] = (ulong)env;
151 if (!DeviceIoControl(_PM_hDevice, PMHELP_SETNUCLEUSPATH32, inBuf, sizeof(inBuf), outBuf, sizeof(outBuf), &count, NULL))
152 PM_fatalError("Unable to set VxD Nucleus path!");
153 }
154
155 /* Enable IOPL for ring-3 code by default if driver is present */
156 if (_PM_haveWinNT)
157 PM_setIOPL(3);
158 }
159
160 /* Indicate that we have been initialised */
161 inited = true;
162 }
c7de829c
WD
163}
164
165/****************************************************************************
166REMARKS:
167We do have BIOS access under Windows 9x, but not under Windows NT.
168****************************************************************************/
169int PMAPI PM_setIOPL(
170 int iopl)
171{
172 DWORD inBuf[1]; /* Buffer to receive data from VxD */
173 DWORD outBuf[1]; /* Buffer to receive data from VxD */
174 DWORD count; /* Count of bytes returned from VxD */
175 static int cntIOPL = 0;
176 int oldIOPL = cntIOPL;
177
178 /* Enable I/O by adjusting the I/O permissions map on Windows NT */
179 if (_PM_haveWinNT) {
8bde7f77
WD
180 CHECK_FOR_PMHELP();
181 if (iopl == 3)
182 DeviceIoControl(_PM_hDevice, PMHELP_ENABLERING3IOPL, inBuf, sizeof(inBuf),outBuf, sizeof(outBuf), &count, NULL);
183 else
184 DeviceIoControl(_PM_hDevice, PMHELP_DISABLERING3IOPL, inBuf, sizeof(inBuf),outBuf, sizeof(outBuf), &count, NULL);
185 cntIOPL = iopl;
186 return oldIOPL;
187 }
c7de829c
WD
188
189 /* We always have IOPL on Windows 9x */
190 return 3;
191}
192
193/****************************************************************************
194REMARKS:
195We do have BIOS access under Windows 9x, but not under Windows NT.
196****************************************************************************/
197ibool PMAPI PM_haveBIOSAccess(void)
198{
199 if (PM_getOSType() == _OS_WINNT)
8bde7f77 200 return false;
c7de829c 201 else
8bde7f77 202 return _PM_hDevice != INVALID_HANDLE_VALUE;
c7de829c
WD
203}
204
205/****************************************************************************
206REMARKS:
207Return the operating system type identifier.
208****************************************************************************/
209long PMAPI PM_getOSType(void)
210{
211 if ((GetVersion() & 0x80000000UL) == 0)
8bde7f77 212 return ___drv_os_type = _OS_WINNT;
c7de829c 213 else
8bde7f77 214 return ___drv_os_type = _OS_WIN95;
c7de829c
WD
215}
216
217/****************************************************************************
218REMARKS:
219Return the runtime type identifier.
220****************************************************************************/
221int PMAPI PM_getModeType(void)
222{
223 return PM_386;
224}
225
226/****************************************************************************
227REMARKS:
228Add a file directory separator to the end of the filename.
229****************************************************************************/
230void PMAPI PM_backslash(
231 char *s)
232{
233 uint pos = strlen(s);
234 if (s[pos-1] != '\\') {
8bde7f77
WD
235 s[pos] = '\\';
236 s[pos+1] = '\0';
237 }
c7de829c
WD
238}
239
240/****************************************************************************
241REMARKS:
242Add a user defined PM_fatalError cleanup function.
243****************************************************************************/
244void PMAPI PM_setFatalErrorCleanup(
245 void (PMAPIP cleanup)(void))
246{
247 fatalErrorCleanup = cleanup;
248}
249
250/****************************************************************************
251REMARKS:
252Report a fatal error condition and halt the program.
253****************************************************************************/
254void PMAPI PM_fatalError(
255 const char *msg)
256{
257 if (fatalErrorCleanup)
8bde7f77 258 fatalErrorCleanup();
c7de829c
WD
259 MessageBox(NULL,msg,"Fatal Error!", MB_ICONEXCLAMATION);
260 exit(1);
261}
262
263/****************************************************************************
264REMARKS:
265Allocate the real mode VESA transfer buffer for communicating with the BIOS.
266****************************************************************************/
267void * PMAPI PM_getVESABuf(
268 uint *len,
269 uint *rseg,
270 uint *roff)
271{
272 DWORD outBuf[4]; /* Buffer to receive data from VxD */
273 DWORD count; /* Count of bytes returned from VxD */
274
275 /* We require the helper VxD to be loaded staticly in order to support
276 * the VESA transfer buffer. We do not support dynamically allocating
277 * real mode memory buffers from Win32 programs (we need a 16-bit DLL
278 * for this, and Windows 9x becomes very unstable if you free the
279 * memory blocks out of order).
280 */
281 if (!inited)
8bde7f77 282 PM_init();
c7de829c 283 if (!VESABuf_ptr) {
8bde7f77
WD
284 CHECK_FOR_PMHELP();
285 if (DeviceIoControl(_PM_hDevice, PMHELP_GETVESABUF32, NULL, 0,
286 outBuf, sizeof(outBuf), &count, NULL)) {
287 if (!outBuf[0])
288 return NULL;
289 VESABuf_ptr = (void*)outBuf[0];
290 VESABuf_len = outBuf[1];
291 VESABuf_rseg = outBuf[2];
292 VESABuf_roff = outBuf[3];
293 }
294 }
c7de829c
WD
295 *len = VESABuf_len;
296 *rseg = VESABuf_rseg;
297 *roff = VESABuf_roff;
298 return VESABuf_ptr;
299}
300
301/****************************************************************************
302REMARKS:
303Check if a key has been pressed.
304****************************************************************************/
305int PMAPI PM_kbhit(void)
306{
307 /* Not used in Windows */
308 return true;
309}
310
311/****************************************************************************
312REMARKS:
313Wait for and return the next keypress.
314****************************************************************************/
315int PMAPI PM_getch(void)
316{
317 /* Not used in Windows */
318 return 0xD;
319}
320
321/****************************************************************************
322REMARKS:
323Set the location of the OS console cursor.
324****************************************************************************/
325void PM_setOSCursorLocation(
326 int x,
327 int y)
328{
329 /* Nothing to do for Windows */
330 (void)x;
331 (void)y;
332}
333
334/****************************************************************************
335REMARKS:
336Set the width of the OS console.
337****************************************************************************/
338void PM_setOSScreenWidth(
339 int width,
340 int height)
341{
342 /* Nothing to do for Windows */
343 (void)width;
344 (void)height;
345}
346
347/****************************************************************************
348REMARKS:
349Set the real time clock handler (used for software stereo modes).
350****************************************************************************/
351ibool PMAPI PM_setRealTimeClockHandler(
352 PM_intHandler ih,
353 int frequency)
354{
355 /* We do not support this from Win32 programs. Rather the VxD handles
356 * this stuff it will take care of hooking the stereo flip functions at
357 * the VxD level.
358 */
359 (void)ih;
360 (void)frequency;
361 return false;
362}
363
364/****************************************************************************
365REMARKS:
366Set the real time clock frequency (for stereo modes).
367****************************************************************************/
368void PMAPI PM_setRealTimeClockFrequency(
369 int frequency)
370{
371 /* Not supported under Win32 */
372 (void)frequency;
373}
374
375/****************************************************************************
376REMARKS:
377Restore the original real time clock handler.
378****************************************************************************/
379void PMAPI PM_restoreRealTimeClockHandler(void)
380{
381 /* Not supported under Win32 */
382}
383
384/****************************************************************************
385REMARKS:
386Return the current operating system path or working directory.
387****************************************************************************/
388char * PMAPI PM_getCurrentPath(
389 char *path,
390 int maxLen)
391{
392 return getcwd(path,maxLen);
393}
394
395/****************************************************************************
396REMARKS:
397Query a string from the registry (extended version).
398****************************************************************************/
399static ibool REG_queryStringEx(
400 HKEY hKey,
401 const char *szValue,
402 char *value,
403 ulong size)
404{
405 DWORD type;
406
407 if (RegQueryValueEx(hKey,(PCHAR)szValue,(PDWORD)NULL,(PDWORD)&type,(LPBYTE)value,(PDWORD)&size) == ERROR_SUCCESS)
8bde7f77 408 return true;
c7de829c
WD
409 return false;
410}
411
412/****************************************************************************
413REMARKS:
414Query a string from the registry.
415****************************************************************************/
416static ibool REG_queryString(
417 const char *szKey,
418 const char *szValue,
419 char *value,
420 DWORD size)
421{
422 HKEY hKey;
423 ibool status = false;
424
425 memset(value,0,sizeof(value));
426 if (RegOpenKey(HKEY_LOCAL_MACHINE,szKey,&hKey) == ERROR_SUCCESS) {
8bde7f77
WD
427 status = REG_queryStringEx(hKey,szValue,value,size);
428 RegCloseKey(hKey);
429 }
c7de829c
WD
430 return status;
431}
432
433/****************************************************************************
434REMARKS:
435Return the drive letter for the boot drive.
436****************************************************************************/
437char PMAPI PM_getBootDrive(void)
438{
439 static char path[256];
440 GetSystemDirectory(path,sizeof(path));
441 return path[0];
442}
443
444/****************************************************************************
445REMARKS:
446Return the path to the VBE/AF driver files.
447****************************************************************************/
448const char * PMAPI PM_getVBEAFPath(void)
449{
450 return "c:\\";
451}
452
453/****************************************************************************
454REMARKS:
455Return the path to the Nucleus driver files.
456****************************************************************************/
457const char * PMAPI PM_getNucleusPath(void)
458{
459 static char path[256];
460 char *env;
461
462 if ((env = getenv("NUCLEUS_PATH")) != NULL)
8bde7f77 463 return env;
c7de829c
WD
464 GetSystemDirectory(path,sizeof(path));
465 strcat(path,"\\nucleus");
466 return path;
467}
468
469/****************************************************************************
470REMARKS:
471Return the path to the Nucleus configuration files.
472****************************************************************************/
473const char * PMAPI PM_getNucleusConfigPath(void)
474{
475 static char path[256];
476 strcpy(path,PM_getNucleusPath());
477 PM_backslash(path);
478 strcat(path,"config");
479 return path;
480}
481
482/****************************************************************************
483REMARKS:
484Return a unique identifier for the machine if possible.
485****************************************************************************/
486const char * PMAPI PM_getUniqueID(void)
487{
488 return PM_getMachineName();
489}
490
491/****************************************************************************
492REMARKS:
493Get the name of the machine on the network.
494****************************************************************************/
495const char * PMAPI PM_getMachineName(void)
496{
497 static char name[256];
498
499 if (REG_queryString(szMachineNameKey,szMachineName,name,sizeof(name)))
8bde7f77 500 return name;
c7de829c 501 if (REG_queryString(szMachineNameKeyNT,szMachineName,name,sizeof(name)))
8bde7f77 502 return name;
c7de829c
WD
503 return "Unknown";
504}
505
506/****************************************************************************
507REMARKS:
508Return a pointer to the real mode BIOS data area.
509****************************************************************************/
510void * PMAPI PM_getBIOSPointer(void)
511{
512 if (_PM_haveWinNT) {
8bde7f77 513 /* On Windows NT we have to map it physically directly */
c7de829c 514 return PM_mapPhysicalAddr(0x400, 0x1000, true);
8bde7f77 515 }
c7de829c 516 else {
8bde7f77
WD
517 /* For Windows 9x we can access this memory directly */
518 return (void*)0x400;
519 }
c7de829c
WD
520}
521
522/****************************************************************************
523REMARKS:
524Return a pointer to 0xA0000 physical VGA graphics framebuffer.
525****************************************************************************/
526void * PMAPI PM_getA0000Pointer(void)
527{
528 if (_PM_haveWinNT) {
8bde7f77 529 /* On Windows NT we have to map it physically directly */
c7de829c 530 return PM_mapPhysicalAddr(0xA0000, 0x0FFFF, false);
8bde7f77 531 }
c7de829c 532 else {
8bde7f77
WD
533 /* Always use the 0xA0000 linear address so that we will use
534 * whatever page table mappings are set up for us (ie: for virtual
535 * bank switching.
536 */
537 return (void*)0xA0000;
538 }
c7de829c
WD
539}
540
541/****************************************************************************
542REMARKS:
543Map a physical address to a linear address in the callers process.
544****************************************************************************/
545void * PMAPI PM_mapPhysicalAddr(
546 ulong base,
547 ulong limit,
548 ibool isCached)
549{
550 DWORD inBuf[3]; /* Buffer to send data to VxD */
551 DWORD outBuf[1]; /* Buffer to receive data from VxD */
552 DWORD count; /* Count of bytes returned from VxD */
553
554 if (!inited)
8bde7f77 555 PM_init();
c7de829c
WD
556 inBuf[0] = base;
557 inBuf[1] = limit;
558 inBuf[2] = isCached;
559 CHECK_FOR_PMHELP();
560 if (DeviceIoControl(_PM_hDevice, PMHELP_MAPPHYS32, inBuf, sizeof(inBuf),
8bde7f77
WD
561 outBuf, sizeof(outBuf), &count, NULL))
562 return (void*)outBuf[0];
c7de829c
WD
563 return NULL;
564}
565
566/****************************************************************************
567REMARKS:
568Free a physical address mapping allocated by PM_mapPhysicalAddr.
569****************************************************************************/
570void PMAPI PM_freePhysicalAddr(
571 void *ptr,
572 ulong limit)
573{
574 /* We never free the mappings under Win32 (the VxD tracks them and
575 * reissues the same mappings until the system is rebooted).
576 */
577 (void)ptr;
578 (void)limit;
579}
580
581/****************************************************************************
582REMARKS:
583Find the physical address of a linear memory address in current process.
584****************************************************************************/
585ulong PMAPI PM_getPhysicalAddr(
586 void *p)
587{
588 DWORD inBuf[1]; /* Buffer to send data to VxD */
589 DWORD outBuf[1]; /* Buffer to receive data from VxD */
590 DWORD count; /* Count of bytes returned from VxD */
591
592 if (!inited)
8bde7f77 593 PM_init();
c7de829c
WD
594 inBuf[0] = (ulong)p;
595 CHECK_FOR_PMHELP();
596 if (DeviceIoControl(_PM_hDevice, PMHELP_GETPHYSICALADDR32, inBuf, sizeof(inBuf),
8bde7f77
WD
597 outBuf, sizeof(outBuf), &count, NULL))
598 return outBuf[0];
c7de829c
WD
599 return 0xFFFFFFFFUL;
600}
601
602/****************************************************************************
603REMARKS:
604Find the physical address of a linear memory address in current process.
605****************************************************************************/
606ibool PMAPI PM_getPhysicalAddrRange(
607 void *p,
608 ulong length,
609 ulong *physAddress)
610{
611 DWORD inBuf[3]; /* Buffer to send data to VxD */
612 DWORD outBuf[1]; /* Buffer to receive data from VxD */
613 DWORD count; /* Count of bytes returned from VxD */
614
615 if (!inited)
8bde7f77 616 PM_init();
c7de829c
WD
617 inBuf[0] = (ulong)p;
618 inBuf[1] = (ulong)length;
619 inBuf[2] = (ulong)physAddress;
620 CHECK_FOR_PMHELP();
621 if (DeviceIoControl(_PM_hDevice, PMHELP_GETPHYSICALADDRRANGE32, inBuf, sizeof(inBuf),
8bde7f77
WD
622 outBuf, sizeof(outBuf), &count, NULL))
623 return outBuf[0];
c7de829c
WD
624 return false;
625}
626
627/****************************************************************************
628REMARKS:
629Sleep for the specified number of milliseconds.
630****************************************************************************/
631void PMAPI PM_sleep(
632 ulong milliseconds)
633{
634 Sleep(milliseconds);
635}
636
637/****************************************************************************
638REMARKS:
639Return the base I/O port for the specified COM port.
640****************************************************************************/
641int PMAPI PM_getCOMPort(int port)
642{
8bde7f77
WD
643 /* TODO: Re-code this to determine real values using the Plug and Play */
644 /* manager for the OS. */
c7de829c 645 switch (port) {
8bde7f77
WD
646 case 0: return 0x3F8;
647 case 1: return 0x2F8;
648 case 2: return 0x3E8;
649 case 3: return 0x2E8;
650 }
c7de829c
WD
651 return 0;
652}
653
654/****************************************************************************
655REMARKS:
656Return the base I/O port for the specified LPT port.
657****************************************************************************/
658int PMAPI PM_getLPTPort(int port)
659{
8bde7f77
WD
660 /* TODO: Re-code this to determine real values using the Plug and Play */
661 /* manager for the OS. */
c7de829c 662 switch (port) {
8bde7f77
WD
663 case 0: return 0x3BC;
664 case 1: return 0x378;
665 case 2: return 0x278;
666 }
c7de829c
WD
667 return 0;
668}
669
670/****************************************************************************
671REMARKS:
672Allocate a block of shared memory. For Win9x we allocate shared memory
673as locked, global memory that is accessible from any memory context
674(including interrupt time context), which allows us to load our important
675data structure and code such that we can access it directly from a ring
6760 interrupt context.
677****************************************************************************/
678void * PMAPI PM_mallocShared(
679 long size)
680{
681 DWORD inBuf[1]; /* Buffer to send data to VxD */
682 DWORD outBuf[1]; /* Buffer to receive data from VxD */
683 DWORD count; /* Count of bytes returned from VxD */
684
685 inBuf[0] = size;
686 CHECK_FOR_PMHELP();
687 if (DeviceIoControl(_PM_hDevice, PMHELP_MALLOCSHARED32, inBuf, sizeof(inBuf),
8bde7f77
WD
688 outBuf, sizeof(outBuf), &count, NULL))
689 return (void*)outBuf[0];
c7de829c
WD
690 return NULL;
691}
692
693/****************************************************************************
694REMARKS:
695Free a block of shared memory.
696****************************************************************************/
697void PMAPI PM_freeShared(
698 void *ptr)
699{
700 DWORD inBuf[1]; /* Buffer to send data to VxD */
701
702 inBuf[0] = (ulong)ptr;
703 CHECK_FOR_PMHELP();
704 DeviceIoControl(_PM_hDevice, PMHELP_FREESHARED32, inBuf, sizeof(inBuf), NULL, 0, NULL, NULL);
705}
706
707/****************************************************************************
708REMARKS:
709Map a linear memory address to the calling process address space. The
710address will have been allocated in another process using the
711PM_mapPhysicalAddr function.
712****************************************************************************/
713void * PMAPI PM_mapToProcess(
714 void *base,
715 ulong limit)
716{
717 (void)base;
718 (void)limit;
719 return base;
720}
721
722/****************************************************************************
723REMARKS:
724Map a real mode pointer to a protected mode pointer.
725****************************************************************************/
726void * PMAPI PM_mapRealPointer(
727 uint r_seg,
728 uint r_off)
729{
730 return (void*)(MK_PHYS(r_seg,r_off));
731}
732
733/****************************************************************************
734REMARKS:
735Allocate a block of real mode memory
736****************************************************************************/
737void * PMAPI PM_allocRealSeg(
738 uint size,
739 uint *r_seg,
740 uint *r_off)
741{
742 /* We do not support dynamically allocating real mode memory buffers
743 * from Win32 programs (we need a 16-bit DLL for this, and Windows
744 * 9x becomes very unstable if you free the memory blocks out of order).
745 */
746 (void)size;
747 (void)r_seg;
748 (void)r_off;
749 return NULL;
750}
751
752/****************************************************************************
753REMARKS:
754Free a block of real mode memory.
755****************************************************************************/
756void PMAPI PM_freeRealSeg(
757 void *mem)
758{
759 /* Not supported in Windows */
760 (void)mem;
761}
762
763/****************************************************************************
764REMARKS:
765Issue a real mode interrupt (parameters in DPMI compatible structure)
766****************************************************************************/
767void PMAPI DPMI_int86(
768 int intno,
769 DPMI_regs *regs)
770{
771 DWORD inBuf[2]; /* Buffer to send data to VxD */
772 DWORD count; /* Count of bytes returned from VxD */
773
774 if (!inited)
8bde7f77 775 PM_init();
c7de829c
WD
776 inBuf[0] = intno;
777 inBuf[1] = (ulong)regs;
778 CHECK_FOR_PMHELP();
779 DeviceIoControl(_PM_hDevice, PMHELP_DPMIINT8632, inBuf, sizeof(inBuf),
8bde7f77 780 NULL, 0, &count, NULL);
c7de829c
WD
781}
782
783/****************************************************************************
784REMARKS:
785Issue a real mode interrupt.
786****************************************************************************/
787int PMAPI PM_int86(
788 int intno,
789 RMREGS *in,
790 RMREGS *out)
791{
792 DWORD inBuf[3]; /* Buffer to send data to VxD */
793 DWORD outBuf[1]; /* Buffer to receive data from VxD */
794 DWORD count; /* Count of bytes returned from VxD */
795
796 if (!inited)
8bde7f77 797 PM_init();
c7de829c
WD
798 inBuf[0] = intno;
799 inBuf[1] = (ulong)in;
800 inBuf[2] = (ulong)out;
801 CHECK_FOR_PMHELP();
802 if (DeviceIoControl(_PM_hDevice, PMHELP_INT8632, inBuf, sizeof(inBuf),
8bde7f77
WD
803 outBuf, sizeof(outBuf), &count, NULL))
804 return outBuf[0];
c7de829c
WD
805 return 0;
806}
807
808/****************************************************************************
809REMARKS:
810Issue a real mode interrupt.
811****************************************************************************/
812int PMAPI PM_int86x(
813 int intno,
814 RMREGS *in,
815 RMREGS *out,
816 RMSREGS *sregs)
817{
818 DWORD inBuf[4]; /* Buffer to send data to VxD */
819 DWORD outBuf[1]; /* Buffer to receive data from VxD */
820 DWORD count; /* Count of bytes returned from VxD */
821
822 if (!inited)
8bde7f77 823 PM_init();
c7de829c
WD
824 inBuf[0] = intno;
825 inBuf[1] = (ulong)in;
826 inBuf[2] = (ulong)out;
827 inBuf[3] = (ulong)sregs;
828 CHECK_FOR_PMHELP();
829 if (DeviceIoControl(_PM_hDevice, PMHELP_INT86X32, inBuf, sizeof(inBuf),
8bde7f77
WD
830 outBuf, sizeof(outBuf), &count, NULL))
831 return outBuf[0];
c7de829c
WD
832 return 0;
833}
834
835/****************************************************************************
836REMARKS:
837Call a real mode far function.
838****************************************************************************/
839void PMAPI PM_callRealMode(
840 uint seg,
841 uint off,
842 RMREGS *in,
843 RMSREGS *sregs)
844{
845 DWORD inBuf[4]; /* Buffer to send data to VxD */
846 DWORD count; /* Count of bytes returned from VxD */
847
848 if (!inited)
8bde7f77 849 PM_init();
c7de829c
WD
850 inBuf[0] = seg;
851 inBuf[1] = off;
852 inBuf[2] = (ulong)in;
853 inBuf[3] = (ulong)sregs;
854 CHECK_FOR_PMHELP();
855 DeviceIoControl(_PM_hDevice, PMHELP_CALLREALMODE32, inBuf, sizeof(inBuf),
8bde7f77 856 NULL, 0, &count, NULL);
c7de829c
WD
857}
858
859/****************************************************************************
860REMARKS:
861Return the amount of available memory.
862****************************************************************************/
863void PMAPI PM_availableMemory(
864 ulong *physical,
865 ulong *total)
866{
867 /* We don't support this under Win32 at the moment */
868 *physical = *total = 0;
869}
870
871/****************************************************************************
872REMARKS:
873Allocate a block of locked, physical memory for DMA operations.
874****************************************************************************/
875void * PMAPI PM_allocLockedMem(
876 uint size,
877 ulong *physAddr,
878 ibool contiguous,
879 ibool below16M)
880{
881 DWORD inBuf[4]; /* Buffer to send data to VxD */
882 DWORD outBuf[1]; /* Buffer to receive data from VxD */
883 DWORD count; /* Count of bytes returned from VxD */
884
885 if (!inited)
8bde7f77 886 PM_init();
c7de829c
WD
887 inBuf[0] = size;
888 inBuf[1] = (ulong)physAddr;
889 inBuf[2] = (ulong)contiguous;
890 inBuf[3] = (ulong)below16M;
891 CHECK_FOR_PMHELP();
892 if (DeviceIoControl(_PM_hDevice, PMHELP_ALLOCLOCKED32, inBuf, sizeof(inBuf),
8bde7f77
WD
893 outBuf, sizeof(outBuf), &count, NULL))
894 return (void*)outBuf[0];
c7de829c
WD
895 return NULL;
896}
897
898/****************************************************************************
899REMARKS:
900Free a block of locked physical memory.
901****************************************************************************/
902void PMAPI PM_freeLockedMem(
903 void *p,
904 uint size,
905 ibool contiguous)
906{
907 DWORD inBuf[3]; /* Buffer to send data to VxD */
908 DWORD count; /* Count of bytes returned from VxD */
909
910 if (!inited)
8bde7f77 911 PM_init();
c7de829c
WD
912 inBuf[0] = (ulong)p;
913 inBuf[1] = size;
914 inBuf[2] = contiguous;
915 CHECK_FOR_PMHELP();
916 DeviceIoControl(_PM_hDevice, PMHELP_FREELOCKED32, inBuf, sizeof(inBuf),
8bde7f77 917 NULL, 0, &count, NULL);
c7de829c
WD
918}
919
920/****************************************************************************
921REMARKS:
922Allocates a page aligned and page sized block of memory
923****************************************************************************/
924void * PMAPI PM_allocPage(
925 ibool locked)
926{
927 DWORD inBuf[2]; /* Buffer to send data to VxD */
928 DWORD outBuf[1]; /* Buffer to receive data from VxD */
929 DWORD count; /* Count of bytes returned from VxD */
930
931 if (!inited)
8bde7f77 932 PM_init();
c7de829c
WD
933 inBuf[0] = locked;
934 CHECK_FOR_PMHELP();
935 if (DeviceIoControl(_PM_hDevice, PMHELP_ALLOCPAGE32, inBuf, sizeof(inBuf),
8bde7f77
WD
936 outBuf, sizeof(outBuf), &count, NULL))
937 return (void*)outBuf[0];
c7de829c
WD
938 return NULL;
939}
940
941/****************************************************************************
942REMARKS:
943Free a page aligned and page sized block of memory
944****************************************************************************/
945void PMAPI PM_freePage(
946 void *p)
947{
948 DWORD inBuf[1]; /* Buffer to send data to VxD */
949 DWORD count; /* Count of bytes returned from VxD */
950
951 if (!inited)
8bde7f77 952 PM_init();
c7de829c
WD
953 inBuf[0] = (ulong)p;
954 CHECK_FOR_PMHELP();
955 DeviceIoControl(_PM_hDevice, PMHELP_FREEPAGE32, inBuf, sizeof(inBuf),
8bde7f77 956 NULL, 0, &count, NULL);
c7de829c
WD
957}
958
959/****************************************************************************
960REMARKS:
961Lock linear memory so it won't be paged.
962****************************************************************************/
963int PMAPI PM_lockDataPages(void *p,uint len,PM_lockHandle *lh)
964{
965 DWORD inBuf[2]; /* Buffer to send data to VxD */
966 DWORD outBuf[1]; /* Buffer to receive data from VxD */
967 DWORD count; /* Count of bytes returned from VxD */
968
969 inBuf[0] = (ulong)p;
970 inBuf[1] = len;
971 inBuf[2] = (ulong)lh;
972 CHECK_FOR_PMHELP();
973 if (DeviceIoControl(_PM_hDevice, PMHELP_LOCKDATAPAGES32, inBuf, sizeof(inBuf),
8bde7f77
WD
974 outBuf, sizeof(outBuf), &count, NULL))
975 return outBuf[0];
c7de829c
WD
976 return 0;
977}
978
979/****************************************************************************
980REMARKS:
981Unlock linear memory so it won't be paged.
982****************************************************************************/
983int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh)
984{
985 DWORD inBuf[2]; /* Buffer to send data to VxD */
986 DWORD outBuf[1]; /* Buffer to receive data from VxD */
987 DWORD count; /* Count of bytes returned from VxD */
988
989 inBuf[0] = (ulong)p;
990 inBuf[1] = len;
991 inBuf[2] = (ulong)lh;
992 CHECK_FOR_PMHELP();
993 if (DeviceIoControl(_PM_hDevice, PMHELP_UNLOCKDATAPAGES32, inBuf, sizeof(inBuf),
8bde7f77
WD
994 outBuf, sizeof(outBuf), &count, NULL))
995 return outBuf[0];
c7de829c
WD
996 return 0;
997}
998
999/****************************************************************************
1000REMARKS:
1001Lock linear memory so it won't be paged.
1002****************************************************************************/
1003int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
1004{
1005 DWORD inBuf[2]; /* Buffer to send data to VxD */
1006 DWORD outBuf[1]; /* Buffer to receive data from VxD */
1007 DWORD count; /* Count of bytes returned from VxD */
1008
1009 inBuf[0] = (ulong)p;
1010 inBuf[1] = len;
1011 inBuf[2] = (ulong)lh;
1012 CHECK_FOR_PMHELP();
1013 if (DeviceIoControl(_PM_hDevice, PMHELP_LOCKCODEPAGES32, inBuf, sizeof(inBuf),
8bde7f77
WD
1014 outBuf, sizeof(outBuf), &count, NULL))
1015 return outBuf[0];
c7de829c
WD
1016 return 0;
1017}
1018
1019/****************************************************************************
1020REMARKS:
1021Unlock linear memory so it won't be paged.
1022****************************************************************************/
1023int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
1024{
1025 DWORD inBuf[2]; /* Buffer to send data to VxD */
1026 DWORD outBuf[1]; /* Buffer to receive data from VxD */
1027 DWORD count; /* Count of bytes returned from VxD */
1028
1029 inBuf[0] = (ulong)p;
1030 inBuf[1] = len;
1031 inBuf[2] = (ulong)lh;
1032 CHECK_FOR_PMHELP();
1033 if (DeviceIoControl(_PM_hDevice, PMHELP_UNLOCKCODEPAGES32, inBuf, sizeof(inBuf),
8bde7f77
WD
1034 outBuf, sizeof(outBuf), &count, NULL))
1035 return outBuf[0];
c7de829c
WD
1036 return 0;
1037}
1038
1039/****************************************************************************
1040REMARKS:
1041Call the VBE/Core software interrupt to change display banks.
1042****************************************************************************/
1043void PMAPI PM_setBankA(
1044 int bank)
1045{
1046 RMREGS regs;
1047 regs.x.ax = 0x4F05;
1048 regs.x.bx = 0x0000;
1049 regs.x.dx = bank;
1050 PM_int86(0x10,&regs,&regs);
1051}
1052
1053/****************************************************************************
1054REMARKS:
1055Call the VBE/Core software interrupt to change display banks.
1056****************************************************************************/
1057void PMAPI PM_setBankAB(
1058 int bank)
1059{
1060 RMREGS regs;
1061 regs.x.ax = 0x4F05;
1062 regs.x.bx = 0x0000;
1063 regs.x.dx = bank;
1064 PM_int86(0x10,&regs,&regs);
1065 regs.x.ax = 0x4F05;
1066 regs.x.bx = 0x0001;
1067 regs.x.dx = bank;
1068 PM_int86(0x10,&regs,&regs);
1069}
1070
1071/****************************************************************************
1072REMARKS:
1073Call the VBE/Core software interrupt to change display start address.
1074****************************************************************************/
1075void PMAPI PM_setCRTStart(
1076 int x,
1077 int y,
1078 int waitVRT)
1079{
1080 RMREGS regs;
1081 regs.x.ax = 0x4F07;
1082 regs.x.bx = waitVRT;
1083 regs.x.cx = x;
1084 regs.x.dx = y;
1085 PM_int86(0x10,&regs,&regs);
1086}
1087
1088/****************************************************************************
1089REMARKS:
1090Enable write combining for the memory region.
1091****************************************************************************/
1092ibool PMAPI PM_enableWriteCombine(
1093 ulong base,
1094 ulong length,
1095 uint type)
1096{
1097 DWORD inBuf[3]; /* Buffer to send data to VxD */
1098 DWORD outBuf[1]; /* Buffer to receive data from VxD */
1099 DWORD count; /* Count of bytes returned from VxD */
1100
1101 if (!inited)
8bde7f77 1102 PM_init();
c7de829c
WD
1103 inBuf[0] = base;
1104 inBuf[1] = length;
1105 inBuf[2] = type;
1106 CHECK_FOR_PMHELP();
1107 if (DeviceIoControl(_PM_hDevice, PMHELP_ENABLELFBCOMB32, inBuf, sizeof(inBuf),
8bde7f77
WD
1108 outBuf, sizeof(outBuf), &count, NULL))
1109 return outBuf[0];
c7de829c
WD
1110 return false;
1111}
1112
1113/****************************************************************************
1114REMARKS:
1115Get the page directory base register value
1116****************************************************************************/
1117ulong PMAPI _PM_getPDB(void)
1118{
1119 DWORD outBuf[1]; /* Buffer to receive data from VxD */
1120 DWORD count; /* Count of bytes returned from VxD */
1121
1122 CHECK_FOR_PMHELP();
1123 if (DeviceIoControl(_PM_hDevice, PMHELP_GETPDB32, NULL, 0,
8bde7f77
WD
1124 outBuf, sizeof(outBuf), &count, NULL))
1125 return outBuf[0];
c7de829c
WD
1126 return 0;
1127}
1128
1129/****************************************************************************
1130REMARKS:
1131Flush the translation lookaside buffer.
1132****************************************************************************/
1133void PMAPI PM_flushTLB(void)
1134{
1135 CHECK_FOR_PMHELP();
1136 DeviceIoControl(_PM_hDevice, PMHELP_FLUSHTLB32, NULL, 0, NULL, 0, NULL, NULL);
1137}
1138
1139/****************************************************************************
1140REMARKS:
1141Execute the POST on the secondary BIOS for a controller.
1142****************************************************************************/
1143ibool PMAPI PM_doBIOSPOST(
1144 ushort axVal,
1145 ulong BIOSPhysAddr,
1146 void *mappedBIOS,
1147 ulong BIOSLen)
1148{
1149 /* This is never done by Win32 programs, but rather done by the VxD
1150 * when the system boots.
1151 */
1152 (void)axVal;
1153 (void)BIOSPhysAddr;
1154 (void)mappedBIOS;
1155 (void)BIOSLen;
1156 return false;
1157}
1158
1159/****************************************************************************
1160REMARKS:
1161Load an OS specific shared library or DLL. If the OS does not support
1162shared libraries, simply return NULL.
1163****************************************************************************/
1164PM_MODULE PMAPI PM_loadLibrary(
1165 const char *szDLLName)
1166{
1167 return (PM_MODULE)LoadLibrary(szDLLName);
1168}
1169
1170/****************************************************************************
1171REMARKS:
1172Get the address of a named procedure from a shared library.
1173****************************************************************************/
1174void * PMAPI PM_getProcAddress(
1175 PM_MODULE hModule,
1176 const char *szProcName)
1177{
1178 return (void*)GetProcAddress((HINSTANCE)hModule,szProcName);
1179}
1180
1181/****************************************************************************
1182REMARKS:
1183Unload a shared library.
1184****************************************************************************/
1185void PMAPI PM_freeLibrary(
1186 PM_MODULE hModule)
1187{
1188 FreeLibrary((HINSTANCE)hModule);
1189}
1190
1191/****************************************************************************
1192REMARKS:
1193Internal function to convert the find data to the generic interface.
1194****************************************************************************/
1195static void convertFindData(
1196 PM_findData *findData,
1197 WIN32_FIND_DATA *blk)
1198{
1199 ulong dwSize = findData->dwSize;
1200
1201 memset(findData,0,findData->dwSize);
1202 findData->dwSize = dwSize;
1203 if (blk->dwFileAttributes & FILE_ATTRIBUTE_READONLY)
8bde7f77 1204 findData->attrib |= PM_FILE_READONLY;
c7de829c 1205 if (blk->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
8bde7f77 1206 findData->attrib |= PM_FILE_DIRECTORY;
c7de829c 1207 if (blk->dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
8bde7f77 1208 findData->attrib |= PM_FILE_ARCHIVE;
c7de829c 1209 if (blk->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
8bde7f77 1210 findData->attrib |= PM_FILE_HIDDEN;
c7de829c 1211 if (blk->dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
8bde7f77 1212 findData->attrib |= PM_FILE_SYSTEM;
c7de829c
WD
1213 findData->sizeLo = blk->nFileSizeLow;
1214 findData->sizeHi = blk->nFileSizeHigh;
1215 strncpy(findData->name,blk->cFileName,PM_MAX_PATH);
1216 findData->name[PM_MAX_PATH-1] = 0;
1217}
1218
1219/****************************************************************************
1220REMARKS:
1221Function to find the first file matching a search criteria in a directory.
1222****************************************************************************/
1223void *PMAPI PM_findFirstFile(
1224 const char *filename,
1225 PM_findData *findData)
1226{
1227 WIN32_FIND_DATA blk;
1228 HANDLE hfile;
1229
1230 if ((hfile = FindFirstFile(filename,&blk)) != INVALID_HANDLE_VALUE) {
8bde7f77
WD
1231 convertFindData(findData,&blk);
1232 return (void*)hfile;
1233 }
c7de829c
WD
1234 return PM_FILE_INVALID;
1235}
1236
1237/****************************************************************************
1238REMARKS:
1239Function to find the next file matching a search criteria in a directory.
1240****************************************************************************/
1241ibool PMAPI PM_findNextFile(
1242 void *handle,
1243 PM_findData *findData)
1244{
1245 WIN32_FIND_DATA blk;
1246
1247 if (FindNextFile((HANDLE)handle,&blk)) {
8bde7f77
WD
1248 convertFindData(findData,&blk);
1249 return true;
1250 }
c7de829c
WD
1251 return false;
1252}
1253
1254/****************************************************************************
1255REMARKS:
1256Function to close the find process
1257****************************************************************************/
1258void PMAPI PM_findClose(
1259 void *handle)
1260{
1261 FindClose((HANDLE)handle);
1262}
1263
1264/****************************************************************************
1265REMARKS:
1266Function to determine if a drive is a valid drive or not. Under Unix this
1267function will return false for anything except a value of 3 (considered
1268the root drive, and equivalent to C: for non-Unix systems). The drive
1269numbering is:
1270
1271 1 - Drive A:
1272 2 - Drive B:
1273 3 - Drive C:
1274 etc
1275
1276****************************************************************************/
1277ibool PMAPI PM_driveValid(
1278 char drive)
1279{
1280 char buf[5];
1281 int type;
1282
1283 sprintf(buf,"%c:\\", drive);
1284 return ((type = GetDriveType(buf)) != 0 && type != 1);
1285}
1286
1287/****************************************************************************
1288REMARKS:
1289Function to get the current working directory for the specififed drive.
1290Under Unix this will always return the current working directory regardless
1291of what the value of 'drive' is.
1292****************************************************************************/
1293void PMAPI PM_getdcwd(
1294 int drive,
1295 char *dir,
1296 int len)
1297{
8bde7f77
WD
1298 /* NT stores the current directory for drive N in the magic environment */
1299 /* variable =N: so we simply look for that environment variable. */
c7de829c
WD
1300 char envname[4];
1301
1302 envname[0] = '=';
1303 envname[1] = drive - 1 + 'A';
1304 envname[2] = ':';
1305 envname[3] = '\0';
1306 if (GetEnvironmentVariable(envname,dir,len) == 0) {
8bde7f77
WD
1307 /* The current directory or the drive has not been set yet, so */
1308 /* simply set it to the root. */
1309 dir[0] = envname[1];
1310 dir[1] = ':';
1311 dir[2] = '\\';
1312 dir[3] = '\0';
1313 SetEnvironmentVariable(envname,dir);
1314 }
c7de829c
WD
1315}
1316
1317/****************************************************************************
1318REMARKS:
1319Function to change the file attributes for a specific file.
1320****************************************************************************/
1321void PMAPI PM_setFileAttr(
1322 const char *filename,
1323 uint attrib)
1324{
1325 DWORD attr = 0;
1326
1327 if (attrib & PM_FILE_READONLY)
8bde7f77 1328 attr |= FILE_ATTRIBUTE_READONLY;
c7de829c 1329 if (attrib & PM_FILE_ARCHIVE)
8bde7f77 1330 attr |= FILE_ATTRIBUTE_ARCHIVE;
c7de829c 1331 if (attrib & PM_FILE_HIDDEN)
8bde7f77 1332 attr |= FILE_ATTRIBUTE_HIDDEN;
c7de829c 1333 if (attrib & PM_FILE_SYSTEM)
8bde7f77 1334 attr |= FILE_ATTRIBUTE_SYSTEM;
c7de829c
WD
1335 SetFileAttributes((LPSTR)filename, attr);
1336}
1337
1338/****************************************************************************
1339REMARKS:
1340Function to get the file attributes for a specific file.
1341****************************************************************************/
1342uint PMAPI PM_getFileAttr(
1343 const char *filename)
1344{
1345 DWORD attr = GetFileAttributes(filename);
1346 uint attrib = 0;
1347
1348 if (attr & FILE_ATTRIBUTE_READONLY)
8bde7f77 1349 attrib |= PM_FILE_READONLY;
c7de829c 1350 if (attr & FILE_ATTRIBUTE_ARCHIVE)
8bde7f77 1351 attrib |= PM_FILE_ARCHIVE;
c7de829c 1352 if (attr & FILE_ATTRIBUTE_HIDDEN)
8bde7f77 1353 attrib |= PM_FILE_HIDDEN;
c7de829c 1354 if (attr & FILE_ATTRIBUTE_SYSTEM)
8bde7f77 1355 attrib |= PM_FILE_SYSTEM;
c7de829c
WD
1356 return attrib;
1357}
1358
1359/****************************************************************************
1360REMARKS:
1361Function to create a directory.
1362****************************************************************************/
1363ibool PMAPI PM_mkdir(
1364 const char *filename)
1365{
1366 return CreateDirectory(filename,NULL);
1367}
1368
1369/****************************************************************************
1370REMARKS:
1371Function to remove a directory.
1372****************************************************************************/
1373ibool PMAPI PM_rmdir(
1374 const char *filename)
1375{
1376 return RemoveDirectory(filename);
1377}
1378
1379/****************************************************************************
1380REMARKS:
1381Function to get the file time and date for a specific file.
1382****************************************************************************/
1383ibool PMAPI PM_getFileTime(
1384 const char *filename,
1385 ibool gmTime,
1386 PM_time *time)
1387{
1388 HFILE f;
1389 OFSTRUCT of;
1390 FILETIME utcTime,localTime;
1391 SYSTEMTIME sysTime;
1392 ibool status = false;
1393
1394 of.cBytes = sizeof(of);
1395 if ((f = OpenFile(filename,&of,OF_READ)) == HFILE_ERROR)
8bde7f77 1396 return false;
c7de829c 1397 if (!GetFileTime((HANDLE)f,NULL,NULL,&utcTime))
8bde7f77 1398 goto Exit;
c7de829c 1399 if (!gmTime) {
8bde7f77
WD
1400 if (!FileTimeToLocalFileTime(&utcTime,&localTime))
1401 goto Exit;
1402 }
c7de829c 1403 else
8bde7f77 1404 localTime = utcTime;
c7de829c 1405 if (!FileTimeToSystemTime(&localTime,&sysTime))
8bde7f77 1406 goto Exit;
c7de829c
WD
1407 time->year = sysTime.wYear;
1408 time->mon = sysTime.wMonth-1;
1409 time->day = sysTime.wYear;
1410 time->hour = sysTime.wHour;
1411 time->min = sysTime.wMinute;
1412 time->sec = sysTime.wSecond;
1413 status = true;
1414
1415Exit:
1416 CloseHandle((HANDLE)f);
1417 return status;
1418}
1419
1420/****************************************************************************
1421REMARKS:
1422Function to set the file time and date for a specific file.
1423****************************************************************************/
1424ibool PMAPI PM_setFileTime(
1425 const char *filename,
1426 ibool gmTime,
1427 PM_time *time)
1428{
1429 HFILE f;
1430 OFSTRUCT of;
1431 FILETIME utcTime,localTime;
1432 SYSTEMTIME sysTime;
1433 ibool status = false;
1434
1435 of.cBytes = sizeof(of);
1436 if ((f = OpenFile(filename,&of,OF_WRITE)) == HFILE_ERROR)
8bde7f77 1437 return false;
c7de829c
WD
1438 sysTime.wYear = time->year;
1439 sysTime.wMonth = time->mon+1;
1440 sysTime.wYear = time->day;
1441 sysTime.wHour = time->hour;
1442 sysTime.wMinute = time->min;
1443 sysTime.wSecond = time->sec;
1444 if (!SystemTimeToFileTime(&sysTime,&localTime))
8bde7f77 1445 goto Exit;
c7de829c 1446 if (!gmTime) {
8bde7f77
WD
1447 if (!LocalFileTimeToFileTime(&localTime,&utcTime))
1448 goto Exit;
1449 }
c7de829c 1450 else
8bde7f77 1451 utcTime = localTime;
c7de829c 1452 if (!SetFileTime((HANDLE)f,NULL,NULL,&utcTime))
8bde7f77 1453 goto Exit;
c7de829c
WD
1454 status = true;
1455
1456Exit:
1457 CloseHandle((HANDLE)f);
1458 return status;
1459}