Hallo,
wie in diesem
Thread nachzulesen ist, versuch ich über GetAdaptersInfo und GetAdaptersAddress Infos zu den Netzwerkverbindungen auszulesen.
Das klappt auch soweit ganz gut.
Ich hab das in einem Testprojekt getestet und hab jetzt für mein eigentliches Projekt eine function erstellt, die aber alles in einem dynamischen Array speichert.
Delphi-Quellcode:
TAdapter_Rec = packed record
AdapterName : String;
FriendlyName: String;
DHCP_Enabled: Boolean;
IP_Address : String;
Subnetmask : String;
Gateway : String;
end;
TAdapter_Array = array of TAdapter_Rec;
function NetzwerkInfos_auslesen(var Liste: TAdapter_Array; out ErrorCode: Integer): Boolean;
var
i : Byte;
pAdapterList : PIP_ADAPTER_INFO;
pAdapterAddresses : PIP_ADAPTER_ADDRESSES;
LenAdapter_List : DWORD;
LenAdapter_Address: DWORD;
ErrorCode_List : DWORD;
ErrorCode_Address : DWORD;
AdapterName : String;
begin
//Rückgabewerte vordefinieren
Result := false;
ErrorCode := 0;
//Variable initialisieren
i := 0;
LenAdapter_List := 0;
LenAdapter_Address := 0;
ErrorCode_List := 0;
ErrorCode_Address := 0;
pAdapterList := nil; // Alles auf 0 ==> Benötigte Buffergrösse ermitteln
//AdapterList
ErrorCode_List := GetAdaptersInfo(pAdapterList, LenAdapter_List);
If ErrorCode_List <> ERROR_BUFFER_OVERFLOW then
begin
ErrorCode := ErrorCode_List;
exit;
end;
//Länge auslesen, bei Fehler Fehlercode setzen und Procedure beenden
ErrorCode_Address := GetAdaptersAddresses(0, 0, nil, nil, @LenAdapter_Address);
If ErrorCode_Address <> ERROR_BUFFER_OVERFLOW then
begin
ErrorCode := ErrorCode_Address;
exit;
end;
//Speicher anfordern
pAdapterList := AllocMem(LenAdapter_List);
pAdapterAddresses := AllocMem(LenAdapter_Address);
try
//AdapterList auslesen
ErrorCode_List := GetAdaptersInfo(pAdapterList, LenAdapter_List);
//wenn das Auslesen der Adapter-List fehlgeschlagen hat, dann Fehlercode
//setzen und Procedure beenden
If ErrorCode_List <> ERROR_SUCCESS then
begin
ErrorCode := ErrorCode_List;
exit;
end;
//AdapterAddresses auslesen
ErrorCode_Address := GetAdaptersAddresses(0, 0, nil, pAdapterAddresses, @LenAdapter_Address);
//wenn das Auslesen der Adapter-Addresses fehlgeschlagen hat, dann Fehlercode
//setzen und Procedure beenden
If ErrorCode_Address <> ERROR_SUCCESS then
begin
ErrorCode := ErrorCode_Address;
exit;
end;
while Assigned(pAdapterList) do
begin
//Variable erhöhen
inc(i);
//Anzahl der Einträge erhöhen
SetLength(Liste, i);
Liste[Pred(i)].AdapterName := String(pAdapterList.AdapterName);
Liste[Pred(i)].DHCP_Enabled := Boolean(pAdapterList.DhcpEnabled);
Liste[Pred(i)].IP_Address := String(pAdapterList.IpAddressList.IpAddress.S);
Liste[Pred(i)].Subnetmask := String(pAdapterList.IpAddressList.IpMask.S);
Liste[Pred(i)].Gateway := String(pAdapterList.GatewayList.IpAddress.S);
pAdapterList := pAdapterList.Next;
end;
while Assigned(pAdapterAddresses) do
begin
for i := low(Liste) to high(Liste) do
If Liste[i].AdapterName = String(pAdapterAddresses.AdapterName) then
begin
Liste[i].FriendlyName := String(pAdapterAddresses.FriendlyName);
break;
end;
pAdapterAddresses := pAdapterAddresses.Next;
end;
//Rückgabewert
Result := true;
finally
//
FreeMem(pAdapterList);
FreeMem(pAdapterAddresses);
end;
end;
Mein Problem ist, dass sich FastMM am Ende vom Programm fast überschlägt weil Speicher nicht freigegeben worden ist.
Nun vermute ich, dass es mit dem SetLength zusammenhängt - ich fordere Speicher an, gib ihn aber nicht mehr frei.
Ich hab schon versucht, dort, wo ich die function aufrufe, am Ende die Variabe für "Liste" freizugeben (
SetLength(Variable, 0)
), aber auch das bringt nicht den gewünschten Erfolg.
Wie gib ich denn nun sauber den Speicher wieder frei?