const
NERR_Success = 0;
MAX_PREFERRED_LENGTH = DWORD(-1);
// Einmal deklarieren reicht ;-)
type
NET_API_STATUS = DWORD;
PSHARE_INFO_2 = ^SHARE_INFO_2;
// kann zwar auch danach deklariert werden,
// aber davor ist halt üblich
SHARE_INFO_2 =
packed record // Auch wenn es hier keine Rolle spielt:
// packed ist bei API-Funktionen meist besser
shi2_netname : PWideChar;
shi2_type : DWORD;
shi2_remark : PWideChar;
shi2_permissions : DWORD;
shi2_max_uses : DWORD;
shi2_current_uses: DWORD;
shi2_path : PWideChar;
shi2_passwd : PWideChar;
end;
// Beides auf const geändert
// Die Strings werden ja nicht in der Prozedur erzeugt, sondern gefüllt: da reicht const
// Nimmt man TStrings kann man auch, z.B., ListBox.Items, und sonstige von TStrings
// abgeleitete Listen übergeben
// Für den Namen/Adresse kann auch nil angegeben werden: Geht ohne const nicht
Procedure EnumNetwork (
const EnumNetworkStringlist :TStrings;
const Computername_or_IP:PWideChar);
// Auch alles auf const geändert, da man so besser die Beispiele (meist in C geschrieben)
// besser nachvollziehen kann
function NetShareEnum(
const ServerName : PWideChar;
const Level : DWORD;
const bufptr : Pointer;
const PrefMaxLen : DWORD;
const EntriesRead : PDWORD;
const TotalEntries : PDWORD;
const Resume_Handle: PDWORD):NET_API_STATUS;
stdcall;
external '
NetAPI32.dll'
name '
NetShareEnum';
function NetApiBufferFree(
const Buffer: Pointer): NET_API_STATUS;
stdcall;
external '
NetAPI32.dll'
name '
NetApiBufferFree';
implementation
{$R *.dfm}
Procedure EnumNetwork (
const EnumNetworkStringlist :TStrings;
const Computername_or_IP:PWideChar);
var
dwEntriesRead : DWORD;
dwTotalEntries : DWORD;
dwResHandle : DWORD;
LShareInfo : PSHARE_INFO_2;
LsiWork : PSHARE_INFO_2;
// Auch die Arbeitsvariable sollte den Typ haben
dwResult : NET_API_STATUS;
i : Integer;
begin
EnumNetworkStringlist.Clear;
dwResHandle := 0;
dwResult := NetShareEnum(Computername_or_IP,2,@LShareInfo,MAX_PREFERRED_LENGTH,@dwEntriesRead,@dwTotalEntries,@dwResHandle);
if(dwResult <> NERR_SUCCESS)
then begin
// Im Fehlerfalle einfach mal sehen, was es war
ShowMessage(SysErrorMessage(dwResult));
Exit;
end;
try
LsiWork := LShareInfo;
// Arbeitsvariable füllen
for i := 1
to dwEntriesRead
do begin // Lieber die tatsächlich gelesenen Einträge nehmen
// auch wenn man bei MAX_PREFERRED_LENGTH alle
// erwischen sollte
EnumNetworkStringlist.Add(LsiWork.shi2_netname+'
, '+LsiWork.shi2_path);
Inc(LsiWork);
// Da der Typ jetzt dem der Struktur entspricht reicht inc
end;
finally
// Hier nicht die Adresse (@) der Variablen übergeben, sondern die
// durch den Aufruf von NetShareEnum reservierten Buffer, sonst
// knirscht es ;-)
// Gilt bei allen Lanmanger Funktionen, die den Buffer selber reservieren
NetApiBufferFree(LShareInfo);
end;
end;