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

📄 logger.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
static _inline void 
BroadcastCeLogSetZones( 
    DWORD dwZoneUser,
    DWORD dwZoneCE,
    DWORD dwZoneProcess
    )
{
    CeLogDLLInfo *pDLL;

    // Global zone settings will be recalculated
    g_dwZoneUser = 0;
    g_dwZoneCE = 0;
    g_dwZoneProcess = 0;
    
    for (pDLL = g_pCeLogList; pDLL; pDLL = pDLL->pNext) {
        if (pDLL->pfnCeLogSetZones) {
            pDLL->pfnCeLogSetZones(dwZoneUser, dwZoneCE, dwZoneProcess);
        }

        // Query the new DLL zone settings
        if (pDLL->pfnCeLogQueryZones) {
            pDLL->pfnCeLogQueryZones(&(pDLL->dwZoneUser), &(pDLL->dwZoneCE), &(pDLL->dwZoneProcess));
        }
        
        // Add the DLL's zones to the global zone settings
        g_dwZoneUser    |= pDLL->dwZoneUser;
        g_dwZoneCE      |= pDLL->dwZoneCE;
        g_dwZoneProcess |= pDLL->dwZoneProcess;
    }
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Wrappers because these calls are functions on some processors and macros on
// others.
DWORD
Phys2VirtWrapper(
    DWORD pfn
    )
{
    return (DWORD) Phys2Virt(pfn);
}

BOOL
InSysCallWrapper(
    )
{
    return InSysCall();
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL KernelLibIoControl_CeLog(
    DWORD   dwIoControlCode,
    LPVOID  lpInBuf,
    DWORD   nInBufSize,
    LPVOID  lpOutBuf,
    DWORD   nOutBufSize,
    LPDWORD lpBytesReturned
    )
{
    switch (dwIoControlCode) {

        case IOCTL_CELOG_IMPORT: {
            //
            // A CeLog DLL is requesting information about the kernel
            //

            CeLogImportTable *pImports = (CeLogImportTable*)lpInBuf;

            extern const PFNVOID Win32Methods[];
            extern const PFNVOID EvntMthds[];
            extern const PFNVOID MapMthds[];
            extern DWORD dwDefaultThreadQuantum;

            // PUBLIC IMPORT TABLE VERSIONS:
            // 4 = Current
            // 3 = Intermediate builds, post-4.2
            // 2 = CE 4.1 / 4.2
            // 1 = CE 4.0
            DEBUGMSG(0, (TEXT("CeLog DLL import version: %u\r\n"), pImports->dwVersion));
            if (pImports->dwVersion == 4) {
                if (nInBufSize != sizeof(CeLogImportTable)) {
                    KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
                    return FALSE;
                }

                pImports->pCreateEventW              = (FARPROC) SC_CreateEvent;
                pImports->pEventModify               = (FARPROC) SC_EventModify;
                pImports->pCreateFileMappingW        = (FARPROC) SC_CreateFileMapping;
                pImports->pMapViewOfFile             = (FARPROC) MapMthds[ID_FSMAP_MAPVIEWOFFILE];  // 0 if nomapfile
                pImports->pUnmapViewOfFile           = (FARPROC) SC_UnmapViewOfFile;
                pImports->pCloseHandle               = (FARPROC) SC_CloseHandle;
                pImports->pLockPages                 = (FARPROC) SC_LockPages;
                pImports->pUnlockPages               = (FARPROC) SC_UnlockPages;
                pImports->pVirtualAlloc              = (FARPROC) Win32Methods[W32_VirtualAlloc];
                pImports->pVirtualFree               = (FARPROC) Win32Methods[W32_VirtualFree];
                pImports->pMapPtrToProcess           = (FARPROC) SC_MapPtrToProcess;
                pImports->pQueryPerformanceCounter   = (FARPROC) SC_QueryPerformanceCounter;
                pImports->pQueryPerformanceFrequency = (FARPROC) SC_QueryPerformanceFrequency;
                pImports->pNKDbgPrintfW              = (FARPROC) NKDbgPrintfW;
                pImports->pCeLogReSync               = (FARPROC) SC_CeLogReSync;
                pImports->pGetLastError              = (FARPROC) SC_GetLastError;
                pImports->pSetLastError              = (FARPROC) SC_SetLastError;
                pImports->pGetThreadCallStack        = (FARPROC) NKGetThreadCallStack;
                pImports->pInSysCall                 = (FARPROC) InSysCallWrapper;
                pImports->pdwCeLogTLBMiss            = &dwCeLogTLBMiss;
                pImports->dwCeLogLargeBuf            = dwCeLogLargeBuf;
                pImports->dwCeLogSmallBuf            = dwCeLogSmallBuf;
                pImports->dwDefaultThreadQuantum     = dwDefaultThreadQuantum;

            } else {
                // Versions 2 & 3 used a totally different import structure from
                // current DLL versions.
                DWORD* prgdwImports;

                // Check import version and struct size
                if (pImports->dwVersion == 2) {
                    if (nInBufSize != 14*sizeof(DWORD)) {
                        KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
                        return FALSE;
                    }
                } else if (pImports->dwVersion == 3) {
                    if (nInBufSize != 16*sizeof(DWORD)) {
                        KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
                        return FALSE;
                    }
                } else {
                    ERRORMSG(1, (TEXT("CeLog DLL version is not supported\r\n")));
                    KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
                    return FALSE;
                }
                
                prgdwImports = (DWORD*)lpInBuf;
                // prgdwImports[0] is the version
                prgdwImports[ 1] = (DWORD) Win32Methods;
                prgdwImports[ 2] = (DWORD) EvntMthds;
                prgdwImports[ 3] = (DWORD) MapMthds;
                prgdwImports[ 4] = (DWORD) INTERRUPTS_ENABLE;
                prgdwImports[ 5] = (DWORD) Phys2VirtWrapper;
                prgdwImports[ 6] = (DWORD) InSysCallWrapper;
                prgdwImports[ 7] = (DWORD) KCall;
                prgdwImports[ 8] = (DWORD) NKDbgPrintfW;
                prgdwImports[ 9] = (DWORD) &KData;
                prgdwImports[10] = (DWORD) &dwCeLogTLBMiss;
                prgdwImports[11] = (DWORD) dwCeLogLargeBuf;
                prgdwImports[12] = (DWORD) dwCeLogSmallBuf;
                prgdwImports[13] = (DWORD) dwDefaultThreadQuantum;

                if (pImports->dwVersion == 3) {
                    prgdwImports[14] = (DWORD) SC_CloseHandle;
                    prgdwImports[15] = (DWORD) KmodeEntries();
                }
            }

            break;
        }

        case IOCTL_CELOG_IMPORT_PRIVATE: {
            //
            // A CeLog DLL is requesting private information about the kernel
            //

            CeLogPrivateImports *pImports = (CeLogPrivateImports*)lpInBuf;

            // PRIVATE IMPORT TABLE VERSIONS:
            // 1 = Current
            // (Did not exist in 4.2 and earlier)
            if ((pImports->dwVersion != CELOG_PRIVATE_IMPORT_VERSION)
                || (nInBufSize != sizeof(CeLogPrivateImports))) {
                ERRORMSG(1, (TEXT("CeLog DLL version does not match kernel\r\n")));
                KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
                return FALSE;
            }

            pImports->pRegQueryValueExW   = (FARPROC) NKRegQueryValueExW;
            pImports->pINTERRUPTS_ENABLE  = (FARPROC) INTERRUPTS_ENABLE;
            pImports->pPhys2Virt          = (FARPROC) Phys2VirtWrapper;
            pImports->pKCall              = (FARPROC) KCall;
            pImports->pCeLogData          = (FARPROC) SC_CeLogData;
            pImports->pKData              = &KData;
            
            break;
        }

        case IOCTL_CELOG_REGISTER: {
            //
            // A CeLog DLL is registering to receive data
            //

            CeLogExportTable *pExports = (CeLogExportTable*)lpInBuf;

            // EXPORT TABLE VERSIONS:
            // 2 = CE 4.1 to Current
            // 1 = CE 4.0
            if ((nInBufSize != sizeof(CeLogExportTable))
                || (pExports->dwVersion != CELOG_EXPORT_VERSION)) {
                ERRORMSG(1, (TEXT("CeLog DLL version does not match kernel\r\n")));
                KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
                return FALSE;
            }

            if (!EnterCeLogRegisterCS()) {
                return FALSE;
            }
            
            // Add the new DLL to the list
            if (!AddCeLogDLL(pExports)) {
                LeaveCeLogRegisterCS();
                return FALSE;
            }
            
            // For each entry point, if it is the first instance, set the pointer
            // directly to the DLL.  If it is any subsequent instance, set the
            // pointer to be the broadcast function.
            
            if (g_pfnCeLogData == NULL) {
                g_pfnCeLogData = pExports->pfnCeLogData;
            } else if (g_pfnCeLogData != BroadcastCeLogData) {
                g_pfnCeLogData = BroadcastCeLogData;
            }

#ifdef NKPROF
            if (g_pfnCeLogInterrupt == NULL) {
                g_pfnCeLogInterrupt = pExports->pfnCeLogInterrupt;
            } else if ((g_pfnCeLogInterrupt != BroadcastCeLogInterrupt)
                       && (pExports->pfnCeLogInterrupt != NULL)) {
                g_pfnCeLogInterrupt = BroadcastCeLogInterrupt;
            }
#endif  // NKPROF

            if (g_dwCeLogDLLCount == 1) {
                // First CeLog DLL to be loaded.  Enable logging.
                CeLogEnable(CELOGSTATUS_ENABLED_GENERAL, g_dwZoneCE);
            } else {
                // Set the new zones in UserKData
                CeLogEnableZones(g_dwZoneCE);
            }
            
            DEBUGMSG(1, (TEXT("New CeLog DLL is now live!  (%u total)\r\n"), g_dwCeLogDLLCount));

            LeaveCeLogRegisterCS();

            break;
        }
        
        case IOCTL_CELOG_DEREGISTER: {
            //
            // A CeLog DLL is deregistering so that it no longer receives data
            //

            CeLogExportTable *pExports = (CeLogExportTable*)lpInBuf;

            if ((nInBufSize != sizeof(CeLogExportTable))
                || (pExports->dwVersion != CELOG_EXPORT_VERSION)) {
                ERRORMSG(1, (TEXT("CeLog DLL version does not match kernel\r\n")));
                KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
                return FALSE;
            }

            if (!EnterCeLogRegisterCS()) {
                return FALSE;
            }
            
            // Remove the DLL from the list
            if (!RemoveCeLogDLL(pExports)) {
                LeaveCeLogRegisterCS();
                return FALSE;
            }
            
            if (g_dwCeLogDLLCount == 0) {
                // Last CeLog DLL to be unloaded.
                
                // Clear the logging function pointers
                g_pfnCeLogData       = NULL;
                g_pfnCeLogInterrupt  = NULL;

                // Disable logging
                CeLogDisable();
                // Safety to make sure zones are all turned off
                g_dwZoneCE = 0;
                
            } else if (g_dwCeLogDLLCount == 1) {
                // One CeLog DLL remains loaded.
                
                // Switch the function pointers from the broadcast functions
                // to direct calls into the remaining DLL
                g_pfnCeLogData       = g_pCeLogList->pfnCeLogData;
#ifdef NKPROF
                g_pfnCeLogInterrupt  = g_pCeLogList->pfnCeLogInterrupt;
#endif
            }

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

            
            DEBUGMSG(1, (TEXT("CeLog DLL unloaded.  (%u remaining)\r\n"), g_dwCeLogDLLCount));
            
            LeaveCeLogRegisterCS();

            break;
        }

        case IOCTL_CELOG_GETDESKTOPZONE: {
            //
            // A CeLog DLL is requesting desktop zone settings
            //

            if (lpInBuf && lpOutBuf && (nOutBufSize == sizeof(DWORD))) {
                DWORD i;
                extern DWORD g_dwKeys[HOST_TRANSCFG_NUM_REGKEYS];
                extern WCHAR* g_keyNames[];
                for (i = 0; i < HOST_TRANSCFG_NUM_REGKEYS; i++) {
                    if (strcmpW (lpInBuf, g_keyNames[i]) == 0) {
                        *(DWORD *)lpOutBuf = g_dwKeys[i];
                        break;
                    }
                }
            } else {
                return FALSE;
            }    
            break;
        }

        case IOCTL_CELOG_REPORTZONECHANGE: {
            //
            // A CeLog DLL is reporting that its zones have changed internally
            // without a call to CeLogSetZones
            //

            CeLogDLLInfo *pDLL;

            // Recalculate global zone settings -- we will have to walk the
            // whole list to recalculate the zones
            g_dwZoneUser = 0;
            g_dwZoneCE = 0;
            g_dwZoneProcess = 0;
            for (pDLL = g_pCeLogList; pDLL; pDLL = pDLL->pNext) {
                // We don't know which DLL changed so we have to query the zone
                // settings for every DLL
                if (pDLL->pfnCeLogQueryZones) {
                    pDLL->pfnCeLogQueryZones(&(pDLL->dwZoneUser), &(pDLL->dwZoneCE), &(pDLL->dwZoneProcess));
                }

                // Add the DLL's zones to the global zone settings
                g_dwZoneUser    |= pDLL->dwZoneUser;
                g_dwZoneCE      |= pDLL->dwZoneCE;
                g_dwZoneProcess |= pDLL->dwZoneProcess;
            }

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

            break;
        }
    
        default:
            return FALSE;
    }

    return TRUE;
}





//------------------------------------------------------------------------------
//
//
//  KERNEL EXPORT APIS
//
//
//------------------------------------------------------------------------------


#ifdef NKPROF

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
CeLogInterrupt( 
    DWORD dwLogValue
    )
{
    // Make use of the CeLog tracking call to count interrupts for the kernel
    // profiler.  This counter is not really related to CeLog.
    extern BOOL  bProfileTimerRunning;
    extern DWORD g_ProfilerState_dwInterrupts;
    
    if (bProfileTimerRunning
        && !(dwLogValue & 0x80000000)) {          g_ProfilerState_dwInterrupts++;
    }

    // Do the IsCeLogZoneEnabled() test here rather than in assembly because it 
    // does not affect non-profiling builds.  The function call(s) to get to
    // this point are wasted work only on profiling builds in which CeLog is not 
    // currently active.
    if (IsCeLogZoneEnabled(CELZONE_INTERRUPT) && g_pfnCeLogInterrupt) {
        g_pfnCeLogInterrupt(dwLogValue);
    }
}

#endif // NKPROF


⌨️ 快捷键说明

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