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

📄 logger.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
CeLogThreadMigrate(
    HANDLE hProcess,
    DWORD dwReserved
    )
{
    DEBUGCHK(IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL));
    if (IsCeLogZoneEnabled(CELZONE_MIGRATE)) {
        CEL_THREAD_MIGRATE cl;
        
        cl.hProcess = hProcess;
        // Ignore the reserved DWORD for now
        
        g_pfnCeLogData(TRUE, CELID_THREAD_MIGRATE, &cl, sizeof(CEL_THREAD_MIGRATE),
                       0, CELZONE_MIGRATE, 0, FALSE);
    }
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
SC_CeLogData( 
    BOOL  fTimeStamp,
    WORD  wID,
    VOID  *pData,
    WORD  wLen,
    DWORD dwZoneUser,
    DWORD dwZoneCE,
    WORD  wFlag,
    BOOL  fFlagged
    )
{
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {  // Do not log during profiling
        // Check caller buffer access
        if ((KERN_TRUST_FULL != pCurProc->bTrustLevel)
            && pData && wLen) {
            pData = SC_MapPtrWithSize(pData, wLen, SC_GetCallerProcess());
            DEBUGCHK(pData);
            if (!pData) {
                // Caller does not have access to the buffer.  Allow the event
                // to be logged, but without any data.
                wLen = 0;
            }
        }

        g_pfnCeLogData(fTimeStamp, wID, pData, wLen, dwZoneUser, dwZoneCE, wFlag, fFlagged);
    }
}


// CeLog zones available in all builds
#define AVAILABLE_ZONES_ALL_BUILDS                                              \
    (CELZONE_RESCHEDULE | CELZONE_MIGRATE | CELZONE_DEMANDPAGE | CELZONE_THREAD \
     | CELZONE_PROCESS | CELZONE_PRIORITYINV | CELZONE_CRITSECT | CELZONE_SYNCH \
     | CELZONE_HEAP | CELZONE_VIRTMEM | CELZONE_LOADER | CELZONE_MEMTRACKING    \
     | CELZONE_ALWAYSON | CELZONE_MISC | CELZONE_BOOT_TIME)
// CeLog zones available only in profiling builds
#define AVAILABLE_ZONES_PROFILING \
    (CELZONE_INTERRUPT | CELZONE_TLB | CELZONE_KCALL | CELZONE_PROFILER)


// Define the zones available on this kernel
#ifdef NKPROF
#define AVAILABLE_ZONES (AVAILABLE_ZONES_ALL_BUILDS | AVAILABLE_ZONES_PROFILING)
#else
#define AVAILABLE_ZONES (AVAILABLE_ZONES_ALL_BUILDS)
#endif // NKPROF


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
SC_CeLogSetZones( 
    DWORD dwZoneUser,
    DWORD dwZoneCE,
    DWORD dwZoneProcess
    )
{
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_ANY)) {
        BroadcastCeLogSetZones(dwZoneUser, dwZoneCE, dwZoneProcess);

        // Set the new zones in UserKData
        CeLogEnableZones(g_dwZoneCE);
    }
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
SC_CeLogGetZones( 
    LPDWORD lpdwZoneUser,        // User-defined zones
    LPDWORD lpdwZoneCE,          // Predefined zones
    LPDWORD lpdwZoneProcess,     // Process zones
    LPDWORD lpdwAvailableZones   // Zones supported by this kernel
    )
{
    BOOL fResult = FALSE;

    if (IsCeLogStatus(CELOGSTATUS_ENABLED_ANY)) {
        // Check caller buffer access
        if (KERN_TRUST_FULL != pCurProc->bTrustLevel) {
            lpdwZoneUser       = SC_MapPtrWithSize(lpdwZoneUser, sizeof(DWORD), SC_GetCallerProcess());
            lpdwZoneCE         = SC_MapPtrWithSize(lpdwZoneCE, sizeof(DWORD), SC_GetCallerProcess());
            lpdwZoneProcess    = SC_MapPtrWithSize(lpdwZoneProcess, sizeof(DWORD), SC_GetCallerProcess());
            lpdwAvailableZones = SC_MapPtrWithSize(lpdwAvailableZones, sizeof(DWORD), SC_GetCallerProcess());
        }

        // Supply the available zones for this kernel
        if (lpdwAvailableZones) {
            *lpdwAvailableZones = AVAILABLE_ZONES;
        }

        // No need to call the CeLog DLLs to get current zones; we know already
        if (lpdwZoneUser) {
            *lpdwZoneUser = g_dwZoneUser;
        }
        if (lpdwZoneCE) {
            *lpdwZoneCE = g_dwZoneCE;
        }
        if (lpdwZoneProcess) {
            *lpdwZoneProcess = g_dwZoneProcess;
        }
        fResult = TRUE;
    }

    return fResult;
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// CELOG RESYNC API:  This function generates a series of calls to CeLogData, 
// to log all currently-existing processes and threads.
//

// This buffer is used during resync to minimize stack usage
union {  // Union so that the buffer is the max of all these and aligned properly
    struct {
        union {
            CEL_PROCESS_CREATE      ProcessBase;
            CEL_EXTRA_PROCESS_INFO  ProcessExtra;
            CEL_THREAD_CREATE       ThreadBase;
            CEL_MODULE_LOAD         ModuleBase;
            CEL_EXTRA_MODULE_INFO   ModuleExtra;
            CEL_SYSTEM_INVERT       Invert;
        };
        WCHAR _sz[MAX_PATH];  // Not used directly; string starts at end of data above
    };
    struct {
        CEL_MODULE_REFERENCES       ModuleRef;
        CEL_PROCESS_REFCOUNT        _ref[MAX_PROCESSES-1];  // Not used directly; list starts at end of ModuleRef
    };
} g_CeLogSyncBuffer;

// Cause the scheduler's default thread quantum to be visible
extern DWORD dwDefaultThreadQuantum;


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Helper func to generate CeLog process events, minimizing stack usage.
_inline static void 
CELOG_SyncProcess(
    PPROCESS pProc
    )
{
    PCEL_PROCESS_CREATE     pclBase  = &g_CeLogSyncBuffer.ProcessBase;
    PCEL_EXTRA_PROCESS_INFO pclExtra = &g_CeLogSyncBuffer.ProcessExtra;
    DWORD dwVMBase;
    WORD  wLen;

    // Special case: fixup nk.exe to tell where the code lives, not the VM
    dwVMBase = pProc->dwVMBase;
    if (dwVMBase == (SECURE_SECTION << VA_SECTION)) {
        dwVMBase = pTOC->physfirst;
    }

    // Log base process info
    wLen = 0;
    pclBase->hProcess = pProc->hProc;
    pclBase->dwVMBase = dwVMBase;
    if (pProc->lpszProcName) {
        wLen = strlenW(pProc->lpszProcName) + 1;
        if (wLen <= MAX_PATH) {
            kstrcpyW(pclBase->szName, pProc->lpszProcName); 
        } else {
            wLen = 0;
        }
    }

    g_pfnCeLogData(TRUE, CELID_PROCESS_CREATE, (PVOID) pclBase,
                   (WORD) (sizeof(CEL_PROCESS_CREATE) + (wLen * sizeof(WCHAR))),
                   0, CELZONE_PROCESS | CELZONE_THREAD | CELZONE_MEMTRACKING | CELZONE_PROFILER,  // CELZONE_THREAD necessary for getting thread names
                   0, FALSE);

    // Log extra process info
    pclExtra->hProcess = pProc->hProc;
    pclExtra->dwVMLen  = pProc->e32.e32_vsize;
    wLen = CELOG_FileInfoFromOE(&pProc->oe, &pclExtra->dwOID,
                                pclExtra->szFullPath);
        
    g_pfnCeLogData(TRUE, CELID_EXTRA_PROCESS_INFO, (PVOID) pclExtra,
                   (WORD) (sizeof(CEL_EXTRA_PROCESS_INFO) + (wLen * sizeof(WCHAR))),
                   0, CELZONE_PROCESS | CELZONE_LOADER | CELZONE_PROFILER,
                   0, FALSE);
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Helper func to generate a CeLog thread create event, minimizing stack usage.
_inline static void 
CELOG_SyncThread(
    PTHREAD pThread,
    HANDLE  hProcess
    )
{
    PCEL_THREAD_CREATE pcl = &g_CeLogSyncBuffer.ThreadBase;
    WORD wLen = 0;

    pcl->hProcess    = hProcess;
    pcl->hThread     = pThread->hTh;
    pcl->hModule     = (HANDLE)0;  // The reader can figure out hModule from dwStartAddr
    pcl->dwStartAddr = pThread->dwStartAddr;
    pcl->nPriority   = pThread->bBPrio;

    if (pThread == pThread->pOwnerProc->pMainTh) {
        // Main thread gets the process' name
        pcl->hModule = hProcess;
        wLen = strlenW(pThread->pOwnerProc->lpszProcName) + 1;
        if (wLen <= MAX_PATH) {
            kstrcpyW(pcl->szName, pThread->pOwnerProc->lpszProcName); 
        } else {
            wLen = 0;
        }

#ifdef NKPROF  // GetThreadName only available in profiling builds
    } else {
        GetThreadName(pThread, &(pcl->hModule), pcl->szName);
        if (pcl->szName[0] != 0) {
            wLen = strlenW(pcl->szName) + 1;
        }
#endif // NKPROF
    }

    g_pfnCeLogData(TRUE, CELID_THREAD_CREATE, (PVOID) pcl, 
                   (WORD)(sizeof(CEL_THREAD_CREATE) + (wLen * sizeof(WCHAR))),
                   0, CELZONE_THREAD | CELZONE_PROFILER, 0, FALSE);
    
    // Log priority inversion if necessary
    if (IsCeLogZoneEnabled(CELZONE_PRIORITYINV)
        && (pThread->bBPrio != pThread->bCPrio)) {

        PCEL_SYSTEM_INVERT pclInvert = &g_CeLogSyncBuffer.Invert;

        pclInvert->hThread   = pThread->hTh;
        pclInvert->nPriority = pThread->bCPrio;

        g_pfnCeLogData(TRUE, CELID_SYSTEM_INVERT, (PVOID) pclInvert,
                       sizeof(CEL_SYSTEM_INVERT), 0, CELZONE_PRIORITYINV,
                       0, FALSE);
    }
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Helper func to generate CeLog module events, minimizing stack usage.
_inline static void 
CELOG_SyncModule(
    HANDLE  hProcess,
    PMODULE pMod
    )
{
    PCEL_MODULE_LOAD       pclBase  = &g_CeLogSyncBuffer.ModuleBase;
    PCEL_EXTRA_MODULE_INFO pclExtra = &g_CeLogSyncBuffer.ModuleExtra;
    PCEL_MODULE_REFERENCES pclRef   = &g_CeLogSyncBuffer.ModuleRef;
    WORD wLen;
    WORD wProc;
    
    // Log base module info
    wLen = 0;
    pclBase->hProcess = hProcess;
    pclBase->hModule  = (HANDLE) pMod;
    pclBase->dwBase   = ZeroPtr(pMod->BasePtr);
    if (pMod->lpszModName) {
        wLen = strlenW(pMod->lpszModName) + 1;
        if (wLen <= MAX_PATH) {
            kstrcpyW(pclBase->szName, pMod->lpszModName);
        } else {
            wLen = 0;
        }
    }
    
    g_pfnCeLogData(TRUE, CELID_MODULE_LOAD, (PVOID) pclBase,
                   (WORD)(sizeof(CEL_MODULE_LOAD) + (wLen * sizeof(WCHAR))),
                   0, CELZONE_LOADER | CELZONE_THREAD | CELZONE_MEMTRACKING | CELZONE_PROFILER,  // CELZONE_THREAD necessary for getting thread names
                   0, FALSE);

    // Log extra module info
    pclExtra->hModule = (HANDLE) pMod;
    pclExtra->dwVMLen = pMod->e32.e32_vsize;
    pclExtra->dwModuleFlags = CELOG_ModuleFlags((DWORD)pMod->BasePtr);
    wLen = CELOG_FileInfoFromOE(&pMod->oe, &pclExtra->dwOID,
                                pclExtra->szFullPath);

    g_pfnCeLogData(TRUE, CELID_EXTRA_MODULE_INFO, (PVOID) pclExtra,
                   (WORD)(sizeof(CEL_EXTRA_MODULE_INFO) + (wLen * sizeof(WCHAR))),
                   0, CELZONE_LOADER | CELZONE_PROFILER,
                   0, FALSE);

    // Log per-process refcounts for the module
    wLen = 0;
    pclRef->hModule = (HANDLE) pMod;
    for (wProc = 0; wProc < MAX_PROCESSES; wProc++) {
        if (pMod->refcnt[wProc] > 0) {
            pclRef->ref[wLen].hProcess = ProcArray[wProc].hProc;
            pclRef->ref[wLen].dwRefCount = pMod->refcnt[wProc];
            wLen++;
        }
    }

    if (wLen > 0) {
        g_pfnCeLogData(TRUE, CELID_MODULE_REFERENCES, (PVOID) pclRef,
                       (WORD) (sizeof(CEL_MODULE_REFERENCES) + ((wLen - 1) * sizeof(CEL_PROCESS_REFCOUNT))),
                       0, CELZONE_LOADER | CELZONE_PROFILER, 0, FALSE);
    }
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_CeLogReSync()
{
    CEL_LOG_MARKER marker;

    // KCall so nobody changes ProcArray or pModList out from under us
    if (!InSysCall()) {
        return KCall((PKFN)SC_CeLogReSync);
    }

    KCALLPROFON(74);

    if (IsCeLogStatus(CELOGSTATUS_ENABLED_ANY)) {
        // Send a marker
        marker.dwFrequency = g_dwCeLogTimerFrequency;
        marker.dwDefaultQuantum = dwDefaultThreadQuantum;
        marker.dwVersion = CELOG_VERSION;
        g_pfnCeLogData(FALSE, CELID_LOG_MARKER, &marker, sizeof(CEL_LOG_MARKER),
                       0, CELZONE_ALWAYSON, 0, FALSE);


        // Log the list of processes and threads
        if (IsCeLogEnabled(CELOGSTATUS_ENABLED_ANY,
                           CELZONE_PROCESS | CELZONE_THREAD
                           | CELZONE_MEMTRACKING | CELZONE_PROFILER)) {
            ACCESSKEY ulOldKey;
            int       nProc;

            // Since we're in a KCall, we must limit stack usage, so we can't
            // call CELOG_ProcessCreate, CELOG_ThreadCreate, CELOG_ModuleLoad
            // -- instead use CELOG_Sync*.
    
            SWITCHKEY(ulOldKey, 0xffffffff); // Need access to touch procnames
            for (nProc = 0; nProc < 32; nProc++) {
    
                if (ProcArray[nProc].dwVMBase) {
                    THREAD* pThread;
    
                    // Log the process
                    CELOG_SyncProcess(&ProcArray[nProc]);
    
                    // Log each of the process' threads
                    if (IsCeLogEnabled(CELOGSTATUS_ENABLED_ANY,
                                       CELZONE_THREAD | CELZONE_PROFILER)) {
                        pThread = ProcArray[nProc].pTh;
                        while (pThread != NULL) {
                            CELOG_SyncThread(pThread, pThread->pOwnerProc->hProc);
                            pThread = pThread->pNextInProc;
                        }
                    }
                }
            }
            SETCURKEY(ulOldKey);
        }

        // Log the list of modules
        if (IsCeLogEnabled(CELOGSTATUS_ENABLED_ANY,
                           CELZONE_LOADER | CELZONE_THREAD
                           | CELZONE_MEMTRACKING | CELZONE_PROFILER)) {
            PMODULE pMod;
            for (pMod = pModList; pMod; pMod = pMod->pMod) {
                CELOG_SyncModule(INVALID_HANDLE_VALUE, pMod);
            }
        }

        // Send a sync end marker
        g_pfnCeLogData(FALSE, CELID_SYNC_END, NULL, 0, 0, CELZONE_ALWAYSON,
                       0, FALSE);
    }

    KCALLPROFOFF(74);

    return TRUE;
}

⌨️ 快捷键说明

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