Добавление и удаление общих сетевых ресурсов
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