首页
社区
课程
招聘
[分享]Win XP/7/8 下 32/64-Bit 枚举多处理器 IDT
发表于: 2013-8-28 10:37 9726

[分享]Win XP/7/8 下 32/64-Bit 枚举多处理器 IDT

2013-8-28 10:37
9726

网上枚举多核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 ()

typedef ULONG (NTAPI * pfnKeQueryActiveProcessorCount)(PKAFFINITY ActiveProcessors);

KEVENT g_Event ;
ULONG_PTR g_CurrentCpuAffinity = 0;

//
// Private methods
//
VOID TraverseIdt (ULONG_PTR CpuOrdinal)
{
       HG_IDT_INFO idt ;
       SIZE_T i = 0;
       SIZE_T address = 0;
       PHG_IDT_ENTRY idt_entry = NULL;
       PHG_IDT_ENTRY idtTmp = NULL;

#if defined (_WIN64)
       __sidt(&idt );
       idt_entry = (PHG_IDT_ENTRY )HGMAKESIZE( idt.LowIDTbase , idt.HiIDTbase );
#else
       _asm{
            sidt idt
      }
       idt_entry = (PHG_IDT_ENTRY )MAKELONG( idt.LowIDTbase , idt.HiIDTbase );
#endif
      
       if (idt_entry )
      {
             for (i = 0; i <= 0xFF; i++)
            {
                   idtTmp = &idt_entry [i];
#if defined (_WIN64)
                   address = HGMAKESIZE (MAKELONG( idtTmp->LowOffset , idtTmp-> MidOffset), idtTmp->HiOffset );
#else
                   address = MAKELONG (idtTmp-> LowOffset, idtTmp->HiOffset );
#endif
                   IdtLog(("CPU Ordinal: %d, Index: %02X, Address: %p\n" , CpuOrdinal, i , address));
            }
      }
}

VOID TraverseIdtDpc (
       __in  struct _KDPC * Dpc,
       __in  ULONG DeferredContext,
       __in  PVOID SystemArgument1,
       __in  PVOID SystemArgument2)
{
       HG_IDT_INFO idt ;
       SIZE_T i = 0;
       SIZE_T address = 0;
       PHG_IDT_ENTRY idt_entry = NULL;
       PHG_IDT_ENTRY idtTmp = NULL;

       TraverseIdt(g_CurrentCpuAffinity );

       HgKeSetEvent(&g_Event , IO_NO_INCREMENT, FALSE);
}

VOID QueryCurrentIdt ()
{
       KAFFINITY CpuAffinity ;
       size_t nCpuCount = 0;
       size_t i = 0;
       KDPC Dpc ;

       CpuAffinity = HgKeQueryActiveProcessors ();

       for(i = 0; i < sizeof(KAFFINITY ); i ++){
             if ((CpuAffinity >> i) & 1){
                   nCpuCount ++;
            }
      }

       if (nCpuCount == 1){
             KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
             TraverseIdt(0);
             KeLowerIrql(OldIrql );
      } else{
             for(i = 0; i < sizeof(KAFFINITY ); i ++){
                   if ((CpuAffinity >> i) & 1){
                         g_CurrentCpuAffinity = i ;
                         HgKeInitializeEvent(&g_Event , NotificationEvent, FALSE);
                         HgKeInitializeDpc(&Dpc , (PKDEFERRED_ROUTINE )TraverseIdtDpc, NULL);
                         HgKeSetTargetProcessorDpc(&Dpc , (CCHAR) i);
                         HgKeSetImportanceDpc(&Dpc , HighImportance);
                         HgKeInsertQueueDpc(&Dpc , NULL, NULL);

                         if (HgKeWaitForSingleObject (&g_Event, (KWAIT_REASON)0, 0, 0, 0) == STATUS_SUCCESS )
                        {
                               continue;
                        }
                  }
            }
      }
}

Win7 64-Bit部分截图:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (6)
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢共享。。。
2013-8-28 10:53
0
雪    币: 129
活跃值: (2753)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2013-8-28 10:55
0
雪    币: 245
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢楼主分享
2013-8-29 00:20
0
雪    币: 11026
活跃值: (17530)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢楼主分享实用的代码,支持一下
2013-8-29 08:56
0
雪    币: 35
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢分享!
2013-8-30 20:41
0
雪    币: 66
活跃值: (49)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
谢谢楼主分享
2013-9-3 09:03
0
游客
登录 | 注册 方可回帖
返回
//