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

Previous  Top  Next

    
 

 

 

Code:

{*******************************************************}

{                                                       }

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

{                                                       }

{ 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.

 

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

Автор: Rouse_, Smike

©Drkb::03317