📄 kernel.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.
//
/*
Kernel.h - internal kernel data
This file contains the kernel's internal data structures, function prototypes,
macros, etc. It is not intended for use outside of the kernel.
*/
#ifndef __KERNEL_H__
#define __KERNEL_H__
#include "windows.h"
#ifndef offsetof
#define offsetof(s,m) ((unsigned)&(((s *)0)->m))
#endif
#if defined(XREF_CPP_FILE)
#define ERRFALSE(exp)
#elif !defined(ERRFALSE)
// This macro is used to trigger a compile error if exp is false.
// If exp is false, i.e. 0, then the array is declared with size 0, triggering a compile error.
// If exp is true, the array is declared correctly.
// There is no actual array however. The declaration is extern and the array is never actually referenced.
#define ERRFALSE(exp) extern char __ERRXX[(exp)!=0]
#endif
#include "pehdr.h"
#include "romldr.h"
#include "patcher.h"
#define C_ONLY
typedef ulong PHYSICAL_ADDRESS;
#define INVALID_PHYSICAL_ADDRESS 0xFFFFFFFF
typedef void (*PKINTERRUPT_ROUTINE)(void);
#define IN
#define OUT
#define OPTIONAL
typedef void (*RETADDR)();
typedef struct Thread THREAD;
typedef THREAD *PTHREAD;
typedef struct Process PROCESS;
typedef PROCESS *PPROCESS;
typedef ulong ACCESSKEY;
typedef ulong ACCESSLOCK;
typedef struct Module MODULE;
typedef MODULE *PMODULE, *LPMODULE;
typedef RETADDR FNDISP(PTHREAD pth, RETADDR ra, void *args);
typedef FNDISP *PFNDISP;
typedef BOOL (*PFNKDBG)(DWORD dwCause, PTHREAD pictx);
#include "kwin32.h"
typedef struct FreeInfo {
PHYSICAL_ADDRESS paStart; /* start of available region */
PHYSICAL_ADDRESS paEnd; /* end of region (last byte + 1) */
PHYSICAL_ADDRESS paRealEnd;
PBYTE pUseMap; /* ptr to page usage count map */
} FREEINFO; /* FreeInfo */
typedef FREEINFO *PFREEINFO;
typedef struct MemoryInfo {
PVOID pKData; /* start of kernel's data */
PVOID pKEnd; /* end of kernel's data & bss */
uint cFi; /* # of entries in free memory array */
FREEINFO *pFi; /* Pointer to cFi FREEINFO entries */
} MEMORYINFO; /* MemoryInfo */
extern MEMORYINFO MemoryInfo;
extern DWORD randdw1,randdw2;
extern HANDLE hCoreDll;
/* Macros for maniputing access keys and locks */
#define AddAccess(pakDest, akSrc) (*(pakDest) |= (akSrc))
#define RemoveAccess(pakDest, akSrc) (*(pakDest) &= ~(akSrc))
#define TestAccess(palk, paky) (*(palk) & *(paky))
#define LockFromKey(palk, paky) (*(palk) = *(paky))
#define IsValidKPtr(p) ((char *)(p) >= (char *)MemoryInfo.pKData \
&& (char *)(p) < (char *)MemoryInfo.pKEnd)
#define IsValidModule(p) (IsValidKPtr(p) && ((p)->lpSelf == (p)))
/** Macros for retrieving and walking the PSL client argument list */
/* (NB. Currently only used in ...nk\kernel\ObjDisp.c::ObjectCall) */
#if defined (MIPSIV)
// *** NOTE: Processors for which "sizeof(int)" is smaller than the
// *** argument size should be added to this list.
#define INT_ARG_SIZE sizeof(__int64)
#else
#define INT_ARG_SIZE sizeof(int)
#endif
#if defined (MIPSIV)
#define WriteArg(ap, type, value) (*(__int64 *)(ap)) = (__int64)(value)
#else
#define WriteArg(ap, type, value) (*(type *)(ap)) = (value)
#endif
#define roundedsizeof(t) ((sizeof(t)+INT_ARG_SIZE-1) & ~(INT_ARG_SIZE-1))
#define IsKernelVa(va) (((DWORD)(va) & 0x80000000) && !IsSecureVa(va))
#define Arg(ap, type) (*(type *)(ap))
#define NextArg(ap, type) ((ap) = (char *)(ap) + roundedsizeof(type))
/**
* Data structures and functions for handle manipulations
*/
typedef struct cinfo {
char acName[4]; /* 00: object type ID string */
uchar disp; /* 04: type of dispatch */
uchar type; /* 05: api handle type */
ushort cMethods; /* 06: # of methods in dispatch table */
const PFNVOID *ppfnMethods;/* 08: ptr to array of methods (in server address space) */
const DWORD *pdwSig; /* 0C: ptr to array of method signatures */
PPROCESS pServer; /* 10: ptr to server process */
} CINFO; /* cinfo */
typedef CINFO *PCINFO;
#define NUM_SYSTEM_SETS 32
extern const CINFO *SystemAPISets[NUM_SYSTEM_SETS];
#define DISPATCH_KERNEL 0 /* dispatch directly in kernel */
#define DISPATCH_I_KERNEL 1 /* dispatch implicit handle in kernel */
#define DISPATCH_KERNEL_PSL 2 /* dispatch as thread in kernel */
#define DISPATCH_I_KPSL 3 /* implicit handle as kernel thread */
#define DISPATCH_PSL 4 /* dispatch as user mode PSL */
#define DISPATCH_I_PSL 5 /* implicit handle as user mode PSL */
BOOL SC_Nop();
BOOL SC_NotSupported();
typedef struct APISet {
CINFO cinfo; /* description of the API set */
int iReg; /* registered API set index (-1 if not registered) */
} APISET;
typedef APISET *PAPISET;
#include "schedule.h"
#include "nkintr.h"
// The user mode virtual address space is 2GB split into 64 32M sections
// of 512 64K blocks of 16 4K pages.
//
// Virtual address format:
// 3322222 222221111 1111 110000000000
// 1098765 432109876 5432 109876543210
// zSSSSSS BBBBBBBBB PPPP oooooooooooo
#define BLOCK_MASK 0x1FF
#define SECTION_MASK 0x03F
#define MAPPER_INCR (1<<VA_SECTION)
#define NUM_MAPPER_SECTIONS ((LAST_MAPPER_ADDRESS - FIRST_MAPPER_ADDRESS)/MAPPER_INCR)
ERRFALSE(NUM_MAPPER_SECTIONS <= 32);
// shared section
#define SHARED_BASE_ADDRESS LAST_MAPPER_ADDRESS
#define SHARED_SECTION (SHARED_BASE_ADDRESS >> VA_SECTION)
#define IsInSharedSection(va) (((DWORD) (va) >= SHARED_BASE_ADDRESS) && ((DWORD) (va) < RESOURCE_BASE_ADDRESS))
// resource section
#define RESOURCE_BASE_ADDRESS (SHARED_BASE_ADDRESS + MAPPER_INCR)
#define RESOURCE_SECTION (RESOURCE_BASE_ADDRESS >> VA_SECTION)
#define IsInResouceSection(va) ((int) (va) >= RESOURCE_BASE_ADDRESS)
ERRFALSE(RESOURCE_BASE_ADDRESS == 0x7E000000);
// Bit offsets of block & section in a virtual address:
#define VA_BLOCK 16
#define VA_SECTION 25
// Values for mb_flags:
#define MB_FLAG_PAGER_TYPE 0x0f
#define MB_FLAG_AUTOCOMMIT 0x10
#define MB_PAGER_NONE 0x00
#define MB_PAGER_FIRST 0x01
#define MB_PAGER_LOADER 0x01
#define MB_PAGER_MAPPING 0x02
#define MB_MAX_PAGER_TYPE 0x02
#define UNKNOWN_BASE (~0)
#define VERIFY_READ_FLAG 0
#define VERIFY_EXECUTE_FLAG 0
#define VERIFY_WRITE_FLAG 1
#define VERIFY_KERNEL_OK 2
// values of fdwInternal for DoVirtualAlloc
#define MEM_CONTIGUOUS 0x40000000
#define MEM_NOSTKCHK 0x80000000 // don't check stack overlapping, used only in system startup
#define MEM_SHAREDONLY 0x20000000 // Force allocation in shared upper 2GB
#define MEM_SHAREDREAD 0x10000000 // give read permission to other processes
LPVOID DoVirtualAlloc(LPVOID lpvAddress, DWORD cbSize, DWORD fdwAllocationType, DWORD fdwProtect, DWORD fdwInternal, DWORD dwPFNBase);
/** Address translation tables */
typedef struct MemBlock MEMBLOCK;
typedef MEMBLOCK *SECTION[BLOCK_MASK+1];
typedef SECTION *PSECTION;
extern SECTION NKSection;
extern SECTION NullSection;
#define NULL_SECTION (&NullSection)
#define NULL_BLOCK 0
#define RESERVED_BLOCK ((MEMBLOCK*)1)
#if defined(MIPS)
#include "nkmips.h"
#elif defined(SHx)
#include "nkshx.h"
#elif defined(x86)
#include "nkx86.h"
#elif defined(ARM)
#include "nkarm.h"
#else
#pragma error("No CPU Defined")
#endif
#define PendEvents1 (KData.aPend1)
#define PendEvents2 (KData.aPend2)
#define MemForPT (KData.nMemForPT)
#define hCurTok ((HANDLE) KData.ahSys[SH_CURTOKEN])
ERRFALSE(SYSHANDLE_OFFSET == offsetof(struct KDataStruct, ahSys));
ERRFALSE(CURTLSPTR_OFFSET == offsetof(struct KDataStruct, lpvTls));
ERRFALSE(KINFO_OFFSET == offsetof(struct KDataStruct, aInfo));
#if PAGE_SIZE == 4096
#define VA_PAGE 12
#define PAGE_MASK 0x00F
#elif PAGE_SIZE == 2048
#define VA_PAGE 11
#define PAGE_MASK 0x01F
#elif PAGE_SIZE == 1024
#define VA_PAGE 10
#define PAGE_MASK 0x03F
#else
#error "Unsupported Page Size"
#endif
#define PAGES_PER_BLOCK (0x10000 / PAGE_SIZE)
ERRFALSE(SECTION_SHIFT == VA_SECTION);
/* Memory Block
* This structure maps a 64K block of memory. All memory reservations
* must begin on a 64k boundary.
*/
struct MemBlock {
ACCESSLOCK alk; /* 00: key code for this set of pages */
uchar cUses; /* 04: # of page table entries sharing this leaf */
uchar flags; /* 05: mapping flags */
short ixBase; /* 06: first block in region */
short hPf; /* 08: handle to pager */
short cLocks; /* 0a: lock count */
#if HARDWARE_PT_PER_PROC
ulong *aPages; /* 0c: pointer to the VA of hardware page table */
#else
ulong aPages[PAGES_PER_BLOCK]; /* 0c: entrylo values */
#endif
}; /* MemBlock */
extern MEMBLOCK *PmbDecommitting;
extern HANDLE hCurrScav;
extern PTHREAD PthScavTarget;
extern PPROCESS PprcScavTarget;
extern RunList_t RunList;
extern void (*MTBFf)(LPVOID, ulong, ulong, ulong, ulong);
void SC_NKTerminateThread(DWORD dwExitCode);
extern LPVOID pExitThread;
extern LPVOID pExcpExitThread;
extern LPVOID pCaptureDumpFileOnDevice;
#define bAllKMode (!(pTOC->ulKernelFlags & KFLAG_NOTALLKMODE))
typedef HANDLE (* PFNOPEN)(LPCWSTR);
typedef void (* PFNCLOSE)(HANDLE);
typedef int FN_PAGEIN(BOOL bWrite, DWORD addr);
typedef BOOL FN_PAGEOUT(DWORD addr);
extern FN_PAGEIN LoaderPageIn;
extern FN_PAGEOUT LoaderPageOut;
extern FN_PAGEIN MappedPageIn;
extern FN_PAGEOUT MappedPageOut;
#define PAGEIN_FAILURE 0
#define PAGEIN_SUCCESS 1
#define PAGEIN_RETRY 2
#define PAGEIN_OTHERRETRY 3
/* Thread Call stack structure
*
* This structure is used by the IPC mechanism to track
* current process, access key, and return addresses for
* IPC calls which are in progress. It is also used by
* the exception handling code to hold critical thread
* state while switching modes.
*/
typedef struct CALLSTACK {
struct CALLSTACK *pcstkNext;
RETADDR retAddr; /* return address */
PPROCESS pprcLast; /* previous process */
ACCESSKEY akyLast; /* previous access key */
uint extra; /* extra CPU dependent data */
//#if defined(MIPS)
// ulong pPad; /* so that excinfo fits in a callstack */
//#endif
#if defined(x86)
ulong ExEsp; /* saved Esp value for exception */
ulong ExEbp; /* saved Ebp " */
ulong ExEbx; /* saved Ebx " */
ulong ExEsi; /* saved Esi " */
ulong ExEdi; /* saved Edi " */
#endif
ulong dwPrevSP; /* SP of caller */
ulong dwPrcInfo; /* information about the caller (mode, callback?, etc) */
} CALLSTACK; /* CallStack */
typedef CALLSTACK *PCALLSTACK;
// bit fields in dwPrcInfo
#define CST_MODE_FROM_USER 0x0001 // indicate if we we calling from KMode (0 == kMode, 1 == umode)
#define CST_MODE_TO_USER 0x0002 // indicate what mode we're calling into (0 == kMode, 1 = umode)
#define CST_CALLBACK 0x0004 // indicate if this is a callback
#define CST_IN_KERNEL 0x0008 // indicate that we're in KPSL
#define CST_THUMB_MODE 0x0020 // THUMB only flag, must be the same as THUMB_STATE
#if defined(x86)
#define MAX_PSL_ARGS 56 // 13 max PSL args + return address
// enough room to hold NK_PCR (can't use sizeof because it's used in assembly)
#define SECURESTK_RESERVE (SIZE_OF_FXSAVE_AREA + 16 + (PRETLS_RESERVED+TLS_MINIMUM_AVAILABLE+3)*4)
ERRFALSE (sizeof(NK_PCR) <= SECURESTK_RESERVE);
#elif defined(MIPS)
#define SECURESTK_RESERVE (SIZE_PRETLS + 4 * sizeof (REG_TYPE)) // +4 register save area for calling convention
#else
#define SECURESTK_RESERVE (SIZE_PRETLS + 4 * sizeof (DWORD)) // +4 register save area for calling convention
#endif
typedef struct _OBJCALLSTRUCT {
int method; // method nubmer
DWORD prevSP; // previous ESP if stack switch occurs
DWORD mode; // what mode we're calling from
DWORD linkage; // exception handler's linkage
RETADDR ra; // return address
DWORD args[1]; // variable size (MIPS may have 64 bit registers, the handler takes care of that
} OBJCALLSTRUCT, *POBJCALLSTRUCT;
typedef struct _SVRRTNSTRUCT {
DWORD prevSP; // previous SP (out parameter)
DWORD mode; // return mode
DWORD linkage; // linkage
} SVRRTNSTRUCT, *PSVRRTNSTRUCT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -