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 + -
显示快捷键?