![]() |
Type-Deklaration PF_INTERFACE_STATS (MSDN-PlattformSDK: RAS)
Hallo,
ich "spiele" etwas mit Packetfiltern (IPHLPAPI.DLL) herum und habe jetzt ein evtl. kleineres Problem. Erstmal die Vorgeschichte: Es gibt in der IPHLPAPI.DLL die function " ![]()
Delphi-Quellcode:
die mir einen Zeiger auf ein Struktur "
function PfGetInterfaceStatistics(
pInterface: INTERFACE_HANDLE; ppfStats: PPF_INTERFACE_STATS; pdwBufferSize: PDWORD; fResetCounters: BOOL): DWORD; stdcall; external IPHLPAPI name '_PfGetInterfaceStatistics@16'; ![]()
Delphi-Quellcode:
Das ganze sollte in Delphi wohl so aussehen:
...
typedef struct _PF_INTERFACE_STATS { PVOID pvDriverContext; DWORD dwFlags; DWORD dwInDrops; DWORD dwOutDrops; PFFORWARD_ACTION eaInAction; PFFORWARD_ACTION eaOutAction; DWORD dwNumInFilters; DWORD dwNumOutFilters; DWORD dwFrag; DWORD dwSpoof; DWORD dwReserved1; DWORD dwReserved2; LARGE_INTEGER liSYN; LARGE_INTEGER liTotalLogged; DWORD dwLostLogEntries; PF_FILTER_STATS FilterInfo[1]; } PF_INTERFACE_STATS, *PPF_INTERFACE_STATS; ...
Delphi-Quellcode:
Die Funktion (PfGetInterfaceStatistics) ansicht tut auch das was sie soll, wenn ich z.B. die Anzahl der Output Filter
...
type _PF_FILTER_DESCRIPTOR = packed record dwFilterFlags: DWORD; dwRule: DWORD; pfatType: PFADDRESSTYPE; SrcAddr: PByteArray; SrcMask: PByteArray; DstAddr: PByteArray; DstMask: PByteArray; dwProtocol: DWORD; fLateBound: DWORD; wSrcPort: Word; wDstPort: Word; wSrcPortHighRange: Word; wDstPortHighRange: Word; end; PF_FILTER_DESCRIPTOR = _PF_FILTER_DESCRIPTOR; PPF_FILTER_DESCRIPTOR = ^PF_FILTER_DESCRIPTOR; type _PF_FILTER_STATS = packed record dwNumPacketsFiltered:DWORD; info: PF_FILTER_DESCRIPTOR; end; PF_FILTER_STATS = _PF_FILTER_STATS; PPF_FILTER_STATS = ^PF_FILTER_STATS; type _PF_INTERFACE_STATS = packed record pvDriverContext: Pointer; dwFlags: DWORD; dwInDrops: DWORD; dwOutDrops: DWORD; eaInAction: PFFORWARD_ACTION; eaOutAction: PFFORWARD_ACTION; dwNumInFilters: DWORD; dwNumOutFilters: DWORD; dwFrag: DWORD; dwSpoof: DWORD; dwReserved1: DWORD; dwReserved2: DWORD; liSyn: LARGE_INTEGER; liTotalLogged: LARGE_INTEGER; dwLostLogEntries: DWORD; // hier liegt mein Problem... FilterInfo: Array[0..0] of PF_FILTER_STATS; end; PF_INTERFACE_STATS = _PF_INTERFACE_STATS; PPF_INTERFACE_STATS = ^PF_INTERFACE_STATS; ... für ein Interface haben will, bekomme ich sie über:
Delphi-Quellcode:
Der Code oben funktioniert, nur bekomme ich in FilterInfo nur die Infos über den ersten Filter, es sind aber mehrere
...
var PStats : PPF_INTERFACE_STATS; ... begin ... // Output Filter ShowMessage('dwNumOutFilter: ' + IntToStr(Stats^.dwNumOutFilters)); // Hier liegt mein Problem ShowMessage('SrcPort: ' + IntToStr(Stats^.FilterInfo[0].info.wSrcPort)); end; vorhanden! Laut MSDN gibt es in Stats^.FilterInfo für jeden Filter ein Element. Wenn ich aber z.B. Stats^.FilterInfo[1].info.wSrcPort abfrage, bekomme ich nur Müll. Ich vermute mal, dass es an der Deklaration des Typs liegt, denn wenn ich einfach
Delphi-Quellcode:
definiere, stehen in Stats^.FilterInfo[1].*** die Informationen zum 2. Filter, in
...
dwLostLogEntries: DWORD; // hier liegt mein Problem... // FilterInfo: Array[0..0] of PF_FILTER_STATS; FilterInfo: Array[0..15] of PF_FILTER_STATS; end; PF_INTERFACE_STATS = _PF_INTERFACE_STATS; ... .FilterInfo[2] zum 3. usw. Jetzt meine Frage: Wie muss ich nun den Type deklarieren, um zur Laufzeit die Infos zu n Filter abzufragen? Ein FilterInfo: Array[0..15] of PF_FILTER_STATS; würde mir ja auch nur die Infos der ersten 16 Filter bringen, der User könnte aber mehr Filter anlegen. Also schonmal vielen Dank für Eure Antwort(en) ... |
Re: Type-Deklaration PF_INTERFACE_STATS (MSDN-PlattformSDK:
Die ursprüngliche Deklaration ist schon OK. Du solltest nur dynamisch mehr Speicher zuweisen, etwa so:
Delphi-Quellcode:
var
THE_INTERFACE_STATS: PPF_INTERFACE_STATS; begin GetMem(THE_INTERFACE_STATS, SizeOf(PF_INTERFACE_STATS) + 15*SizeOf(PF_FILTER_STATS)); //... FreeMem(THE_INTERFACE_STATS); end; |
Re: Type-Deklaration PF_INTERFACE_STATS (MSDN-PlattformSDK:
Die Speicherzuordnung sollte zweistufig erfolgen. Beim ersten Aufruf wird BufferSize mit SizeOf(PF_INTERFACE_STATS) initialisiert. Das Ergebnis des Aufrufs ist eine korrekte Initialisierung von Buffersize für den zweiten Aufruf. Der Zugriff auf die einzelnen Filter erfolgt dann einfach über Zeiger-Arithmetik.
Grüße vom marabu |
Re: Type-Deklaration PF_INTERFACE_STATS (MSDN-PlattformSDK:
Zitat:
Delphi-Quellcode:
Hier hab ich eigentlich nichts anderes gemacht, als wie im 1. Posting von mir. Die MessageBox
procedure FltStats;
Type TFilter = Array[0..15] of PF_FILTER_STATS; PFilter = ^TFilter; var bufSize : DWord; dwResult : DWord; ppfStats : PPF_INTERFACE_STATS; i : Integer; Filter : PFilter; begin bufSize := SizeOf(PF_INTERFACE_STATS); GetMem(ppfStats, bufSize); try dwResult := PfGetInterfaceStatistics(hIf, ppfStats, @bufSize, false); case dwResult of ERROR_INSUFFICIENT_BUFFER : begin FreeMem(ppfStats); GetMem(ppfStats, bufSize); dwResult := PfGetInterfaceStatistics(hIf, ppfStats, @bufSize, false); if dwResult <> NO_ERROR then Exit; end; ERROR_INVALID_HANDLE : Exit; end; Filter := @ppfStats^.filterinfo; for i:= 0 to Length(Filter^)-1 do ShowMessage( 'Filter (' + IntToStr(Succ(i)) + ')'#13#10 + ' SourcePort: ' + IntToStr(Filter[i].info.wSrcPort) + #13#10+ ' DestinationPort: ' + IntToStr(Filter[i].info.wDstPort)); finally FreeMem(ppfStats); end; end; gibt mir jedenfalls für die Filter die auch existieren, die Korrekten Infos. Mein Problem ist anscheinend genau das: Zitat:
(Das muss doch auch irgendwie dynamisch gehen, also OHNE das ich vorher ein array mit fester länge definiere?!) |
Re: Type-Deklaration PF_INTERFACE_STATS (MSDN-PlattformSDK:
Das ist ein bischen tricky. In C kann man am Ende eines Record ein Array der Laenge Null deklarieren.
Das nimmt dann keinen Platz im Record ein, sondern benennt den Bereich hinter dem Record. In C liefert dann auch noch der Name eines Arrays den Zeiger auf das erste Element des Arrays. InterfaceStats.FilterInfo ist also in C ein Zeiger hinter InterfaceStats. Zeiger in C sind direkt mit dem Arrayindex zu benutzen. Da es keine Checks fuer Arrayzugriffe erfolgen, kann man einfach die Elemente des FilterInfo-Arrays zugreifen. Wie viele es sind steht im Record. Microsoft verwendet die Laenge 1 was keinerlei praktische Auswirkungen hat. Es erklaert nur das erste Element des FilterInfo-Arrays zum Teil des Records. Wenn FilterInfo als array [0..0] deklariert ist, kann man auch in Delphi auf die FilteRInfo-Elemente zugreifen. Man muss nur den Check der Arraygrenzen abschalten. |
Re: Type-Deklaration PF_INTERFACE_STATS (MSDN-PlattformSDK:
iMaxFilter musst du dir ausrechnen: Angeforderte Gesamtgröße - Größe der Struktur bis zum FilterInfo. Wenn du über Zeigerarithmetik zugreifst, dann spielen die Array-Grenzen keine Rolle.
Delphi-Quellcode:
marabu
var
pf: ^PF_FILTER_INFO; begin for i := 0 to iMaxFilter do begin ... Inc(pf); end; end; |
Re: Type-Deklaration PF_INTERFACE_STATS (MSDN-PlattformSDK:
Ok,
dank dem Code-Schnippsel von marabu und der ausführlichen Erklärung von Robert habe ich folgende Lösung:
Delphi-Quellcode:
Sollte oben doch noch was nicht so wirklich OK sein, wäre ich für Hinweise dankbar :)
procedure FltStats;
var bufSize : DWord; dwResult : DWord; ppfStats : PPF_INTERFACE_STATS; i : Integer; Filter : ^PF_FILTER_STATS; begin bufSize := SizeOf(PF_INTERFACE_STATS); GetMem(ppfStats, bufSize); try dwResult := PfGetInterfaceStatistics(hIf, ppfStats, @bufSize, false); case dwResult of ERROR_INSUFFICIENT_BUFFER : begin FreeMem(ppfStats); GetMem(ppfStats, bufSize); dwResult := PfGetInterfaceStatistics(hIf, ppfStats, @bufSize, false); if dwResult <> NO_ERROR then Exit; end; ERROR_INVALID_HANDLE : Exit; end; Filter := @ppfStats^.filterinfo; for i := 0 to (ppfStats^.dwNumInFilters + ppfStats^.dwNumOutFilters) -1 do begin ShowMessage( 'Filter (' + IntToStr(Succ(i)) + ')'#13#10 + ' SourcePort: ' + IntToStr(Integer(Filter^.info.wSrcPort)) + #13#10+ ' DestinationPort: ' + IntToStr(Filter^.info.wDstPort)); Inc(Filter); end; finally FreeMem(ppfStats); end; end; Meine Frage wurde perfekt beantwortet und ich habe mal wieder ein Stück dazugelernt... Thx.. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz