home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kompon / d2345 / MSYSINFO.ZIP / Source / MSI_CPUUsage.pas < prev    next >
Pascal/Delphi Source File  |  2001-06-05  |  8KB  |  305 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {         MiTeC System Information Components           }
  5. {          CPU Usage Evaluation Component               }
  6. {           version 1.1 for Delphi 3,4,5                }
  7. {                                                       }
  8. {           Copyright ⌐ 2001 Michal Mutl                }
  9. {                                                       }
  10. {*******************************************************}
  11.  
  12. {$INCLUDE MITEC_DEF.INC}
  13.  
  14. unit MSI_CPUUsage;
  15.  
  16. interface
  17.  
  18. uses
  19.   SysUtils, Windows, Classes, ExtCtrls;
  20.  
  21. type
  22.   TOnIntervalEvent = procedure (Sender: TObject; Value: DWORD) of object;
  23.  
  24.   TMCPUUsage = class(TComponent)
  25.   private
  26.     Timer: TTimer;
  27.     FOnInterval: TOnIntervalEvent;
  28.     FLastValue, FValue: comp;
  29.     FReady: Boolean;
  30.     function GetActive: Boolean;
  31.     function GetInterval: DWORD;
  32.     procedure SetActive(const Value: Boolean);
  33.     procedure SetInterval(const Value: DWORD);
  34.     procedure OnTimer(Sender: TObject);
  35.   public
  36.     constructor Create(AOwner: TComponent); override;
  37.     destructor Destroy; override;
  38.   published
  39.     property Active: Boolean read GetActive write SetActive;
  40.     property Interval: DWORD read GetInterval write SetInterval;
  41.     property OnInterval: TOnIntervalEvent read FOnInterval write FOnInterval;
  42.   end;
  43.  
  44. function Init9xCPUData: Boolean;
  45. function Get9xCPUUsage: integer;
  46. procedure Release9xCPUData;
  47.  
  48. function InitNTCPUData: Boolean;
  49. function GetNTCPUUsage: comp;
  50. procedure ReleaseNTCPUData;
  51.  
  52. const
  53.   ObjCounter = 'KERNEL\CPUUsage';
  54.   StartStat = 'PerfStats\StartStat';
  55.   StatData = 'PerfStats\StatData';
  56.   StopStat = 'PerfStats\StopStat';
  57.  
  58. implementation
  59.  
  60. {$R 'MSI_CPUUsage.dcr'}
  61.  
  62. uses MiTeC_Routines, Registry;
  63.  
  64. type
  65.   PULONG = ^ULONG;
  66.  
  67.   ULONG = DWORD;
  68.  
  69.   NTSTATUS = ULONG;
  70.  
  71.   PVOID = Pointer;
  72.  
  73.   _SYSTEM_INFORMATION_CLASS = (
  74.           SystemBasicInformation,
  75.           SystemProcessorInformation,
  76.           SystemPerformanceInformation,
  77.           SystemTimeOfDayInformation,
  78.           SystemNotImplemented1,
  79.           SystemProcessesAndThreadsInformation,
  80.           SystemCallCounts,
  81.           SystemConfigurationInformation,
  82.           SystemProcessorTimes,
  83.           SystemGlobalFlag,
  84.           SystemNotImplemented2,
  85.           SystemModuleInformation,
  86.           SystemLockInformation,
  87.           SystemNotImplemented3,
  88.           SystemNotImplemented4,
  89.           SystemNotImplemented5,
  90.           SystemHandleInformation,
  91.           SystemObjectInformation,
  92.           SystemPagefileInformation,
  93.           SystemInstructionEmulationCounts,
  94.           SystemInvalidInfoClass1,
  95.           SystemCacheInformation,
  96.           SystemPoolTagInformation,
  97.           SystemProcessorStatistics,
  98.           SystemDpcInformation,
  99.           SystemNotImplemented6,
  100.           SystemLoadImage,
  101.           SystemUnloadImage,
  102.           SystemTimeAdjustment,
  103.           SystemNotImplemented7,
  104.           SystemNotImplemented8,
  105.           SystemNotImplemented9,
  106.           SystemCrashDumpInformation,
  107.           SystemExceptionInformation,
  108.           SystemCrashDumpStateInformation,
  109.           SystemKernelDebuggerInformation,
  110.           SystemContextSwitchInformation,
  111.           SystemRegistryQuotaInformation,
  112.           SystemLoadAndCallImage,
  113.           SystemPrioritySeparation,
  114.           SystemNotImplemented10,
  115.           SystemNotImplemented11,
  116.           SystemInvalidInfoClass2,
  117.           SystemInvalidInfoClass3,
  118.           SystemTimeZoneInformation,
  119.           SystemLookasideInformation,
  120.           SystemSetTimeSlipEvent,
  121.           SystemCreateSession,
  122.           SystemDeleteSession,
  123.           SystemInvalidInfoClass4,
  124.           SystemRangeStartInformation,
  125.           SystemVerifierInformation,
  126.           SystemAddVerifier,
  127.           SystemSessionProcessesInformation);
  128.      SYSTEM_INFORMATION_CLASS = _SYSTEM_INFORMATION_CLASS;
  129.  
  130.      _SYSTEM_PROCESSOR_TIMES = packed record
  131.           IdleTime,
  132.           KernelTime,
  133.           UserTime,
  134.           DpcTime,
  135.           InterruptTime: int64;
  136.           InterruptCount: ULONG;
  137.      end;
  138.  
  139.      SYSTEM_PROCESSOR_TIMES = _SYSTEM_PROCESSOR_TIMES;
  140.      PSYSTEM_PROCESSOR_TIMES = ^_SYSTEM_PROCESSOR_TIMES;
  141.  
  142.   TNativeQuerySystemInformation = function(
  143.           SystemInformationClass: SYSTEM_INFORMATION_CLASS;
  144.           SystemInformation: PVOID;
  145.           SystemInformationLength: ULONG;
  146.           ReturnLength: PULONG
  147.           ): NTSTATUS; stdcall;
  148.  
  149. const
  150.   NTDLL_DLL_Name = 'NTDLL.DLL';
  151.  
  152.   STATUS_SUCCESS = $00000000;
  153.   STATUS_INFO_LENGTH_MISMATCH = $C0000004;
  154.  
  155.   Timer100N = 10000000;
  156.   Timer1S = 1000;
  157.  
  158. var
  159.   CPUSize, Cpu9xUsage: DWORD;
  160.   CPUNTUsage: PSYSTEM_PROCESSOR_TIMES;
  161.   Reg: TRegistry;
  162.  
  163.   NTDLL_DLL: THandle = 0;
  164.   ZwQuerySystemInformation: TNativeQuerySystemInformation = nil;
  165.  
  166. function Init9xCPUData: Boolean;
  167. begin
  168.   Reg:=TRegistry.Create;
  169.   with Reg do
  170.     try
  171.       Rootkey:=HKEY_DYN_DATA;
  172.       if OpenKey(StartStat,False) then begin
  173.         GetDataType(ObjCounter);
  174.         ReadBinaryData(ObjCounter,CPU9xUsage,GetDataSize(ObjCounter));
  175.         CloseKey;
  176.         if not OpenKey(StatData,False) then
  177.           raise Exception.Create('Unable to read performance data');
  178.       end else
  179.         raise Exception.Create('Unable to start performance monitoring');
  180.     finally
  181.       Result:=CurrentPath=StatData;
  182.     end;
  183. end;
  184.  
  185. function Get9xCPUUsage: integer;
  186. begin
  187.   with Reg do begin
  188.     ReadBinaryData(ObjCounter,CPU9xUsage,4);
  189.   end;
  190.   Result:=Cpu9xUsage;
  191. end;
  192.  
  193. procedure Release9xCPUData;
  194. begin
  195.   with Reg do begin
  196.     CloseKey;
  197.     if OpenKey(StopStat,False) then begin
  198.       GetDataType(ObjCounter);
  199.       GetDataType(ObjCounter);
  200.       ReadBinaryData(ObjCounter,CPU9xUsage,GetDataSize(ObjCounter));
  201.       CloseKey;
  202.     end;
  203.     Free;
  204.   end;
  205. end;
  206.  
  207. function InitNTCPUData: Boolean;
  208. var
  209.   R: NTSTATUS;
  210.   n: DWORD;
  211. begin
  212.   n:=0;
  213.   CPUNTUsage:=AllocMem(SizeOf(SYSTEM_PROCESSOR_TIMES));
  214.   R:=ZwQuerySystemInformation(SystemProcessorTimes,CPUNTUsage,SizeOf(SYSTEM_PROCESSOR_TIMES),nil);
  215.   while R=STATUS_INFO_LENGTH_MISMATCH do begin
  216.     Inc(n);
  217.     ReallocMem(CPUNTUsage,n*SizeOf(CPUNTUsage^));
  218.     R:=ZwQuerySystemInformation(SystemProcessorTimes,CPUNTUsage,n*SizeOf(SYSTEM_PROCESSOR_TIMES),nil);
  219.   end;
  220.   CPUSize:=n*SizeOf(CPUNTUsage^);
  221.   Result:=R=STATUS_SUCCESS;
  222. end;
  223.  
  224. function GetNTCPUUsage;
  225. begin
  226.   ZwQuerySystemInformation(SystemProcessorTimes,CPUNTUsage,CPUSize,nil);
  227.   Result:=CPUNTUsage^.IdleTime;
  228. end;
  229.  
  230. procedure ReleaseNTCPUData;
  231. begin
  232.   Freemem(CPUNTUsage);
  233. end;
  234.  
  235. { TMCPUUsage }
  236.  
  237. constructor TMCPUUsage.Create(AOwner: TComponent);
  238. begin
  239.   inherited;
  240.   Timer:=TTimer.Create(Self);
  241.   Timer.Interval:=1000;
  242.   Timer.Enabled:=False;
  243.   if IsNT then
  244.     FReady:=InitNTCPUData
  245.   else
  246.     FReady:=Init9xCPUData;
  247.   if FReady then
  248.     Timer.OnTimer:=OnTimer;
  249. end;
  250.  
  251. destructor TMCPUUsage.Destroy;
  252. begin
  253.   Timer.Free;
  254.   if FReady then begin
  255.     if IsNT then
  256.       ReleaseNTCPUData
  257.     else
  258.       Release9xCPUData;
  259.   end;
  260.   inherited;
  261. end;
  262.  
  263. function TMCPUUsage.GetActive: Boolean;
  264. begin
  265.   Result:=Timer.Enabled;
  266. end;
  267.  
  268. function TMCPUUsage.GetInterval: DWORD;
  269. begin
  270.   Result:=Timer.Interval;
  271. end;
  272.  
  273. procedure TMCPUUsage.OnTimer(Sender: TObject);
  274. var
  275.   v: DWORD;
  276. begin
  277.   if IsNT then begin
  278.     FLastValue:=FValue;
  279.     FValue:=GetNTCPUUsage;
  280.     v:=Round((Timer100n-(FValue-FLastValue)/(Timer.Interval/Timer1s))/Timer100n*100);
  281.   end else
  282.     v:=Get9xCPUUsage;
  283.   if Assigned(FOnInterval) then
  284.     FOnInterval(Self,v);
  285. end;
  286.  
  287. procedure TMCPUUsage.SetActive(const Value: Boolean);
  288. begin
  289.   Timer.Enabled:=Value and FReady;
  290. end;
  291.  
  292. procedure TMCPUUsage.SetInterval(const Value: DWORD);
  293. begin
  294.   Timer.Interval:=Value;
  295. end;
  296.  
  297. initialization
  298.   if IsNT then begin
  299.     if NTDLL_DLL=0 then
  300.       NTDLL_DLL:=GetModuleHandle(NTDLL_DLL_name);
  301.     if NTDLL_DLL<>0 then
  302.       @ZwQuerySystemInformation:=GetProcAddress(NTDLL_DLL,'ZwQuerySystemInformation');
  303.   end;
  304. end.
  305.