📄 celognk.h
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
//------------------------------------------------------------------------------
//
// Module Name:
//
// celognk.h
//
// Abstract:
//
// Kernel's interface to the event logging functions.
//
//------------------------------------------------------------------------------
#ifndef __CELOGNK_H_
#define __CELOGNK_H_
#ifdef IN_KERNEL
//------------------------------------------------------------------------------
// Logging operation
//
// Include the public SDK structures.
#include <celog.h>
// Include exported profiler functions
#include <profiler.h>
// Globals that allow a logging engine to be hot-plugged in the system.
#ifdef __cplusplus
extern void (*g_pfnCeLogData)(...);
#else
extern void (*g_pfnCeLogData)();
#endif
extern PFNVOID g_pfnCeLogInterrupt;
extern PFNVOID g_pfnCeLogSetZones;
// Instead of using the CELOGDATA macro in these inline functions, call the
// function pointer directly.
#define CELOGDATANK(T,I,D,L,Y,Z) g_pfnCeLogData(T,I,D,L,Y,Z,0,FALSE)
#undef IsCeLogStatus
#undef IsCeLogEnabled
#undef IsCeLogZoneEnabled
#define IsCeLogStatus(Status) ((KInfoTable[KINX_CELOGSTATUS] & (Status)) != 0)
#define IsCeLogEnabled(Status, ZoneCE) (IsCeLogStatus(Status) && ((KInfoTable[KINX_CELOGSTATUS] & (ZoneCE)) != 0))
#define IsCeLogZoneEnabled(ZoneCE) (IsCeLogEnabled(CELOGSTATUS_ENABLED_GENERAL, (ZoneCE)))
// Set the proper status and zones
#define CeLogEnable(Status, ZoneCE) (KInfoTable[KINX_CELOGSTATUS] = ((Status) | ((ZoneCE) & ~CELOGSTATUS_ENABLED_ANY)))
// Set the proper status without changing the zones
#define CeLogEnableStatus(Status) (CeLogEnable((Status), KInfoTable[KINX_CELOGSTATUS] & ~CELOGSTATUS_ENABLED_ANY))
// Set the proper zones without changing the status
#define CeLogEnableZones(ZoneCE) (CeLogEnable(KInfoTable[KINX_CELOGSTATUS] & CELOGSTATUS_ENABLED_ANY, (ZoneCE)))
// Disable all logging
#define CeLogDisable() (KInfoTable[KINX_CELOGSTATUS] = 0)
//------------------------------------------------------------------------------
// ZONES
// KCall profiling is turned off by default to prevent overwhelming logs
#ifndef CELOG_USER_MASK
#define CELOG_USER_MASK 0xFFBFFFFF
#endif
#ifndef CELOG_CE_MASK
#define CELOG_CE_MASK 0xFFBFFFFF
#endif
#ifndef CELOG_PROCESS_MASK
#define CELOG_PROCESS_MASK 0xFFFFFFFF
#endif
//------------------------------------------------------------------------------
// Interface to a CeLog plugin DLL
//
#define CELOG_IMPORT_VERSION 4
#define CELOG_PRIVATE_IMPORT_VERSION 1
#define CELOG_EXPORT_VERSION 2
// Private kernel functions and data provided for CeLog to use.
// Queried with IOCTL_CELOG_IMPORT_PRIVATE.
// This structure may change on future OS versions.
typedef struct _CeLogPrivateImports {
DWORD dwVersion; // Version of this structure, set to CELOG_PRIVATE_IMPORT_VERSION
FARPROC pRegQueryValueExW; // Pointer to NKRegQueryValueExW function
FARPROC pINTERRUPTS_ENABLE; // Pointer to INTERRUPTS_ENABLE function
FARPROC pPhys2Virt; // Pointer to Phys2Virt wrapper function
FARPROC pKCall; // Pointer to KCall function
FARPROC pCeLogData; // Pointer to kernel's CeLogData entry point
struct KDataStruct *pKData; // Pointer to KData struct
} CeLogPrivateImports;
// The kernel wrappers
//----------------------------------------------------------
_inline void CELOG_ThreadSwitch(PTHREAD pThread)
{
// Logged for both general and profiling mode, all zones, because celog.dll
// requires thread switches to know when to flush its small buffer.
if (IsCeLogStatus(CELOGSTATUS_ENABLED_ANY)) {
CEL_THREAD_SWITCH cl;
if (pThread) {
cl.hThread = pThread->hTh;
} else {
cl.hThread = 0;
}
CELOGDATANK(TRUE, CELID_THREAD_SWITCH, &cl, sizeof(cl), 0, CELZONE_RESCHEDULE | CELZONE_PROFILER);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadQuantumExpire()
{
if (IsCeLogZoneEnabled(CELZONE_RESCHEDULE)) {
CELOGDATANK(TRUE, CELID_THREAD_QUANTUMEXPIRE, NULL, 0, 0, CELZONE_RESCHEDULE);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadSetPriority(HANDLE hThread, int nPriority)
{
if (IsCeLogZoneEnabled(CELZONE_THREAD)) {
CEL_THREAD_PRIORITY cl;
cl.hThread = hThread;
cl.nPriority = nPriority;
CELOGDATANK(TRUE, CELID_THREAD_PRIORITY, &cl, sizeof(CEL_THREAD_PRIORITY), 0, CELZONE_THREAD);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadSetQuantum(HANDLE hThread, DWORD dwQuantum)
{
if (IsCeLogZoneEnabled(CELZONE_THREAD)) {
CEL_THREAD_QUANTUM cl;
cl.hThread = hThread;
cl.dwQuantum = dwQuantum;
CELOGDATANK(TRUE, CELID_THREAD_QUANTUM, &cl, sizeof(CEL_THREAD_QUANTUM), 0, CELZONE_THREAD);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadSuspend(HANDLE hThread)
{
if (IsCeLogZoneEnabled(CELZONE_RESCHEDULE)) {
CEL_THREAD_SUSPEND cl;
cl.hThread = hThread;
CELOGDATANK(TRUE, CELID_THREAD_SUSPEND, &cl, sizeof(CEL_THREAD_SUSPEND), 0, CELZONE_RESCHEDULE);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadResume(HANDLE hThread)
{
if (IsCeLogZoneEnabled(CELZONE_RESCHEDULE)) {
CEL_THREAD_RESUME cl;
cl.hThread = hThread;
CELOGDATANK(TRUE, CELID_THREAD_RESUME, &cl, sizeof(CEL_THREAD_RESUME), 0, CELZONE_RESCHEDULE);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadCreate(PTHREAD pThread, HANDLE hProcess,
LPCWSTR lpProcName, BOOL fSuspended)
{
// Logged for both general and profiling mode
if (IsCeLogEnabled(CELOGSTATUS_ENABLED_GENERAL | CELOGSTATUS_ENABLED_PROFILE,
CELZONE_THREAD | CELZONE_PROFILER)
&& pThread) {
BYTE pTmp[(MAX_PATH*sizeof(WCHAR)) + sizeof(CEL_THREAD_CREATE)];
PCEL_THREAD_CREATE pcl = (PCEL_THREAD_CREATE) pTmp;
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 the process name was passed in, we assume this is the primary
// thread of a process, and take the process' name and module handle.
// Otherwise, look up the thread's function name and module handle.
if (lpProcName) {
wLen = strlenW(lpProcName) + 1;
if (wLen <= MAX_PATH) {
kstrcpyW(pcl->szName, lpProcName);
} 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
}
CELOGDATANK(TRUE, CELID_THREAD_CREATE, (PVOID) pcl,
(WORD)(sizeof(CEL_THREAD_CREATE) + (wLen * sizeof(WCHAR))),
0, CELZONE_THREAD | CELZONE_PROFILER);
}
if (fSuspended && pThread) {
CELOG_ThreadSuspend(pThread->hTh);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadCloseHandle(HANDLE hThread)
{
if (IsCeLogZoneEnabled(CELZONE_THREAD)) {
CEL_THREAD_CLOSE cl;
cl.hThread = hThread;
CELOGDATANK(TRUE, CELID_THREAD_CLOSE, &cl, sizeof(CEL_THREAD_CLOSE), 0, CELZONE_THREAD);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadTerminate(HANDLE hThread)
{
// Logged for both general and profiling mode
if (IsCeLogEnabled(CELOGSTATUS_ENABLED_GENERAL | CELOGSTATUS_ENABLED_PROFILE,
CELZONE_THREAD | CELZONE_PROFILER)) {
CEL_THREAD_TERMINATE cl;
cl.hThread = hThread;
CELOGDATANK(TRUE, CELID_THREAD_TERMINATE, &cl, sizeof(CEL_THREAD_TERMINATE), 0, CELZONE_THREAD | CELZONE_PROFILER);
}
}
//----------------------------------------------------------
_inline void CELOG_ThreadDelete(HANDLE hThread)
{
if (IsCeLogZoneEnabled(CELZONE_THREAD)) {
CEL_THREAD_DELETE cl;
cl.hThread = hThread;
CELOGDATANK(TRUE, CELID_THREAD_DELETE, &cl, sizeof(CEL_THREAD_DELETE), 0, CELZONE_THREAD);
}
}
//----------------------------------------------------------
_inline void CELOG_ProcessCreate(
HANDLE hProcess, // Process being created
LPCWSTR lpProcName, // Process name, not including path to EXE
DWORD dwVMBase // VM base address the process is loaded at
)
{
// Logged for both general and profiling mode
if (IsCeLogEnabled(CELOGSTATUS_ENABLED_GENERAL | CELOGSTATUS_ENABLED_PROFILE,
CELZONE_PROCESS | CELZONE_THREAD | CELZONE_MEMTRACKING | CELZONE_PROFILER)) {
BYTE pTmp[(MAX_PATH*sizeof(WCHAR)) + sizeof(CEL_PROCESS_CREATE)];
PCEL_PROCESS_CREATE pclBase = (PCEL_PROCESS_CREATE) pTmp;
WORD wLen;
// Special case: fixup nk.exe to tell where the code lives, not the VM
if (dwVMBase == (SECURE_SECTION << VA_SECTION)) {
dwVMBase = pTOC->physfirst;
}
// Log base process info
wLen = 0;
pclBase->hProcess = hProcess;
pclBase->dwVMBase = dwVMBase;
if (lpProcName) {
wLen = strlenW(lpProcName) + 1;
if (wLen <= MAX_PATH) {
kstrcpyW(pclBase->szName, lpProcName);
} else {
wLen = 0;
}
}
CELOGDATANK(TRUE, CELID_PROCESS_CREATE, (PVOID) pclBase,
(WORD) (sizeof(CEL_PROCESS_CREATE) + (wLen * sizeof(WCHAR))), 0,
CELZONE_PROCESS | CELZONE_THREAD | CELZONE_MEMTRACKING | CELZONE_PROFILER);
}
}
//----------------------------------------------------------
// Similar to GetNameFromOE.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -