Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Добавление и удаление общих сетевых ресурсов

01.01.2007
{*******************************************************}
{                                                       }
{       Добавление и удаление общих сетевых ресурсов    }
{                                                       }
{ Copyright (c)                                         }
{    1998-2002 Rouse_                                   }
{              (базовый код, взят из примера NetMon)    }
{    2006 Smike                                         }
{              (- доработка для возможности создания    }
{                 ресурсов, открытых только для чтения  }
{                 под NT/2000/XP/2003,                  }
{               - небольшой рефакторинг ;) )            }
{                                                       }
{*******************************************************}
 
unit
Shares;
 
interface
 
uses
 
Windows, SysUtils, AclApi;
 
function ShareDirectory(const Directory: string): DWORD;
function UnShareDirectory(const Directory: string): DWORD;
 
implementation
 
const
  STYPE_DISKTREE
= 0;
 
function ShareDirectoryNT(const Directory, ShareName: string): DWORD;
type
  TShareInfo502
= packed record
    shi502_netname
: PWChar;
    shi502_type
: DWORD;
    shi502_remark
:PWChar;
    shi502_permissions
: DWORD;
    shi502_max_uses
: DWORD;
    shi502_current_uses
: DWORD;
    shi502_path
: PWChar;
    shi502_passwd
: PWChar;
    shi502_reserved
: DWORD;
    shi502_security_descriptor
: PSECURITY_DESCRIPTOR;
 
end;
const
  ACL_REVISION
= 2;
  SECURITY_WORLD_SID_AUTHORITY
: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 1));
  SECURITY_WORLD_RID
= ($00000000);
  SECURITY_NT_AUTHORITY
: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
  SECURITY_BUILTIN_DOMAIN_RID
= ($00000020);
  DOMAIN_ALIAS_RID_ADMINS
= ($00000220);          
var
 
NetShareAddNT: function(servername: PWideChar;
                          level
: DWORD;
                          buf
: Pointer;
                          parm_err
: LPDWORD): DWORD; stdcall;
 
ShareNT : TShareInfo502;
 
FLibHandle: THandle;
 
TmpDirNT, TmpNameNT: PWChar;
 
TmpLength: Integer;
  pSd
: PSECURITY_DESCRIPTOR;
  pDacl
: PACL;
 
EveryoneSid, AdminSid: Pointer;  
begin
 
Result := DWORD(-1);
 
FLibHandle := LoadLibrary('NETAPI32.DLL');
 
if FLibHandle = 0 then Exit;
 
try
   
NetShareAddNT := GetProcAddress(FLibHandle,'NetShareAdd');
   
if not Assigned(NetShareAddNT) then Exit;
 
   
TmpLength := SizeOf(WideChar) * 256; //Определяем необходимый размер
 
   
GetMem(TmpNameNT, TmpLength); //Конвертируем в PWChar
   
StringToWideChar(ShareName, TmpNameNT, TmpLength);
   
ShareNT.shi502_netname := TmpNameNT; //Имя
 
   
ShareNT.shi502_type := STYPE_DISKTREE; //Тип ресурса
   
ShareNT.shi502_remark := ''; //Комментарий
   
// В NT, 2000, XP, 2003 разрешения на уровне расшаренной папки не поддерживается
   
// Для этого задаем ниже атрибуты доступа на уровне групп
   
ShareNT.shi502_permissions := 0;
   
ShareNT.shi502_max_uses := DWORD(-1); //Кол-во максим. подключ.
   
ShareNT.shi502_current_uses := 0; //Кол-во тек подкл.
 
   
GetMem(TmpDirNT, TmpLength);
   
StringToWideChar(Directory, TmpDirNT, TmpLength);
   
ShareNT.shi502_path := TmpDirNT; //Путь к ресурсу
 
   
ShareNT.shi502_passwd := ''; //Пароль
 
   
ShareNT.shi502_reserved := 0;
 
   
// Здесь начинается самое интересное - задаем разрешения :)
   
GetMem(pDacl, 256);
   
InitializeAcl(pDacl^, 256, ACL_REVISION);
   
EveryoneSid := nil;
   
AdminSid := nil;
   
AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, EveryoneSid);
   
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminSid);
   
AddAccessAllowedAce(pDacl^, ACL_REVISION, GENERIC_ALL, AdminSid);
   
AddAccessAllowedAce(pDacl^, ACL_REVISION, (GENERIC_READ or GENERIC_EXECUTE or READ_CONTROL or STANDARD_RIGHTS_READ), EveryoneSid);
   
GetMem(pSd, SECURITY_DESCRIPTOR_MIN_LENGTH);
   
InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION);
   
SetSecurityDescriptorDacl(pSd, TRUE, pDacl, FALSE);
   
ShareNT.shi502_security_descriptor := pSd;
 
   
Result := NetShareAddNT(nil, 502, @ShareNT, nil); //Добавляем ресурс
 
   
if Assigned(EveryoneSid) then
     
FreeSid(EveryoneSid);
 
   
if Assigned(AdminSid) then
     
FreeSid(AdminSid);
 
   
//освобождаем память
   
FreeMem(pDacl);
   
FreeMem(pSd);
   
FreeMem(TmpNameNT);
   
FreeMem(TmpDirNT);
 
finally
   
FreeLibrary(FLibHandle);
 
end;
end;
 
function ShareDirectory9x(const Directory, ShareName: string): DWORD;
type
  TShareInfo50
= packed record
    shi50_netname
: array [0..12] of Char;
    shi50_type
: Byte;
    shi50_flags
: Word;
    shi50_remark
: PChar;
    shi50_path
: PChar;
    shi50_rw_password
: array [0..8] of Char;
    shi50_ro_password
: array [0..8] of Char;
 
end;
const
  SHI50F_RDONLY  
= $1;
var
 
NetShareAdd: function(pszServer: PAnsiChar;
                        sLevel
: Cardinal;
                        pbBuffer
: PAnsiChar;
                        cbBuffer
: Word):DWORD; stdcall;
  Share9x
: TShareInfo50;
 
FLibHandle : THandle;  
begin
 
Result := DWORD(-1);
 
FLibHandle := LoadLibrary('SVRAPI.DLL');
 
if FLibHandle = 0 then Exit;
 
try
   
NetShareAdd := GetProcAddress(FLibHandle,'NetShareAdd');
   
if not Assigned(NetShareAdd) then Exit;
 
   
FillChar(Share9x.shi50_netname, SizeOf(Share9x.shi50_netname), #0);
   
Move(ShareName[1], Share9x.shi50_netname[0], Length(ShareName)); //Имя
    Share9x
.shi50_type := STYPE_DISKTREE; //Тип ресурса
    Share9x
.shi50_flags := SHI50F_RDONLY; //Доступ
   
FillChar(Share9x.shi50_remark,
     
SizeOf(Share9x.shi50_remark), #0); //Комментарий
   
FillChar(Share9x.shi50_path,
     
SizeOf(Share9x.shi50_path), #0);
    Share9x
.shi50_path := PAnsiChar(Directory); //Путь к ресурсу
   
FillChar(Share9x.shi50_rw_password,
     
SizeOf(Share9x.shi50_rw_password), #0); //Пароль полного доступа
   
FillChar(Share9x.shi50_ro_password,
     
SizeOf(Share9x.shi50_ro_password), #0); //Пароль для чтения
   
Result := NetShareAdd(nil, 50, @Share9x, SizeOf(Share9x));
 
finally
   
FreeLibrary(FLibHandle);
 
end;
end;
 
function ShareDirectory(const Directory: string): DWORD;
var
 
ShareDir, ShareName: string;
begin
 
ShareDir := ExcludeTrailingPathDelimiter(Directory);
 
ShareName := ExtractFileName(ShareDir);
 
 
if Win32Platform = VER_PLATFORM_WIN32_NT then
   
Result := ShareDirectoryNT(ShareDir, ShareName)
 
else
   
Result := ShareDirectory9x(ShareDir, ShareName);
end;
 
function UnShareDirectoryNT(const ShareName: string): DWORD;
var
 
FLibHandle : THandle;
 
NameNT: PWChar;
 
NetShareDelNT: function(servername: PWideChar;
                          netname
: PWideChar;
                          reserved
: DWORD): LongInt; stdcall;
 
Size: Integer;
begin
 
Result := DWORD(-1);
 
FLibHandle := LoadLibrary('NETAPI32.DLL');
 
if FLibHandle = 0 then Exit;
 
try
   
NetShareDelNT := GetProcAddress(FLibHandle, 'NetShareDel');
   
if not Assigned(NetShareDelNT) then //Проверка
   
begin
     
FreeLibrary(FLibHandle);
     
Exit;
   
end;
   
Size := SizeOf(WideChar) * 256;
   
GetMem(NameNT, Size);  //Выделяем память под переменную
   
StringToWideChar(ShareName, NameNT, Size); //Преобразуем в PWideChar
   
NetShareDelNT(nil, NameNT, 0);   //Удаляем ресурс
   
FreeMem(NameNT);  //Освобождаем память
 
finally
   
FreeLibrary(FLibHandle);
 
end;
end;
 
function UnShareDirectory9x(const ShareName: string): DWORD;
var
 
FLibHandle: THandle;
  Name9x
: array [0..12] of Char;
 
NetShareDel: function(pszServer,
                        pszNetName
: PChar;
                        usReserved
: Word): DWORD; stdcall;
begin
 
Result := DWORD(-1);
 
FLibHandle := LoadLibrary('SVRAPI.DLL');
 
if FLibHandle = 0 then Exit;
 
try
   
NetShareDel := GetProcAddress(FLibHandle,'NetShareDel');
   
if not Assigned(NetShareDel) then Exit;
   
FillChar(Name9x, SizeOf(Name9x), #0); //Очищаем массив
   
Move(ShareName[1], Name9x[0], Length(ShareName)); //Заполняем массив
   
Result := NetShareDel(nil, @Name9x, 0); //Удаляем ресурс
 
finally
   
FreeLibrary(FLibHandle);
 
end;
end;
 
function UnShareDirectory(const Directory: string): DWORD;
var
 
ShareName: string;
begin
 
ShareName := ExtractFileName(ExcludeTrailingPathDelimiter(Directory));
 
 
if Win32Platform = VER_PLATFORM_WIN32_NT then       //Код для NT
   
Result := UnShareDirectoryNT(ShareName)
 
else                                                //Код для 9х-Ме
   
Result := UnShareDirectory9x(ShareName);
end;
 
end.

Взято из https://forum.sources.ru

Автор: Rouse_, Smike