网上枚举多核IDT的代码或多或少都有些问题,以下代码在WinXP 32-Bit、Win7 32/64-Bit、Win8 32/64-Bit测试通过。
//
#define HGMAKESIZE (a, b) (( ULONG64)(((ULONG32 )(((ULONG64)( a)) & 0xFFFFFFFF)) | ((ULONG64)((ULONG32 )(((ULONG64)( b)) & 0xFFFFFFFF))) << 32))
//
// Define struct
//
typedef struct _HG_IDT_ENTRY
{
unsigned short LowOffset;
unsigned short selector;
unsigned char unused_lo;
unsigned char segment_type:4; // 0x0E is an interrupt gate
unsigned char system_segment_flag:1;
unsigned char DPL:2; // descriptor privilege level
unsigned char P:1; // present
#if defined (_WIN64)
UINT16 MidOffset ;
ULONG32 HiOffset ;
ULONG32 Placeholder ; // not use
#else
unsigned short HiOffset;
#endif
} HG_IDT_ENTRY, * PHG_IDT_ENTRY ;
//
// sidt return idt in this format
// Stores the interrupt descriptor table register (IDTR) in the destination operand. In legacy and
// compatibility mode, the destination operand is 6 bytes; in 64-bit mode it is 10 bytes. In all modes,
// operand-size prefixes are ignored.
// In non-64-bit mode, the lower two bytes of the operand specify the 16-bit limit and the upper 4 bytes
// specify the 32-bit base address.
// In 64-bit mode, the lower two bytes of the operand specify the 16-bit limit and the upper 8 bytes
// specify the 64-bit base address.
//
#pragma pack (1)
typedef struct _HG_IDT_INFO
{
unsigned short IDTLimit;
#if defined (_WIN64)
ULONG32 LowIDTbase ;
ULONG32 HiIDTbase ;
#else
unsigned short LowIDTbase;
unsigned short HiIDTbase;
#endif
}HG_IDT_INFO, * PHG_IDT_INFO;
#pragma pack ()