934 lines
29 KiB
C
934 lines
29 KiB
C
/****************************************************************************
|
|
*
|
|
* SciTech OS Portability Manager Library
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* The contents of this file are subject to the SciTech MGL Public
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.scitechsoft.com/mgl-license.txt
|
|
*
|
|
* Software distributed under the License is distributed on an
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
|
|
*
|
|
* The Initial Developer of the Original Code is SciTech Software, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* Language: ANSI C
|
|
* Environment: 32-bit Windows NT device drivers.
|
|
*
|
|
* Description: Implementation for the OS Portability Manager Library, which
|
|
* contains functions to implement OS specific services in a
|
|
* generic, cross platform API. Porting the OS Portability
|
|
* Manager library is the first step to porting any SciTech
|
|
* products to a new platform.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "pmapi.h"
|
|
#include "drvlib/os/os.h"
|
|
#include "sdd/sddhelp.h"
|
|
#include "mtrr.h"
|
|
#include "oshdr.h"
|
|
|
|
/*--------------------------- Global variables ----------------------------*/
|
|
|
|
char _PM_cntPath[PM_MAX_PATH] = "";
|
|
char _PM_nucleusPath[PM_MAX_PATH] = "";
|
|
static void (PMAPIP fatalErrorCleanup)(void) = NULL;
|
|
|
|
static char *szNTWindowsKey = "\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion";
|
|
static char *szNTSystemRoot = "SystemRoot";
|
|
static char *szMachineNameKey = "\\REGISTRY\\Machine\\System\\CurrentControlSet\\control\\ComputerName\\ComputerName";
|
|
static char *szMachineNameKeyNT = "\\REGISTRY\\Machine\\System\\CurrentControlSet\\control\\ComputerName\\ActiveComputerName";
|
|
static char *szMachineName = "ComputerName";
|
|
|
|
/*----------------------------- Implementation ----------------------------*/
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Initialise the PM library.
|
|
****************************************************************************/
|
|
void PMAPI PM_init(void)
|
|
{
|
|
/* Initialiase the MTRR module */
|
|
MTRR_init();
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the operating system type identifier.
|
|
****************************************************************************/
|
|
long PMAPI PM_getOSType(void)
|
|
{
|
|
return _OS_WINNTDRV;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the runtime type identifier.
|
|
****************************************************************************/
|
|
int PMAPI PM_getModeType(void)
|
|
{
|
|
return PM_386;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Add a file directory separator to the end of the filename.
|
|
****************************************************************************/
|
|
void PMAPI PM_backslash(char *s)
|
|
{
|
|
uint pos = strlen(s);
|
|
if (s[pos-1] != '\\') {
|
|
s[pos] = '\\';
|
|
s[pos+1] = '\0';
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Add a user defined PM_fatalError cleanup function.
|
|
****************************************************************************/
|
|
void PMAPI PM_setFatalErrorCleanup(
|
|
void (PMAPIP cleanup)(void))
|
|
{
|
|
fatalErrorCleanup = cleanup;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Handle fatal errors internally in the driver.
|
|
****************************************************************************/
|
|
void PMAPI PM_fatalError(
|
|
const char *msg)
|
|
{
|
|
ULONG BugCheckCode = 0;
|
|
ULONG MoreBugCheckData[4] = {0};
|
|
char *p;
|
|
ULONG len;
|
|
|
|
if (fatalErrorCleanup)
|
|
fatalErrorCleanup();
|
|
|
|
#ifdef DBG /* Send output to debugger, just return so as not to force a reboot */
|
|
#pragma message("INFO: building for debug, PM_fatalError() re-routed")
|
|
DBGMSG2("SDDHELP> PM_fatalError(): ERROR: %s\n", msg);
|
|
return ;
|
|
#endif
|
|
/* KeBugCheckEx brings down the system in a controlled */
|
|
/* manner when the caller discovers an unrecoverable */
|
|
/* inconsistency that would corrupt the system if */
|
|
/* the caller continued to run. */
|
|
/* */
|
|
/* hack - dump the first 20 chars in hex using the variables */
|
|
/* provided - Each ULONG is equal to four characters... */
|
|
for(len = 0; len < 20; len++)
|
|
if (msg[len] == (char)0)
|
|
break;
|
|
|
|
/* This looks bad but it's quick and reliable... */
|
|
p = (char *)&BugCheckCode;
|
|
if(len > 0) p[3] = msg[0];
|
|
if(len > 1) p[2] = msg[1];
|
|
if(len > 2) p[1] = msg[2];
|
|
if(len > 3) p[0] = msg[3];
|
|
|
|
p = (char *)&MoreBugCheckData[0];
|
|
if(len > 4) p[3] = msg[4];
|
|
if(len > 5) p[2] = msg[5];
|
|
if(len > 6) p[1] = msg[6];
|
|
if(len > 7) p[0] = msg[7];
|
|
|
|
p = (char *)&MoreBugCheckData[1];
|
|
if(len > 8) p[3] = msg[8];
|
|
if(len > 9) p[2] = msg[9];
|
|
if(len > 10) p[1] = msg[10];
|
|
if(len > 11) p[0] = msg[11];
|
|
|
|
p = (char *)&MoreBugCheckData[2];
|
|
if(len > 12) p[3] = msg[12];
|
|
if(len > 13) p[2] = msg[13];
|
|
if(len > 14) p[1] = msg[14];
|
|
if(len > 15) p[0] = msg[15];
|
|
|
|
p = (char *)&MoreBugCheckData[3];
|
|
if(len > 16) p[3] = msg[16];
|
|
if(len > 17) p[2] = msg[17];
|
|
if(len > 18) p[1] = msg[18];
|
|
if(len > 19) p[0] = msg[19];
|
|
|
|
/* Halt the system! */
|
|
KeBugCheckEx(BugCheckCode, MoreBugCheckData[0], MoreBugCheckData[1], MoreBugCheckData[2], MoreBugCheckData[3]);
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the current operating system path or working directory.
|
|
****************************************************************************/
|
|
char * PMAPI PM_getCurrentPath(
|
|
char *path,
|
|
int maxLen)
|
|
{
|
|
strncpy(path,_PM_cntPath,maxLen);
|
|
path[maxLen-1] = 0;
|
|
return path;
|
|
}
|
|
|
|
/****************************************************************************
|
|
PARAMETERS:
|
|
szKey - Key to query (can contain version number formatting)
|
|
szValue - Value to get information for
|
|
value - Place to store the registry key data read
|
|
size - Size of the string buffer to read into
|
|
|
|
RETURNS:
|
|
true if the key was found, false if not.
|
|
****************************************************************************/
|
|
static ibool REG_queryString(
|
|
char *szKey,
|
|
const char *szValue,
|
|
char *value,
|
|
DWORD size)
|
|
{
|
|
ibool status;
|
|
NTSTATUS rval;
|
|
ULONG length;
|
|
HANDLE Handle;
|
|
OBJECT_ATTRIBUTES keyAttributes;
|
|
UNICODE_STRING *uniKey = NULL;
|
|
UNICODE_STRING *uniValue = NULL;
|
|
PKEY_VALUE_FULL_INFORMATION fullInfo = NULL;
|
|
STRING stringdata;
|
|
UNICODE_STRING unidata;
|
|
|
|
/* Convert strings to UniCode */
|
|
status = false;
|
|
if ((uniKey = _PM_CStringToUnicodeString(szKey)) == NULL)
|
|
goto Exit;
|
|
if ((uniValue = _PM_CStringToUnicodeString(szValue)) == NULL)
|
|
goto Exit;
|
|
|
|
/* Open the key */
|
|
InitializeObjectAttributes( &keyAttributes,
|
|
uniKey,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL );
|
|
rval = ZwOpenKey( &Handle,
|
|
KEY_ALL_ACCESS,
|
|
&keyAttributes );
|
|
if (!NT_SUCCESS(rval))
|
|
goto Exit;
|
|
|
|
/* Query the value */
|
|
length = sizeof (KEY_VALUE_FULL_INFORMATION)
|
|
+ size * sizeof(WCHAR);
|
|
if ((fullInfo = ExAllocatePool (PagedPool, length)) == NULL)
|
|
goto Exit;
|
|
RtlZeroMemory(fullInfo, length);
|
|
rval = ZwQueryValueKey (Handle,
|
|
uniValue,
|
|
KeyValueFullInformation,
|
|
fullInfo,
|
|
length,
|
|
&length);
|
|
if (NT_SUCCESS (rval)) {
|
|
/* Create the UniCode string so we can convert it */
|
|
unidata.Buffer = (PWCHAR)(((PCHAR)fullInfo) + fullInfo->DataOffset);
|
|
unidata.Length = (USHORT)fullInfo->DataLength;
|
|
unidata.MaximumLength = (USHORT)fullInfo->DataLength + sizeof(WCHAR);
|
|
|
|
/* Convert unicode univalue to ansi string. */
|
|
rval = RtlUnicodeStringToAnsiString(&stringdata, &unidata, TRUE);
|
|
if (NT_SUCCESS(rval)) {
|
|
strcpy(value,stringdata.Buffer);
|
|
status = true;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (fullInfo) ExFreePool(fullInfo);
|
|
if (uniKey) _PM_FreeUnicodeString(uniKey);
|
|
if (uniValue) _PM_FreeUnicodeString(uniValue);
|
|
return status;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the drive letter for the boot drive.
|
|
****************************************************************************/
|
|
char PMAPI PM_getBootDrive(void)
|
|
{
|
|
char path[256];
|
|
if (REG_queryString(szNTWindowsKey,szNTSystemRoot,path,sizeof(path)))
|
|
return 'c';
|
|
return path[0];
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the path to the VBE/AF driver files.
|
|
****************************************************************************/
|
|
const char * PMAPI PM_getVBEAFPath(void)
|
|
{
|
|
return "c:\\";
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the path to the Nucleus driver files.
|
|
****************************************************************************/
|
|
const char * PMAPI PM_getNucleusPath(void)
|
|
{
|
|
static char path[256];
|
|
|
|
if (strlen(_PM_nucleusPath) > 0) {
|
|
strcpy(path,_PM_nucleusPath);
|
|
PM_backslash(path);
|
|
return path;
|
|
}
|
|
if (!REG_queryString(szNTWindowsKey,szNTSystemRoot,path,sizeof(path)))
|
|
strcpy(path,"c:\\winnt");
|
|
PM_backslash(path);
|
|
strcat(path,"system32\\nucleus");
|
|
return path;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the path to the Nucleus configuration files.
|
|
****************************************************************************/
|
|
const char * PMAPI PM_getNucleusConfigPath(void)
|
|
{
|
|
static char path[256];
|
|
strcpy(path,PM_getNucleusPath());
|
|
PM_backslash(path);
|
|
strcat(path,"config");
|
|
return path;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return a unique identifier for the machine if possible.
|
|
****************************************************************************/
|
|
const char * PMAPI PM_getUniqueID(void)
|
|
{
|
|
return PM_getMachineName();
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Get the name of the machine on the network.
|
|
****************************************************************************/
|
|
const char * PMAPI PM_getMachineName(void)
|
|
{
|
|
static char name[256];
|
|
|
|
if (REG_queryString(szMachineNameKey,szMachineName,name,sizeof(name)))
|
|
return name;
|
|
if (REG_queryString(szMachineNameKeyNT,szMachineName,name,sizeof(name)))
|
|
return name;
|
|
return "Unknown";
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Check if a key has been pressed.
|
|
****************************************************************************/
|
|
int PMAPI PM_kbhit(void)
|
|
{
|
|
/* Not used in NT drivers */
|
|
return true;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Wait for and return the next keypress.
|
|
****************************************************************************/
|
|
int PMAPI PM_getch(void)
|
|
{
|
|
/* Not used in NT drivers */
|
|
return 0xD;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Open a console for output to the screen, creating the main event handling
|
|
window if necessary.
|
|
****************************************************************************/
|
|
PM_HWND PMAPI PM_openConsole(
|
|
PM_HWND hwndUser,
|
|
int device,
|
|
int xRes,
|
|
int yRes,
|
|
int bpp,
|
|
ibool fullScreen)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)hwndUser;
|
|
(void)device;
|
|
(void)xRes;
|
|
(void)yRes;
|
|
(void)bpp;
|
|
(void)fullScreen;
|
|
return NULL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Find the size of the console state buffer.
|
|
****************************************************************************/
|
|
int PMAPI PM_getConsoleStateSize(void)
|
|
{
|
|
/* Not used in NT drivers */
|
|
return 1;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Save the state of the console.
|
|
****************************************************************************/
|
|
void PMAPI PM_saveConsoleState(
|
|
void *stateBuf,
|
|
PM_HWND hwndConsole)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)stateBuf;
|
|
(void)hwndConsole;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Set the suspend application callback for the fullscreen console.
|
|
****************************************************************************/
|
|
void PMAPI PM_setSuspendAppCallback(
|
|
PM_saveState_cb saveState)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)saveState;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Restore the console state.
|
|
****************************************************************************/
|
|
void PMAPI PM_restoreConsoleState(
|
|
const void *stateBuf,
|
|
PM_HWND hwndConsole)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)stateBuf;
|
|
(void)hwndConsole;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Close the fullscreen console.
|
|
****************************************************************************/
|
|
void PMAPI PM_closeConsole(
|
|
PM_HWND hwndConsole)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)hwndConsole;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Set the location of the OS console cursor.
|
|
****************************************************************************/
|
|
void PMAPI PM_setOSCursorLocation(
|
|
int x,
|
|
int y)
|
|
{
|
|
/* Nothing to do for Windows */
|
|
(void)x;
|
|
(void)y;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Set the width of the OS console.
|
|
****************************************************************************/
|
|
void PMAPI PM_setOSScreenWidth(
|
|
int width,
|
|
int height)
|
|
{
|
|
/* Nothing to do for Windows */
|
|
(void)width;
|
|
(void)height;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Maps a shared memory block into process address space. Does nothing since
|
|
the memory blocks are already globally mapped into all processes.
|
|
****************************************************************************/
|
|
void * PMAPI PM_mapToProcess(
|
|
void *base,
|
|
ulong limit)
|
|
{
|
|
/* Not used anymore */
|
|
(void)base;
|
|
(void)limit;
|
|
return NULL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Execute the POST on the secondary BIOS for a controller.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_doBIOSPOST(
|
|
ushort axVal,
|
|
ulong BIOSPhysAddr,
|
|
void *mappedBIOS,
|
|
ulong BIOSLen)
|
|
{
|
|
/* This may not be possible in NT and should be done by the OS anyway */
|
|
(void)axVal;
|
|
(void)BIOSPhysAddr;
|
|
(void)mappedBIOS;
|
|
(void)BIOSLen;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return a pointer to the real mode BIOS data area.
|
|
****************************************************************************/
|
|
void * PMAPI PM_getBIOSPointer(void)
|
|
{
|
|
/* Note that on NT this probably does not do what we expect! */
|
|
return PM_mapPhysicalAddr(0x400, 0x1000, true);
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return a pointer to 0xA0000 physical VGA graphics framebuffer.
|
|
****************************************************************************/
|
|
void * PMAPI PM_getA0000Pointer(void)
|
|
{
|
|
return PM_mapPhysicalAddr(0xA0000,0xFFFF,false);
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Sleep for the specified number of milliseconds.
|
|
****************************************************************************/
|
|
void PMAPI PM_sleep(
|
|
ulong milliseconds)
|
|
{
|
|
/* We never use this in NT drivers */
|
|
(void)milliseconds;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the base I/O port for the specified COM port.
|
|
****************************************************************************/
|
|
int PMAPI PM_getCOMPort(int port)
|
|
{
|
|
/* TODO: Re-code this to determine real values using the Plug and Play */
|
|
/* manager for the OS. */
|
|
switch (port) {
|
|
case 0: return 0x3F8;
|
|
case 1: return 0x2F8;
|
|
case 2: return 0x3E8;
|
|
case 3: return 0x2E8;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Return the base I/O port for the specified LPT port.
|
|
****************************************************************************/
|
|
int PMAPI PM_getLPTPort(int port)
|
|
{
|
|
/* TODO: Re-code this to determine real values using the Plug and Play */
|
|
/* manager for the OS. */
|
|
switch (port) {
|
|
case 0: return 0x3BC;
|
|
case 1: return 0x378;
|
|
case 2: return 0x278;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Returns available memory. Not possible under Windows.
|
|
****************************************************************************/
|
|
void PMAPI PM_availableMemory(
|
|
ulong *physical,
|
|
ulong *total)
|
|
{
|
|
*physical = *total = 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
OS specific shared libraries not supported inside a VxD
|
|
****************************************************************************/
|
|
PM_MODULE PMAPI PM_loadLibrary(
|
|
const char *szDLLName)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)szDLLName;
|
|
return NULL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
OS specific shared libraries not supported inside a VxD
|
|
****************************************************************************/
|
|
void * PMAPI PM_getProcAddress(
|
|
PM_MODULE hModule,
|
|
const char *szProcName)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)hModule;
|
|
(void)szProcName;
|
|
return NULL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
OS specific shared libraries not supported inside a VxD
|
|
****************************************************************************/
|
|
void PMAPI PM_freeLibrary(
|
|
PM_MODULE hModule)
|
|
{
|
|
/* Not used in NT drivers */
|
|
(void)hModule;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to find the first file matching a search criteria in a directory.
|
|
****************************************************************************/
|
|
void *PMAPI PM_findFirstFile(
|
|
const char *filename,
|
|
PM_findData *findData)
|
|
{
|
|
/* TODO: This function should start a directory enumeration search */
|
|
/* given the filename (with wildcards). The data should be */
|
|
/* converted and returned in the findData standard form. */
|
|
(void)filename;
|
|
(void)findData;
|
|
return PM_FILE_INVALID;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to find the next file matching a search criteria in a directory.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_findNextFile(
|
|
void *handle,
|
|
PM_findData *findData)
|
|
{
|
|
/* TODO: This function should find the next file in directory enumeration */
|
|
/* search given the search criteria defined in the call to */
|
|
/* PM_findFirstFile. The data should be converted and returned */
|
|
/* in the findData standard form. */
|
|
(void)handle;
|
|
(void)findData;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to close the find process
|
|
****************************************************************************/
|
|
void PMAPI PM_findClose(
|
|
void *handle)
|
|
{
|
|
/* TODO: This function should close the find process. This may do */
|
|
/* nothing for some OS'es. */
|
|
(void)handle;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to determine if a drive is a valid drive or not. Under Unix this
|
|
function will return false for anything except a value of 3 (considered
|
|
the root drive, and equivalent to C: for non-Unix systems). The drive
|
|
numbering is:
|
|
|
|
1 - Drive A:
|
|
2 - Drive B:
|
|
3 - Drive C:
|
|
etc
|
|
|
|
****************************************************************************/
|
|
ibool PMAPI PM_driveValid(
|
|
char drive)
|
|
{
|
|
/* Not supported in NT drivers */
|
|
(void)drive;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to get the current working directory for the specififed drive.
|
|
Under Unix this will always return the current working directory regardless
|
|
of what the value of 'drive' is.
|
|
****************************************************************************/
|
|
void PMAPI PM_getdcwd(
|
|
int drive,
|
|
char *dir,
|
|
int len)
|
|
{
|
|
/* Not supported in NT drivers */
|
|
(void)drive;
|
|
(void)dir;
|
|
(void)len;
|
|
}
|
|
|
|
/****************************************************************************
|
|
PARAMETERS:
|
|
base - The starting physical base address of the region
|
|
size - The size in bytes of the region
|
|
type - Type to place into the MTRR register
|
|
|
|
RETURNS:
|
|
Error code describing the result.
|
|
|
|
REMARKS:
|
|
Function to enable write combining for the specified region of memory.
|
|
****************************************************************************/
|
|
int PMAPI PM_enableWriteCombine(
|
|
ulong base,
|
|
ulong size,
|
|
uint type)
|
|
{
|
|
return MTRR_enableWriteCombine(base,size,type);
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to change the file attributes for a specific file.
|
|
****************************************************************************/
|
|
void PMAPI PM_setFileAttr(
|
|
const char *filename,
|
|
uint attrib)
|
|
{
|
|
NTSTATUS status;
|
|
ACCESS_MASK DesiredAccess = GENERIC_READ | GENERIC_WRITE;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
ULONG ShareAccess = FILE_SHARE_READ;
|
|
ULONG CreateDisposition = FILE_OPEN;
|
|
HANDLE FileHandle = NULL;
|
|
UNICODE_STRING *uniFile = NULL;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
FILE_BASIC_INFORMATION FileBasic;
|
|
char kernelFilename[PM_MAX_PATH+5];
|
|
ULONG FileAttributes = 0;
|
|
|
|
/* Convert file attribute flags */
|
|
if (attrib & PM_FILE_READONLY)
|
|
FileAttributes |= FILE_ATTRIBUTE_READONLY;
|
|
if (attrib & PM_FILE_ARCHIVE)
|
|
FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
|
|
if (attrib & PM_FILE_HIDDEN)
|
|
FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
|
if (attrib & PM_FILE_SYSTEM)
|
|
FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
|
|
|
|
/* Add prefix for addressing the file system. "\??\" is short for "\DosDevices\" */
|
|
strcpy(kernelFilename, "\\??\\");
|
|
strcat(kernelFilename, filename);
|
|
|
|
/* Convert filename string to ansi string */
|
|
if ((uniFile = _PM_CStringToUnicodeString(kernelFilename)) == NULL)
|
|
goto Exit;
|
|
|
|
/* Must open a file to query it's attributes */
|
|
InitializeObjectAttributes (&ObjectAttributes,
|
|
uniFile,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL );
|
|
status = ZwCreateFile( &FileHandle,
|
|
DesiredAccess | SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
NULL, /*AllocationSize OPTIONAL, */
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
ShareAccess,
|
|
CreateDisposition,
|
|
FILE_RANDOM_ACCESS, /*CreateOptions, */
|
|
NULL, /*EaBuffer OPTIONAL, */
|
|
0 /*EaLength (required if EaBuffer) */
|
|
);
|
|
if (!NT_SUCCESS (status))
|
|
goto Exit;
|
|
|
|
/* Query timestamps */
|
|
status = ZwQueryInformationFile(FileHandle,
|
|
&IoStatusBlock,
|
|
&FileBasic,
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
FileBasicInformation
|
|
);
|
|
if (!NT_SUCCESS (status))
|
|
goto Exit;
|
|
|
|
/* Change the four bits we change */
|
|
FileBasic.FileAttributes &= ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE
|
|
| FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
|
|
FileBasic.FileAttributes |= FileAttributes;
|
|
|
|
/* Set timestamps */
|
|
ZwSetInformationFile( FileHandle,
|
|
&IoStatusBlock,
|
|
&FileBasic,
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
FileBasicInformation
|
|
);
|
|
|
|
Exit:
|
|
if (FileHandle) ZwClose(FileHandle);
|
|
if (uniFile) _PM_FreeUnicodeString(uniFile);
|
|
return;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to get the file attributes for a specific file.
|
|
****************************************************************************/
|
|
uint PMAPI PM_getFileAttr(
|
|
const char *filename)
|
|
{
|
|
NTSTATUS status;
|
|
ACCESS_MASK DesiredAccess = GENERIC_READ | GENERIC_WRITE;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
ULONG ShareAccess = FILE_SHARE_READ;
|
|
ULONG CreateDisposition = FILE_OPEN;
|
|
HANDLE FileHandle = NULL;
|
|
UNICODE_STRING *uniFile = NULL;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
FILE_BASIC_INFORMATION FileBasic;
|
|
char kernelFilename[PM_MAX_PATH+5];
|
|
ULONG FileAttributes = 0;
|
|
uint retval = 0;
|
|
|
|
/* Add prefix for addressing the file system. "\??\" is short for "\DosDevices\" */
|
|
strcpy(kernelFilename, "\\??\\");
|
|
strcat(kernelFilename, filename);
|
|
|
|
/* Convert filename string to ansi string */
|
|
if ((uniFile = _PM_CStringToUnicodeString(kernelFilename)) == NULL)
|
|
goto Exit;
|
|
|
|
/* Must open a file to query it's attributes */
|
|
InitializeObjectAttributes (&ObjectAttributes,
|
|
uniFile,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL );
|
|
status = ZwCreateFile( &FileHandle,
|
|
DesiredAccess | SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
NULL, /*AllocationSize OPTIONAL, */
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
ShareAccess,
|
|
CreateDisposition,
|
|
FILE_RANDOM_ACCESS, /*CreateOptions, */
|
|
NULL, /*EaBuffer OPTIONAL, */
|
|
0 /*EaLength (required if EaBuffer) */
|
|
);
|
|
if (!NT_SUCCESS (status))
|
|
goto Exit;
|
|
|
|
/* Query timestamps */
|
|
status = ZwQueryInformationFile(FileHandle,
|
|
&IoStatusBlock,
|
|
&FileBasic,
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
FileBasicInformation
|
|
);
|
|
if (!NT_SUCCESS (status))
|
|
goto Exit;
|
|
|
|
/* Translate the file attributes */
|
|
if (FileBasic.FileAttributes & FILE_ATTRIBUTE_READONLY)
|
|
retval |= PM_FILE_READONLY;
|
|
if (FileBasic.FileAttributes & FILE_ATTRIBUTE_ARCHIVE)
|
|
retval |= PM_FILE_ARCHIVE;
|
|
if (FileBasic.FileAttributes & FILE_ATTRIBUTE_HIDDEN)
|
|
retval |= PM_FILE_HIDDEN;
|
|
if (FileBasic.FileAttributes & FILE_ATTRIBUTE_SYSTEM)
|
|
retval |= PM_FILE_SYSTEM;
|
|
|
|
Exit:
|
|
if (FileHandle) ZwClose(FileHandle);
|
|
if (uniFile) _PM_FreeUnicodeString(uniFile);
|
|
return retval;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to create a directory.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_mkdir(
|
|
const char *filename)
|
|
{
|
|
/* Not supported in NT drivers */
|
|
(void)filename;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to remove a directory.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_rmdir(
|
|
const char *filename)
|
|
{
|
|
/* Not supported in NT drivers */
|
|
(void)filename;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to get the file time and date for a specific file.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_getFileTime(
|
|
const char *filename,
|
|
ibool gmTime,
|
|
PM_time *time)
|
|
{
|
|
/* Not supported in NT drivers */
|
|
(void)filename;
|
|
(void)gmTime;
|
|
(void)time;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to set the file time and date for a specific file.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_setFileTime(
|
|
const char *filename,
|
|
ibool gmTime,
|
|
PM_time *time)
|
|
{
|
|
/* Not supported in NT drivers */
|
|
(void)filename;
|
|
(void)gmTime;
|
|
(void)time;
|
|
return false;
|
|
}
|