📄 kmisc.c
字号:
/* Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved. */
#include <kernel.h>
extern CRITICAL_SECTION rtccs, LLcs, NameCS;
extern LPVOID pGwesHandler;
DWORD curridlelow, curridlehigh, idleconv;
Name *pDebugger, *pPath;
LPVOID pGwesHandler = SC_Nop;
BOOL bAllKMode;
int InitializeJit(PFNOPEN, PFNCLOSE);
PFN_OEMKDIoControl pKDIoControl = NULL;
// DVCM Collector functions, assigned if DVCM is included in the image
HRESULT (*pInitialize_DataCollector)();
HRESULT (*pIoctl_Register_DataCollector)(LPVOID,DWORD,LPVOID,DWORD);
HRESULT (*pIoctl_Send_DataCollector)(LPVOID,DWORD,LPVOID,DWORD);
HRESULT (*pIoctl_Unregister_DataCollector)(LPVOID,DWORD,LPVOID,DWORD);
BOOL SC_CeSetExtendedPdata(LPVOID pData) {
#ifdef x86
KSetLastError(pCurThread,ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
#else
if (pCurProc->bTrustLevel != KERN_TRUST_FULL) {
KSetLastError(pCurThread,ERROR_ACCESS_DENIED);
return 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));
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_IsBadPtr(DWORD flag, LPBYTE lpv, DWORD len) {
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr entry: %8.8lx %8.8lx %8.8lx\r\n",flag,lpv,len));
if (!len) {
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr exit: FALSE (ptr OK - zero length)\r\n"));
return FALSE;
}
if ((DWORD)lpv + len < (DWORD)lpv) {
KSetLastError(pCurThread,ERROR_INVALID_ADDRESS);
DEBUGMSG(ZONE_ENTRY,(L"SC_IsBadPtr exit: TRUE (ptr bad)\r\n"));
return TRUE;
}
if (((ulong)lpv>>VA_SECTION) > SECTION_MASK) {
if (bAllKMode || ((DWORD)pCurThread->pcstkTop->pprcLast == KERNEL_MODE))
return FALSE;
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 | MapPtrToProcess | 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 caller
// has access to dereference that pointer, else 0 is returned. If the pointer is
// unmapped, it first maps it, then returns the mapped pointer if the caller can access
// it, else 0. 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;
}
// @func HANDLE | GetProcFromPtr | Returns the process id which owns the pointer passed in
// @parm LPVOID | ptr | pointer from which to find a process
// @rdesc Returns the process id of the owning process
// @comm Returns the owner process of the pointer, or NULL if the pointer is not valid.
HANDLE SC_GetProcFromPtr(LPVOID lpv) {
int loop;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetProcFromPtr entry: %8.8lx\r\n",lpv));
if (ZeroPtr(lpv) == (DWORD)lpv) {
DEBUGMSG(ZONE_ENTRY,(L"SC_GetProcFromPtr exit: %8.8lx\r\n",hCurProc));
return hCurProc;
}
loop = ((DWORD)lpv>>VA_SECTION)-1;
if ((loop >= MAX_PROCESSES) || !ProcArray[loop].dwVMBase) {
DEBUGMSG(ZONE_ENTRY,(L"SC_GetProcFromPtr exit: %8.8lx\r\n",0));
return 0;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_GetProcFromPtr exit :%8.8lx\r\n",ProcArray[loop].hProc));
return ProcArray[loop].hProc;
}
// @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 MapPtrToProcess>
LPVOID SC_MapPtrToProcess(LPVOID lpv, HANDLE hProc) {
PPROCESS pProc;
DEBUGMSG(ZONE_ENTRY,(L"SC_MapPtrToProcess entry: %8.8lx %8.8lx\r\n",lpv,hProc));
if (!(pProc = HandleToProc(hProc))) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
lpv = 0;
} else if ((DWORD)lpv>>VA_SECTION != 0) {
if (!IsAccessOK(lpv,CurAKey)) {
KSetLastError(pCurThread,ERROR_ACCESS_DENIED);
lpv = 0;
}
} else if ((DWORD)lpv > 0x10000)
lpv = MapPtrProc(lpv,pProc);
DEBUGMSG(ZONE_ENTRY,(L"SC_MapPtrToProcess exit: %8.8lx\r\n",lpv));
return lpv;
}
DWORD SC_GetProcAddrBits(HANDLE hproc) {
PPROCESS pproc;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetProcAddrBits entry: %8.8lx\r\n",hproc));
if (!(pproc = HandleToProc(hproc))) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
DEBUGMSG(ZONE_ENTRY,(L"SC_GetProcAddrBits exit: %8.8lx\r\n",0));
return 0;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_GetProcAddrBits exit: %8.8lx\r\n",pproc->dwVMBase));
return pproc->dwVMBase;
}
// @func DWORD | GetFSHeapInfo | Gets info on the physical space reserved for the file system
// @comm Retrieves the start of the physical memory reserved for the file system
DWORD SC_GetFSHeapInfo(void) {
DEBUGMSG(ZONE_ENTRY,(L"SC_GetFSHeapInfo entry\r\n"));
DEBUGMSG(ZONE_ENTRY,(L"SC_GetFSHeapInfo exit: %8.8lx\r\n",PAGEALIGN_UP(pTOC->ulRAMFree)));
return PAGEALIGN_UP(pTOC->ulRAMFree);
}
void SC_UpdateNLSInfo(DWORD ocp, DWORD acp, DWORD locale) {
KInfoTable[KINX_NLS_OCP] = ocp;
KInfoTable[KINX_NLS_ACP] = acp;
KInfoTable[KINX_NLS_LOC] = locale;
}
DWORD randdw1, randdw2;
__int64 SC_CeGetRandomSeed() {
return (((__int64)randdw1)<<32) | (__int64)randdw2;
}
DWORD SC_GetIdleTime(void) {
DWORD result;
__int64 temp;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetIdleTime entry\r\n"));
temp = curridlehigh;
if (idleconv) {
temp = (temp * 0x100000000) + curridlelow;
result = (DWORD)(temp/idleconv);
} else
result = 0xffffffff;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetIdleTime exit: %8.8lx\r\n",result));
return result;
}
LPCWSTR SC_GetProcName(void) {
LPWSTR retval;
DEBUGMSG(ZONE_ENTRY,(L"SC_ProcGetName entry\r\n"));
retval = MapPtr(pCurProc->lpszProcName);
DEBUGMSG(ZONE_ENTRY,(L"SC_ProcGetName exit: %8.8lx\r\n",retval));
return retval;
}
// @func HANDLE | GetOwnerProcess | Returns the process id which owns the current thread
// @rdesc Returns the process id of the process which spawned the current thread
// @comm Returns the process id of the process which spawned the current thread
HANDLE SC_GetOwnerProcess(void) {
DEBUGMSG(ZONE_ENTRY,(L"SC_GetOwnerProcess entry\r\n"));
DEBUGMSG(ZONE_ENTRY,(L"SC_GetOwnerProcess exit: %8.8lx\r\n",pCurThread->pOwnerProc->hProc));
return pCurThread->pOwnerProc->hProc;
}
LPWSTR SC_GetCommandLineW(void) {
DEBUGMSG(ZONE_ENTRY,(L"SC_GetCommandLineW entry\r\n"));
DEBUGMSG(ZONE_ENTRY,(L"SC_GetCommandLineW exit: %8.8lx\r\n",pCurThread->pOwnerProc->pcmdline));
return (LPWSTR)pCurThread->pOwnerProc->pcmdline;
}
// @func HANDLE | GetCallerProcess | Returns the process id which called the currently running PSL
// @rdesc Returns the process id of the process which called the currently running PSL
// @comm Returns the process id of the process which called the currently running PSL
HANDLE SC_GetCallerProcess(void) {
HANDLE retval = 0;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetCallerProcess entry\r\n"));
if (pCurThread->pcstkTop)
if ((DWORD)pCurThread->pcstkTop->pprcLast >= 0x10000)
retval = pCurThread->pcstkTop->pprcLast->hProc;
else if ((pCurThread->pcstkTop->pcstkNext) &&
((DWORD)pCurThread->pcstkTop->pcstkNext->pprcLast >= 0x10000))
retval = pCurThread->pcstkTop->pcstkNext->pprcLast->hProc;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetCallerProcess exit: %8.8lx\r\n",retval));
return retval;
}
DWORD SC_CeGetCurrentTrust(void) {
DWORD retval;
DEBUGMSG(ZONE_ENTRY,(L"SC_CeGetCurrentTrust entry\r\n"));
retval = pCurProc->bTrustLevel;
DEBUGMSG(ZONE_ENTRY,(L"SC_CeGetCurrentTrust exit: %8.8lx\r\n",retval));
return retval;
}
DWORD SC_CeGetCallerTrust(void) {
HANDLE hval = SC_GetCallerProcess();
DWORD retval;
PPROCESS pproc;
DEBUGMSG(ZONE_ENTRY,(L"SC_CeGetCallerTrust entry\r\n"));
if (hval) {
pproc = HandleToProc(hval);
DEBUGCHK(pproc);
retval = pproc->bTrustLevel;
} else
retval = pCurProc->bTrustLevel;
DEBUGMSG(ZONE_ENTRY,(L"SC_CeGetCallerTrust exit: %8.8lx\r\n",retval));
return retval;
}
DWORD SC_GetCallerIndex(void) {
HANDLE hval = SC_GetCallerProcess();
DWORD retval;
PPROCESS pproc;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetCallerIndex entry\r\n"));
if (hval) {
pproc = HandleToProc(hval);
DEBUGCHK(pproc);
retval = pproc->procnum;
} else
retval = (DWORD)-1;
DEBUGMSG(ZONE_ENTRY,(L"SC_GetCallerIndex exit: %8.8lx\r\n",retval));
return retval;
}
#define MAX_APPSTART_INDEX 32
#define MAX_APPSTART_KEYNAME 128
typedef struct appinfo_t {
DWORD index;
DWORD done;
WORD depchain[MAX_APPSTART_INDEX];
WCHAR appname[MAX_PATH];
} appinfo_t;
HANDLE hSignalApp;
DWORD nextapp;
appinfo_t *pappinfo;
DWORD atoiW(LPWSTR str);
void SC_SignalStarted(DWORD dw) {
DWORD loop;
if (!pappinfo)
return;
if (!dw)
SetEvent(hSignalApp);
else
for (loop = 0; loop < nextapp; loop++)
if (pappinfo[loop].index == dw) {
pappinfo[loop].done = 1;
SetEvent(hSignalApp);
break;
}
}
BOOL Kbstrcmpn(LPWSTR p1, LPWSTR p2, int len) {
while (len && *p1 && (*p1 == *p2)) {
len--;
p1++;
p2++;
}
if (!len || (!*p1 && !*p2))
return 0;
return 1;
}
void kItoW(LPWSTR pStr, DWORD dw) {
if (dw >= 10000)
*pStr++ = (WCHAR)(((dw/10000)%10) + '0');
if (dw >= 1000)
*pStr++ = (WCHAR)(((dw/1000)%10) + '0');
if (dw >= 100)
*pStr++ = (WCHAR)(((dw/100)%10) + '0');
if (dw >= 10)
*pStr++ = (WCHAR)(((dw/10)%10) + '0');
*pStr++ = (WCHAR)((dw%10) + '0');
*pStr = 0;
}
BOOL CanBeLaunched(DWORD index) {
LPWORD pW;
DWORD loop;
pW = pappinfo[index].depchain;
while (*pW) {
for (loop = 0; loop < nextapp; loop++)
if (pappinfo[loop].index == *pW)
break;
if ((loop != nextapp) && !pappinfo[loop].done)
return 0;
pW++;
}
return 1;
}
BOOL fJitIsPresent;
void RunApps(ulong param) {
HKEY key;
DWORD index, enumindex;
WCHAR pName[MAX_APPSTART_KEYNAME];
BYTE pProp[MAX_PATH*sizeof(WCHAR)];
DWORD size,size2,type, loop;
appinfo_t AppInfo[MAX_APPSTART_INDEX];
appinfo_t SwapInfo;
hSignalApp = CreateEvent(0,0,0,0);
pappinfo = &AppInfo[0];
CreateProcess(L"filesys.exe",0,0,0,0,0x80000000,0,0,0,0);
WaitForMultipleObjects(1,&hSignalApp,0,INFINITE);
fJitIsPresent = InitializeJit(JitOpenFile,JitCloseFile);
// Initialize MUI-Resource loader (requires registry)
InitMUILanguages();
// read registry in
size = sizeof(pName);
if (!RegQueryValueExW(HKEY_LOCAL_MACHINE,L"JITDebugger",(LPDWORD)L"Debug",&type,(LPBYTE)pName,&size) &&
(type == REG_SZ) && (size < MAX_PATH*sizeof(WCHAR)) && (pDebugger = AllocName((strlenW(pName)+1)*2)))
kstrcpyW(pDebugger->name,pName);
size = sizeof(pProp);
if (!RegQueryValueExW(HKEY_LOCAL_MACHINE,L"SystemPath",(LPDWORD)L"Loader",&type,(LPBYTE)pProp,&size) &&
(type == REG_MULTI_SZ) && (size < MAX_PATH*sizeof(WCHAR)) && (pPath = AllocName(size)))
memcpy(pPath->name,pProp,size);
if (!(RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"init",0,KEY_ALL_ACCESS,&key))) {
size = MAX_APPSTART_KEYNAME;
size2 = MAX_PATH*sizeof(WCHAR);
enumindex = 0;
while (!RegEnumValue(key,enumindex++,pName,&size,0,&type,pProp,&size2)) {
if (!Kbstrcmpn(pName,L"Launch",6)) {
if (size2 > MAX_PATH*sizeof(WCHAR))
goto nextkey;
index = atoiW(pName+6);
for (loop = 0; loop < nextapp; loop++)
if (index == AppInfo[loop].index)
break;
if (loop == nextapp) {
if (nextapp == MAX_APPSTART_INDEX)
goto nextkey;
AppInfo[nextapp++].index = index;
}
kstrcpyW(AppInfo[loop].appname,(LPWSTR)pProp);
} else if (!Kbstrcmpn(pName,L"Depend",6)) {
if ((size2 > MAX_APPSTART_INDEX*sizeof(WORD)) || (size2 & 1))
goto nextkey;
index = atoiW(pName+6);
for (loop = 0; loop < nextapp; loop++)
if (index == AppInfo[loop].index)
break;
if (loop == nextapp) {
if (nextapp == MAX_APPSTART_INDEX)
goto nextkey;
AppInfo[nextapp++].index = index;
}
memcpy(AppInfo[loop].depchain,pProp,size2);
if (size2 != MAX_APPSTART_INDEX*sizeof(WORD))
AppInfo[loop].depchain[size2/2] = 0;
}
nextkey:
size = MAX_APPSTART_KEYNAME;
size2 = MAX_PATH*sizeof(WCHAR);
}
RegCloseKey(key);
for (size = 1; size < nextapp; size++) {
for (size2 = 0; size2 < size; size2++)
if (AppInfo[size].index < AppInfo[size2].index)
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -