为什么获取到的CPU ID会变呢?(100分)

  • 主题发起人 主题发起人 taizhi
  • 开始时间 开始时间
T

taizhi

Unregistered / Unconfirmed
GUEST, unregistred user!
function GetCPUIDStr:String;<br>var<br>&nbsp; CPUID:TCPUID;<br>begin<br>&nbsp; CPUID:=GetCPUID;<br>&nbsp; Result:=IntToHex(CPUID[1],8)+IntToHex(CPUID[2],8)+IntToHex(CPUID[3],8)+IntToHex(CPUID[4],8);<br>end;
 
直奇怪,如果发的贴含的字符太多的话,发不出来,只好分开来发,下面代码继续.<br>function GetCPUVendor: TVendor; assembler; register; <br>asm <br>&nbsp;PUSH &nbsp; &nbsp;EBX &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{Save affected register} <br>&nbsp;PUSH &nbsp; &nbsp;EDI <br>&nbsp;MOV &nbsp; &nbsp; EDI,EAX &nbsp; &nbsp; &nbsp;{@Result (TVendor)} <br>&nbsp;MOV &nbsp; &nbsp; EAX,0 <br>&nbsp;DW &nbsp; &nbsp; &nbsp;$A20F &nbsp; &nbsp; &nbsp; &nbsp;{CPUID Command} <br>&nbsp;MOV &nbsp; &nbsp; EAX,EBX <br>&nbsp;XCHG &nbsp; &nbsp;EBX,ECX &nbsp; &nbsp; {save ECX result} <br>&nbsp;MOV &nbsp; &nbsp; &nbsp;ECX,4 <br>@1: <br>&nbsp;STOSB <br>&nbsp;SHR &nbsp; &nbsp; EAX,8 <br>&nbsp;LOOP &nbsp; &nbsp;@1 <br>&nbsp;MOV &nbsp; &nbsp; EAX,EDX <br>&nbsp;MOV &nbsp; &nbsp; &nbsp;ECX,4 <br>@2: <br>&nbsp;STOSB <br>&nbsp;SHR &nbsp; &nbsp; EAX,8 <br>&nbsp;LOOP &nbsp; &nbsp;@2 <br>&nbsp;MOV &nbsp; &nbsp; EAX,EBX <br>&nbsp;MOV &nbsp; &nbsp; &nbsp;ECX,4 <br>@3: <br>&nbsp;STOSB <br>&nbsp;SHR &nbsp; &nbsp; EAX,8 <br>&nbsp;LOOP &nbsp; &nbsp;@3 <br>&nbsp;POP &nbsp; &nbsp; EDI &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{Restore registers} <br>&nbsp;POP &nbsp; &nbsp; EBX <br>end;
 
function GetCPUInfo: string; <br>var <br>&nbsp;CPUID: TCPUID; <br>&nbsp;I: Integer; <br>&nbsp;S: TVendor;<br>begin <br>&nbsp;for I := Low(CPUID) to High(CPUID) do<br>&nbsp; &nbsp;CPUID := -1; <br>&nbsp; &nbsp; <br>&nbsp;CPUID := GetCPUID; <br><br>&nbsp;S := GetCPUVendor; <br><br>&nbsp;Result := S + IntToHex(CPUID[1], 8) + IntToHex(CPUID[2], 8) <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + IntToHex(CPUID[3], 8) <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + IntToHex(CPUID[4], 8); <br>end;<br><br>通过GetCPUInfo方法来获取CPU ID,结果总在<br>GenuineIntel00000F43010208000000649DBFEBFBFF<br>与<br>GenuineIntel00000F43000208000000649DBFEBFBFF之间变换,这是为什么呢?请高手们指点.
 
很明白,因为你是双核CPU.<br><br>在加载软件时,,不一定是哪一个CPU优化加载,<br><br>所以,一般情况下,谁先加载就读哪一个CPU的 ID.<br><br>呵呵,,至于 哪一核加载也是系统说了算。。<br><br>所以,你的 CPU ID 会在两个ID间互换(因为你是双核CPU,你试试 四核 CPU就知道,,是在四个CPUID互换)。<br><br><br>解决方法。。<br><br>cnpack 发布的那个控件包里面,有解决方法。<br><br>你想要哪一个CPU的ID就要哪一个的。。。<br><br>两个。四个。。八个CPU的。。<br><br>都没有问题。。呵呵,,
 
好人作到底。。<br><br>贴代码给你。<br><br><br>{******************************************************************************}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CnPack For Delphi/C++Builder &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 中国人自己的开放源码第三方开发包 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (C)Copyright 2001-2008 CnPack 开发组 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ------------------------------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp;改和重新发布这一程序。 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp;适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp;还没有,可访问我们的网站: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;网站地址:http://www.cnpack.org &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;电子邮件:master@cnpack.org &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{******************************************************************************}<br><br>unit CnHardWareInfo;<br>{* |&lt;PRE&gt;<br>================================================================================<br>* 软件名称:CnPack 组件包<br>* 单元名称:硬件信息单元<br>* 单元作者:SkyJacker<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LiuXiao<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Yock<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Bahamut<br>* 备 &nbsp; &nbsp;注:硬件信息单元,目前只实现获取多核、多CPU系统中指定CPU的序列号与占用率<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 以及部分 BIOS 的 ID.<br>* 开发平台:WindowsXP sp2 + Delphi 6.0 up2<br>* 兼容测试:Win2000/XP + Delphi 5、6<br>* 本 地 化:该单元中的字符串均符合本地化处理方式<br>* 单元标识:$Id: CnHardWareInfo.pas,v 1.9 2008/09/25 12:41:12 liuxiao Exp $<br>* 修改记录:2008.08.01 V1.3<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 加入 Bahamut 的获取 BIOS ID 的过程,但只支持小部分 BIOS<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2008.04.12 V1.2<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LiuXiao 加入对 CPU 生产厂商名的读取与是否支持 cpuid 指令与序列号<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 的属性,感谢 Yock。<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2008.01.12 V1.1<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LiuXiao 加入对 CPU 占用率的读取<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2007.01.23 V1.0<br>* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 创建单元,实现功能<br>================================================================================<br>|&lt;/PRE&gt;}<br><br>interface<br><br>{$I CnPack.inc}<br><br>uses<br>&nbsp; Classes, Windows, SysUtils, ExtCtrls;<br>&nbsp; <br>type<br>&nbsp; TCnCPUIdFormat = (ifContinuous, ifDashed);<br>&nbsp; {* CPU序列号与信息串显示样式<br>&nbsp; &nbsp;|&lt;PRE&gt;<br>&nbsp; &nbsp; &nbsp;ifContinuous: &nbsp;-连续型<br>&nbsp; &nbsp; &nbsp;ifDashed: &nbsp; &nbsp; &nbsp;-使用分割符'-'分割<br>&nbsp; &nbsp;|&lt;/PRE&gt;<br>&nbsp; }<br><br>&nbsp; TCnCpuId = class(TPersistent)<br>&nbsp; {CPU 信息类}<br>&nbsp; private<br>&nbsp; &nbsp; FTimer: TTimer;<br>&nbsp; &nbsp; FCPUCount: Integer;<br>&nbsp; &nbsp; FCPUIds: TStrings;<br>&nbsp; &nbsp; FCPUInfos: TStrings;<br>&nbsp; &nbsp; FSupportCpuIds: TList;<br>&nbsp; &nbsp; FSupportCpuSns: TList;<br>&nbsp; &nbsp; FCPUOems: TStrings;<br>&nbsp; &nbsp; FCPUIdFormat: TCnCPUIdFormat;<br>&nbsp; &nbsp; FCPUUsageRead: Boolean;<br>&nbsp; &nbsp; FCPUUsage: array[0..255] of Integer; // 总不会超过 256 个 CPU 吧?<br>&nbsp; &nbsp; FCurCnt, FLastCnt: array[0..255] of Integer;<br>&nbsp; &nbsp; FAverageCPUUsage: Integer;<br>&nbsp; &nbsp; function GetFirstCPUId: string;<br>&nbsp; &nbsp; function GetCPUId(Index: Integer): string;<br>&nbsp; &nbsp; procedure SetCPUIdFormat(ACPUIdFormat: TCnCPUIdFormat);<br>&nbsp; &nbsp; function GetAverageCPUUsage: Integer;<br>&nbsp; &nbsp; function GetCPUUsage(Index: Integer): Integer;<br>&nbsp; &nbsp; function GetFirstCPUUsage: Integer;<br><br>&nbsp; &nbsp; function RefreshCPUUsages: Cardinal; // 只被定时调用<br>&nbsp; &nbsp; procedure CpuUsageTimer(Sender: TObject);<br>&nbsp; &nbsp; function GetCPUOem(Index: Integer): string;<br>&nbsp; &nbsp; function GetFirstCPUOem: string;<br>&nbsp; &nbsp; function GetSupportCPUId(Index: Integer): Boolean;<br>&nbsp; &nbsp; function GetSupportCPUSn(Index: Integer): Boolean;<br>&nbsp; &nbsp; function GetFirstSupportCPUId: Boolean;<br>&nbsp; &nbsp; function GetFirstSupportCPUSn: Boolean;<br>&nbsp; &nbsp; function GetCPUInfoString(Index: Integer): string;<br>&nbsp; &nbsp; function GetFirstCPUInfoString: string;<br>&nbsp; public<br>&nbsp; &nbsp; constructor Create;<br>&nbsp; &nbsp; {* 构造函数,创建 FCPUIds 并调用 ReadCPUId}<br>&nbsp; &nbsp; destructor Destroy; override;<br><br>&nbsp; &nbsp; procedure ReadCPUId;<br>&nbsp; &nbsp; {* 获得所有 CPU 内核的序列号和其他信息,并存入各个列表}<br><br>&nbsp; &nbsp; property CPUIdFormat: TCnCPUIdFormat read FCPUIdFormat write SetCPUIdFormat;<br>&nbsp; &nbsp; {* CPU 序列号显示样式}<br>&nbsp; &nbsp; property CPUCount: Integer read FCPUCount;<br>&nbsp; &nbsp; {* 系统中 CPU 核总数}<br>&nbsp; &nbsp; property FirstCPUId: string read GetFirstCPUId;<br>&nbsp; &nbsp; {* 获取首个 CPU 的 ID,用于单 CPU 系统}<br>&nbsp; &nbsp; property FirstCPUInfoString: string read GetFirstCPUInfoString;<br>&nbsp; &nbsp; {* 获取首个 CPU 的信息字符串,用于单 CPU 系统}<br>&nbsp; &nbsp; property FirstCPUOem: string read GetFirstCPUOem;<br>&nbsp; &nbsp; {* 获取首个 CPU 的生产厂商,用于单 CPU 系统}<br>&nbsp; &nbsp; property FirstSupportCPUId: Boolean read GetFirstSupportCPUId;<br>&nbsp; &nbsp; {* 获取首个 CPU 是否支持 CPUID 指令,用于单 CPU 系统}<br>&nbsp; &nbsp; property FirstSupportCPUSn: Boolean read GetFirstSupportCPUSn;<br>&nbsp; &nbsp; {* 获取首个 CPU 是否支持读取 CPU 序列号,用于单 CPU 系统}<br>&nbsp; &nbsp; property SupportCPUId[Index: Integer]: Boolean read GetSupportCPUId;<br>&nbsp; &nbsp; {* 获取指定 CPU 是否支持 CPUID 指令}<br>&nbsp; &nbsp; property SupportCPUSn[Index: Integer]: Boolean read GetSupportCPUSn;<br>&nbsp; &nbsp; {* 获取指定 CPU 是否支持读取 CPU 序列号}<br>&nbsp; &nbsp; property CPUId[Index: Integer]: string read GetCPUId;<br>&nbsp; &nbsp; {* 获得指定 CPU 的序列号。索引 Index 从 0 开始。<br>&nbsp; &nbsp; &nbsp; &nbsp;需要说明的是,序列号很多 CPU 被禁止读取了因此此属性全 0;而网络上流传的<br>&nbsp; &nbsp; &nbsp; &nbsp;CPU 序列号读取,很多情况下读的是下面的“信息字符串”的属性}<br>&nbsp; &nbsp; property CPUInfoString[Index: Integer]: string read GetCPUInfoString;<br>&nbsp; &nbsp; {* 获得指定 CPU 的信息字符串。索引 Index 从 0 开始。<br>&nbsp; &nbsp; &nbsp; &nbsp;此信息字符串包括了 CPU 的一些特性说明,非唯一,很多情况下被误当做 CPU ID。}<br>&nbsp; &nbsp; property CPUOem[Index: Integer]: string read GetCPUOem;<br>&nbsp; &nbsp; &nbsp;{* 获得指定 CPU 的生产厂商。索引 Index 从 0 开始}<br>&nbsp; &nbsp; property CPUUsage[Index: Integer]: Integer read GetCPUUsage;<br>&nbsp; &nbsp; {* 获得指定 CPU 的占用率,0 到 100<br>&nbsp; &nbsp; &nbsp; &nbsp;需要说明的是,本类在 NT 系统上采用定时采样获得 CPU 的忙周期数再计算而来,<br>&nbsp; &nbsp; &nbsp; &nbsp;因此在刚实例化、未采样完成时,得到的 CPU 占用率可能有误。以下同。<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; property AverageCPUUsage: Integer read GetAverageCPUUsage;<br>&nbsp; &nbsp; {* 获得平均 CPU 占用率,0 到 100}<br>&nbsp; &nbsp; property FirstCPUUsage: Integer read GetFirstCPUUsage;<br>&nbsp; &nbsp; {* 获得首个 CPU 的占用率,0 到 100,用于单 CPU 系统}<br>&nbsp; end;<br><br>function CnGetBiosID: string;<br>{* 获得 BIOS 的 ID,只支持小部分 BIOS,而且旧式的主板由于不规范,无法获取 ID}<br><br>implementation<br><br>const<br>&nbsp; BiosOffset: array[0..2] of DWORD = ($6577, $7196, $7550);<br><br>type<br>&nbsp; PUNICODE_STRING = ^TUNICODE_STRING;<br>&nbsp; _UNICODE_STRING = record<br>&nbsp; &nbsp; Length: Word;<br>&nbsp; &nbsp; MaximumLength: Word;<br>&nbsp; &nbsp; Buffer: PWChar;<br>&nbsp; end;<br>&nbsp; TUNICODE_STRING = _UNICODE_STRING;<br><br>&nbsp; POBJECT_ATTRIBUTES = ^TOBJECT_ATTRIBUTES;<br>&nbsp; _OBJECT_ATTRIBUTES = record<br>&nbsp; &nbsp; Length: ULONG;<br>&nbsp; &nbsp; RootDirectory: THandle;<br>&nbsp; &nbsp; ObjectName: PUNICODE_STRING;<br>&nbsp; &nbsp; Attributes: ULONG;<br>&nbsp; &nbsp; SecurityDescriptor: Pointer;<br>&nbsp; &nbsp; SecurityQualityOfService: Pointer;<br>&nbsp; end;<br>&nbsp; TOBJECT_ATTRIBUTES = _OBJECT_ATTRIBUTES;<br><br>&nbsp; PLARGE_INTEGER = ^LARGE_INTEGER;<br>&nbsp; PPByte = ^PByte;<br><br>&nbsp; _SYSTEM_BASIC_INFORMATION = record<br>&nbsp; &nbsp; Unknown: ULONG;<br>&nbsp; &nbsp; MaximumIncrement: ULONG;<br>&nbsp; &nbsp; PhysicalPageSize: ULONG;<br>&nbsp; &nbsp; NumberOfPhysicalPages: ULONG;<br>&nbsp; &nbsp; LowestPhysicalPage: ULONG;<br>&nbsp; &nbsp; HighestPhysicalPage: ULONG;<br>&nbsp; &nbsp; AllocationGranularity: ULONG;<br>&nbsp; &nbsp; LowestUserAddress: ULONG;<br>&nbsp; &nbsp; HighestUserAddress: ULONG;<br>&nbsp; &nbsp; ActiveProcessors: ULONG;<br>&nbsp; &nbsp; NumberProcessors: UCHAR;<br>&nbsp; end;<br>&nbsp; SYSTEM_BASIC_INFORMATION = _SYSTEM_BASIC_INFORMATION;<br>&nbsp; PSYSTEM_BASIC_INFORMATION = ^SYSTEM_BASIC_INFORMATION;<br>&nbsp; TSystemBasicInformation = SYSTEM_BASIC_INFORMATION;<br>&nbsp; PSystemBasicInformation = ^TSystemBasicInformation;<br><br>&nbsp; SYSTEM_PROCESSOR_TIMES = packed record<br>&nbsp; &nbsp; IdleTime: LARGE_INTEGER;<br>&nbsp; &nbsp; KernelTime: LARGE_INTEGER;<br>&nbsp; &nbsp; UserTime: LARGE_INTEGER;<br>&nbsp; &nbsp; DpcTime: LARGE_INTEGER;<br>&nbsp; &nbsp; InterruptTime: LARGE_INTEGER;<br>&nbsp; &nbsp; InterruptCount: ULONG;<br>&nbsp; end;<br>&nbsp; TSystemProcessorTimes = SYSTEM_PROCESSOR_TIMES;<br>&nbsp; PSystemProcessorTimes = ^TSystemProcessorTimes;<br>&nbsp; <br>&nbsp; SYSTEM_INFORMATION_CLASS = (<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemBasicInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemProcessorInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemPerformanceInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemTimeOfDayInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented1,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemProcessesAndThreadsInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemCallCounts,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemConfigurationInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemProcessorTimes,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemGlobalFlag,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented2,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemModuleInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemLockInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented3,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented4,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented5,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemHandleInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemObjectInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemPagefileInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemInstructionEmulationCounts,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemInvalidInfoClass1,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemCacheInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemPoolTagInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemProcessorStatistics,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemDpcInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented6,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemLoadImage,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemUnloadImage,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemTimeAdjustment,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented7,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented8,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented9,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemCrashDumpInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemExceptionInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemCrashDumpStateInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemKernelDebuggerInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemContextSwitchInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemRegistryQuotaInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemLoadAndCallImage,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemPrioritySeparation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented10,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemNotImplemented11,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemInvalidInfoClass2,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemInvalidInfoClass3,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemTimeZoneInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemLookasideInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemSetTimeSlipEvent,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemCreateSession,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemDeleteSession,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemInvalidInfoClass4,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemRangeStartInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemVerifierInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemAddVerifier,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemSessionProcessesInformation);<br>&nbsp; TSystemInformationClass = SYSTEM_INFORMATION_CLASS;<br>&nbsp; <br>&nbsp; TNativeQuerySystemInformation = function(SystemInformationClass:<br>&nbsp; &nbsp; TSystemInformationClass; SystemInformation: Pointer; SystemInformationLength:<br>&nbsp; &nbsp; Cardinal; ReturnLength: PDWORD): Cardinal; stdcall;<br><br>&nbsp; TZwOpenSection = function (var hWnd: THandle; dwMask: DWORD; PObject: POBJECT_ATTRIBUTES): DWORD; stdcall;<br><br>&nbsp; TZwMapViewOfSection = function (hWnd: THandle; ViewHandle: THandle; PBaseAddr: Pointer;<br>&nbsp; &nbsp; dwLength: ULONG; dwAllocLen: ULONG; PRealAddr: PLARGE_INTEGER; PReadLen: PDWORD;<br>&nbsp; &nbsp; dwInherite: DWORD; dwAllocType: ULONG; dwProtectType: ULONG): DWORD; stdcall;<br><br>&nbsp; TZwUnmapViewOfSection = function (hWnd: THandle; PBaseAddr: Pointer): DWORD; stdcall;<br><br>const<br>&nbsp; STATUS_SUCCESS = $00000000;<br><br>var<br>&nbsp; NtDllHandle: THandle = 0;<br>&nbsp; NtDllNeedFree: Boolean = False;<br><br>&nbsp; NtQuerySystemInformation: TNativeQuerySystemInformation = nil;<br><br>&nbsp; ZwOpenSection: TZwOpenSection = nil;<br><br>&nbsp; ZwMapViewOfSection: TZwMapViewOfSection = nil;<br><br>&nbsp; ZwUnmapViewOfSection: TZwUnmapViewOfSection = nil;<br><br>function GetNtNativeAPIs: Boolean;<br>begin<br>&nbsp; if Win32Platform = VER_PLATFORM_WIN32_NT then<br>&nbsp; begin<br>&nbsp; &nbsp; NtDllHandle := GetModuleHandle('NTDLL.DLL');<br>&nbsp; &nbsp; if NtDllHandle = 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; NtDllHandle := LoadLibrary('NTDLL.DLL');<br>&nbsp; &nbsp; &nbsp; NtDllNeedFree := NtDllHandle &lt;&gt; 0;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; if NtDllHandle &lt;&gt; 0 then<br>&nbsp; &nbsp; begin<br>// &nbsp; &nbsp; &nbsp;@NtQueryInformationToken:=GetProcAddress(NtDllHandle,'NtQueryInformationToken');<br>// &nbsp; &nbsp; &nbsp;@NtOpenProcessToken := GetProcAddress(NtDllHandle,'NtOpenProcessToken');<br>// &nbsp; &nbsp; &nbsp;@NtOpenSection := GetProcAddress(NtDllHandle,'NtOpenSection');<br>// &nbsp; &nbsp; &nbsp;@NtClose := GetProcAddress(NtDllHandle,'NtClose');<br>// &nbsp; &nbsp; &nbsp;@NtOpenProcess := GetProcAddress(NtDllHandle,'NtOpenProcess');<br>&nbsp; &nbsp; &nbsp; @NtQuerySystemInformation := GetProcAddress(NtDllHandle, 'NtQuerySystemInformation');<br>// &nbsp; &nbsp; &nbsp;@NtCreateSection := GetProcAddress(NtDllHandle,'NtCreateSection');<br>// &nbsp; &nbsp; &nbsp;@NtCreateToken := GetProcAddress(NtDllHandle,'NtCreateToken');<br>// &nbsp; &nbsp; &nbsp;@NtMapViewOfSection := GetProcAddress(NtDllHandle,'NtMapViewOfSection');<br>// &nbsp; &nbsp; &nbsp;@NtUnmapViewOfSection := GetProcAddress(NtDllHandle,'NtUnmapViewOfSection');<br>// &nbsp; &nbsp; &nbsp;@NtOpenFile := GetProcAddress(NtDllHandle,'NtOpenFile');<br>// &nbsp; &nbsp; &nbsp;@NtCreateFile := GetProcAddress(NtDllHandle,'NtCreateFile');<br>// &nbsp; &nbsp; &nbsp;@NtQueryObject := GetProcAddress(NtDllHandle,'NtQueryObject');<br>// &nbsp; &nbsp; &nbsp;@NtQueryInformationProcess := GetProcAddress(NtDllHandle,'NtQueryInformationProcess');<br>// &nbsp; &nbsp; &nbsp;@NtQueryInformationThread := GetProcAddress(NtDllHandle,'NtQueryInformationThread');<br>// &nbsp; &nbsp; &nbsp;@NtQueryInformationFile := GetProcAddress(NtDllHandle,'NtQueryInformationFile');<br>// &nbsp; &nbsp; &nbsp;@NtDuplicateObject := GetProcAddress(NtDllHandle,'NtDuplicateObject');<br>// &nbsp; &nbsp; &nbsp;@NtDeviceIoControlFile := GetProcAddress(NtDllHandle,'NtDeviceIoControlFile');<br><br>&nbsp; &nbsp; &nbsp; @ZwOpenSection := GetProcAddress(NtDllHandle, 'ZwOpenSection');<br>&nbsp; &nbsp; &nbsp; @ZwMapViewOfSection := GetProcAddress(NtDllHandle, 'ZwMapViewOfSection');<br>&nbsp; &nbsp; &nbsp; @ZwUnmapViewOfSection := GetProcAddress(NtDllHandle, 'ZwUnmapViewOfSection');<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; Result := NtDllHandle &lt;&gt; 0;<br>end;<br><br>procedure FreeNtNativeAPIs;<br>begin<br>&nbsp; if (NtDllHandle &lt;&gt; 0) and NtDllNeedFree then<br>&nbsp; begin<br>&nbsp; &nbsp; FreeLibrary(NtDllHandle);<br>&nbsp; &nbsp; NtDllHandle := 0;<br>&nbsp; end;<br>end;<br><br>constructor TCnCpuId.Create;<br>begin<br>&nbsp; FSupportCpuIds := TList.Create;<br>&nbsp; FSupportCpuSns := TList.Create;<br>&nbsp; FCPUIds := TStringList.Create;<br>&nbsp; FCPUInfos := TStringList.Create;<br>&nbsp; FCPUOems := TStringList.Create;<br>&nbsp; FCPUIdFormat := ifContinuous;<br>&nbsp; ReadCPUId;<br><br>&nbsp; FTimer := TTimer.Create(nil);<br>&nbsp; FTimer.Interval := 1000;<br>&nbsp; FTimer.OnTimer := CpuUsageTimer;<br>&nbsp; FTimer.Enabled := True;<br>&nbsp; RefreshCPUUsages;<br><br>&nbsp; if Win32Platform = VER_PLATFORM_WIN32_NT then // NT 下需要采样判断<br>&nbsp; &nbsp; FCPUUsageRead := False;<br>end;<br><br>destructor TCnCpuId.Destroy;<br>begin<br>&nbsp; FTimer.Free;<br>&nbsp; FCPUOems.Free;<br>&nbsp; FCPUInfos.Free;<br>&nbsp; FCPUIds.Free;<br>&nbsp; FSupportCpuSns.Free;<br>&nbsp; FSupportCpuIds.Free;<br>end;<br><br>// 获取所有 CPU 的序列号<br>procedure TCnCpuId.ReadCPUId;<br>const<br>&nbsp; SCN_CPUID_BIT = $200000; //CPU ID 位标记<br>var<br>&nbsp; I: Integer;<br>&nbsp; Mask: Integer;<br>&nbsp; CurrProc: THandle;<br>&nbsp; SysInfo: TSystemInfo;<br>&nbsp; ProcessAffinityOld: Cardinal;<br>&nbsp; ProcessAffinity: Cardinal;<br>&nbsp; SystemAffinity: Cardinal;<br><br>&nbsp; function GetCnCpuIdSupport: Boolean;<br>&nbsp; asm<br>&nbsp; &nbsp; PUSHFD &nbsp; //不允许直接存取,必须通过堆栈<br>&nbsp; &nbsp; POP &nbsp; &nbsp; EAX<br>&nbsp; &nbsp; MOV &nbsp; &nbsp; EDX, EAX<br>&nbsp; &nbsp; XOR &nbsp; &nbsp; EAX, SCN_CPUID_BIT<br>&nbsp; &nbsp; PUSH &nbsp; &nbsp;EAX<br>&nbsp; &nbsp; POPFD<br>&nbsp; &nbsp; PUSHFD<br>&nbsp; &nbsp; POP &nbsp; &nbsp; EAX<br>&nbsp; &nbsp; XOR &nbsp; &nbsp; EAX,EDX &nbsp;// 检测 ID 位是否受影响<br>&nbsp; &nbsp; JZ &nbsp; &nbsp; &nbsp;@exit &nbsp; &nbsp;// CPUID 无效<br>&nbsp; &nbsp; MOV &nbsp; &nbsp; AL, 1 &nbsp;// CPUID 有效<br>&nbsp; @exit:<br>&nbsp; end;<br><br>&nbsp; // 获取 CPU 信息字符串<br>&nbsp; function GetCnCPUInfoString: string;<br>&nbsp; const<br>&nbsp; &nbsp; cnIFContinuous = '%.8x%.8x%.8x%.8x';<br>&nbsp; &nbsp; cnIFDashed = '%.8x-%.8x-%.8x-%.8x';<br>&nbsp; var<br>&nbsp; &nbsp; iEax,iEbx,iEcx,iEdx: Integer;<br>&nbsp; begin<br>&nbsp; &nbsp; asm<br>&nbsp; &nbsp; &nbsp; push ebx<br>&nbsp; &nbsp; &nbsp; push ecx<br>&nbsp; &nbsp; &nbsp; push edx<br>&nbsp; &nbsp; &nbsp; mov &nbsp;eax, $1<br>&nbsp; &nbsp; &nbsp; dw $A20F &nbsp; &nbsp; &nbsp;//CPUID<br>&nbsp; &nbsp; &nbsp; mov iEax, eax<br>&nbsp; &nbsp; &nbsp; mov iEbx, ebx<br>&nbsp; &nbsp; &nbsp; mov iEcx, ecx<br>&nbsp; &nbsp; &nbsp; mov iEdx, edx<br>&nbsp; &nbsp; &nbsp; pop edx<br>&nbsp; &nbsp; &nbsp; pop ecx<br>&nbsp; &nbsp; &nbsp; pop ebx<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; if FCPUIdFormat = ifContinuous then<br>&nbsp; &nbsp; &nbsp; Result := Format(cnIFContinuous, [iEax, iEbx, iEcx, iEdx])<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; Result := Format(cnIFDashed, [iEax, iEbx, iEcx, iEdx])<br>&nbsp; end;<br><br>&nbsp; // 获取 CPU 序列号<br>&nbsp; function GetCnCPUID: string;<br>&nbsp; const<br>&nbsp; &nbsp; SCnIFContinuous = '%.4x%.4x%.4x%.4x%.4x%.4x';<br>&nbsp; &nbsp; SCnIFDashed = '%.4x-%.4x-%.4x-%.4x-%.4x-%.4x';<br>&nbsp; var<br>&nbsp; &nbsp; SFmt: string;<br>&nbsp; &nbsp; iEax, iEcx, iEdx, iEdx1: Integer;<br>&nbsp; begin<br>&nbsp; &nbsp; asm<br>&nbsp; &nbsp; &nbsp; push ebx<br>&nbsp; &nbsp; &nbsp; push ecx<br>&nbsp; &nbsp; &nbsp; push edx<br>&nbsp; &nbsp; &nbsp; mov &nbsp;eax, $1<br>&nbsp; &nbsp; &nbsp; dw $A20F &nbsp; &nbsp; &nbsp;//CPUID<br>&nbsp; &nbsp; &nbsp; mov iEax, eax<br>&nbsp; &nbsp; &nbsp; mov iEdx1, edx<br>&nbsp; &nbsp; &nbsp; mov eax, $3<br>&nbsp; &nbsp; &nbsp; dw $A20F<br>&nbsp; &nbsp; &nbsp; mov iEcx, ecx<br>&nbsp; &nbsp; &nbsp; mov iEdx, edx<br>&nbsp; &nbsp; &nbsp; pop edx<br>&nbsp; &nbsp; &nbsp; pop ecx<br>&nbsp; &nbsp; &nbsp; pop ebx<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; if FCPUIdFormat=ifContinuous then<br>&nbsp; &nbsp; &nbsp; SFmt := SCnIFContinuous<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; SFmt := SCnIFDashed;<br><br>&nbsp; &nbsp; if iEdx1 and (1 shr 18) = 0 then // Cpu 序列号不能读,返回全0<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Result := Format(SFmt, [0, 0, 0, 0, 0, 0]);<br>&nbsp; &nbsp; &nbsp; FSupportCpuSns.Add(nil); // 加 False<br>&nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; FSupportCpuSns.Add(Pointer(True));<br>&nbsp; &nbsp; &nbsp; Result := Format(SFmt,<br>&nbsp; &nbsp; &nbsp; &nbsp; [(iEax and $FFFF0000) shr 16, iEax and $FFFF,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(iEcx and $FFFF0000) shr 16, iEcx and $FFFF,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(iEdx and $FFFF0000) shr 16, iEdx and $FFFF]);<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; // 获得 CPU OEM 厂商名<br>&nbsp; function GetCnCPUOem: string;<br>&nbsp; var<br>&nbsp; &nbsp; iEax, iEbx, iEcx, iEdx: Integer;<br>&nbsp; begin<br>&nbsp; &nbsp; asm<br>&nbsp; &nbsp; &nbsp; push ebx<br>&nbsp; &nbsp; &nbsp; push ecx<br>&nbsp; &nbsp; &nbsp; push edx<br>&nbsp; &nbsp; &nbsp; mov &nbsp;eax, $0<br>&nbsp; &nbsp; &nbsp; dw $A20F &nbsp; &nbsp; &nbsp;//CPUID<br>&nbsp; &nbsp; &nbsp; mov iEax, eax<br>&nbsp; &nbsp; &nbsp; mov iEbx, ebx<br>&nbsp; &nbsp; &nbsp; mov iEcx, ecx<br>&nbsp; &nbsp; &nbsp; mov iEdx, edx<br>&nbsp; &nbsp; &nbsp; pop edx<br>&nbsp; &nbsp; &nbsp; pop ecx<br>&nbsp; &nbsp; &nbsp; pop ebx<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; SetLength(Result, 3 * SizeOf(Integer));<br>&nbsp; &nbsp; CopyMemory(@Result[1], @iEbx, SizeOf(Integer));<br>&nbsp; &nbsp; CopyMemory(@Result[1 + SizeOf(Integer)], @iEdx, SizeOf(Integer));<br>&nbsp; &nbsp; CopyMemory(@Result[1 + 2 * SizeOf(Integer)], @iEcx, SizeOf(Integer));<br>&nbsp; end;<br>begin<br>&nbsp; FCPUCount := 0;<br>&nbsp; FSupportCpuIds.Clear;<br>&nbsp; FSupportCpuSns.Clear;<br>&nbsp; FCPUIds.Clear;<br>&nbsp; FCPUOems.Clear;<br>&nbsp; <br>&nbsp; // 获取 CPU 个数<br>&nbsp; GetSystemInfo(SysInfo);<br>&nbsp; FCPUCount := SysInfo.dwNumberOfProcessors;<br><br>&nbsp; // 获取所有 CPU 的序列号<br>&nbsp; Mask := $1;<br>&nbsp; CurrProc := GetCurrentProcess;<br>&nbsp; if not GetProcessAffinityMask(CurrProc, ProcessAffinityOld, SystemAffinity) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; try<br>&nbsp; &nbsp; for I := 0 to FCpuCount - 1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; ProcessAffinity := Mask shl I;<br>&nbsp; &nbsp; &nbsp; if not SetProcessAffinityMask(CurrProc, ProcessAffinity) then<br>&nbsp; &nbsp; &nbsp; &nbsp; Break;<br><br>&nbsp; &nbsp; &nbsp; FSupportCpuIds.Add(Pointer(GetCnCpuIdSupport));<br>&nbsp; &nbsp; &nbsp; if FSupportCpuIds[FSupportCpuIds.Count - 1] &lt;&gt; nil then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUIds.Add(GetCnCPUID);<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUInfos.Add(GetCnCPUInfoString);<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUOems.Add(GetCnCPUOem);<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUIds.Add('');<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUInfos.Add('');<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUOems.Add(''); &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; finally<br>&nbsp; &nbsp; //恢复默认<br>&nbsp; &nbsp; SetProcessAffinityMask(CurrProc, ProcessAffinityOld);<br>&nbsp; end;<br>end;<br><br>procedure TCnCpuId.SetCPUIdFormat(ACPUIdFormat: TCnCPUIdFormat);<br>begin<br>&nbsp; if FCPUIdFormat &lt;&gt; ACPUIdFormat then<br>&nbsp; begin<br>&nbsp; &nbsp; FCPUIdFormat := ACPUIdFormat;<br>&nbsp; &nbsp; ReadCPUId;<br>&nbsp; end;<br>end;<br><br>// 获得单 CPU 系统 ID<br>function TCnCpuId.GetFirstCPUId: string;<br>begin<br>&nbsp; if FCPUIds.Count &gt; 0 then<br>&nbsp; &nbsp; Result := FCPUIds.Strings[0];<br>end;<br><br>// 得到第几个 CPU 的序列号<br>function TCnCpuId.GetCPUId(Index: Integer): string;<br>begin<br>&nbsp; Result := '';<br>&nbsp; // 保证 FCPUIds 索引的合法性<br>&nbsp; if (Index &lt; 0) or (Index &gt; FCPUIds.Count - 1) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; Result := FCPUIds.Strings[Index];<br>end;<br><br>function TCnCpuId.GetAverageCPUUsage: Integer;<br>begin<br>&nbsp; if not FCPUUsageRead then<br>&nbsp; &nbsp; Result := -1<br>&nbsp; else<br>&nbsp; &nbsp; Result := FAverageCPUUsage;<br>end;<br><br>function TCnCpuId.GetCPUUsage(Index: Integer): Integer;<br>begin<br>&nbsp; if not FCPUUsageRead or (Index &gt; FCPUCount - 1) then<br>&nbsp; &nbsp; Result := -1<br>&nbsp; else<br>&nbsp; &nbsp; Result := FCPUUsage[Index];<br>end;<br><br>function TCnCpuId.GetFirstCPUUsage: Integer;<br>begin<br>&nbsp; if FCPUUsageRead and (FCPUCount &gt; 0) then<br>&nbsp; &nbsp; Result := FCPUUsage[0]<br>&nbsp; else<br>&nbsp; &nbsp; Result := -1;<br>end;<br><br>function TCnCpuId.RefreshCPUUsages: Cardinal;<br>var<br>&nbsp; CpuCnt: Cardinal;<br>&nbsp; I: integer;<br>&nbsp; Spt: Pointer;<br>&nbsp; Sbi: TSystemBasicInformation;<br><br>&nbsp; dwType, cbData: Cardinal;<br>&nbsp; hOpen: HKEY;<br>&nbsp; Buffer: Cardinal;<br>begin<br>&nbsp; if Win32Platform = VER_PLATFORM_WIN32_NT then<br>&nbsp; begin<br>&nbsp; &nbsp; for I := 0 to FCPUCount - 1 do // 保存旧值<br>&nbsp; &nbsp; &nbsp; FLastCnt := FCurCnt;<br><br>&nbsp; &nbsp; if NtQuerySystemInformation(SystemBasicInformation, @Sbi, SizeOf(Sbi), nil)<br>&nbsp; &nbsp; &nbsp; &lt;&gt; STATUS_SUCCESS then<br>&nbsp; &nbsp; &nbsp; CpuCnt := 1<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; CpuCnt := Sbi.NumberProcessors;<br><br>&nbsp; &nbsp; Spt := AllocMem(CpuCnt * (SizeOf(TSystemProcessorTimes) + 4));<br>&nbsp; &nbsp; NtQuerySystemInformation(SystemProcessorTimes, Spt, CpuCnt * (SizeOf(TSystemProcessorTimes) + 4), @Result);<br><br>&nbsp; &nbsp; for I := 0 to CpuCnt - 1 &nbsp;do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; with PSystemProcessorTimes(PChar(Spt) + I * (sizeof(TSystemProcessorTimes) + 4))^ do<br>&nbsp; &nbsp; &nbsp; &nbsp; FCurCnt := IdleTime.QuadPart;<br>&nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; // 采样后计算<br>&nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUUsage := Round((10000000 - (FCurCnt - FLastCnt) / (FTimer.Interval / 1000)) / 10000000 * 100);<br>&nbsp; &nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUUsage := 0;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; FreeMem(spt);<br>&nbsp; end<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; if RegOpenKeyEx(HKEY_DYN_DATA,'PerfStats/StatData', 0, KEY_READ, hOpen) = ERROR_SUCCESS then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; cbData:=sizeof(Cardinal);<br>&nbsp; &nbsp; &nbsp; if RegQueryValueEx(hOpen, 'KERNEL/CPUUsage', nil, @dwType, PBYTE(@Buffer),<br>&nbsp; &nbsp; &nbsp; &nbsp; @cbData) = ERROR_SUCCESS then<br>&nbsp; &nbsp; &nbsp; &nbsp; FCPUUsage[0] := Buffer;<br>&nbsp; &nbsp; &nbsp; RegCloseKey(hOpen);<br>&nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; FCPUUsage[0] := -1;<br>&nbsp; end;<br><br>&nbsp; FCPUUsageRead := True;<br>end;<br><br>procedure TCnCpuId.CpuUsageTimer(Sender: TObject);<br>var<br>&nbsp; I: Integer;<br>begin<br>&nbsp; RefreshCPUUsages;<br>&nbsp; <br>&nbsp; FAverageCPUUsage := 0;<br>&nbsp; for I := 0 to FCPUCount - 1 do<br>&nbsp; begin<br>&nbsp; &nbsp; if FCPUUsage &lt;&gt; -1 then<br>&nbsp; &nbsp; &nbsp; FAverageCPUUsage := FAverageCPUUsage + FCPUUsage;<br>&nbsp; end;<br><br>&nbsp; if FCPUCount &gt; 0 then<br>&nbsp; &nbsp; FAverageCPUUsage := Round(FAverageCPUUsage / FCPUCount)<br>&nbsp; else<br>&nbsp; &nbsp; FAverageCPUUsage := -1;<br>end;<br><br>function TCnCpuId.GetCPUOem(Index: Integer): string;<br>begin<br>&nbsp; Result := '';<br>&nbsp; // 保证 FCPUIds 索引的合法性<br>&nbsp; if (Index &lt; 0) or (Index &gt; FCPUOems.Count - 1) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; Result := FCPUOems.Strings[Index];<br>end;<br><br>function TCnCpuId.GetFirstCPUOem: string;<br>begin<br>&nbsp; if FCPUOems.Count &gt; 0 then<br>&nbsp; &nbsp; Result := FCPUOems.Strings[0];<br>end;<br><br>function TCnCpuId.GetSupportCPUId(Index: Integer): Boolean;<br>begin<br>&nbsp; Result := False;<br>&nbsp; // 保证 FSupportCpuIds 索引的合法性<br>&nbsp; if (Index &lt; 0) or (Index &gt; FSupportCpuIds.Count - 1) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; Result := Boolean(FSupportCpuIds[Index]);<br>end;<br><br>function TCnCpuId.GetSupportCPUSn(Index: Integer): Boolean;<br>begin<br>&nbsp; Result := False;<br>&nbsp; // 保证 FSupportCpuIds 索引的合法性<br>&nbsp; if (Index &lt; 0) or (Index &gt; FSupportCpuSns.Count - 1) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; Result := Boolean(FSupportCpuSns[Index]);<br>end;<br><br>function TCnCpuId.GetFirstSupportCPUId: Boolean;<br>begin<br>&nbsp; Result := False;<br>&nbsp; if FSupportCpuIds.Count &gt; 0 then<br>&nbsp; &nbsp; Result := Boolean(FSupportCpuIds[0]);<br>end;<br><br>function TCnCpuId.GetFirstSupportCPUSn: Boolean;<br>begin<br>&nbsp; Result := False;<br>&nbsp; if FSupportCpuSns.Count &gt; 0 then<br>&nbsp; &nbsp; Result := Boolean(FSupportCpuSns[0]);<br>end;<br><br>function TCnCpuId.GetCPUInfoString(Index: Integer): string;<br>begin<br>&nbsp; Result := '';<br>&nbsp; if (Index &lt; 0) or (Index &gt; FCPUInfos.Count - 1) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; Result := FCPUInfos.Strings[Index];<br>end;<br><br>function TCnCpuId.GetFirstCPUInfoString: string;<br>begin<br>&nbsp; if FCPUInfos.Count &gt; 0 then<br>&nbsp; &nbsp; Result := FCPUInfos[0];<br>end;<br><br>function FindAwardBios(var BiosAddr: PByte): UINT;<br>var<br>&nbsp; ABiosAddr: PByte;<br>&nbsp; szBiosData: array [0..127] of Char;<br>&nbsp; Len: Integer;<br>&nbsp; Loop: Byte;<br>begin<br>&nbsp; Result:= 0;<br>&nbsp; ABiosAddr:= PByte(DWORD(BiosAddr) + $EC71);<br><br>&nbsp; CopyMemory(@szBiosData[0], ABiosAddr, 127);<br>&nbsp; szBiosData[127]:= #0;<br><br>&nbsp; Len:= StrLen(PChar(@szBiosData[0]));<br>&nbsp; if (Len &lt;= 0) or (Len &gt;= 128) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; //AWard: &nbsp; &nbsp; &nbsp; &nbsp; 07/08/2002-i845G-ITE8712-JF69VD0CC-00<br>&nbsp; //Phoenix-Award: 03/12/2002-sis645-p4s333<br>&nbsp; if (szBiosData[2] &lt;&gt; '/') or (szBiosData[5] &lt;&gt; '/') then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; Loop:= 0;<br>&nbsp; while szBiosData[Loop] &lt;&gt; #0 do<br>&nbsp; begin<br>&nbsp; &nbsp; if (szBiosData[Loop] &lt; ' ') or (szBiosData[Loop] &gt;= Chr(127)) then<br>&nbsp; &nbsp; &nbsp; Break;<br>&nbsp; &nbsp; Inc(Loop);<br>&nbsp; end;<br><br>&nbsp; if szBiosData[Loop] = #0 then<br>&nbsp; begin<br>&nbsp; &nbsp; BiosAddr:= ABiosAddr;<br>&nbsp; &nbsp; Result:= Len;<br>&nbsp; end;<br>end;<br><br>function FindAmiBios(var BiosAddr: PByte): UINT;<br>var<br>&nbsp; ABiosAddr: PByte;<br>&nbsp; szBiosData: array [0..127] of Char;<br>&nbsp; Len: Integer;<br>&nbsp; Loop: Byte;<br>begin<br>&nbsp; Result:= 0;<br>&nbsp; ABiosAddr:= PByte(DWORD(BiosAddr) + $F478);<br><br>&nbsp; CopyMemory(@szBiosData[0], ABiosAddr, 127);<br>&nbsp; szBiosData[127]:= #0;<br><br>&nbsp; Len:= StrLen(PChar(@szBiosData[0]));<br>&nbsp; if (Len &lt;= 0) or (Len &gt;= 128) then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; // Example: "AMI: 51-2300-000000-00101111-030199-"<br>&nbsp; if (szBiosData[2] &lt;&gt; '-') or (szBiosData[7] &lt;&gt; '-') then<br>&nbsp; &nbsp; Exit;<br><br>&nbsp; Loop:= 0;<br>&nbsp; while szBiosData[Loop] &lt;&gt; #0 do<br>&nbsp; begin<br>&nbsp; &nbsp; if (szBiosData[Loop] &lt; ' ') or (szBiosData[Loop] &gt;= Chr(127)) then<br>&nbsp; &nbsp; &nbsp; Break;<br>&nbsp; &nbsp; Inc(Loop);<br>&nbsp; end;<br><br>&nbsp; if szBiosData[Loop] = #0 then<br>&nbsp; begin<br>&nbsp; &nbsp; BiosAddr:= ABiosAddr;<br>&nbsp; &nbsp; Result:= Len;<br>&nbsp; end;<br>end;<br><br>function FindPhoenixBios(var BiosAddr: PByte): UINT;<br>var<br>&nbsp; ABiosAddr: PByte;<br>&nbsp; szBiosData: array [0..127] of Char;<br>&nbsp; Len: Integer;<br>&nbsp; I, Loop: Byte;<br>begin<br>&nbsp; for I := 0 to 2 do<br>&nbsp; begin<br>&nbsp; &nbsp; ABiosAddr:= PByte(DWORD(BiosAddr) + BiosOffset);<br>&nbsp; &nbsp; CopyMemory(@szBiosData[0], ABiosAddr, 127);<br>&nbsp; &nbsp; szBiosData[127]:= #0;<br>&nbsp; &nbsp; Len:= StrLen(PChar(@szBiosData[0]));<br>&nbsp; &nbsp; if (Len &lt;= 0) or (Len &gt;= 128) then<br>&nbsp; &nbsp; &nbsp; Continue;<br><br>&nbsp; &nbsp; // Example: Phoenix "NITELT0.86B.0044.P11.9910111055"<br>&nbsp; &nbsp; if (szBiosData[7] &lt;&gt; '.') or (szBiosData[11] &lt;&gt; '.') then<br>&nbsp; &nbsp; &nbsp; Continue;<br><br>&nbsp; &nbsp; Loop:= 0;<br>&nbsp; &nbsp; while szBiosData[Loop] &lt;&gt; #0 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if (szBiosData[Loop] &lt; ' ') or (szBiosData[Loop] &gt;= Chr(127)) then<br>&nbsp; &nbsp; &nbsp; &nbsp; Break;<br>&nbsp; &nbsp; &nbsp; Inc(Loop);<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; if szBiosData[Loop] = #0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; BiosAddr:= ABiosAddr;<br>&nbsp; &nbsp; &nbsp; Result:= Len;<br>&nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; Result:= 0;<br>end;<br><br>function CnGetBiosID: string;<br>var<br>&nbsp; Size: DWORD;<br>&nbsp; RealAddr: LARGE_INTEGER;<br>&nbsp; Path: PWCHAR;<br>&nbsp; BaseAddr: DWORD;<br>&nbsp; UniString: TUNICODE_STRING;<br>&nbsp; Obj: TOBJECT_ATTRIBUTES;<br>&nbsp; hSection: THandle;<br>&nbsp; PBiosSerial: PByte;<br>&nbsp; uBiosSerialLen: UINT;<br>&nbsp; szSystemInfo: array [0..4095] of Char;<br>&nbsp; ReturnLen: UINT;<br>begin<br>&nbsp; FillChar(szSystemInfo, 4096, 0);<br>&nbsp; ReturnLen:= 0;<br><br>&nbsp; RealAddr.LowPart:= $000F0000;<br>&nbsp; RealAddr.HighPart:= $00000000;<br>&nbsp; Size:= $FFFF;<br>&nbsp; Path:= '/device/physicalmemory';<br>&nbsp; BaseAddr:= 0;<br>&nbsp; UniString.Buffer:= Path;<br>&nbsp; UniString.Length:= $2C;<br>&nbsp; UniString.MaximumLength:= $2E;<br><br>&nbsp; Obj.Attributes:= 64;<br>&nbsp; Obj.Length:= 24;<br>&nbsp; Obj.ObjectName:= @UniString;<br>&nbsp; Obj.RootDirectory:= 0;<br>&nbsp; Obj.SecurityDescriptor:= nil;<br>&nbsp; Obj.SecurityQualityOfService:= nil;<br><br>&nbsp; //调用函数,对物理内存进行映射<br>&nbsp; if (ZwOpenSection(hSection, 4, @Obj) = 0) and<br>&nbsp; &nbsp; &nbsp;(ZwMapViewOfSection(hSection, $FFFFFFFF, @BaseAddr, 0, $FFFF, @RealAddr, @Size, 1, 0, 2) = 0) then<br>&nbsp; begin<br>&nbsp; &nbsp; //执行后会在当前进程的空间开辟一段64k的空间,并把f000:0000到f000:ffff处的内容映射到这里<br>&nbsp; &nbsp; //映射的基址由BaseAddr返回,如果映射不再有用,应该用ZwUnmapViewOfSection断开映射<br>&nbsp; &nbsp; PBiosSerial:= PByte(BaseAddr);<br>&nbsp; &nbsp; uBiosSerialLen:= FindAwardBios(PBiosSerial);<br>&nbsp; &nbsp; if uBiosSerialLen = 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; uBiosSerialLen:= FindAmiBios(PBiosSerial);<br>&nbsp; &nbsp; &nbsp; if uBiosSerialLen = 0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; uBiosSerialLen:= FindPhoenixBios(PBiosSerial);<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; if uBiosSerialLen &lt;&gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; CopyMemory(Pointer(szSystemInfo + ReturnLen), PBiosSerial, uBiosSerialLen);<br>&nbsp; &nbsp; &nbsp; Inc(ReturnLen, uBiosSerialLen);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; ZwUnmapViewOfSection($FFFFFFFF, Pointer(BaseAddr));<br>&nbsp; end;<br><br>&nbsp; if ReturnLen &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; SetLength(Result, ReturnLen);<br>&nbsp; &nbsp; MoveMemory(@Result[1], @szSystemInfo[0], ReturnLen);<br>&nbsp; end;<br>end;<br><br>initialization<br>&nbsp; GetNtNativeAPIs;<br><br>finalization<br>&nbsp; FreeNtNativeAPIs;<br><br>end.
 
后退
顶部