⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kwin32.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 4 页
字号:
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
SC_SetHardwareWatch(
    LPVOID vAddr,
    DWORD flags
    )
{
    LPVOID pAddr = 0;
    extern SetCPUHardwareWatch(LPVOID,DWORD);

    TRUSTED_API ("SC_SetHardwareWatch", FALSE);
    
#ifdef MIPS
    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 {
        TRUSTED_API (L"SC_SetKMode", FALSE);
        
        pcstk = pCurThread->pcstkTop;
        bRet = !((DWORD)pcstk->dwPrcInfo & CST_MODE_FROM_USER);

        // can't set kmode to false if our base mode is kmode
        if (!pcstk->pcstkNext || (pcstk->pcstkNext->dwPrcInfo & CST_MODE_TO_USER)) {
            if (newMode)
                pcstk->dwPrcInfo &= ~CST_MODE_FROM_USER;     // to KMode --> clear the bit
            else
                pcstk->dwPrcInfo |= CST_MODE_FROM_USER;      // to UMode --> set the bit
        } else {
            DEBUGCHK (bRet);    // we must be in KMode here
        }
    }
    return bRet;
}

void UpdateCallerInfo (PTHREAD pth, BOOL fInKMode);
void SwitchBack();
void InitClock(void);

PPROCESS SwitchToProcPtr(
	CALLSTACK*	pcstk,
	PPROCESS    pprc
	)
{
	pcstk->pprcLast = pCurProc;
	pcstk->akyLast = CurAKey;
	pcstk->retAddr = 0;
	pcstk->dwPrevSP = 0;
	pcstk->pcstkNext = pCurThread->pcstkTop;
	pcstk->dwPrcInfo = 0;
	pCurThread->pcstkTop = pcstk;
	pCurThread->pProc = pprc;
	AddAccess(&pCurThread->aky, pprc->aky);
	SetCPUASID(pCurThread);
	UpdateCallerInfo (pCurThread, TRUE);

	return pcstk->pprcLast;
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
SC_SetPowerOffHandler(
    FARPROC pfn
    )
{
    TRUSTED_API (L"SC_SetPowerOffHandler", FALSE);
    
    PowerKey = GETCURKEY();
    PowerFunc = pfn;
    PowerProc = pCurProc;
    return TRUE;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
SC_SetGwesPowerHandler(
    FARPROC pfn
    )
{
    TRUSTED_API (L"SC_SetGwesPowerHandler", FALSE);
    GwesPowerKey = GETCURKEY();
    GwesPowerFunc = pfn;
    GwesPowerProc = pCurProc;
    return TRUE;
}



//------------------------------------------------------------------------------
//
//  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(
        PPROCESS    pprc,
        FARPROC     pfn,
        BOOL        bOff,
        LPCWSTR     pszMsg
    )
{

    if (pfn) {
        CALLSTACK cstk;
        RETAILMSG(1, (pszMsg));

        SwitchToProcPtr (&cstk, pprc);
        (*pfn)(bOff);       /* set power off state */
        SwitchBack ();
    }
}

void CallOEMPowerOff (void)
{
    INTERRUPTS_OFF ();
#if SHx
    OEMCacheRangeFlush (0, 0, CACHE_SYNC_DISCARD | CACHE_SYNC_INSTRUCTIONS);
#endif
    OEMPowerOff ();
#if SHx
    OEMCacheRangeFlush (0, 0, CACHE_SYNC_DISCARD | CACHE_SYNC_INSTRUCTIONS);
#endif
    InitClock ();
    INTERRUPTS_ON ();
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void SC_PowerOffSystem(void) 
{
    extern DWORD bLastIdle;
    extern HANDLE hEvtPwrHndlr;
    DWORD  bPrio = GET_BPRIO(pCurThread);
    DWORD  dwQuantum = pCurThread->dwQuantum;

    TRUSTED_API_VOID (L"SC_PowerOffSystem");
    bLastIdle = 0;
    
    SC_CeSetThreadPriority (hCurThread, 0);
    SC_CeSetThreadQuantum (hCurThread, 0);

    // this retail message is required to make sure no other thread holds the 
    // CS for debug transport. 
    // NOTE: must be done after we change the priority and before setting 
    //       PowerOffFlag
    RETAILMSG(1, (TEXT("Powering Off system:\r\n")));

    PowerOffFlag = TRUE;

    SetEvent (hEvtPwrHndlr);

    /* Tell GWES and FileSys that we are turning power off */
    CallPowerProc (GwesPowerProc, GwesPowerFunc, TRUE, TEXT("  Calling GWES power proc.\r\n"));
    CallPowerProc (PowerProc, PowerFunc, TRUE, TEXT("  Calling device manager power proc.\r\n"));

    RETAILMSG(1, (TEXT("  Calling OEMPowerOff...\r\n")));

    KCall ((FARPROC) CallOEMPowerOff);

    KInfoTable[KINX_TIMECHANGECOUNT] ++;    // indicate time changed since tick won't run while powered off
    RETAILMSG(1, (TEXT("Back from OEMPowerOff\r\n")));

    /* Tell GWES and Device manager that we are turning power back on */
    CallPowerProc (PowerProc, PowerFunc, FALSE, TEXT("  Calling device manager power proc.\r\n"));
    CallPowerProc (GwesPowerProc, GwesPowerFunc, FALSE, TEXT("  Calling GWES power proc.\r\n"));

    RETAILMSG(1, (TEXT("  Returning to normally scheduled programming.\r\n")));

    // If platform supports debug Ethernet, turn interrupts back on
    if (pKITLInitializeInterrupt)
        pKITLInitializeInterrupt();

    PowerOffFlag = FALSE;

    SC_CeSetThreadQuantum (hCurThread, dwQuantum);
    SC_CeSetThreadPriority (hCurThread, bPrio);
}




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
KITLWriteDebugString(
    unsigned short *str
    ) 
{
    UCHAR FmtBuf[256+sizeof(KITL_DBGMSG_INFO)];
    KITL_DBGMSG_INFO *pDbgInfo = (KITL_DBGMSG_INFO *)FmtBuf;
    // Prepend a header so that application on the other side can get timing
    // and thread info.
    pDbgInfo->dwLen      = sizeof(KITL_DBGMSG_INFO);
    pDbgInfo->dwThreadId = (DWORD)hCurThread;
    pDbgInfo->dwProcId   = (DWORD)hCurProc;
    pDbgInfo->dwTimeStamp = CurMSec;
    KUnicodeToAscii(FmtBuf+sizeof(KITL_DBGMSG_INFO),str,256);
    pKITLSend(KITL_SVC_DBGMSG, FmtBuf, sizeof(KITL_DBGMSG_INFO)+strlen(FmtBuf+sizeof(KITL_DBGMSG_INFO))+1);
}

// kernelIoctl: route it through KITL before calling OEMIoControl
BOOL KernelIoctl (DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
    DWORD dwRet = ERROR_NOT_SUPPORTED;
    BOOL fRet;

    switch (dwIoControlCode) {
    // allow non-trusted apps to get device id/info
    case IOCTL_HAL_GET_CACHE_INFO:
        if (sizeof (CacheInfo) != nOutBufSize) {
            KSetLastError (pCurThread, ERROR_INVALID_PARAMETER);
            return FALSE;
        }
        // fall through
    case IOCTL_HAL_GET_DEVICE_INFO:
    case IOCTL_HAL_GET_DEVICEID:
        // validate parameters if caller is not fully trusted
        if ((KERN_TRUST_FULL != pCurProc->bTrustLevel)
            && ((lpInBuf && !SC_MapPtrWithSize (lpInBuf, nInBufSize, hCurProc))
                || !lpOutBuf
                || !SC_MapPtrWithSize (lpOutBuf, nOutBufSize, hCurProc)
                || (lpBytesReturned && !SC_MapPtrWithSize (lpBytesReturned, sizeof (DWORD), hCurProc)))) {
            KSetLastError (pCurThread, ERROR_INVALID_PARAMETER);
            return FALSE;
        }
        break;
    default:
        TRUSTED_API (L"KernelIoctl", FALSE);
        if (pKITLIoCtl) {
            dwRet =  pKITLIoCtl (dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned);
        }
        break;
    }

    if (ERROR_NOT_SUPPORTED == dwRet){
        if (IOCTL_HAL_REBOOT == dwIoControlCode){
            KDReboot(TRUE);     // Inform kdstub we are about to reboot
        }
        fRet = OEMIoControl (dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned);
        if (IOCTL_HAL_REBOOT == dwIoControlCode){
            Sleep(1000);        // Allow time for hardware to reset        
            KDReboot(FALSE);    // Inform kdstub reboot failed
        }
    }
    else {
        fRet = (BOOL) dwRet;
    }
    return fRet;
}


//------------------------------------------------------------------------------
//
//  Routine to start DBGMSG and PPSH KITL service.
//
//------------------------------------------------------------------------------
BOOL
SetKernelCommDev (
    UCHAR Service,
    UCHAR CommDevice
    )
{
    UCHAR *PpfsEthBuf;

    // only support KERNEL_COMM_ETHER
    if (KERNEL_COMM_ETHER != CommDevice) {
        return FALSE;
    }
    switch (Service) {
    case KERNEL_SVC_DBGMSG:
        if (pKITLRegisterDfltClient &&
            pKITLRegisterDfltClient(KITL_SVC_DBGMSG,0,NULL,NULL)) {
            lpWriteDebugStringFunc = KITLWriteDebugString;
            return TRUE;
        }
        break;

    case KERNEL_SVC_PPSH:
        if (pKITLRegisterDfltClient &&
            pKITLRegisterDfltClient(KITL_SVC_PPSH,0,&PpfsEthBuf,&PpfsEthBuf)) {
            return TRUE;
        }
        break;
    default:
        break;
    }
    return FALSE;
}

void UnloadExe(PPROCESS pProc);
void UnloadMod(PMODULE pMod);

static DWORD UnloadDepends (PPROCESS pprc, DWORD dwFlags)
{
    PMODULE pMod;
    DWORD   dwErr = 0;
    EnterCriticalSection (&ModListcs);
    __try {
        for (pMod = pModList; pMod; pMod = pMod->pMod) {
            if ((pMod->inuse & pprc->aky)               // the module is loaded by the process
                && PageAble (&pMod->oe)                 // the module is pageable
                && ((PAGE_OUT_ALL_DEPENDENT_DLL == dwFlags)     // either the flags say to page out all
                    || !(pMod->inuse & ~pprc->aky))) {          // or we're the only only process using this moudle
                UnloadMod (pMod);
            }
        }
    } __except (EXCEPTION_EXECUTE_HANDLER) {
        dwErr = ERROR_INVALID_PARAMETER;
    }
    LeaveCriticalSection (&ModListcs);
    return dwErr;
}

//------------------------------------------------------------------------------
// Page out a particular module
//------------------------------------------------------------------------------
static BOOL SC_PageOutModule (HANDLE hModule, DWORD dwFlags)
{
    PPROCESS pprc = NULL;
    PMODULE  pMod = NULL;
    DWORD    dwErr = 0;
    ACCESSKEY oldaky;


    TRUSTED_API (L"SC_PageOutModule", FALSE);

    EnterCriticalSection (&PageOutCS);      // criticalsection ordering require pageoutCS to 
    EnterCriticalSection (&LLcs);           // be held before Loader CS

    switch (dwFlags) {
    case PAGE_OUT_PROCESS_ONLY:
    case PAGE_OUT_DLL_USED_ONLY_BY_THISPROC:
    case PAGE_OUT_ALL_DEPENDENT_DLL:
        if (!hModule
            || (hModule == ProcArray[0].hProc)          // cannot page out NK
            || (GetCurrentProcess() == hModule)         // page out current process - not a good idea
            || (hCurProc == hModule)
            || (!(pprc = HandleToProc (hModule))                    // has to be valid process
                && !IsValidModule (pMod = (PMODULE) hModule))) {    // or a valid module
            dwErr = ERROR_INVALID_HANDLE;
            break;
        }

        SWITCHKEY (oldaky, 0xFFFFFFFF);
        __try {
            if (pprc) {
                // paging out a process
                UnloadExe (pprc);

                // pageout dependent modules based on flags
                if  (PAGE_OUT_PROCESS_ONLY != dwFlags)
                    dwErr = UnloadDepends (pprc, dwFlags);
                
            } else if (PageAble (&pMod->oe)) {
                UnloadMod (pMod);
            }
        } __except (EXCEPTION_EXECUTE_HANDLER) {
            dwErr = ERROR_INVALID_PARAMETER;
        }
        SETCURKEY (oldaky);
        break;
    default:
        dwErr = ERROR_INVALID_PARAMETER;
    }
    
    LeaveCriticalSection (&LLcs);
    LeaveCriticalSection (&PageOutCS);

    if (dwErr)
        KSetLastError (pCurThread, dwErr);

    return !dwErr;
}

⌨️ 快捷键说明

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