免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

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

网上枚举多核IDT的代码或多或少都有些问题,以下代码在WinXP 32-Bit、Win7 32/64-Bit、Win8 32/64-Bit测试通过。
  1. //
  2. #define     HGMAKESIZE (a, b)               (( ULONG64)(((ULONG32 )(((ULONG64)( a)) & 0xFFFFFFFF)) | ((ULONG64)((ULONG32 )(((ULONG64)( b)) & 0xFFFFFFFF))) << 32))
  3. //
  4. // Define struct
  5. //
  6. typedef struct _HG_IDT_ENTRY
  7. {
  8.         unsigned short      LowOffset;
  9.         unsigned short      selector;
  10.         unsigned char       unused_lo;
  11.         unsigned char       segment_type:4;                // 0x0E is an interrupt gate
  12.         unsigned char       system_segment_flag:1;
  13.         unsigned char       DPL:2;                               // descriptor privilege level
  14.         unsigned char       P:1;                           // present
  15. #if defined (_WIN64)
  16.         UINT16                    MidOffset ;
  17.         ULONG32                   HiOffset ;
  18.         ULONG32                   Placeholder ;                   // not use
  19. #else
  20.         unsigned short      HiOffset;
  21. #endif
  22. } HG_IDT_ENTRY, * PHG_IDT_ENTRY ;

  23. //
  24. // sidt return idt in this format
  25. //  Stores the interrupt descriptor table register (IDTR) in the destination operand. In legacy and
  26. //  compatibility mode, the destination operand is 6 bytes; in 64-bit mode it is 10 bytes. In all modes,
  27. //    operand-size prefixes are ignored.
  28. //    In non-64-bit mode, the lower two bytes of the operand specify the 16-bit limit and the upper 4 bytes
  29. //    specify the 32-bit base address.
  30. //    In 64-bit mode, the lower two bytes of the operand specify the 16-bit limit and the upper 8 bytes
  31. //    specify the 64-bit base address.
  32. //
  33. #pragma pack (1)   
  34. typedef struct _HG_IDT_INFO
  35. {
  36.         unsigned short IDTLimit;
  37. #if defined (_WIN64)
  38.         ULONG32 LowIDTbase ;
  39.         ULONG32 HiIDTbase ;
  40. #else
  41.         unsigned short LowIDTbase;
  42.         unsigned short HiIDTbase;
  43. #endif
  44. }HG_IDT_INFO, * PHG_IDT_INFO;
  45. #pragma pack ()

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

  47. KEVENT g_Event ;
  48. ULONG_PTR g_CurrentCpuAffinity = 0;

  49. //
  50. // Private methods
  51. //
  52. VOID TraverseIdt (ULONG_PTR CpuOrdinal)
  53. {
  54.         HG_IDT_INFO idt ;
  55.         SIZE_T i = 0;
  56.         SIZE_T address = 0;
  57.         PHG_IDT_ENTRY idt_entry = NULL;
  58.         PHG_IDT_ENTRY idtTmp = NULL;

  59. #if defined (_WIN64)
  60.         __sidt(&idt );
  61.         idt_entry = (PHG_IDT_ENTRY )HGMAKESIZE( idt.LowIDTbase , idt.HiIDTbase );
  62. #else
  63.         _asm{
  64.              sidt idt
  65.        }
  66.         idt_entry = (PHG_IDT_ENTRY )MAKELONG( idt.LowIDTbase , idt.HiIDTbase );
  67. #endif
  68.       
  69.         if (idt_entry )
  70.        {
  71.               for (i = 0; i <= 0xFF; i++)
  72.              {
  73.                     idtTmp = &idt_entry [i];
  74. #if defined (_WIN64)
  75.                     address = HGMAKESIZE (MAKELONG( idtTmp->LowOffset , idtTmp-> MidOffset), idtTmp->HiOffset );
  76. #else
  77.                     address = MAKELONG (idtTmp-> LowOffset, idtTmp->HiOffset );
  78. #endif
  79.                     IdtLog(("CPU Ordinal: %d, Index: %02X, Address: %p\n" , CpuOrdinal, i , address));
  80.              }
  81.        }
  82. }

  83. VOID TraverseIdtDpc (
  84.         __in  struct _KDPC * Dpc,
  85.         __in  ULONG DeferredContext,
  86.         __in  PVOID SystemArgument1,
  87.         __in  PVOID SystemArgument2)
  88. {
  89.         HG_IDT_INFO idt ;
  90.         SIZE_T i = 0;
  91.         SIZE_T address = 0;
  92.         PHG_IDT_ENTRY idt_entry = NULL;
  93.         PHG_IDT_ENTRY idtTmp = NULL;

  94.         TraverseIdt(g_CurrentCpuAffinity );

  95.         HgKeSetEvent(&g_Event , IO_NO_INCREMENT, FALSE);
  96. }

  97. VOID QueryCurrentIdt ()
  98. {
  99.         KAFFINITY CpuAffinity ;
  100.         size_t nCpuCount = 0;
  101.         size_t i = 0;
  102.         KDPC Dpc ;

  103.         CpuAffinity = HgKeQueryActiveProcessors ();

  104.         for(i = 0; i < sizeof(KAFFINITY ); i ++){
  105.               if ((CpuAffinity >> i) & 1){
  106.                     nCpuCount ++;
  107.              }
  108.        }

  109.         if (nCpuCount == 1){
  110.               KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
  111.               TraverseIdt(0);
  112.               KeLowerIrql(OldIrql );
  113.        } else{
  114.               for(i = 0; i < sizeof(KAFFINITY ); i ++){
  115.                     if ((CpuAffinity >> i) & 1){
  116.                           g_CurrentCpuAffinity = i ;
  117.                           HgKeInitializeEvent(&g_Event , NotificationEvent, FALSE);
  118.                           HgKeInitializeDpc(&Dpc , (PKDEFERRED_ROUTINE )TraverseIdtDpc, NULL);
  119.                           HgKeSetTargetProcessorDpc(&Dpc , (CCHAR) i);
  120.                           HgKeSetImportanceDpc(&Dpc , HighImportance);
  121.                           HgKeInsertQueueDpc(&Dpc , NULL, NULL);

  122.                           if (HgKeWaitForSingleObject (&g_Event, (KWAIT_REASON)0, 0, 0, 0) == STATUS_SUCCESS )
  123.                          {
  124.                                 continue;
  125.                          }
  126.                    }
  127.              }
  128.        }
  129. }
复制代码

返回列表