-
Всем день добрый. Не первый день бьюсь с ошибкой и чего уже только не пробовал менять... Всё бестолку... Поэтому прошу помощи.
Суть простая - необходимо выдать права доступа до файла для группы "Все/Everyone". По идее - всё не так уж и сложно:
//--------------------------------------------------------------------------- const SECURITY_WORLD_SID_AUTHORITY: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 1)); SECURITY_WORLD_RID = $0; var ExplicitAccess: EXPLICIT_ACCESS; psidEveryOne: PSID; pSD: PSECURITY_DESCRIPTOR; ptACL: PACL; ErrNo: Cardinal; begin psidEveryOne := nil; pSD := nil; ptACL := nil; try // получаем SID для группы EVERYONE win32check(AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, psidEveryone));
try // Заполняем ExplicitAccess ZeroMemory(@ExplicitAccess, SizeOf(EXPLICIT_ACCESS)); with ExplicitAccess do begin grfAccessPermissions:= GENERIC_ALL; grfAccessMode:= GRANT_ACCESS; grfInheritance:= NO_INHERITANCE; Trustee.TrusteeForm:= TRUSTEE_IS_SID; Trustee.TrusteeType:= TRUSTEE_IS_WELL_KNOWN_GROUP; Trustee.ptstrName:= psidEveryone; end; // И собственно, создаём новый DACL с текущими настройками доступа ErrNo := SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL); if ErrNo <> ERROR_SUCCESS then raise Exception.Create(Format('Error № %u', [ErrNo])) //---------------------------------------------------------------------------
И каждый раз вызов ф-ции SetEntriesInAcl возвращает ошибку 87 (ERROR_INVALID_PARAMETER). Всё это дело происходит в Delphi 7. И самое печальное, что ровно этот же код, но исполненный в Delphi 2010 прекрасно отрабатывает =( Но к сожалению проект на Delphi7, и заставить его работать нужно именно на семёрке...
Кто и что может подсказать по этой проблеме ?
-
> Кто и что может подсказать по этой проблеме ?
Delphi 2006,
замена на ExplicitAccess: EXPLICIT_ACCESS_A;
не выдает ошибки.
-
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses
AclApi, AccCtrl;
procedure TForm1.Button1Click(Sender: TObject);
const
SECURITY_WORLD_SID_AUTHORITY: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 1));
SECURITY_WORLD_RID = $0;
var
ExplicitAccess: EXPLICIT_ACCESS_A;
psidEveryOne: PSID;
ptACL: PACL;
ErrNo: Cardinal;
begin
psidEveryOne := nil;
ptACL := nil;
win32check(AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY,
1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, psidEveryone));
ZeroMemory(@ExplicitAccess, SizeOf(EXPLICIT_ACCESS));
with ExplicitAccess do
begin
grfAccessPermissions:= GENERIC_ALL;
grfAccessMode:= GRANT_ACCESS;
grfInheritance:= NO_INHERITANCE;
Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
Trustee.TrusteeForm:= TRUSTEE_IS_SID;
Trustee.TrusteeType:= TRUSTEE_IS_WELL_KNOWN_GROUP;
Trustee.ptstrName:= psidEveryone;
end;
ErrNo := SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL);
Win32Check(ErrNo = ERROR_SUCCESS);
end;
end.
-
Пробовал. Не помогло. Точно с таким же успехом пробовал и с "_W"... Как была ошибка, так и осталась...
-
> Как была ошибка, так и осталась...
может, в rtl\win в описании структур ошибка ? попробуй взять из jedi
-
> может, в rtl\win в описании структур ошибка ?
Юниты родные... В инете вроде не встречал упоминаний об ошибке именно в 7ой дельфе... 6ая и ранее - были... Но решения для тех версий не сработали в моём случае =(
> попробуй взять из jedi
У нас не приветствуется наличие сторонних компонент и кода, поэтому всё делается самими... Да и вроде же всё должно работать (в d2010 же отрабатывает прекрасно этот же код)
-
> У нас не приветствуется наличие сторонних компонент и кода, > поэтому всё делается самими
В jedi набор переведенных API со всеми структурами - то есть, это не "сторонний код"
> в d2010 же отрабатывает прекрасно этот же код
У меня в 2006 тоже отрабатывает без ошибок, код я привел.
А то, что Borland допускает ляпы при переводе заголовков MS в rtl\win - это, увы, известно. С каждой версией Delphi что-то исправляется, что-то вносится.
Могу посоветовать сравнить описания структур из rtl\win\accctrl.pas в 2010 и 7
и у меня еще добавка:
> Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
-
> и у меня еще добавка: > > Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
Пробовал... Не помогло...
-
> В jedi набор переведенных API со всеми структурами - то > есть, это не "сторонний код"
Посмотрел Jedi... Попробовал даже его использовать... Но т.к. там переопределено практически всё API, кол-во конфликтов зашкалило так, то я отказался от дальнейших попыток использования Jedi
-
От джеди не нужно отказываться - более грамотно оформлен код и обьявления типов. А у тебя по всей видимости проблема с выравниванием. Проверь значения SizeOf там где работает и там где нет...
-
> Rouse_ © (21.08.10 01:45) [9]
Уж почти трое суток лучшие люди Дельфийских форумов (ИШ и СМ) бьются над решением данного вопроса.
-
-
> > И каждый раз вызов ф-ции SetEntriesInAcl возвращает ошибку > 87 (ERROR_INVALID_PARAMETER). > Всё это дело происходит в Delphi 7. > И самое печальное, что ровно этот же код, но исполненный > в Delphi 2010 прекрасно отрабатывает =( Но к сожалению проект > на Delphi7, и заставить его работать нужно именно на семёрке. > .. > > Кто и что может подсказать по этой проблеме ?
Я абсолютно не буду удивлен, если вдруг окажется, что у функции, задекларированной в MSDN как: BOOL WINAPI AllocateAndInitializeSid(
__in PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
__in BYTE nSubAuthorityCount,
__in DWORD dwSubAuthority0,
__in DWORD dwSubAuthority1,
__in DWORD dwSubAuthority2,
__in DWORD dwSubAuthority3,
__in DWORD dwSubAuthority4,
__in DWORD dwSubAuthority5,
__in DWORD dwSubAuthority6,
__in DWORD dwSubAuthority7,
__out PSID *pSid
); параметр nSubAuthorityCount на самом деле не BYTE, а DWORD. На это я уже натыкался при разборе аналогичной ошибки с функциями GetNamedSecurityInf и SetNamedSecurityInfo. Ихнее BYTE надо рассматривать как DWORD
-
> параметр nSubAuthorityCount на самом деле не BYTE, а DWORD. > На это я уже натыкался при разборе аналогичной ошибки с > функциями GetNamedSecurityInf и SetNamedSecurityInfo. Ихнее > BYTE надо рассматривать как DWORD
насмешил
-
> насмешил
Я рад! Однако это на самом деле.
Если хочется поспорить, то аргументы - в студию!
-
Я тут немного понажимал кнопки. Глюк подтверждаю. Копать где-то в районе Trustee.ptstrName. SizeOf(Trustee.ptstrName). То ли psidEveryone какой-то не такой возвращается, то ли еще что-то.
-
Апну немного. Может кто решил проблему? Delphi6. И та же проблема. Пробовал все структуры откопипастить из jedi, как советовали выше, результат тот же. При этом заметил, что если в код добавить вывод ошибки
if SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL)<>ERROR_SUCCESS then
begin
caption:=inttostr(GetLasterror);
exit;
end;
то функция отрабатывает на ура. Т.е. компилятор,если правильно понимаю, немного подругому распределяет память, при которой случайно функции SetEntriesInAcl всё нравится во входящих параметрах.
-
-
> Всё закончилось хорошо
говорили же - jedi
-
> Всё закончилось хорошо, причина тут : http://groups.google. > com/group/borland.public.delphi.winapi/msg/8d48349715137c6b
Как и предполагалось. В AccCtrl и AclAPI чуть ли не половина объявлений выполнены криво, без соответствующих проверок.
|