📄 kmisc.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include <kernel.h>
#include <psapi.h>
#ifndef _PREFAST_
#pragma warning(disable: 4068) // Disable pragma warnings
#endif
// memory usage watermark, borrowed from physmem.c
#define PAGEOUT_LOW (( 68*1024)/PAGE_SIZE) // do pageout once below this mark, reset when above high
#define PAGEOUT_HIGH ((132*1024)/PAGE_SIZE)
extern CRITICAL_SECTION rtccs, LLcs, NameCS;
extern LPVOID pGwesHandler;
extern long PageOutTrigger; // Threshold level to start page out.
extern long PageOutLevel; // Threshold to stop page out.
DWORD curridlelow, curridlehigh, idleconv;
Name *pDebugger, *pPath, *pInjectDLLs;
LPVOID pGwesHandler = SC_Nop;
DWORD g_fSysFileReadable;
// Default registry values, may be overwritten with actual desktop zone settings
DWORD g_dwKeys[HOST_TRANSCFG_NUM_REGKEYS] = {
(DWORD)-1, // nk
(DWORD)-1, // filesys
(DWORD)-1, // fsdmgr
(DWORD)-1, // relfsd
(DWORD)-1, // device
CELOG_CE_MASK, // CeLogZoneCE
CELOG_USER_MASK, // CeLogZoneUser
CELOG_PROCESS_MASK, // CeLogZoneProcess
};
WCHAR* g_keyNames[] = {L"Nk", L"FileSys", L"FSDMGR", L"ReleaseFSD", L"Device", L"CeLogZoneCE", L"CeLogZoneUser", L"CeLogZoneProcess"};
void UpdateCallerInfo (PTHREAD pth, BOOL fInKMode);
PFN_OEMKDIoControl pKDIoControl = NULL;
/* xref ref regset
; NK references two registry settings:
; HKLM\Debug\JITDebugger - for just in time debugging
; and
; HKLM\Loader\SystemPath - for alternative loader path
[HKEY_LOCAL_MACHINE\Debug]
; update the JITDebugger field to be the JIT debugger of your platform
;"JITDebugger"="My Debugger Name"
[HKEY_LOCAL_MACHINE\Loader]
; specifies all the alternative paths for loader to search when loading an app/module
; Note that every string must end with "\\" as the loader uses direct concantenation
; to obtain the path of the exe/dll.
;"SystemPath"=multi_sz:"AltPath1\\","AltPath2\\"
[HKEY_LOCAL_MACHINE\KERNEL]
; specifies all DLLs file name to be injected into process
;"InjectDLL"=multi_sz:"INJECT1.DLL","INJECT2.DLL"
*/
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_CeSetExtendedPdata(
LPVOID pData
)
{
#ifdef x86
KSetLastError(pCurThread,ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
#else
TRUSTED_API (L"SC_CeSetExtendedPdata", FALSE);
pCurProc->pExtPdata = pData;
return TRUE;
#endif
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
VOID
SC_GetSystemInfo(
LPSYSTEM_INFO lpSystemInfo
)
{
DEBUGMSG(ZONE_ENTRY,(L"SC_GetSystemInfo entry: %8.8lx\r\n",lpSystemInfo));
if (SC_MapPtrWithSize(lpSystemInfo, sizeof (SYSTEM_INFO), hCurProc)) {
lpSystemInfo->wProcessorArchitecture = PROCESSOR_ARCHITECTURE;
lpSystemInfo->wReserved = 0;
lpSystemInfo->dwPageSize = PAGE_SIZE;
lpSystemInfo->lpMinimumApplicationAddress = (LPVOID)0x10000;
lpSystemInfo->lpMaximumApplicationAddress = (LPVOID)0x7fffffff;
lpSystemInfo->dwActiveProcessorMask = 1;
lpSystemInfo->dwNumberOfProcessors = 1;
lpSystemInfo->dwProcessorType = CEProcessorType;
lpSystemInfo->wProcessorLevel = ProcessorLevel;
lpSystemInfo->wProcessorRevision = ProcessorRevision;
lpSystemInfo->dwAllocationGranularity = 0x10000;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_GetSystemInfo exit\r\n"));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL SC_QueryInstructionSet(DWORD dwInstSet, LPDWORD lpdwOSInstSet)
{
BOOL fRet = TRUE;
DEBUGMSG(ZONE_ENTRY,(L"SC_QueryInstructionSet entry: %8.8lx %8.8lx\r\n",dwInstSet, lpdwOSInstSet));
if (!SC_MapPtrWithSize (lpdwOSInstSet, sizeof (DWORD), hCurProc)) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
fRet = FALSE;
} else if (dwInstSet != CEInstructionSet) {
switch (dwInstSet) {
case PROCESSOR_QUERY_INSTRUCTION:
// query always okay
break;
case PROCESSOR_MIPS_MIPSII_INSTRUCTION:
// MIPSII can run on MIPS16
fRet = (PROCESSOR_MIPS_MIPS16_INSTRUCTION == CEInstructionSet);
break;
// OS never build THUMB anymore
case PROCESSOR_ARM_V4IFP_INSTRUCTION:
case PROCESSOR_ARM_V4TFP_INSTRUCTION:
fRet = (PROCESSOR_ARM_V4IFP_INSTRUCTION == CEInstructionSet);
break;
case PROCESSOR_ARM_V4T_INSTRUCTION:
case PROCESSOR_ARM_V4I_INSTRUCTION:
case PROCESSOR_ARM_V4_INSTRUCTION:
fRet = (PROCESSOR_ARM_V4I_INSTRUCTION == CEInstructionSet)
|| (PROCESSOR_ARM_V4IFP_INSTRUCTION == CEInstructionSet);
break;
default:
// MIPS use different calling convention between HW FP and FP emulator
// so don't support FP emulator binary on HW FP OS.
fRet = ((CEInstructionSet >> 24) != PROCESSOR_ARCHITECTURE_MIPS)
&& ((dwInstSet | PROCESSOR_FEATURE_FP) == CEInstructionSet);
break;
}
}
__try {
*lpdwOSInstSet = CEInstructionSet;
} __except (EXCEPTION_EXECUTE_HANDLER) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
fRet = FALSE;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_QueryInstructionSet exit %d\r\n", fRet));
return fRet;
}
BOOL (* pOEMIsProcessorFeaturePresent) (DWORD dwProcessorFeature);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_IsProcessorFeaturePresent(
DWORD dwProcessorFeature
)
{
BOOL fRet = FALSE;
DEBUGMSG(ZONE_ENTRY,(L"SC_IsProcessorFeaturePresent entry: %8.8lx\r\n",dwProcessorFeature));
switch( dwProcessorFeature )
{
#ifdef _X86_
//
// x86 Processor Features
//
case PF_FLOATING_POINT_PRECISION_ERRATA:
fRet = ProcessorFeatures;
break;
case PF_MMX_INSTRUCTIONS_AVAILABLE:
fRet = ProcessorFeatures & CPUID_MMX;
break;
case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
fRet = ProcessorFeaturesEx & CPUIDEX_3DNOW;
break;
case PF_XMMI_INSTRUCTIONS_AVAILABLE:
fRet = ProcessorFeatures & CPUID_SSE;
break;
case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
fRet = ProcessorFeatures & CPUID_SSE2;
break;
case PF_RDTSC_INSTRUCTION_AVAILABLE:
fRet = ProcessorFeatures & CPUID_TSC;
break;
case PF_FLOATING_POINT_EMULATED:
fRet = (dwFPType == FPTYPE_SOFTWARE);
break;
case PF_COMPARE_EXCHANGE_DOUBLE:
fRet = ProcessorFeatures & CPUID_CX8;
break;
#elif defined (ARM)
//
// ARM Processor Features
//
case PF_ARM_VFP10:
fRet = vfpStat & VFP_EXIST;
break;
case PF_ARM_V4:
#if defined(ARMV4I) || defined(ARMV4T)
case PF_ARM_THUMB:
#endif
fRet = TRUE;
break;
#elif defined (MIPS)
//
// MIPS Processor Features
//
case PF_MIPS_MIPS16:
fRet = IsMIPS16Supported;
break;
case PF_MIPS_MIPSII:
#ifdef MIPSIV
case PF_MIPS_MIPSIV:
#endif
#ifdef MIPS_HAS_FPU
case PF_MIPS_FPU:
#endif
fRet = TRUE;
break;
#elif defined (SHx)
//
// SHx Processor Features
//
#ifdef SH3
case PF_SHX_SH3:
#elif defined (SH4)
case PF_SHX_SH4:
case PF_SHX_FPU:
#else
#error Unknown CPU
#endif
fRet = TRUE;
break;
#endif
default:
// call down to OEM for everything we don't know
if (pOEMIsProcessorFeaturePresent) {
fRet = pOEMIsProcessorFeaturePresent (dwProcessorFeature);
}
break;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_IsProcessorFeaturePresent exit %d\r\n", fRet));
return fRet;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_IsBadPtr(
DWORD flag,
LPBYTE lpv,
DWORD len
)
{
DWORD dwBeg = (DWORD) lpv;
DWORD dwEnd = (DWORD) lpv+len-1;
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr entry: %8.8lx %8.8lx %8.8lx\r\n",flag,lpv,len));
// return false if zero length
if ((int) len <= 0) {
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr exit: %8.8lx zero or negative length)\r\n", len != 0));
return len != 0;
}
// cannot span across Kernel/User address
if ((dwBeg & 0x80000000) != (dwEnd & 0x80000000)) {
KSetLastError(pCurThread,ERROR_INVALID_ADDRESS);
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr exit: TRUE (ptr bad)\r\n"));
return TRUE;
}
if (dwBeg & 0x80000000) {
// must be in KMode if it's a kernel address
if (!bAllKMode && !(pCurThread->tlsPtr[PRETLS_THRDINFO] & UTLS_INKMODE)) {
KSetLastError(pCurThread,ERROR_INVALID_ADDRESS);
return TRUE;
}
// return if the range is not completely within Secure Section
if (!IsSecureVa (dwBeg) || !IsSecureVa (dwEnd)) {
return (dwEnd >= (SECURE_SECTION << VA_SECTION))
&& (dwBeg < ((SECURE_SECTION+1) << VA_SECTION));
}
} else {
DWORD aky, i;
DEBUGMSG (ZONE_ENTRY, (L"Testing Access, pCurThread->aky = %8.8lx\r\n", pCurThread->aky));
// not kernel addresses, check access right
for (i = dwBeg >> VA_SECTION; (i <= MAX_PROCESSES) && (i <= (dwEnd >> VA_SECTION)); i ++) {
if (i) {
aky = 1 << (i - 1);
if (!TestAccess (&pCurThread->aky, &aky)) {
KSetLastError (pCurThread,ERROR_INVALID_ADDRESS);
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr exit: TRUE (ptr bad)\r\n"));
return TRUE;
}
}
}
// special handling for shared section -- only writeable when in KMode
if ((VERIFY_WRITE_FLAG == flag) // write access
&& IsInSharedSection (dwBeg) // in shared section
&& !(pCurThread->tlsPtr[PRETLS_THRDINFO] & UTLS_INKMODE)) { // not k-mode
KSetLastError (pCurThread,ERROR_INVALID_ADDRESS);
return TRUE;
}
}
if (!LockPages(lpv, len, 0, flag==VERIFY_WRITE_FLAG ?
(LOCKFLAG_QUERY_ONLY | LOCKFLAG_WRITE) : (LOCKFLAG_QUERY_ONLY | LOCKFLAG_READ))) {
KSetLastError(pCurThread,ERROR_INVALID_ADDRESS);
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr exit: TRUE (ptr bad)\r\n"));
return TRUE;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr exit: FALSE (ptr OK)\r\n"));
return FALSE;
}
//------------------------------------------------------------------------------
// @func LPVOID | MapPtrUnsecure | Maps an unmapped pointer to a mapped pointer in a process
// @parm LPVOID | lpv | pointer to map
// @parm HANDLE | hProc | process to map into
// @rdesc Returns a mapped version of the pointer, or 0 for failure
// @comm If the pointer is already mapped, the original pointer is returned. If the pointer
// is unmapped, it first maps it, then returns the mapped pointer. No access validation is performed.
// This function should be called to map pointers which are passed to a PSL where the pointer is not
// a parameter directly, but obtained from a structure, and needs to be adjusted for the address space.
// @xref <f MapPtrUnsecure>
//------------------------------------------------------------------------------
LPVOID
SC_MapPtrUnsecure(
LPVOID lpv,
HANDLE hProc
)
{
LPVOID retval;
PPROCESS pProc;
DEBUGMSG(ZONE_ENTRY,(L"SC_MapPtrUnsecure entry: %8.8lx %8.8lx\r\n",lpv,hProc));
if (!hProc || (hProc == GetCurrentProcess()))
hProc = hCurProc;
if (!(pProc = HandleToProc(hProc))) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
retval = 0;
} else
retval = MapPtrProc(lpv,pProc);
DEBUGMSG(ZONE_ENTRY,(L"SC_MapPtrUnsecure exit: %8.8lx\r\n",retval));
return retval;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -