📄 pm.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 VxD** 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"/*--------------------------- Global variables ----------------------------*/#define MAX_MEMORY_SHARED 100#define MAX_MEMORY_MAPPINGS 100typedef struct { void *linear; ulong global; ulong length; int npages; } memshared;typedef struct { ulong physical; ulong linear; ulong length; int npages; ibool isCached; } mmapping;static int numMappings = 0;static memshared shared[MAX_MEMORY_MAPPINGS] = {0};static mmapping maps[MAX_MEMORY_MAPPINGS];extern ibool _PM_haveBIOS;char _PM_cntPath[PM_MAX_PATH] = "";char _PM_nucleusPath[PM_MAX_PATH] = "";uchar *_PM_rmBufAddr = NULL;ushort _VARAPI _PM_savedDS = 0;static uchar _PM_oldCMOSRegA;static uchar _PM_oldCMOSRegB;PM_intHandler _PM_rtcHandler = NULL;IRQHANDLE RTCIRQHandle = 0;VPICD_HWInt_THUNK RTCInt_Thunk;static char *szWindowsKey = "Software\\Microsoft\\Windows\\CurrentVersion";static char *szSystemRoot = "SystemRoot";static char *szMachineNameKey = "System\\CurrentControlSet\\control\\ComputerName\\ComputerName";static char *szMachineName = "ComputerName";static void (PMAPIP fatalErrorCleanup)(void) = NULL;/*----------------------------- Implementation ----------------------------*//* Functions to read and write CMOS registers */ulong PMAPI _PM_getPDB(void);uchar PMAPI _PM_readCMOS(int index);void PMAPI _PM_writeCMOS(int index,uchar value);/****************************************************************************REMARKS:PM_malloc override function for Nucleus drivers loaded in VxD's.****************************************************************************/void * VXD_malloc( size_t size){ return PM_mallocShared(size);}/****************************************************************************REMARKS:PM_calloc override function for Nucleus drivers loaded in VxD's.****************************************************************************/void * VXD_calloc( size_t nelem, size_t size){ void *p = PM_mallocShared(nelem * size); if (p) memset(p,0,nelem * size); return p;}/****************************************************************************REMARKS:PM_realloc override function for Nucleus drivers loaded in VxD's.****************************************************************************/void * VXD_realloc( void *ptr, size_t size){ void *p = PM_mallocShared(size); if (p) { memcpy(p,ptr,size); PM_freeShared(ptr); } return p;}/****************************************************************************REMARKS:PM_free override function for Nucleus drivers loaded in VxD's.****************************************************************************/void VXD_free( void *p){ PM_freeShared(p);}/****************************************************************************REMARKS:Initialise the PM library.****************************************************************************/void PMAPI PM_init(void){ /* Override the default memory allocators for all Nucleus drivers * loaded in SDDHELP/PMHELP. We do this so that we can ensure all memory * dynamically allocated by Nucleus drivers and internal C runtime * library functions are shared memory blocks that all processes * connecting to SDDHELP can see. */ PM_useLocalMalloc(VXD_malloc,VXD_calloc,VXD_realloc,VXD_free); /* Initialiase the MTRR module */ MTRR_init();}ibool PMAPI PM_haveBIOSAccess(void){ return _PM_haveBIOS; }long PMAPI PM_getOSType(void){ return _OS_WIN32VXD; }int PMAPI PM_getModeType(void){ return PM_386; }void PMAPI PM_backslash(char *s){ uint pos = strlen(s); if (s[pos-1] != '\\') { s[pos] = '\\'; s[pos+1] = '\0'; }}void PMAPI PM_setFatalErrorCleanup( void (PMAPIP cleanup)(void)){ fatalErrorCleanup = cleanup;}void PMAPI PM_fatalError(const char *msg){ if (fatalErrorCleanup) fatalErrorCleanup(); Fatal_Error_Handler(msg,0);}/****************************************************************************PARAMETERS:len - Place to store the length of the bufferrseg - Place to store the real mode segment of the bufferroff - Place to store the real mode offset of the bufferREMARKS:This function returns the address and length of the global VESA transferbuffer that is used for communicating with the VESA BIOS functions fromWin16 and Win32 programs under Windows.****************************************************************************/void * PMAPI PM_getVESABuf( uint *len, uint *rseg, uint *roff){ /* If the VxD is dynamically loaded we will not have a real mode * transfer buffer to return, so we fail the call. */ if (_PM_rmBufAddr) { *len = VESA_BUF_SIZE; *rseg = (ulong)(_PM_rmBufAddr) >> 4; *roff = (ulong)(_PM_rmBufAddr) & 0xF; return _PM_rmBufAddr; } return NULL;}int PMAPI PM_int386( int intno, PMREGS *in, PMREGS *out){ /* Unused in VxDs */ return 0;}void PMAPI _PM_getRMvect( int intno, long *realisr){ WORD seg; DWORD off; Get_V86_Int_Vector(intno,&seg,&off); *realisr = ((long)seg << 16) | (off & 0xFFFF);}void PMAPI _PM_setRMvect( int intno, long realisr){ Set_V86_Int_Vector(intno,realisr >> 16,realisr & 0xFFFF);}char * PMAPI PM_getCurrentPath( char *path, int maxLen){ strncpy(path,_PM_cntPath,maxLen); path[maxLen-1] = 0; return path;}char PMAPI PM_getBootDrive(void){ return 'c'; }const char * PMAPI PM_getVBEAFPath(void){ return "c:\\"; }/****************************************************************************PARAMETERS:szKey - Key to query (can contain version number formatting)szValue - Value to get information forvalue - Place to store the registry key data readsize - Size of the string buffer to read intoRETURNS:true if the key was found, false if not.****************************************************************************/static ibool REG_queryString( char *szKey, char *szValue, char *value, ulong size){ HKEY hKey; ulong type; ibool status = false; memset(value,0,sizeof(value)); if (RegOpenKey(HKEY_LOCAL_MACHINE,szKey,&hKey) == ERROR_SUCCESS) { if (RegQueryValueEx(hKey,(PCHAR)szValue,(ulong*)NULL,(ulong*)&type,value,(ulong*)&size) == ERROR_SUCCESS) status = true; RegCloseKey(hKey); } return status;}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(szWindowsKey,szSystemRoot,path,sizeof(path))) strcpy(path,"c:\\windows"); PM_backslash(path); strcat(path,"system\\nucleus"); return path;}const char * PMAPI PM_getNucleusConfigPath(void){ static char path[256]; strcpy(path,PM_getNucleusPath()); PM_backslash(path); strcat(path,"config"); return path;}const char * PMAPI PM_getUniqueID(void){ return PM_getMachineName(); }const char * PMAPI PM_getMachineName(void){ static char name[256]; if (REG_queryString(szMachineNameKey,szMachineName,name,sizeof(name))) return name; return "Unknown";}int PMAPI PM_kbhit(void){ return 1; }int PMAPI PM_getch(void){ return 0; }PM_HWND PMAPI PM_openConsole( PM_HWND hwndUser, int device, int xRes, int yRes, int bpp, ibool fullScreen){ /* Unused in VxDs */ return NULL;}int PMAPI PM_getConsoleStateSize(void){ /* Unused in VxDs */ return 1;}void PMAPI PM_saveConsoleState( void *stateBuf, PM_HWND hwndConsole){ /* Unused in VxDs */}void PMAPI PM_setSuspendAppCallback( int (_ASMAPIP saveState)( int flags)){ /* Unused in VxDs */}void PMAPI PM_restoreConsoleState( const void *stateBuf, PM_HWND hwndConsole){ /* Unused in VxDs */}void PMAPI PM_closeConsole( PM_HWND hwndConsole){ /* Unused in VxDs */}void PM_setOSCursorLocation( int x, int y){ uchar *_biosPtr = PM_getBIOSPointer(); PM_setByte(_biosPtr+0x50,x); PM_setByte(_biosPtr+0x51,y);}void PM_setOSScreenWidth( int width, int height){ uchar *_biosPtr = PM_getBIOSPointer(); PM_setByte(_biosPtr+0x4A,width); PM_setByte(_biosPtr+0x84,height-1);}/****************************************************************************REMARKS:Allocate a block of shared memory. For Win9x we allocate shared memoryas locked, global memory that is accessible from any memory context(including interrupt time context), which allows us to load our importantdata structure and code such that we can access it directly from a ring0 interrupt context.****************************************************************************/void * PMAPI PM_mallocShared( long size){ MEMHANDLE hMem; DWORD pgNum,nPages = (size + 0xFFF) >> 12; int i; /* First find a free slot in our shared memory table */ for (i = 0; i < MAX_MEMORY_SHARED; i++) { if (shared[i].linear == 0) break; } if (i < MAX_MEMORY_SHARED) { PageAllocate(nPages,PG_SYS,0,0,0,0,NULL,0,&hMem,&shared[i].linear); shared[i].npages = nPages; pgNum = (ulong)shared[i].linear >> 12; shared[i].global = LinPageLock(pgNum,nPages,PAGEMAPGLOBAL); return (void*)shared[i].global; } return NULL;}/****************************************************************************REMARKS:Free a block of shared memory****************************************************************************/void PMAPI PM_freeShared(void *p){ int i; /* Find a shared memory block in our table and free it */ for (i = 0; i < MAX_MEMORY_SHARED; i++) { if (shared[i].global == (ulong)p) { LinPageUnLock(shared[i].global >> 12,shared[i].npages,PAGEMAPGLOBAL); PageFree((ulong)shared[i].linear,0); shared[i].linear = 0; break; } }}/****************************************************************************REMARKS:Maps a shared memory block into process address space. Does nothing sincethe memory blocks are already globally7 mapped into all processes.****************************************************************************/void * PMAPI PM_mapToProcess( void *base, ulong limit){ return (void*)base;}ibool PMAPI PM_doBIOSPOST( ushort axVal, ulong BIOSPhysAddr,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -