📄 kwin32.c
字号:
ERRORMSG(1,(L"SC_ConnectDebugger failed due to insufficient trust\r\n"));
KSetLastError(pCurThread,ERROR_ACCESS_DENIED);
return FALSE;
}
if (DbgInit(&kdp,pTOC,ProcArray,&p1, &p2, &p3,(LPVOID)KDCleanup,&p4,&p5)) {
KDPrintString = (BOOLEAN (*)(IN LPCWSTR))p1;
KDUpdateSymbols = (void (*)(DWORD, BOOL))p2;
KDTrap = (ULONG (*)(PEXCEPTION_RECORD, CONTEXT *, BOOLEAN))p3;
KDSetLoadSymbolsFlag=(BOOLEAN (*)())p4;
KDResetLoadSymbolsFlag=(BOOLEAN (*)())p5;
EnterCriticalSection(&LLcs);
DoLoadAllSymbols();
LeaveCriticalSection(&LLcs);
return TRUE;
}
#ifdef DEBUG
lpWriteDebugStringFunc(TEXT("ConnectDebugger Failed\r\n"));
#endif
return FALSE;
}
void KernelInit(void) {
#ifdef DEBUG
lpWriteDebugStringFunc(TEXT("Windows CE KernelInit\r\n"));
#endif
/* setup the well known system API sets & API types */
SystemAPISets[SH_WIN32] = &cinfWin32;
SystemAPISets[SH_CURTHREAD] = &cinfThread;
SystemAPISets[SH_CURPROC] = &cinfProc;
SystemAPISets[HT_EVENT] = &cinfEvent;
SystemAPISets[HT_MUTEX] = &cinfMutex;
SystemAPISets[HT_SEMAPHORE] = &cinfSem;
SystemAPISets[HT_APISET] = &cinfAPISet;
SystemAPISets[HT_FILE] = &CinfFile;
SystemAPISets[HT_FIND] = &CinfFind;
SystemAPISets[HT_DBFILE] = &CinfDBFile;
SystemAPISets[HT_DBFIND] = &CinfDBFind;
SystemAPISets[HT_SOCKET] = &CinfSocket;
SystemAPISets[HT_FSMAP] = &cinfMap;
SystemAPISets[HT_WNETENUM] = &CinfWnetEnum;
KInfoTable[KINX_APISETS] = (DWORD)SystemAPISets;
HeapInit();
InitMemoryPool();
ProcInit();
SchedInit();
ProfInit();
#ifdef DEBUG
lpWriteDebugStringFunc(TEXT("Scheduling the first thread.\r\n"));
#endif
}
void KernelInit2(void) {
LPVOID p1, p2, p3,p4,p5;
DEBUGMSG(1, (TEXT("KernelInit2: pCurThread=%8.8lx hCurThread=%8.8lx hCurProc=%8.8lx\r\n"),
pCurThread, hCurThread, hCurProc));
/* initialize kernel debugger subsystem if present. */
if (PKDInit) {
#ifdef DEBUG
lpWriteDebugStringFunc(TEXT("Entering KdInit\r\n"));
#endif
// rameshk
// added an additional arg KDCleanup and p4,p5
if (PKDInit(&p1, &p2, &p3,(LPVOID)KDCleanup,&p4,&p5)) {
KDPrintString = (BOOLEAN (*)(IN LPCWSTR))p1;
KDUpdateSymbols = (void (*)(DWORD, BOOL))p2;
KDTrap = (ULONG (*)(PEXCEPTION_RECORD, CONTEXT *, BOOLEAN))p3;
KDUpdateSymbols((DWORD)ProcArray[0].BasePtr+1, FALSE); // the kernel
if ((CommDev[KERNEL_SVC_DBGMSG] == KERNEL_COMM_SERIAL) &&
(CommDev[KERNEL_SVC_KDBG] == KERNEL_COMM_SERIAL))
lpWriteDebugStringFunc = KDPrintString;
ReadyForStrings = TRUE;
}
#ifdef DEBUG
lpWriteDebugStringFunc(TEXT("KdInit Done\r\n"));
#endif
}
InitializeCriticalSection(&ODScs);
InitializeCriticalSection(&CompCS);
InitializeCriticalSection(&PhysCS);
InitializeCriticalSection(&VAcs);
InitializeCriticalSection(&LLcs);
InitializeCriticalSection(&ModListcs);
InitializeCriticalSection(&ppfscs);
InitializeCriticalSection(&RFBcs);
InitializeCriticalSection(&MapCS);
InitializeCriticalSection(&NameCS);
InitializeCriticalSection(&MapNameCS);
InitializeCriticalSection(&DbgApiCS);
InitializeCriticalSection(&PagerCS);
InitializeCriticalSection(&PageOutCS);
InitializeCriticalSection(&WriterCS);
// If logging enabled (NKPROF), initialize.
CELOGINIT();
#ifdef MEMTRACKING
MemTrackInit();
#endif
}
void SC_SetExceptionHandler(PEXCEPTION_ROUTINE per) {
ERRORMSG(pCurProc->bTrustLevel != KERN_TRUST_FULL,(L"SC_SetExceptionHandler failed due to insufficient trust\r\n"));
if (pCurProc->bTrustLevel == KERN_TRUST_FULL)
pCurProc->pfnEH = per;
}
BOOL SC_Nop() {
return TRUE;
}
BOOL SC_NotSupported() {
KSetLastError(pCurThread,ERROR_NOT_SUPPORTED);
return FALSE;
}
BOOL SC_SetHardwareWatch(LPVOID vAddr, DWORD flags)
{
extern SetCPUHardwareWatch(LPVOID,DWORD);
#ifdef MIPS
LPVOID pAddr;
vAddr = MapPtrProc(vAddr, pCurProc);
pAddr = VerifyAccess(vAddr, VERIFY_KERNEL_OK|VERIFY_READ_FLAG, 0xffffffff);
SetCPUHardwareWatch(pAddr, flags);
return TRUE;
#elif x86
// Make sure this runs without preemption
vAddr = MapPtrProc(vAddr, pCurProc);
SetCPUHardwareWatch(vAddr, flags);
return TRUE;
#else
return FALSE;
#endif
}
BOOL SC_SetKMode(BOOL newMode)
{
PCALLSTACK pcstk;
BOOL bRet;
// Retrive the previous mode from the callstack structure because the thread is now
// in kernel mode because it is running here. Then update the callstack to switch to
// the desired mode when we return.
if (bAllKMode)
bRet = 1;
else {
pcstk = pCurThread->pcstkTop;
bRet = (DWORD)pcstk->pprcLast == KERNEL_MODE;
ERRORMSG(pCurProc->bTrustLevel != KERN_TRUST_FULL,(L"SC_SetKMode failed due to insufficient trust\r\n"));
if (pCurProc->bTrustLevel == KERN_TRUST_FULL)
pcstk->pprcLast = (HANDLE)(newMode ? KERNEL_MODE : USER_MODE);
}
return bRet;
}
void SC_PowerOffSystem(void) {
if (pCurProc->bTrustLevel == KERN_TRUST_FULL)
PowerOffFlag = TRUE;
}
BOOL SC_SetPowerOffHandler(FARPROC pfn)
{
ERRORMSG(pCurProc->bTrustLevel != KERN_TRUST_FULL,(L"SC_SetPowerOffHandler failed due to insufficient trust\r\n"));
if ((pCurProc->bTrustLevel == KERN_TRUST_FULL) && !PowerProc) {
PowerKey = GETCURKEY();
PowerFunc = pfn;
PowerProc = pCurProc;
return TRUE;
}
return FALSE;
}
BOOL SC_SetGwesPowerHandler(FARPROC pfn)
{
ERRORMSG(pCurProc->bTrustLevel != KERN_TRUST_FULL,(L"SC_SetGwesPowerHandler failed due to insufficient trust\r\n"));
if ((pCurProc->bTrustLevel == KERN_TRUST_FULL) && !GwesPowerProc) {
GwesPowerKey = GETCURKEY();
GwesPowerFunc = pfn;
GwesPowerProc = pCurProc;
return TRUE;
}
return FALSE;
}
BOOL SC_SetWDevicePowerHandler(FARPROC pfn)
{
ERRORMSG(pCurProc->bTrustLevel != KERN_TRUST_FULL,(L"SC_SetWDevicePowerHandler failed due to insufficient trust\r\n"));
if ((pCurProc->bTrustLevel == KERN_TRUST_FULL) && !WDevicePowerProc) {
WDevicePowerKey = GETCURKEY();
WDevicePowerFunc = pfn;
WDevicePowerProc = pCurProc;
return TRUE;
}
return FALSE;
}
/* Invoke power on/off handler in the registered process space. Note that the
* current thread is used to set the access key and process address space information
* but that the thread is not actually scheduled in this state. Since a reschedule
* will always occur after a power off, it is not necessary to call SetCPUASID to
* restore the address space information when we are done.
*/
void CallPowerProc(PTHREAD pth, ACCESSKEY aky, PPROCESS pprc, FARPROC pfn, BOOL bOff)
{
ACCESSKEY oldAky;
PPROCESS pOldProc;
if (pfn) {
oldAky = pth->aky;
pOldProc = pth->pProc;
pth->aky = aky;
pth->pProc = pprc;
SetCPUASID(pCurThread);
(*pfn)(bOff); /* set power off state */
pth->aky = oldAky;
pth->pProc = pOldProc;
}
}
extern void InitClock(void);
void DoPowerOff(void)
{
extern DWORD bLastIdle;
/* Tell GWES and FileSys that we are turning power off */
bLastIdle = 0;
RETAILMSG(1, (TEXT("Powering Off system:\r\n")));
RETAILMSG(1, (TEXT(" Calling GWES power proc.\r\n")));
CallPowerProc(pCurThread, GwesPowerKey, GwesPowerProc, GwesPowerFunc, TRUE);
RETAILMSG(1, (TEXT(" Calling WDevice power proc.\r\n")));
CallPowerProc(pCurThread, WDevicePowerKey, WDevicePowerProc, WDevicePowerFunc, TRUE);
RETAILMSG(1, (TEXT(" Calling Filesys power proc.\r\n")));
CallPowerProc(pCurThread, PowerKey, PowerProc, PowerFunc, TRUE);
RETAILMSG(1, (TEXT(" Calling OEMPowerOff...\r\n")));
#if SHx
FlushCache();
#endif
OEMPowerOff();
RETAILMSG(1, (TEXT("Back from OEMPowerOff\r\n")));
#if SHx
FlushCache();
#endif
InitClock(); /* reinitialize timer h/w */
/* Tell GWES and FileSys that we are turning power back on */
RETAILMSG(1, (TEXT(" Calling Filesys power proc.\r\n")));
CallPowerProc(pCurThread, PowerKey, PowerProc, PowerFunc, FALSE);
RETAILMSG(1, (TEXT(" Calling WDevice power proc.\r\n")));
CallPowerProc(pCurThread, WDevicePowerKey, WDevicePowerProc, WDevicePowerFunc, FALSE);
RETAILMSG(1, (TEXT(" Calling GWES power proc.\r\n")));
CallPowerProc(pCurThread, GwesPowerKey, GwesPowerProc, GwesPowerFunc, FALSE);
RETAILMSG(1, (TEXT(" Returning to normally scheduled programming.\r\n")));
// If platform supports debug Ethernet, turn interrupts back on
if (pEdbgInitializeInterrupt)
pEdbgInitializeInterrupt();
}
// rameshk
// This function is called when kdstub gets Terminate Message from windbg
// It simply reverts back KDTrap,KDUpdateSymbols and KDPrintString function pointers
// to FAKE functions.
BOOLEAN KDCleanup(void)
{
KDTrap=FakeKDTrap;
KDUpdateSymbols=FakeUpdateSymbols;
KDPrintString=FakePrintString;
return TRUE;
}
BOOLEAN FakePrintString(IN LPCWSTR Output)
{
return TRUE;
}
BOOLEAN FakeSetLoadSymbolsFlag()
{
return TRUE;
}
BOOLEAN FakeResetLoadSymbolsFlag()
{
return TRUE;
}
VOID (*pWriteDebugLED)(WORD wIndex, DWORD dwPattern);
VOID SC_WriteDebugLED(WORD wIndex, DWORD dwPattern) {
if( pWriteDebugLED )
pWriteDebugLED( wIndex, dwPattern );
}
// Print debug message using debug Ethernet card
void
EdbgWriteDebugString(unsigned short *str) {
UCHAR FmtBuf[256+sizeof(EDBG_DBGMSG_INFO)];
EDBG_DBGMSG_INFO *pDbgInfo = (EDBG_DBGMSG_INFO *)FmtBuf;
// Prepend a header so that application on the other side can get timing
// and thread info.
pDbgInfo->dwLen = sizeof(EDBG_DBGMSG_INFO);
pDbgInfo->dwThreadId = (DWORD)pCurThread;
pDbgInfo->dwProcId = (DWORD)pCurProc;
pDbgInfo->dwTimeStamp = CurMSec;
KUnicodeToAscii(FmtBuf+sizeof(EDBG_DBGMSG_INFO),str,256);
pEdbgSend(EDBG_SVC_DBGMSG, FmtBuf, sizeof(EDBG_DBGMSG_INFO)+strlenW(str)+1);
}
/* Routine to change communications device used for debug kernel services (debug msgs,
* PPFS, kernel debugger). Be careful with PPSH and windbg - if they are configured
* to run over a serial or parallel link with debug messages, an alternate debug message
* function must be called to format the data. Note that windbg and ppsh cannot
* be run together over serial or parallel.
*/
BOOL
SetKernelCommDev (UCHAR Service, UCHAR CommDevice)
{
switch (Service) {
case KERNEL_SVC_DBGMSG:
switch(CommDevice) {
case KERNEL_COMM_SERIAL:
if (CommDev[KERNEL_SVC_PPSH] == KERNEL_COMM_SERIAL)
lpWriteDebugStringFunc = PpfsWriteDebugString;
else if (ReadyForStrings && (CommDev[KERNEL_SVC_KDBG] == KERNEL_COMM_SERIAL))
lpWriteDebugStringFunc = KDPrintString;
else
lpWriteDebugStringFunc = OEMWriteDebugString;
break;
case KERNEL_COMM_PARALLEL:
lpWriteDebugStringFunc = PpfsWriteDebugString;
break;
case KERNEL_COMM_ETHER:
if (pEdbgRegisterDfltClient &&
pEdbgRegisterDfltClient(EDBG_SVC_DBGMSG,0,NULL,NULL))
lpWriteDebugStringFunc = EdbgWriteDebugString;
else
return FALSE;
break;
}
break;
case KERNEL_SVC_PPSH:
switch(CommDevice) {
case KERNEL_COMM_SERIAL:
lpParallelPortSendByteFunc = OEMWriteDebugByte;
lpParallelPortGetByteFunc = OEMReadDebugByte;
if (CommDev[KERNEL_SVC_DBGMSG] == KERNEL_COMM_SERIAL)
lpWriteDebugStringFunc = PpfsWriteDebugString;
break;
case KERNEL_COMM_PARALLEL:
lpParallelPortSendByteFunc = OEMParallelPortSendByte;
lpParallelPortGetByteFunc = OEMParallelPortGetByte;
break;
case KERNEL_COMM_ETHER:
if (pEdbgRegisterDfltClient &&
pEdbgRegisterDfltClient(EDBG_SVC_PPSH,0,&PpfsEthBuf,&PpfsEthBuf)) {
lpParallelPortSendByteFunc = ppfs_send_byte_ether;
lpParallelPortGetByteFunc = ppfs_get_byte_ether;
BufferedPPFS = TRUE;
}
else
return FALSE;
break;
}
break;
case KERNEL_SVC_KDBG:
// For debugger, just set CommDev, KD will look at this in
// KDInit and set up communications appropriately. So, this will
// only work at init (e.g. in OEMInit) time...
break;
}
CommDev[Service] = CommDevice;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -