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

📄 celog.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
EXT_LogData( 
    BOOL fTimeStamp,
    WORD wID,
    VOID *pData,
    WORD wLen,
    DWORD dwZoneUser,
    DWORD dwZoneCE,
    WORD wFlag,
    BOOL fFlagged
    )
{
    LARGE_INTEGER liPerfCount;
    DWORD dwLen, dwHeaderLen;
    WORD wFlagID = 0;
    BOOL fWasIntEnabled;

    if (!g_fInit) {
        //
        // we either failed the init, or haven't been initialized yet!
        //
        return;
    }

    // Better provide data if wLen > 0
    if ((pData == NULL) && (wLen != 0)) {
        DEBUGCHK(0);
        return;
    }
    
    DEBUGCHK(wID < CELID_MAX);                // Out of range
    DEBUGCHK(dwZoneCE || dwZoneUser);         // Need to provide some zone.

    
//    if (!(pCelBuf->dwMaskProcess & (pCurThread->pOwnerProc->aky))) {
//        //
//        // Logging is disabled for all threads of this process
//        //
//        return;
//    }

    fWasIntEnabled = PRIV_FUNC(INTERRUPTS_ENABLE, (FALSE));
    if (wID == CELID_THREAD_SWITCH) {
        //
        // We handle thread switches specially. Flush the immediate buffer.
        //
        if (PUB_FUNC(InSysCall, ())) {
            INT_FlushBuffer();
        } else {
            PRIV_FUNC(KCall, ((PKFN)INT_FlushBuffer));
        }
    }

    if (!(pCelBuf->dwMaskUser & dwZoneUser) && !(pCelBuf->dwMaskCE & dwZoneCE)) {
        //
        // This zone(s) is disabled.
        //
        PRIV_FUNC(INTERRUPTS_ENABLE, (fWasIntEnabled));
        return;
    }
       
    //
    // DWORD-aligned length
    //
    dwLen = (wLen + 3) & ~3;
    dwHeaderLen = 8 + (fFlagged ? 4 : 0);
    
    if (pCelBuf->dwBytesLeft < (dwLen + dwHeaderLen)) {
        if (PUB_FUNC(InSysCall, ())) {
            INT_FlushBuffer();
        } else {
            PRIV_FUNC(KCall, ((PKFN)INT_FlushBuffer));
        }
    }
    
    // Must get timestamp AFTER the flushbuffer call, because CeLog calls can
    // be generated by the flush itself, and appear out-of-order.
    if (fTimeStamp) {
        if (PUB_FUNC(QueryPerformanceCounter, (&liPerfCount))) {
            liPerfCount.QuadPart >>= g_dwPerfTimerShift;
        } else {
            // Call failed; caller is probably not trusted
            fTimeStamp = FALSE;
        }
    }

        
    // Header for unflagged data:
    
    //   <---------------- 1 DWORD ----------------->
    //  |T|R|       ID        |          Len         |
    //  |                 Timestamp                  | (if T=1)
    //  |                   Data...                  | (etc)

    // Header for flagged data:
    
    //   <---------------- 1 DWORD ----------------->
    //  |T|R|  CELID_FLAGGED  |          Len         |
    //  |                 Timestamp                  | (if T=1)
    //  |         ID          |         Flag         |
    //  |                   Data...                  | (etc)
        
    
    // If the data has a flag, use the ID CELID_FLAGGED and move the real ID
    // inside the data.
    if (fFlagged) {
        wFlagID = wID;
        wID = CELID_FLAGGED;
    }


    *pCelBuf->pWrite++ = fTimeStamp << 31 | wID << 16 | wLen;
    pCelBuf->dwBytesLeft -= sizeof(DWORD);

    if (fTimeStamp) {
        *pCelBuf->pWrite++ = liPerfCount.LowPart;
        pCelBuf->dwBytesLeft -= sizeof(DWORD);
    }

    if (fFlagged) {
        *pCelBuf->pWrite++ = wFlagID << 16 | wFlag;
        pCelBuf->dwBytesLeft -= sizeof(DWORD);
    }

    if (pData && wLen) {
        memcpy(pCelBuf->pWrite, pData, wLen);
    }
    pCelBuf->pWrite += (dwLen >> 2);
    pCelBuf->dwBytesLeft -= dwLen;
    
    PRIV_FUNC(INTERRUPTS_ENABLE, (fWasIntEnabled));
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
EXT_LogInterrupt( 
    DWORD dwLogValue
    )
{
    LARGE_INTEGER liPerfCount;

    if (!g_fInit) {
        //
        // we either failed the init, or haven't been initialized yet!
        //
        return;
    }

    if (!(pCelBuf->dwMaskCE & CELZONE_INTERRUPT)) {
        //
        // This zone(s) is disabled.
        //
        return;
    }

    if (PUB_FUNC(QueryPerformanceCounter, (&liPerfCount))) {
        liPerfCount.QuadPart >>= g_dwPerfTimerShift;
    } else {
        // Call failed; caller is probably not trusted
        liPerfCount.QuadPart = 0;
    }
    
    if (!IntBuf.dwBytesLeft) {
        //
        // The interrupt buffer is full! Just have to drop some from the 
        // beginning (keep most recent)
        //
        g_dwDiscardedInterrupts++;

        IntBuf.dwBytesLeft = 2*sizeof(DWORD);
        IntBuf.pRead += 2*sizeof(DWORD);
        if (IntBuf.pRead >= IntBuf.pWrap) {
            IntBuf.pRead = IntBuf.pBuffer;
        }
    }

    //
    // Write the data to the interrupt buffer.
    //
    *((PDWORD) (IntBuf.pWrite)) = liPerfCount.LowPart;
    *((PDWORD) (IntBuf.pWrite + sizeof(DWORD))) = dwLogValue;

        IntBuf.pWrite += 2*sizeof(DWORD);
     
    if (IntBuf.pWrite >= IntBuf.pWrap) {
        IntBuf.pWrite = IntBuf.pBuffer;
    }
    IntBuf.dwBytesLeft -= 2*sizeof(DWORD);
}


//------------------------------------------------------------------------------
// Check preset zones
//------------------------------------------------------------------------------
void static
INT_InitZones(
    FARPROC pfnKernelLibIoControl
    )
{
    DWORD dwType, dwVal, dwBufSize;
    
    // Start with built-in zone defaults
    pCelBuf->dwMaskUser    = CELOG_USER_MASK;
    pCelBuf->dwMaskCE      = CELOG_CE_MASK;
    pCelBuf->dwMaskProcess = CELOG_PROCESS_MASK;   

    // Check the desktop PC's registry
    pfnKernelLibIoControl((HANDLE)KMOD_CELOG, IOCTL_CELOG_GETDESKTOPZONE,
                          TEXT("CeLogZoneUser"), 13*sizeof(WCHAR),
                          &(pCelBuf->dwMaskUser), sizeof(DWORD), NULL);
    pCelBuf->dwMaskUser = VALIDATE_ZONES(pCelBuf->dwMaskUser);
    pfnKernelLibIoControl((HANDLE)KMOD_CELOG, IOCTL_CELOG_GETDESKTOPZONE,
                          TEXT("CeLogZoneCE"), 11*sizeof(WCHAR),
                          &(pCelBuf->dwMaskCE), sizeof(DWORD), NULL);
    pCelBuf->dwMaskCE = VALIDATE_ZONES(pCelBuf->dwMaskCE);
    pfnKernelLibIoControl((HANDLE)KMOD_CELOG, IOCTL_CELOG_GETDESKTOPZONE,
                          TEXT("CeLogZoneProcess"), 16*sizeof(WCHAR),
                          &(pCelBuf->dwMaskProcess), sizeof(DWORD), NULL);
    
    // Check the device-side registry
    if (ISAPIREADY(SH_FILESYS_APIS)) {
        dwBufSize = sizeof(DWORD);
        if ((PRIV_FUNC(RegQueryValueExW, (HKEY_LOCAL_MACHINE, TEXT("ZoneCE"),
                                          TEXT("System\\CeLog"), &dwType,
                                          (LPBYTE)&dwVal,
                                          &dwBufSize)) == ERROR_SUCCESS)
            && (dwType == REG_DWORD)) {
            pCelBuf->dwMaskCE = VALIDATE_ZONES(dwVal);
        }
    }

    RETAILMSG(1, (TEXT("CeLog Zones : CE = 0x%08X, User = 0x%08X, Proc = 0x%08X\r\n"),
                  pCelBuf->dwMaskCE, pCelBuf->dwMaskUser, pCelBuf->dwMaskProcess));
}


//------------------------------------------------------------------------------
// Hook up function pointers and initialize logging
//------------------------------------------------------------------------------
BOOL static
INT_InitLibrary(
    FARPROC pfnKernelLibIoControl
    )
{
    CeLogExportTable exports;
    LARGE_INTEGER liPerfFreq;

    //
    // KernelLibIoControl provides the back doors we need to obtain kernel
    // function pointers and register logging functions.
    //
    
    // Get public imports from kernel
    g_PubImports.dwVersion = CELOG_IMPORT_VERSION;
    if (!pfnKernelLibIoControl((HANDLE)KMOD_CELOG, IOCTL_CELOG_IMPORT, &g_PubImports,
                               sizeof(CeLogImportTable), NULL, 0, NULL)) {
        // Can't DEBUGMSG or anything here b/c we need the import table to do that
        return FALSE;
    }

    // CeLog requires MapViewOfFile
    if (g_PubImports.pMapViewOfFile == NULL) {
        DEBUGMSG(1, (MODNAME TEXT(": Error, cannot run because this kernel does not support memory-mapped files\r\n")));
        PUB_FUNC(SetLastError, (ERROR_NOT_SUPPORTED));
        return FALSE;
    }
    
    // Get private imports from kernel
    g_PrivImports.dwVersion = CELOG_PRIVATE_IMPORT_VERSION;
    if (!pfnKernelLibIoControl((HANDLE)KMOD_CELOG, IOCTL_CELOG_IMPORT_PRIVATE, &g_PrivImports,
                               sizeof(CeLogPrivateImports), NULL, 0, NULL)) {
        DEBUGMSG(1, (MODNAME TEXT(": Error, private import failed\r\n")));
        PUB_FUNC(SetLastError, (ERROR_NOT_SUPPORTED));
        return FALSE;
    }

    // Now initialize logging
    if (!INT_Init()) {
        return FALSE;
    }

    // Get the high-performance timer's frequency
    PUB_FUNC(QueryPerformanceFrequency, (&liPerfFreq));

    // scale the frequency down so that the 32 bits of the high-performance
    // timer we associate with log events doesn't wrap too quickly.
    g_dwPerfTimerShift = 0;
    while (liPerfFreq.QuadPart > MAX_ROLLOVER_COUNT) {
        g_dwPerfTimerShift++;
        liPerfFreq.QuadPart >>= 1;
    }

    INT_InitZones(pfnKernelLibIoControl);
    
    // Register logging functions with the kernel
    exports.dwVersion          = CELOG_EXPORT_VERSION;
    exports.pfnCeLogData       = EXT_LogData;
    exports.pfnCeLogInterrupt  = EXT_LogInterrupt;
    exports.pfnCeLogSetZones   = EXT_SetZones;
    exports.pfnCeLogQueryZones = EXT_QueryZones;
    exports.dwCeLogTimerFrequency = liPerfFreq.LowPart;
    if (!pfnKernelLibIoControl((HANDLE)KMOD_CELOG, IOCTL_CELOG_REGISTER, &exports,
                               sizeof(CeLogExportTable), NULL, 0, NULL)) {
        DEBUGMSG(1, (MODNAME TEXT(": Unable to register logging functions with kernel\r\n")));
        return FALSE;
    }

    g_fInit = TRUE;
    
    // Now that logging functions are registered, request a resync
    DEBUGMSG(ZONE_VERBOSE, (TEXT("CeLog resync\r\n")));
    PUB_FUNC(CeLogReSync, ());
    
    return TRUE;
}


//------------------------------------------------------------------------------
// DLL entry
//------------------------------------------------------------------------------
BOOL WINAPI
CeLogDLLEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved)
{
    switch (Reason) {
    case DLL_PROCESS_ATTACH:
        if (!g_fInit) {
            if (Reserved) {
                // Reserved parameter is a pointer to KernelLibIoControl function
                return INT_InitLibrary((FARPROC)Reserved);
            }
            // Loaded via LoadLibrary instead of LoadKernelLibrary?
            return FALSE;
        }
        break;

    case DLL_PROCESS_DETACH:
        break;
    }
    
    return TRUE;
}

⌨️ 快捷键说明

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