меня это тоже сначало порадовало, а потом задумался - не особо охота перебирать ip и смотреть, какой из них подходит к твоему диалап-соединению, а в винде есть специальные разделы реестра. отвечающие за эту инфу:
| Код | //-------DialStat.pas-------// unit DialStat;
interface
uses Windows, SysUtils, WinPerf;
type TDialStat = class(TObject) private function GetIndex(const pszCounter: string): string; function Collect(m_SObj, m_sCounter: string): DWORD; function fInit: boolean; function fGetBR: DWORD; function fGetBT: DWORD; public property Init: boolean read fInit; property GetBR: DWORD read fGetBR; property GetBT: DWORD read fGetBT; end;
const perf_key = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009';
var rt{, tc}, br, bt: string;
implementation
uses unit1;
{ TDialStat }
function TDialStat.Collect(m_SObj, m_sCounter: string): DWORD; var dw, dwCounterIdOffset: dword; i: integer; pdb: PPERF_DATA_BLOCK; pot: PPERF_OBJECT_TYPE; pcd: PPERF_COUNTER_DEFINITION; pid: PPERF_INSTANCE_DEFINITION; begin dw := 12000; dwCounterIdOffset := 0; pdb := PPERF_DATA_BLOCK(HeapAlloc(GetProcessHeap(), $00000008, dw)); while RegQueryValueEx(HKEY_PERFORMANCE_DATA, pchar(m_SObj), nil, nil, pbyte(pdb), @dw) = ERROR_MORE_DATA do begin dw := dw + 1000; pdb := PPERF_DATA_BLOCK(HeapReAlloc(GetProcessHeap(), $00000008, pointer(pdb), dw)); end; pot := PPERF_OBJECT_TYPE(DWORD(PByte(pdb)) + pdb.HeaderLength); pcd := PPERF_COUNTER_DEFINITION(DWORD(PByte(pot)) + pot.HeaderLength); for i := 0 to pot.NumCounters do begin if pcd.CounterNameTitleIndex = DWORD(strtoint(m_sCounter)) then begin dwCounterIdOffset := pcd.CounterOffset; break; end; pcd := PPERF_COUNTER_DEFINITION(DWORD(PByte(pcd)) + pcd.ByteLength); end; pid := PPERF_INSTANCE_DEFINITION(DWORD(PByte(pot)) + pot.DefinitionLength); Result := PDWORD(DWORD(PByte(pid)) + dwCounterIdOffset)^; HeapFree(GetProcessHeap(), 0, pointer(pdb)); RegCloseKey(HKEY_PERFORMANCE_DATA); end;
function TDialStat.GetIndex(const pszCounter: string): string; var key: HKEY; buf: pchar; szObject, szIndex: string; dw: dword; i: integer; begin RegOpenKeyEx(HKEY_LOCAL_MACHINE, perf_key, 0, KEY_READ, key); RegQueryValueEx(key, 'Counter', nil, nil, nil, addr(dw)); buf := AllocMem(dw); RegQueryValueEx(key, 'Counter', nil, nil, pbyte(buf), addr(dw)); RegCloseKey(key); for i := 0 to (dw - 2) do begin if buf[i] = #0 then if szObject = pszCounter then break else begin szIndex := szObject; szObject := ''; end else szObject := szObject + buf[i]; end; //---------------- Result := szIndex; FreeMem(buf); end;
function TDialStat.fInit: boolean; begin try rt := GetIndex('RAS Total'); //tc := GetIndex('Total Connections'); br := GetIndex('Bytes Received'); bt := GetIndex('Bytes Transmitted'); {если открыть в регедите HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\019 - там можно почитать про все типы по-русски (у кого русская винда:))} finally result := true; end; end;
function TDialStat.fGetBR: DWORD; begin result := Collect(rt, br); end;
function TDialStat.fGetBT: DWORD; begin result := Collect(rt, bt); end;
end.
|
| Код | //--------------winperf.pas------------// unit winperf;
{с большими сокращениями, но нужно только эти типы данных}
interface
uses windows;
type _PERF_DATA_BLOCK = record Signature: array [0..3] of widechar; LittleEndian: DWORD; Version: DWORD; Revision: DWORD; TotalByteLength: DWORD; HeaderLength: DWORD; NumObjectTypes: DWORD; DefaultObject: longint; SystemTime: SYSTEMTIME; PerfTime: LARGE_INTEGER; PerfFreq: LARGE_INTEGER; PerfTime100nSec: LARGE_INTEGER; SystemNameLength: DWORD; SystemNameOffset: DWORD; end; PERF_DATA_BLOCK = _PERF_DATA_BLOCK; PPERF_DATA_BLOCK = ^_PERF_DATA_BLOCK;
_PERF_OBJECT_TYPE = record TotalByteLength: DWORD; DefinitionLength: DWORD; HeaderLength: DWORD; ObjectNameTitleIndex: DWORD; {$ifdef _WIN64} ObjectNameTitle: DWORD; {$else} ObjectNameTitle: LPWSTR; {$endif} ObjectHelpTitleIndex: DWORD; {$ifdef _WIN64} ObjectHelpTitle: DWORD; {$else} ObjectHelpTitle: LPWSTR; {$endif} DetailLevel: DWORD; NumCounters: DWORD; DefaultCounter: longint; NumInstances: longint; CodePage: DWORD; PerfTime: LARGE_INTEGER; PerfFreq: LARGE_INTEGER; end; PERF_OBJECT_TYPE = _PERF_OBJECT_TYPE; PPERF_OBJECT_TYPE = ^_PERF_OBJECT_TYPE;
type _PERF_COUNTER_DEFINITION = record ByteLength: DWORD; CounterNameTitleIndex: DWORD; {$ifdef _WIN64} CounterNameTitle: DWORD; {$else} CounterNameTitle: LPWSTR; {$endif} CounterHelpTitleIndex: DWORD; {$ifdef _WIN64} CounterHelpTitle: DWORD; {$else} CounterHelpTitle: LPWSTR; {$endif} DefaultScale: longint; DetailLevel: DWORD; CounterType: DWORD; CounterSize: DWORD; CounterOffset: DWORD; end; PERF_COUNTER_DEFINITION = _PERF_COUNTER_DEFINITION; PPERF_COUNTER_DEFINITION = ^_PERF_COUNTER_DEFINITION;
type _PERF_INSTANCE_DEFINITION = record ByteLength: DWORD; ParentObjectTitleIndex: DWORD; ParentObjectInstance: DWORD; UniqueID: longint; NameOffset: DWORD; NameLength: DWORD; end; PERF_INSTANCE_DEFINITION = _PERF_INSTANCE_DEFINITION; PPERF_INSTANCE_DEFINITION = ^_PERF_INSTANCE_DEFINITION;
implementation
end.
| |