📄 kernel.h
字号:
/* Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved. */
/*
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"
#include "osver.h"
#ifndef offsetof
#define offsetof(s,m) ((unsigned)&(((s *)0)->m))
#endif
#define ERRFALSE(exp) extern char __ERRXX[(exp)!=0]
#include "pehdr.h"
#include "romldr.h"
#include "patcher.h"
#define C_ONLY
#include "xtime.h"
typedef ulong PHYSICAL_ADDRESS;
typedef int KAFFINITY;
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) */
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 */
#define GetRegionFromAddr(addr) ((((addr) >= MemoryInfo.pFi[0].paStart) && ((addr) < MemoryInfo.pFi[0].paEnd)) ? \
&MemoryInfo.pFi[0] : (((addr) >= MemoryInfo.pFi[1].paStart) && ((addr) < MemoryInfo.pFi[1].paEnd)) ? \
&MemoryInfo.pFi[1] : 0)
extern MEMORYINFO MemoryInfo;
extern DWORD randdw1,randdw2;
/* 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 client argument list */
#define roundedsizeof(t) (sizeof(t)+sizeof(int)-1 & ~(sizeof(int)-1))
#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();
#define MAX_PROCESSES 32
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 RESERVED_SECTIONS 1 // reserve section 0 for current process
#define FIRST_MAPPER_ADDRESS ((MAX_PROCESSES+RESERVED_SECTIONS) << VA_SECTION)
#define LAST_MAPPER_ADDRESS 0x7E000000
#define MAPPER_INCR (1<<VA_SECTION)
#define NUM_MAPPER_SECTIONS ((LAST_MAPPER_ADDRESS - FIRST_MAPPER_ADDRESS)/MAPPER_INCR)
ERRFALSE(NUM_MAPPER_SECTIONS <= 32);
// 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
/** Address translation tables */
typedef struct MemBlock MEMBLOCK;
typedef MEMBLOCK *SECTION[BLOCK_MASK+1];
typedef SECTION *PSECTION;
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(PPC)
#include "nkppc.h"
#elif defined(ARM)
#include "nkarm.h"
#else
#pragma error("No CPU Defined")
#endif
#define PendEvents (KData.aInfo[KINX_PENDEVENTS])
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 */
ulong aPages[PAGES_PER_BLOCK]; /* 12: entrylo values */
}; /* 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 BOOL bAllKMode;
typedef HANDLE (* PFNOPEN)(LPCWSTR);
typedef void (* PFNCLOSE)(HANDLE);
extern DWORD (*JITf)(LPCWSTR, LPWSTR, HANDLE *);
HANDLE JitOpenFile(LPCWSTR);
void JitCloseFile(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;
/* 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
} CALLSTACK; /* CallStack */
typedef CALLSTACK *PCALLSTACK;
#define PM_NOPAGING 0
#define PM_FULLPAGING 1
#define PM_NOPAGEOUT 2
#define FT_PPFSFILE 1
#define FT_OBJSTORE 2
#define FT_ROMIMAGE 3
ERRFALSE(sizeof(CEOID) == 4);
typedef struct openexe_t {
union {
int hppfs; // ppfs handle
HANDLE hf; // object store handle
TOCentry *tocptr; // rom entry pointer
};
BYTE filetype;
BYTE bIsOID;
WORD pagemode;
DWORD offset;
union {
Name *lpName;
CEOID ceOid;
};
} openexe_t;
typedef struct OEinfo_t {
WCHAR plainname[MAX_PATH], tmpname[MAX_PATH];
CEOIDINFO ceoi;
BY_HANDLE_FILE_INFORMATION bhfi;
WIN32_FIND_DATA wfd;
} OEinfo_t;
BOOL OpenExe(LPWSTR lpszName, openexe_t *oeptr, BOOL bIsDll, BOOL bAllowPaging);
BOOL SafeOpenExe(LPWSTR lpszName, openexe_t *oeptr, BOOL bIsDll, BOOL bAllowPaging, OEinfo_t *poeinfo);
void CloseExe(openexe_t *oeptr);
DWORD LoadE32(openexe_t *oeptr, e32_lite *eptr, DWORD *lpFlags, DWORD *lpEntry, BOOL bIgnoreCPU, BOOL bAllowPaging, LPBYTE pbTrustLevel);
BOOL GetNameFromOE(CEOIDINFO *pceoi, openexe_t *oeptr);
void CloseAllCrits(void);
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
/* 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 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 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))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -