Конференция "WinAPI" » SetEntriesInAcl Error 87 [D7]
 
  • ZeBriD © (18.08.10 13:11) [0]
    Всем день добрый.
    Не первый день бьюсь с ошибкой и чего уже только не пробовал менять... Всё бестолку... Поэтому прошу помощи.

    Суть простая - необходимо выдать права доступа до файла для группы "Все/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, и заставить его работать нужно именно на семёрке...

    Кто и что может подсказать по этой проблеме ?
  • Игорь Шевченко © (18.08.10 13:58) [1]

    > Кто и что может подсказать по этой проблеме ?


    Delphi 2006,

    замена на
    ExplicitAccess: EXPLICIT_ACCESS_A;

    не выдает ошибки.
  • Игорь Шевченко © (18.08.10 13:59) [2]
    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;

    {$R *.dfm}

    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;
    // pSD: PSECURITY_DESCRIPTOR;
    ptACL: PACL;
    ErrNo: Cardinal;
    begin
    psidEveryOne := nil;
    // pSD := nil;
    ptACL := nil;
    // получаем SID для группы EVERYONE
    win32check(AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY,
      1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, psidEveryone));
    // Заполняем ExplicitAccess
    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;
    // И собственно, создаём новый DACL с текущими настройками доступа
    ErrNo := SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL);
    Win32Check(ErrNo = ERROR_SUCCESS);
    end;

    end.

  • ZeBriD © (18.08.10 14:51) [3]
    Пробовал. Не помогло.
    Точно с таким же успехом пробовал и с "_W"... Как была ошибка, так и осталась...
  • Игорь Шевченко © (18.08.10 15:09) [4]

    > Как была ошибка, так и осталась...


    может, в rtl\win в описании структур ошибка ?
    попробуй взять из jedi
  • ZeBriD © (18.08.10 20:18) [5]

    > может, в rtl\win в описании структур ошибка ?

    Юниты родные... В инете вроде не встречал упоминаний об ошибке именно в 7ой дельфе... 6ая и ранее - были... Но решения для тех версий не сработали в моём случае =(


    > попробуй взять из jedi

    У нас не приветствуется наличие сторонних компонент и кода, поэтому всё делается самими... Да и вроде же всё должно работать (в d2010 же отрабатывает прекрасно этот же код)
  • Игорь Шевченко © (18.08.10 21:42) [6]

    > У нас не приветствуется наличие сторонних компонент и кода,
    >  поэтому всё делается самими


    В jedi набор переведенных API со всеми структурами - то есть, это не "сторонний код"


    > в d2010 же отрабатывает прекрасно этот же код


    У меня в 2006 тоже отрабатывает без ошибок, код я привел.

    А то, что Borland допускает ляпы при переводе заголовков MS в rtl\win - это, увы, известно. С каждой версией Delphi что-то исправляется, что-то вносится.

    Могу посоветовать сравнить описания структур из rtl\win\accctrl.pas в 2010 и 7

    и у меня еще добавка:


    >   Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
  • ZeBriD © (19.08.10 07:44) [7]

    > и у меня еще добавка:
    > >   Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;

    Пробовал... Не помогло...
  • ZeBriD © (19.08.10 08:35) [8]

    > В jedi набор переведенных API со всеми структурами - то
    > есть, это не "сторонний код"

    Посмотрел Jedi... Попробовал даже его использовать... Но т.к. там переопределено практически всё API, кол-во конфликтов зашкалило так, то я отказался от дальнейших попыток использования Jedi
  • Rouse_ © (21.08.10 01:45) [9]
    От джеди не нужно отказываться - более грамотно оформлен код и обьявления типов. А у тебя по всей видимости проблема с выравниванием. Проверь значения SizeOf там где работает и там где нет...
  • Германн © (21.08.10 02:37) [10]

    > Rouse_ ©   (21.08.10 01:45) [9]

    Уж почти трое суток лучшие люди Дельфийских форумов (ИШ и СМ) бьются над решением данного вопроса.
  • Loginov Dmitry © (24.08.10 20:52) [11]

    >
    > Суть простая - необходимо выдать права доступа до файла
    > для группы "Все/Everyone". По идее - всё не так уж и сложно:
    >


    Попробуй
    http://matrix.kladovka.net.ru/download.php?getfilename=uploads/other/ldssecurityunit.zip
  • Loginov Dmitry © (24.08.10 21:03) [12]

    >
    > И каждый раз вызов ф-ции 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
  • Игорь Шевченко © (24.08.10 21:14) [13]

    > параметр nSubAuthorityCount на самом деле не BYTE, а DWORD.
    >  На это я уже натыкался при разборе аналогичной ошибки с
    > функциями GetNamedSecurityInf и SetNamedSecurityInfo. Ихнее
    > BYTE надо рассматривать как DWORD


    насмешил
  • Loginov Dmitry © (25.08.10 09:10) [14]

    > насмешил


    Я рад!
    Однако это на самом деле.

    Если хочется поспорить, то аргументы - в студию!
  • Дмитрий Белькевич (25.08.10 18:18) [15]
    Я тут немного понажимал кнопки. Глюк подтверждаю. Копать где-то в районе  Trustee.ptstrName. SizeOf(Trustee.ptstrName). То ли psidEveryone какой-то не такой возвращается, то ли еще что-то.
  • PavelM (26.04.11 02:46) [16]
    Апну немного.
    Может кто решил проблему?
    Delphi6. И та же проблема. Пробовал все структуры откопипастить из jedi, как советовали выше, результат тот же.
    При этом заметил, что если в код добавить вывод ошибки

    if SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL)<>ERROR_SUCCESS then
    begin
     caption:=inttostr(GetLasterror);
     exit;
    end;


    то функция отрабатывает на ура. Т.е. компилятор,если правильно понимаю, немного подругому распределяет память, при которой случайно функции SetEntriesInAcl всё нравится во входящих параметрах.
  • PavelM (26.04.11 03:21) [17]
    Всё закончилось хорошо, причина тут : http://groups.google.com/group/borland.public.delphi.winapi/msg/8d48349715137c6b
  • Игорь Шевченко © (26.04.11 21:50) [18]

    > Всё закончилось хорошо


    говорили же - jedi
  • Loginov Dmitry © (21.05.11 13:50) [19]

    > Всё закончилось хорошо, причина тут : http://groups.google.
    > com/group/borland.public.delphi.winapi/msg/8d48349715137c6b


    Как и предполагалось. В AccCtrl и AclAPI чуть ли не половина объявлений выполнены криво, без соответствующих проверок.
 
Конференция "WinAPI" » SetEntriesInAcl Error 87 [D7]
Есть новые Нет новых   [134431   +13][b:0][p:0.002]