Enumerate Local Shares via NetShareEnum - Delphi

DarkCoderSc
Jean-Pierre LESUEUR
uses
System.SysUtils, Winapi.Windows, Generics.Collections;
const
MAX_PREFERRED_LENGTH = DWORD(-1);
NERR_Success = 0;
STYPE_DISKTREE = $00000000;
STYPE_PRINTQ = $00000001;
STYPE_DEVICE = $00000002;
STYPE_IPC = $00000003;
STYPE_TEMPORARY = $40000000;
STYPE_SPECIAL = $80000000;
STYPE_MASK = $0000000F;
// ...
type
NET_API_STATUS = DWORD;
_SHARE_INFO_2 = record
shi2_netname : PWideChar;
shi2_type : DWORD;
shi2_remark : PWideChar;
shi2_permissions : DWORD; // Deprecated
shi2_max_uses : DWORD;
shi2_current_uses : DWORD;
shi2_path : PWideChar;
shi2_passwd : PWideChar;
end;
TShareInfo2 = _SHARE_INFO_2;
PShareInfo2 = ^TShareInfo2;
// ...
function NetShareEnum(
servername : PWideChar;
level : DWORD;
var bufptr : Pointer;
prefmaxlen : DWORD;
var entriedread : DWORD;
var totalentries : DWORD;
var resume_handle : DWORD
) : NET_API_STATUS; stdcall; external 'Netapi32.dll';
function NetApiBufferFree(
Buffer : Pointer
) : NET_API_STATUS; stdcall; external 'Netapi32.dll';
// ...
type
TNetworkShare = class
private
FName : String;
FRemark : String;
FPath : String;
FPasswd : String;
FType : DWORD;
FPermissions : DWORD;
FMaxUses : DWORD;
FCurrentUses : DWORD;
{@M}
function GetReadableType() : String;
public
{@C}
constructor Create(const AShareInfo2: TShareInfo2);
{@G}
property Name : String read FName;
property Remark : String read FRemark;
property Path : String read FPath;
property Passwd : String read FPasswd;
property ShareType : DWORD read FType;
property ReadableType : String read GetReadableType;
property Permissions : DWORD read FPermissions;
property MaxUses : DWORD read FMaxUses;
property CurrentUses : DWORD read FCurrentUses;
end;
// ...
(* TNetworkShare *)
constructor TNetworkShare.Create(const AShareInfo2: TShareInfo2);
begin
inherited Create();
///
FName := string(AShareInfo2.shi2_netname);
FRemark := string(AShareInfo2.shi2_remark);
FPath := string(AShareInfo2.shi2_path);
FPasswd := string(AShareInfo2.shi2_passwd);
FType := AShareInfo2.shi2_type;
FPermissions := AShareInfo2.shi2_permissions;
FMaxUses := AShareInfo2.shi2_max_uses;
FCurrentUses := AShareInfo2.shi2_current_uses;
end;
function TNetworkShare.GetReadableType(): string;
begin
case FType and STYPE_MASK of
STYPE_DISKTREE : result := 'Disk';
STYPE_PRINTQ : result := 'Print Queue';
STYPE_DEVICE : result := 'Communication Device';
STYPE_IPC : result := 'IPC';
STYPE_SPECIAL : result := 'Special';
STYPE_TEMPORARY : result := 'Temporary';
else
result := 'Unknown';
end;
end;
// ...
(* Local *)
function EnumerateLocalShares(var AList : TObjectList<TNetworkShare>) : Cardinal;
begin
result := 0;
///
if not Assigned(AList) then
AList := TObjectList<TNetworkShare>.Create(True)
else begin
if not AList.OwnsObjects then
AList.OwnsObjects := True;
///
AList.Clear();
end;
///
var pShareInfo : PShareInfo2;
var ANumberOfEntries : DWORD;
var AEntriesRead : DWORD;
var AResumeHandle : DWORD := 0;
const LEVEL_2 = 2;
var AStatus := NetShareEnum(nil, LEVEL_2, Pointer(pShareInfo), MAX_PREFERRED_LENGTH, AEntriesRead, ANumberOfEntries, AResumeHandle);
try
if AStatus <> NERR_Success then
Exit();
///
var pShareInfoRow := pShareInfo;
for var I := 0 to ANumberOfEntries -1 do begin
AList.Add(TNetworkShare.Create(pShareInfoRow^));
///
Inc(pShareInfoRow);
end;
///
result := AList.Count;
finally
if pShareInfo <> nil then
NetApiBufferFree(pShareInfo);
end;
end;
// ...
var AList := TObjectList<TNetworkShare>.Create(True);
try
EnumerateLocalShares(AList);
///
const NETWORK_SHARE_ROW_MASK = '%-10s | %-20s | %-10s | %s';
const ALine = StringOfChar('-', 80);
WriteLn(ALine);
WriteLn(Format(NETWORK_SHARE_ROW_MASK, [
'Name',
'Path',
'Type',
'Description'
]));
WriteLn(ALine);
for var ANetworkShare in AList do begin
WriteLn(Format(NETWORK_SHARE_ROW_MASK, [
ANetworkShare.Name,
ANetworkShare.Path,
ANetworkShare.ReadableType,
ANetworkShare.Remark
]));
end;
WriteLn(ALine);
finally
FreeAndNil(AList);
end;
// ...
Creating and researching code snippets takes time and effort. You’re welcome to share them through your own platforms, but please don’t forget to credit the original author, here: Jean-Pierre LESUEUR.
Implemented By Technique
Featured Windows APIs
Created
May 9, 2025
Last Revised
May 14, 2025