pm.c

来自「适合KS8695X」· C语言 代码 · 共 934 行 · 第 1/2 页

C
934
字号
/****************************************************************************
*
*                   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;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?