Сейчас на форуме: ==DJ==[ZLO], Dart Raiden, Alf (+6 невидимых) |
![]() |
eXeL@B —› Основной форум —› проблемы с ZwQuerySystemInformation |
Посл.ответ | Сообщение |
|
Создано: 19 августа 2004 03:43 · Личное сообщение · #1 здраствуйте. вот захотелось мне написать маленький мониторчик, чтобы мониторил память фаил покачки процессор и сетевые подключения. все это уже реализовано кроме мониторинга загруженности процессора. я узнал что эту инфу можно получить вызвав ZwQuerySystemInformation, но эта функия недокументирована. собственно вопрос: что я делаю не так ? ![]() вот код: STATUS_SUCCESS equ 0 SystemProcessorTimes equ 8 .data? SYSTEM_PROCESSOR_TIMES STRUCT IdleTime QWORD ? KernelTime QWORD ? UserTime QWORD ? DpcTime QWORD ? InterruptTime QWORD ? InterruptCount QWORD ? SYSTEM_PROCESSOR_TIMES ENDS ZwQuerySystemInformation dd ? P PVOID ? .data NtDll db "NTDLL.DLL",0 ZQSI db "ZwQuerySystemInformation",0 CPU db "загрузка CPU: %u",0 .code invoke GetModuleHandleA,ADDR NtDll invoke GetProcAddress,eax,ADDR ZQSI mov ZwQuerySystemInformation,eax mov Temp, 0 push offset Temp push 0 push offset P push SystemProcessorTimes call ZwQuerySystemInformation .if Temp != 0 invoke GlobalAlloc,GMEM_MOVEABLE,Temp mov [tcphand],eax invoke GlobalLock,eax mov [tcpmem],eax push offset Temp push [tcpmem] push Temp push SystemProcessorTimes call ZwQuerySystemInformation .if eax==STATUS_SUCCESS mov esi,[tcpmem] assume esi:PTR SYSTEM_PROCESSOR_TIMES invoke wsprintf,addr Buffer,addr CPU,[esi].IdleTime invoke MessageBox,0,addr Buffer,0,0 assume esi:nothing .endif invoke GlobalFree,[tcphand] .endif ![]() |
|
Создано: 19 августа 2004 05:18 · Личное сообщение · #2 Эта функция документирована, есть справочник по native api. Вот работающий код: .686p .MMX .XMM .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib STATUS_SUCCESS equ 0 SystemProcessorTimes equ 8 SYSTEM_PROCESSOR_TIMES STRUCT IdleTime QWORD ? KernelTime QWORD ? UserTime QWORD ? DpcTime QWORD ? InterruptTime QWORD ? InterruptCount QWORD ? SYSTEM_PROCESSOR_TIMES ENDS .data NtDll db "NTDLL.DLL",0 ZQSI db "ZwQuerySystemInformation",0 CPU db "çàãðóçêà CPU: %u",0 .data? ZwQuerySystemInformation dd ? Temp dd ? tcphand dd ? tcpmem dd ? processors SYSTEM_PROCESSOR_TIMES MAXIMUM_PROCESSORS dup(<>) Buffer db 512 dup(?) .code start: invoke GetModuleHandleA,ADDR NtDll invoke GetProcAddress,eax,ADDR ZQSI mov ZwQuerySystemInformation, eax push offset Temp push offset MAXIMUM_PROCESSORS*sizeof SYSTEM_PROCESSOR_TIMES push offset processors push SystemProcessorTimes call ZwQuerySystemInformation invoke wsprintf,addr Buffer,addr CPU, DWORD PTR processors[0*sizeof SYSTEM_PROCESSOR_TIMES].InterruptCount invoke MessageBox,0,addr Buffer,0,0 invoke ExitProcess, NULL end start ![]() |
|
Создано: 19 августа 2004 05:34 · Поправил: Blow · Личное сообщение · #3 |
|
Создано: 19 августа 2004 12:21 · Личное сообщение · #4 |
|
Создано: 19 августа 2004 15:13 · Личное сообщение · #5 |
|
Создано: 19 августа 2004 19:10 · Поправил: Blow · Личное сообщение · #6 |
|
Создано: 19 августа 2004 19:16 · Личное сообщение · #7 |
|
Создано: 20 августа 2004 01:34 · Личное сообщение · #8 |
|
Создано: 20 августа 2004 04:00 · Личное сообщение · #9 |
|
Создано: 20 августа 2004 05:48 · Поправил: Blow · Личное сообщение · #10 |
|
Создано: 20 августа 2004 12:10 · Личное сообщение · #11 |
|
Создано: 20 августа 2004 12:41 · Личное сообщение · #12 |
|
Создано: 20 августа 2004 13:07 · Личное сообщение · #13 |
|
Создано: 20 августа 2004 19:12 · Личное сообщение · #14 |
|
Создано: 21 августа 2004 19:01 · Личное сообщение · #15 |
|
Создано: 22 августа 2004 04:30 · Личное сообщение · #16 |
|
Создано: 22 августа 2004 05:06 · Личное сообщение · #17 |
|
Создано: 22 августа 2004 05:32 · Личное сообщение · #18 |
|
Создано: 22 августа 2004 06:00 · Личное сообщение · #19 |
|
Создано: 22 августа 2004 08:23 · Личное сообщение · #20 |
|
Создано: 22 августа 2004 08:32 · Личное сообщение · #21 |
|
Создано: 22 августа 2004 18:59 · Личное сообщение · #22 |
|
Создано: 23 августа 2004 07:02 · Личное сообщение · #23 unit adCpuUsage; {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * CPU Usage Measurement routines for Delphi and C++ Builder Author: Alexey A. Dynnikov EMail: aldyn@chat.ru WebSite: www.aldyn.ru/ Support: Use the e-mail aldyn@chat.ru or support@aldyn.ru Creation: Jul 8, 2000 Version: 1.02 Legal issues: Copyright (C) 2000 by Alexey A. Dynnikov <aldyn@chat.ru> This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented, you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++ USAGE: 1. Include this unit into project. 2. Call GetCPUCount to obtain the numbr of processors in the system 3. Each time you need to know the value of CPU usage call the CollectCPUData to refresh the CPU usage information. Then call the GetCPUUsage to obtain the CPU usage for given processor. Note that succesive calls of GetCPUUsage without calling CollectCPUData will return the same CPU usage value. Example: procedure TTestForm.TimerTimer(Sender: TObject); var i: Integer; begin CollectCPUData; // Get the data for all processors for i:=0 to GetCPUCount-1 do // Show data for each processor MInfo.Lines[i]:=Format('CPU #%d - %5.2f%%',[i,GetCPUUsage(i)*100]); end; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} interface uses Windows, SysUtils; // Call CollectCPUData to refresh information about CPU usage procedure CollectCPUData; // Call it to obtain the number of CPU's in the system function GetCPUCount: Integer; // Call it to obtain the % of usage for given CPU function GetCPUUsage(Index: Integer): Double; // For Win9x only: call it to stop CPU usage monitoring and free system resources procedure ReleaseCPUData; implementation {$ifndef ver110} {$ifndef ver90} {$ifndef ver100} {$define UseInt64} {$endif} {$endif} {$ifdef UseInt64} type TInt64 = Int64; {$else} type TInt64 = Comp; {$endif} {$else} type TInt64 = TLargeInteger; {$endif} type PInt64 = ^TInt64; type TPERF_DATA_BLOCK = record Signature : array[0..4 - 1] of WCHAR; LittleEndian : DWORD; Version : DWORD; Revision : DWORD; TotalByteLength : DWORD; HeaderLength : DWORD; NumObjectTypes : DWORD; DefaultObject : Longint; SystemTime : TSystemTime; Reserved: DWORD; PerfTime : TInt64; PerfFreq : TInt64; PerfTime100nSec : TInt64; SystemNameLength : DWORD; SystemNameOffset : DWORD; end; PPERF_DATA_BLOCK = ^TPERF_DATA_BLOCK; TPERF_OBJECT_TYPE = record TotalByteLength : DWORD; DefinitionLength : DWORD; HeaderLength : DWORD; ObjectNameTitleIndex : DWORD; ObjectNameTitle : LPWSTR; ObjectHelpTitleIndex : DWORD; ObjectHelpTitle : LPWSTR; DetailLevel : DWORD; NumCounters : DWORD; DefaultCounter : Longint; NumInstances : Longint; CodePage : DWORD; PerfTime : TInt64; PerfFreq : TInt64; end; PPERF_OBJECT_TYPE = ^TPERF_OBJECT_TYPE; type TPERF_COUNTER_DEFINITION = record ByteLength : DWORD; CounterNameTitleIndex : DWORD; CounterNameTitle : LPWSTR; CounterHelpTitleIndex : DWORD; CounterHelpTitle : LPWSTR; DefaultScale : Longint; DetailLevel : DWORD; CounterType : DWORD; CounterSize : DWORD; CounterOffset : DWORD; end; PPERF_COUNTER_DEFINITION = ^TPERF_COUNTER_DEFINITION; TPERF_COUNTER_BLOCK = record ByteLength : DWORD; end; PPERF_COUNTER_BLOCK = ^TPERF_COUNTER_BLOCK; TPERF_INSTANCE_DEFINITION = record ByteLength : DWORD; ParentObjectTitleIndex : DWORD; ParentObjectInstance : DWORD; UniqueID : Longint; NameOffset : DWORD; NameLength : DWORD; end; PPERF_INSTANCE_DEFINITION = ^TPERF_INSTANCE_DEFINITION; //-------------------------------------------------------------------- ---------- {$ifdef ver130} {$L-} // The L+ causes internal error in Delphi 5 compiler {$O-} // The O+ causes internal error in Delphi 5 compiler {$Y-} // The Y+ causes internal error in Delphi 5 compiler {$endif} {$ifndef ver110} type TInt64F = TInt64; {$else} type TInt64F = Extended; {$endif} {$ifdef ver110} function FInt64(Value: TInt64): TInt64F; function Int64D(Value: DWORD): TInt64; {$else} type FInt64 = TInt64F; Int64D = TInt64; {$endif} {$ifdef ver110} function FInt64(Value: TInt64): TInt64F; var V: TInt64; begin if (Value.HighPart and $80000000) = 0 then // positive value begin result:=Value.HighPart; result:=result*$10000*$10000; result:=result+Value.LowPart; end else begin V.HighPart:=Value.HighPart xor $FFFFFFFF; V.LowPart:=Value.LowPart xor $FFFFFFFF; result:= -1 - FInt64(V); end; end; function Int64D(Value: DWORD): TInt64; begin result.LowPart:=Value; result.HighPart := 0; // positive only end; {$endif} //-------------------------------------------------------------------- ---------- const Processor_IDX_Str = '238'; Processor_IDX = 238; CPUUsageIDX = 6; type AInt64F = array[0..$FFFF] of TInt64F; PAInt64F = ^AInt64F; var _PerfData : PPERF_DATA_BLOCK; _BufferSize: Integer; _POT : PPERF_OBJECT_TYPE; _PCD: PPerf_Counter_Definition; _ProcessorsCount: Integer; _Counters: PAInt64F; _PrevCounters: PAInt64F; _SysTime: TInt64F; _PrevSysTime: TInt64F; _IsWinNT: Boolean; _W9xCollecting: Boolean; _W9xCpuUsage: DWORD; _W9xCpuKey: HKEY; //-------------------------------------------------------------------- ---------- function GetCPUCount: Integer; begin if _IsWinNT then begin if _ProcessorsCount < 0 then CollectCPUData; result:=_ProcessorsCount; end else begin result:=1; end; end; //-------------------------------------------------------------------- ---------- procedure ReleaseCPUData; var H: HKEY; R: DWORD; dwDataSize, dwType: DWORD; begin if _IsWinNT then exit; if not _W9xCollecting then exit; _W9xCollecting:=False; RegCloseKey(_W9xCpuKey); R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StopStat', 0, KEY_ALL_ACCESS, H ); if R <> ERROR_SUCCESS then exit; dwDataSize:=sizeof(DWORD); RegQueryValueEx ( H, 'KERNEL\CPUUsage', nil, @dwType, PBYTE(@_W9xCpuUsage), @dwDataSize); RegCloseKey(H); end; //-------------------------------------------------------------------- ---------- function GetCPUUsage(Index: Integer): Double; begin if _IsWinNT then begin if _ProcessorsCount < 0 then CollectCPUData; if (Index >= _ProcessorsCount) or (Index < 0) then raise Exception.Create('CPU index out of bounds'); if _PrevSysTime = _SysTime then result:=0 else result:=1-(_Counters[index] - _PrevCounters[index])/(_SysTime-_PrevSysTime); end else begin if Index <> 0 then raise Exception.Create('CPU index out of bounds'); if not _W9xCollecting then CollectCPUData; result:=_W9xCpuUsage / 100; end; end; var VI: TOSVERSIONINFO; //-------------------------------------------------------------------- ---------- procedure CollectCPUData; var BS: integer; i: Integer; _PCB_Instance: PPERF_COUNTER_BLOCK; _PID_Instance: PPERF_INSTANCE_DEFINITION; ST: TFileTime; var H: HKEY; R: DWORD; dwDataSize, dwType: DWORD; begin if _IsWinNT then begin BS:=_BufferSize; while RegQueryValueEx( HKEY_PERFORMANCE_DATA, Processor_IDX_Str, nil, nil, PByte(_PerfData), @BS ) = ERROR_MORE_DATA do begin // Get a buffer that is big enough. INC(_BufferSize,$1000); BS:=_BufferSize; ReallocMem( _PerfData, _BufferSize ); end; // Locate the performance object _POT := PPERF_OBJECT_TYPE(DWORD(_PerfData) + _PerfData.HeaderLength); for i := 1 to _PerfData.NumObjectTypes do begin if _POT.ObjectNameTitleIndex = Processor_IDX then Break; _POT := PPERF_OBJECT_TYPE(DWORD(_POT) + _POT.TotalByteLength); end; // Check for success if _POT.ObjectNameTitleIndex <> Processor_IDX then raise Exception.Create('Unable to locate the "Proce ![]() |
![]() |
eXeL@B —› Основной форум —› проблемы с ZwQuerySystemInformation |