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