Добавление и удаление общих сетевых ресурсов
Материал из DRKB
{*******************************************************}
{ }
{ Добавление и удаление общих сетевых ресурсов }
{ }
{ 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.
Author: Rouse_, Smike
Source: http://forum.sources.ru
ID: 03317