Приветствую всех. :)
Проблема следующая. Необходимо изменить права доступа на определенный каталог.
Нашел пример с использованием функций из ADVAPI32.DLL
Вот пример.
function AddAceToObjectsSecurityDescriptorW(pszObjName: PWideChar;
ObjectType: SE_OBJECT_TYPE;
pszTrustee: PWideChar;
TrusteeForm: TRUSTEE_FORM;
dwAccessRights: DWORD;
AccessMode: ACCESS_MODE;
dwInheritance: DWORD): DWORD;
var
pOldDACL, pNewDACL: PACL;
pSD: PSECURITY_DESCRIPTOR;
EA: EXPLICIT_ACCESS_W;
begin
pOldDACL := nil;
pNewDACL := nil;
pSD := nil;
Result := GetNamedSecurityInfoW(pszObjName, DWORD(ObjectType), DACL_SECURITY_INFORMATION, nil, nil, pOldDACL, nil, pSD);
if Result <> ERROR_SUCCESS then
Exit;
ZeroMemory(@EA, SizeOf(EXPLICIT_ACCESS_W));
BuildExplicitAccessWithNameW(@EA, pszTrustee, dwAccessRights, AccessMode, dwInheritance);
Result := SetEntriesInAclW(1, @EA, pOldDACL, pNewDACL);
if Result <> ERROR_SUCCESS then
Exit;
Result := SetNamedSecurityInfoW(pszObjName, DWORD(ObjectType), DACL_SECURITY_INFORMATION, nil, nil, pNewDACL, nil);
end;
i:= SizeOf(WideChar)*256;
GetMem(SharePathNT1,i);
StringToWideChar(SharePath1,SharePathNT1,i);
For j:=0 to OtvUser.Count-1 Do begin
u1:=OtvUser.Strings[j];
GetMem(OUser,i);
StringToWideChar(u1,OUser,i);
Err := AddAceToObjectsSecurityDescriptorW(SharePathNT1,
SE_FILE_OBJECT,
OUser,
TRUSTEE_IS_NAME,
GENERIC_ALL,
GRANT_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT);
If Err<>0
Then begin
TimedMessageBox('Ошибка '+IntToStr(Err),'Ошибка',mtError,[mbOk],mbOk,Sec);
Exit;
end;
FreeMem(OUser);
end;
FreeMem(SharePathNT1);
end;
Но в процессе использования оказалось что данная функция почему-то не добавляет права доступа, а замещает те что установлены на каталоге, сохраняя только те что получены каталогом по наследству. То есть если я этой функцией (или в ручную, все равно как) предоставлю права на каталог пользователю 'Юзер1', а потом этой же функцией дам права на этот же каталог пользователю 'Юзер2' - то права на каталог предоставленные первому юзеру пропадут. В моем примере мне нужно предоставить права пользователям находящимся в списке OtvUser. После выполнения программы на каталог имеет права только юзер стоявший в списке последним.
После нудных проверок заметил что функция
GetNamedSecurityInfoW(pszObjName, DWORD(ObjectType), DACL_SECURITY_INFORMATION, nil, nil, pOldDACL, nil, pSD);Почему то в переменную
pOldDACL ВСЕГДА возвращает
nil Хотя сама функция отрабатывает без ошибок. По некоторым источникам (
http://dmgate.k210.org/?id=1275211735&n=3) нашел что она возвращает не просто указатель, а указатель на структуру, но попытка использовать данноую рекомендацию привела к тому что в функция
SetEntriesInAclW стала возвращать ошибку 87.
Очень прошу помочь разобраться.. Чувствую что решение где-то рядом, но найти его самому не хватает опыта