kernel.h
来自「WinCE5.0部分核心源码」· C头文件 代码 · 共 1,528 行 · 第 1/4 页
H
1,528 行
//
// paging modes
// Note: the relative order is important as we use < or > to determine the code path
//
#define PM_FULLPAGING 0 // fully pageable
#define PM_PARTPAGING 1 // partly pageable
#define PM_NOPAGING 2 // not pageable,
#define PM_CANNOT_PAGE 3 // paging not supported at all (hardware limitation)
#define FullyPageAble(oeptr) (PM_FULLPAGING == (oeptr)->pagemode)
#define PageAble(oeptr) (PM_PARTPAGING >= (oeptr)->pagemode)
#define PagingSupported(oeptr) (PM_CANNOT_PAGE != (oeptr)->pagemode)
#define FA_XIP 0x1 // xip-able media
#define FA_PREFIXUP 0x2 // already fixedup by romimage (in module section)
#define FA_DIRECTROM 0x4 // can be accessed directly with pointer
#define FA_NORMAL 0x8 // normal executable (not fixed up)
#define FT_OBJSTORE (FA_NORMAL) // object store
#define FT_EXTIMAGE (FA_PREFIXUP) // external Module, not XIP-able
#define FT_EXTXIP (FA_PREFIXUP|FA_XIP) // external XIP-able media
#define FT_ROMIMAGE (FA_PREFIXUP|FA_XIP|FA_DIRECTROM) // ROM XIP (the region where pTOC resides)
ERRFALSE(sizeof(CEOID) == 4);
typedef struct openexe_t {
union {
HANDLE hf; // object store handle
TOCentry *tocptr; // rom entry pointer
};
BYTE filetype;
BYTE bIsOID;
WORD pagemode;
union {
DWORD offset;
DWORD dwExtRomAttrib;
};
union {
Name *lpName;
CEOID ceOid;
};
} openexe_t;
typedef struct OEinfo_t {
WCHAR plainname[MAX_PATH], tmpname[MAX_PATH];
CEOIDINFOEX ceoi;
WIN32_FIND_DATA wfd;
} OEinfo_t;
BOOL OpenExecutable (LPCWSTR lpszName, openexe_t *oeptr, BOOL bIsDll, BOOL bAllowPaging);
void CloseExe(openexe_t *oeptr);
DWORD LoadE32(openexe_t *oeptr, e32_lite *eptr, DWORD *lpFlags, DWORD *lpEntry, BOOL bIgnoreCPU);
BOOL GetNameFromOE(CEOIDINFOEX *pceoi, openexe_t *oeptr);
void CloseAllCrits(void);
BOOL IsROM (LPVOID, DWORD);
__inline BOOL IsInRange (DWORD x, DWORD start, DWORD end)
{
return (x >= start) && (x < end);
}
#if defined(x86) || defined (ARM)
BOOL MDValidateRomChain (ROMChain_t *pROMChain);
#else
// MIPS and x86 doesn't have OEMAddressTable and therefore nothing to validate
#define MDValidateRomChain(x) (TRUE)
#endif
extern DWORD PagedInCount;
typedef struct {
HANDLE hFirstThrd; // first thread being debugged by this thread
HANDLE hNextThrd; // next thread being debugged
PCONTEXT psavedctx; // pointer to saved context, if any
HANDLE hEvent; // handle to wait on for debug event for this thread
HANDLE hBlockEvent; // handle that thread is waiting on
DEBUG_EVENT dbginfo;// debug info
BOOL bDispatched;
} THRDDBG, *LPTHRDDBG;
#define KERN_TRUST_FULL 2
#define KERN_TRUST_RUN 1
#define TRUSTED_API(apiName, retval) \
{ if (KERN_TRUST_FULL != pCurProc->bTrustLevel) { \
ERRORMSG(1, (L"%s failed due to insufficient trust\r\n", apiName)); \
KSetLastError (pCurThread, ERROR_ACCESS_DENIED); \
return (retval); \
} \
}
#define TRUSTED_API_VOID(apiName) \
{ if (KERN_TRUST_FULL != pCurProc->bTrustLevel) { \
ERRORMSG(1, (L"%s failed due to insufficient trust\r\n", apiName)); \
KSetLastError (pCurThread, ERROR_ACCESS_DENIED); \
return; \
} \
}
/* Thread data structures */
#define RUNSTATE_RUNNING 0 // must be 0
#define RUNSTATE_RUNNABLE 1
#define RUNSTATE_BLOCKED 2
#define RUNSTATE_NEEDSRUN 3 // on way to being runnable
#define WAITSTATE_SIGNALLED 0
#define WAITSTATE_PROCESSING 1
#define WAITSTATE_BLOCKED 2
#define TIMEMODE_USER 0
#define TIMEMODE_KERNEL 1
#define RUNSTATE_SHIFT 0 // 2 bits
#define DYING_SHIFT 2 // 1 bit
#define DEAD_SHIFT 3 // 1 bit
#define BURIED_SHIFT 4 // 1 bit
#define SLEEPING_SHIFT 5 // 1 bit
#define TIMEMODE_SHIFT 6 // 1 bit
#define NEEDDBG_SHIFT 7 // 1 bit
#define STACKFAULT_SHIFT 8 // 1 bit
#define DEBUGBLK_SHIFT 9 // 1 bit
#define NOPRIOCALC_SHIFT 10 // 1 bit
#define DEBUGWAIT_SHIFT 11 // 1 bit
#define USERBLOCK_SHIFT 12 // 1 bit
#ifdef DEBUG
#define DEBUG_LOOPCNT_SHIFT 13 // 1 bit - only in debug
#endif
#define NEEDSLEEP_SHIFT 14 // 1 bit
#define PROFILE_SHIFT 15 // 1 bit, must be 15! Used by assembly code!
#define GET_BPRIO(T) ((WORD)((T)->bBPrio)) /* base priority */
#define GET_CPRIO(T) ((WORD)((T)->bCPrio)) /* current priority */
#define SET_BPRIO(T,S) ((T)->bBPrio = (BYTE)(S))
#define SET_CPRIO(T,S) ((T)->bCPrio = (BYTE)(S))
#define GET_TIMEMODE(T) (((T)->wInfo >> TIMEMODE_SHIFT)&0x1) /* What timemode are we in */
#define GET_RUNSTATE(T) (((T)->wInfo >> RUNSTATE_SHIFT)&0x3) /* Is thread runnable */
#define GET_BURIED(T) (((T)->wInfo >> BURIED_SHIFT)&0x1) /* Is thread 6 feet under */
#define GET_SLEEPING(T) (((T)->wInfo >> SLEEPING_SHIFT)&0x1) /* Is thread sleeping */
#define GET_DEBUGBLK(T) (((T)->wInfo >> DEBUGBLK_SHIFT)&0x1) /* Has DebugActive suspended thread */
#define GET_DYING(T) (((T)->wInfo >> DYING_SHIFT)&0x1) /* Has been set to die */
#define TEST_STACKFAULT(T) ((T)->wInfo & (1<<STACKFAULT_SHIFT))
#define GET_DEAD(T) (((T)->wInfo >> DEAD_SHIFT)&0x1)
#define GET_NEEDDBG(T) (((T)->wInfo >> NEEDDBG_SHIFT)&0x1)
#define GET_PROFILE(T) (((T)->wInfo >> PROFILE_SHIFT)&0x1) /* montecarlo profiling */
#define GET_NOPRIOCALC(T) (((T)->wInfo >> NOPRIOCALC_SHIFT)&0x1)
#define GET_DEBUGWAIT(T) (((T)->wInfo >> DEBUGWAIT_SHIFT)&0x1)
#define GET_USERBLOCK(T) (((T)->wInfo >> USERBLOCK_SHIFT)&0x1) /* did thread voluntarily block? */
#define GET_NEEDSLEEP(T) (((T)->wInfo >> NEEDSLEEP_SHIFT)&0x1) /* should the thread put back to sleepq? */
#define SET_RUNSTATE(T,S) ((T)->wInfo = (WORD)(((T)->wInfo & ~(3<<RUNSTATE_SHIFT)) | ((S)<<RUNSTATE_SHIFT)))
#define SET_BURIED(T) ((T)->wInfo |= (1<<BURIED_SHIFT))
#define SET_SLEEPING(T) ((T)->wInfo |= (1<<SLEEPING_SHIFT))
#define CLEAR_SLEEPING(T) ((T)->wInfo &= ~(1<<SLEEPING_SHIFT))
#define SET_DEBUGBLK(T) ((T)->wInfo |= (1<<DEBUGBLK_SHIFT))
#define CLEAR_DEBUGBLK(T) ((T)->wInfo &= ~(1<<DEBUGBLK_SHIFT))
#define SET_DYING(T) ((T)->wInfo |= (1<<DYING_SHIFT))
#define SET_STACKFAULT(T) ((T)->wInfo |= (1<<STACKFAULT_SHIFT))
#define CLEAR_STACKFAULT(T) ((T)->wInfo &= ~(1<<STACKFAULT_SHIFT))
#define SET_DEAD(T) ((T)->wInfo |= (1<<DEAD_SHIFT))
#define SET_TIMEUSER(T) ((T)->wInfo &= ~(1<<TIMEMODE_SHIFT))
#define SET_TIMEKERN(T) ((T)->wInfo |= (1<<TIMEMODE_SHIFT))
#define SET_NEEDDBG(T) ((T)->wInfo |= (1<<NEEDDBG_SHIFT))
#define CLEAR_NEEDDBG(T) ((T)->wInfo &= ~(1<<NEEDDBG_SHIFT))
#define SET_PROFILE(T) ((T)->wInfo |= (1<<PROFILE_SHIFT))
#define CLEAR_PROFILE(T) ((T)->wInfo &= ~(1<<PROFILE_SHIFT))
#define SET_NOPRIOCALC(T) ((T)->wInfo |= (1<<NOPRIOCALC_SHIFT))
#define CLEAR_NOPRIOCALC(T) ((T)->wInfo &= ~(1<<NOPRIOCALC_SHIFT))
#define SET_DEBUGWAIT(T) ((T)->wInfo |= (1<<DEBUGWAIT_SHIFT))
#define CLEAR_DEBUGWAIT(T) ((T)->wInfo &= ~(1<<DEBUGWAIT_SHIFT))
#define SET_USERBLOCK(T) ((T)->wInfo |= (1<<USERBLOCK_SHIFT))
#define CLEAR_USERBLOCK(T) ((T)->wInfo &= ~(1<<USERBLOCK_SHIFT))
#define SET_NEEDSLEEP(T) ((T)->wInfo |= (1<<NEEDSLEEP_SHIFT))
#define CLEAR_NEEDSLEEP(T) ((T)->wInfo &= ~(1<<NEEDSLEEP_SHIFT))
struct Thread {
WORD wInfo; /* 00: various info about thread, see above */
BYTE bSuspendCnt;/* 02: thread suspend count */
BYTE bWaitState; /* 03: state of waiting loop */
LPPROXY pProxList; /* 04: list of proxies to threads blocked on this thread */
PTHREAD pNextInProc;/* 08: next thread in this process */
PPROCESS pProc; /* 0C: pointer to current process */
PPROCESS pOwnerProc; /* 10: pointer to owner process */
ACCESSKEY aky; /* 14: keys used by thread to access memory & handles */
PCALLSTACK pcstkTop; /* 18: current api call info */
DWORD dwOrigBase; /* 1C: Original stack base */
DWORD dwOrigStkSize; /* 20: Size of the original thread stack */
LPDWORD tlsPtr; /* 24: tls pointer */
DWORD dwWakeupTime; /* 28: sleep count, also pending sleepcnt on waitmult */
LPDWORD tlsSecure; /* 2c: TLS for secure stack */
LPDWORD tlsNonSecure; /* 30: TLS for non-secure stack */
LPPROXY lpProxy; /* 34: first proxy this thread is blocked on */
DWORD dwLastError;/* 38: last error */
HANDLE hTh; /* 3C: Handle to this thread, needed by NextThread */
BYTE bBPrio; /* 40: base priority */
BYTE bCPrio; /* 41: curr priority */
WORD wCount; /* 42: nonce for blocking lists */
PTHREAD pPrevInProc;/* 44: previous thread in this process */
LPTHRDDBG pThrdDbg; /* 48: pointer to thread debug structure, if any */
LPBYTE pSwapStack; /* 4c */
FILETIME ftCreate; /* 50: time thread is created */
CLEANEVENT *lpce; /* 58: cleanevent for unqueueing blocking lists */
DWORD dwStartAddr; /* 5c: thread PC at creation, used to get thread name */
CPUCONTEXT ctx; /* 60: thread's cpu context information */
PTHREAD pNextSleepRun; /* ??: next sleeping thread, if sleeping, else next on runq if runnable */
PTHREAD pPrevSleepRun; /* ??: back pointer if sleeping or runnable */
PTHREAD pUpRun; /* ??: up run pointer (circulaar) */
PTHREAD pDownRun; /* ??: down run pointer (circular) */
PTHREAD pUpSleep; /* ??: up sleep pointer (null terminated) */
PTHREAD pDownSleep; /* ??: down sleep pointer (null terminated) */
LPCRIT pOwnedList; /* ??: list of crits and mutexes for priority inversion */
LPCRIT pOwnedHash[PRIORITY_LEVELS_HASHSIZE];
DWORD dwQuantum; /* ??: thread quantum */
DWORD dwQuantLeft;/* ??: quantum left */
LPPROXY lpCritProxy;/* ??: proxy from last critical section block, in case stolen back */
LPPROXY lpPendProxy;/* ??: pending proxies for queueing */
DWORD dwPendReturn;/* ??: return value from pended wait */
DWORD dwPendTime; /* ??: timeout value of wait operation */
PTHREAD pCrabPth;
WORD wCrabCount;
WORD wCrabDir;
DWORD dwPendWakeup;/* ??: pending timeout */
WORD wCount2; /* ??: nonce for SleepList */
BYTE bPendSusp; /* ??: pending suspend count */
BYTE bDbgCnt; /* ??: recurse level in debug message */
HANDLE hLastCrit; /* ??: Last crit taken, cleared by nextthread */
//DWORD dwCrabTime;
CALLSTACK IntrStk;
DWORD dwKernTime; /* ??: elapsed kernel time */
DWORD dwUserTime; /* ??: elapsed user time */
HANDLE hTok; /* ??: thread token */
}; /* Thread */
#define THREAD_CONTEXT_OFFSET 0x60
ERRFALSE(THREAD_CONTEXT_OFFSET == offsetof(THREAD, ctx));
#define KSetLastError(pth, err) (pth->dwLastError = err)
#define KGetLastError(pth) (pth->dwLastError)
// Macros to access stack base/bound
#define KSTKBASE(pth) ((pth)->tlsPtr[PRETLS_STACKBASE])
#define KSTKBOUND(pth) ((pth)->tlsPtr[PRETLS_STACKBOUND])
#define KCURFIBER(pth) ((pth)->tlsNonSecure? (pth)->tlsNonSecure[PRETLS_CURFIBER] : 0)
#define KPROCSTKSIZE(pth) ((pth)->tlsPtr[PRETLS_PROCSTKSIZE])
#define KCALLERVMBASE(pth) ((pth)->tlsPtr[PRETLS_CALLERVMBASE])
#define KCALLERTRUST(pth) ((pth)->tlsPtr[PRETLS_CALLERTRUST])
#define KTHRDINFO(pth) ((pth)->tlsPtr[PRETLS_THRDINFO])
#define INVALID_PG_INDEX ((WORD) 0xfdfd)
typedef struct _PGPOOL_Q {
WORD idxHead; /* head of the queue */
WORD idxTail; /* tail of the queue */
} PGPOOL_Q, *PPGPOOL_Q;
extern BOOL InitPgPool (void);
extern LPBYTE GetPagingPage (PPGPOOL_Q ppq, o32_lite *optr, BYTE filetype, WORD *pidx);
extern void FreePagingPage (PPGPOOL_Q ppq, WORD idx);
extern void AddPageToQueue (PPGPOOL_Q ppq, WORD idx, DWORD vaddr, LPVOID pModProc);
extern void AddPageToFreeList (WORD idx);
extern void FreeAllPagesFromQ (PPGPOOL_Q ppq);
typedef struct _MODULELIST {
struct _MODULELIST *pNext; // next entry
PMODULE pMod; // the module
} MODULELIST, *PMODULELIST;
typedef struct _TOKENLIST {
struct _TOKENLIST *pNext; // next entry
HANDLE hTok; // the token
} TOKENLIST, *PTOKENLIST;
__inline HANDLE KThrdToken (PTHREAD pth) {
return (((DWORD)pth->hTok & 3) == 2)? pth->hTok : ((PTOKENLIST) pth->hTok)->hTok;
}
// Any time this structure is redefined, we need to recalculate
// the offset used in the SHx profiler ISR located at
// %_WINCEROOT%\platform\ODO\kernel\profiler\shx\profisr.src
struct Process {
BYTE procnum; /* 00: ID of this process [ie: it's slot number] */
BYTE DbgActive; /* 01: ID of process currently DebugActiveProcess'ing this process */
BYTE bChainDebug; /* 02: Did the creator want to debug child processes? */
BYTE bTrustLevel; /* 03: level of trust of this exe */
#define OFFSET_TRUSTLVL 3 // offset of the bTrustLevel member in Process structure
LPPROXY pProxList; /* 04: list of proxies to threads blocked on this process */
HANDLE hProc; /* 08: handle for this process, needed only for SC_GetProcFromPtr */
DWORD dwVMBase; /* 0C: base of process's memory section, or 0 if not in use */
PTHREAD pTh; /* 10: first thread in this process */
ACCESSKEY aky; /* 14: default address space key for process's threads */
LPVOID BasePtr; /* 18: Base pointer of exe load */
HANDLE hDbgrThrd; /* 1C: handle of thread debugging this process, if any */
LPWSTR lpszProcName; /* 20: name of process */
DWORD tlsLowUsed; /* 24: TLS in use bitmask (first 32 slots) */
DWORD tlsHighUsed; /* 28: TLS in use bitmask (second 32 slots) */
PEXCEPTION_ROUTINE pfnEH; /* 2C: process exception handler */
LPDBGPARAM ZonePtr; /* 30: Debug zone pointer */
PTHREAD pMainTh; /* 34 primary thread in this process*/
PMODULE pmodResource; /* 38: module that contains the resources */
LPName pStdNames[3]; /* 3C: Pointer to names for stdio */
LPCWSTR pcmdline; /* 48: Pointer to command line */
DWORD dwDyingThreads; /* 4C: number of pending dying threads */
openexe_t oe; /* 50: Pointer to executable file handle */
e32_lite e32; /* ??: structure containing exe header */
o32_lite *o32_ptr; /* ??: o32 array pointer for exe */
LPVOID pExtPdata; /* ??: extend pdata */
BYTE bPrio; /* ??: highest priority of all threads of the process */
BYTE fNoDebug; /* ??: this process cannot be debugged */
WORD wModCount; /* ??: # of modules in pLastModList */
PGPOOL_Q pgqueue; /* ??: list of the page owned by the process */
PMODULELIST pLastModList; /* ??: the list of modules that just loaded/unloaded into the process */
HANDLE hTok; /* ??: process default token */
#if HARDWARE_PT_PER_PROC
ulong pPTBL[HARDWARE_PT_PER_PROC]; /* hardware page tables */
#endif
LPVOID pShimInfo; /* pointer to shim information */
}; /* Process */
#define ProcStarted(P) (((P)->dwVMBase >> VA_SECTION) == ((DWORD)((P)->lpszProcName)>>VA_SECTION))
#define pFileSysProc (&ProcArray[1])
#define FIRST_MAPPER_SLOT (MAX_PROCESSES + RESERVED_SECTIONS)
#define MapperSlotToBit(slot) (1 << ((slot) - FIRST_MAPPER_SLOT))
#define IsSlotInObjStore(slot) (g_ObjStoreSlotBits & MapperSlotToBit (slot))
extern DWORD g_ObjStoreSlotBits;
#define MIN_STACK_SIZE PAGE_SIZE
#define CNP_STACK_SIZE (64*1024) // the size of the stack when bootstrapping a new process
#define KRN_STACK_SIZE (64*1024) // the size of kernel thread stacks
// MIN_STACK_RESERVE is the minimum amount of stack space for the debugger and/or SEH code to run.
// When there is less than this amount of stack left and another stack page is committed,
// a stack overflow exception will be raised.
#if (PAGE_SIZE == 1024)
#define MIN_STACK_RESERVE 4096
#else
#define MIN_STACK_RESERVE 8192
#endif
#define MAX_STACK_RESERVE (1024*1024)
#define MapPtr(P) (!(P) || ((DWORD)(P)>>VA_SECTION) ? (LPVOID)(P) : \
(LPVOID)((DWORD)(P)|(DWORD)pCurProc->dwVMBase))
#define MapPtrProc(Ptr, Proc) (!(Ptr) || ((DWORD)(Ptr)>>VA_SECTION) ? (LPVOID)(Ptr) : \
(LPVOID)((DWORD)(Ptr)|(DWORD)(Proc)->dwVMBase))
extern PROCESS ProcArray[MAX_PROCESSES]; // in schedule.c
typedef BOOL (*PFNIOCTL)(DWORD dwInstData, DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned);
typedef struct KernelMod {
LPVOID lpSelf; // Self pointer for validation
FARPROC pfnHandler; // the ISR
PFNIOCTL pfnIoctl; // IOCTL funciton
PMODULE pMod; // where the module is
DWORD dwInstData; // ISR instance data
BYTE bIRQ; // IRQ number
BYTE bPad[3]; // padding
} KERNELMOD, *PKERNELMOD;
extern BOOL HookIntChain(BYTE bIRQ, PKERNELMOD pkMod);
extern BOOL UnhookIntChain(BYTE bIRQ, PKERNELMOD pkMod);
// dwFlags for MODULES
// #define DONT_RESOLVE_DLL_REFERENCES 0x00000001 // defined in winbase.h
// #define LOAD_LIBRARY_AS_DATAFILE 0x00000002 // defined in winbase.h
// #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 // defined in winbase.h
ERRFALSE(!(DONT_RESOLVE_DLL_REFERENCES & 0xffff0000));
ERRFALSE(!(LOAD_LIBRARY_AS_DATAFILE & 0xffff0000));
ERRFALSE(!(LOAD_WITH_ALTERED_SEARCH_PATH & 0xffff0000));
typedef struct Module {
LPVOID lpSelf; /* Self pointer for validation */
PMODULE pMod; /* Next module in chain */
LPWSTR lpszModName; /* Module name */
DWORD inuse; /* Bit vector of use */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?