[Win32] В библиотеках Delphi функция описана правильно. Смотреть внутри ж-))16.07.02 23:03 Число просмотров: 1369 Автор: HandleX <Александр М.> Статус: The Elderman
> > Hi, All! > > Блин, досадная трабла, не знаю как побороться. > > Уже что только не переделал. > > Итак, вот кусок кода (Delphi): > >
>> Var
> > PSec: PSecurityDescriptor;
> > Count: DWORD;
> > pAccessList: PEXPLICIT_ACCESS_A;
> > J: Integer;
> > aDACL: PACL;
> > dDefaulted, dPresent: BOOL;
> > Begin
> > PSec := GetServiceSD(DACL_SECURITY_INFORMATION);
> > Try
> > //ConvertSDtoAbsolute(pSec);
> > Win32Check(GetSecurityDescriptorDacl(pSec,
> dPresent,
> > aDACL, dDefaulted));
> > If Not dPresent Then Exit;
> > pAccessList := Nil; Count := 0;
> > J := GetExplicitEntriesFromAcl(aDacl^, Count,
> > pAccessList);
dolzhen peredat1 pointer na -> Count
If J <> ERROR_SUCCESS Then // <=== Здесь происходит трабла. Возвращаемый код
// равен ошибке 87, что означает "Параметр задан неверно"
---
В Delphi функция задана вот так:
function GetExplicitEntriesFromAclA(var pacl: ACL; var pcCountOfExplicitEntries: ULONG;
pListOfExplicitEntries: PEXPLICIT_ACCESS_A): DWORD; stdcall;
--- То есть получается, что pcCountOfExplicitEntries толкается в стек как указатель на Count, поскольку VAR.
Что делать, пока не знаю.
Изтрахался уже ;-)))))
[Win32] Вот я попал с Win2k Security. Help, please ;-))))15.07.02 22:12 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 15.07.02 22:14 Количество правок: 1
Hi, All!
Блин, досадная трабла, не знаю как побороться.
Уже что только не переделал.
Итак, вот кусок кода (Delphi):
Var
PSec: PSecurityDescriptor;
Count: DWORD;
pAccessList: PEXPLICIT_ACCESS_A;
J: Integer;
aDACL: PACL;
dDefaulted, dPresent: BOOL;
Begin
PSec := GetServiceSD(DACL_SECURITY_INFORMATION);
Try
//ConvertSDtoAbsolute(pSec);
Win32Check(GetSecurityDescriptorDacl(pSec, dPresent, aDACL, dDefaulted));
If Not dPresent Then Exit;
pAccessList := Nil; Count := 0;
J := GetExplicitEntriesFromAcl(aDacl^, Count, pAccessList);
If J <> ERROR_SUCCESS Then // <=== Здесь происходит трабла. Возвращаемый код
// равен ошибке 87, что означает "Параметр задан неверно"
Raise Exception.Create('Win32Error: ' + SysErrorMessage(J));
---
Что здравого можно придумать по этому поводу? Я уже изматюгался весь. Мелкософт говорит, что GetExplicitEntriesFromAcl сам создаст нужный буфер, который надо потом LocalFree.
Причём неважно, из кагого SD DACL пихаешь - абсолютного или Self-relative, всё равно ЕГГОГ 87 ;-))
Заранее спасибо за советы, добрый All!
[Win32] Внимание! Найден новый баг от Microsoft! Пожалуйста, проверьте.18.07.02 22:06 Автор: HandleX <Александр М.> Статус: The Elderman
У кого Delphi5 или 6 могут напрямую ввести кусок вот такого кода:
implementation
Uses AclAPI, AccCtrl, WinSvc;
procedure TForm1.Button1Click(Sender: TObject);
Type
TExplicitAccessArray = Array[0..0] Of EXPLICIT_ACCESS;
PExplicitAccessArray = ^TExplicitAccessArray;
Function GetEAListFromService(ServiceKeyName: String): PExplicitAccessArray;
Var scHndl, srvHndl: THandle;
Function GetServiceSD(SDFlags: DWORD): PSecurityDescriptor;
Var BytesNeeded: DWord;
Begin
New(Result);
BytesNeeded := 0;
QueryServiceObjectSecurity(srvHndl, SDFlags, Result, 0, BytesNeeded);
If BytesNeeded = 0 Then RaiseLastWin32Error;
If SizeOf(Result^) <> BytesNeeded Then
Begin
ReallocMem(Result, BytesNeeded);
Win32Check(QueryServiceObjectSecurity(srvHndl, SDFlags, Result, BytesNeeded, BytesNeeded));
End;
End;
Var
aSD: PSecurityDescriptor;
pDACL: PACL;
dPresent, dDefaulted: Bool;
EACount, ErrCode: DWORD;
Begin
scHndl := OpenSCManager(Nil, Nil, GENERIC_EXECUTE);
Win32Check(scHndl <> 0);
Try
srvHndl := OpenService(SCHndl, PChar(ServiceKeyName), STANDARD_RIGHTS_REQUIRED);
Win32Check(srvHndl <> 0);
Try
aSD := GetServiceSD(DACL_SECURITY_INFORMATION);
Result := Nil;
If Not IsValidSecurityDescriptor(aSD) Then Exit;
Try
Win32Check(GetSecurityDescriptorDacl(aSD, dPresent, pDACL, dDefaulted));
If Not dPresent Then Exit;
ErrCode := GetExplicitEntriesFromAcl(pDACL^, EACount, @Result);
If ErrCode <> ERROR_SUCCESS Then
Application.MessageBox(PChar(Format('Error (%d): %s', [ErrCode, SysErrorMessage(ErrCode)])), Nil, mb_IconError);
Finally
FreeMem(aSD);
End;
Finally
CloseServiceHandle(srvHndl);
End;
Finally
CloseServiceHandle(scHndl);
End;
End;
Var
pEAList: PExplicitAccessArray;
begin
pEAList := GetEAListFromService('Messenger');
If pEAList = Nil Then Application.MessageBox('Найден новый баг! Call for service ;-))', 'Microsoft снова обложался?', mb_IconQuestion)
Else LocalFree(DWord(pEAList));
end;
---
Указание по компиляции на Delphi5:
Найти в каталоге Source\Rtl\Win библиотеку AclAPI.pas.
Открыть библиотеку каким-либо текстовым редактором.
Найти строчку: ModName = 'aclapi.dll' .
Поменять на: ModName = 'advapi32.dll' . (И здесь баги! ;-))))))))
Скомпилировать библиотеку командной строкой: dcc32 AclAPI.pas .
Получившийся модуль aclapi.dcu переместить в каталог Delphi5\LIB, затерев старый файл.
Запустить Delphi5. Дальше вроде всем понятно ;-)))))
Очень было бы неплохо, если бы кто-нибудь сваял подобное на С — так, на всякий случай.
По-моему, налицо явный баг.
Всем спасибо! Кто всё-таки обложался, непонятно! Этот код у меня тоже заработал!20.07.02 08:27 Автор: HandleX <Александр М.> Статус: The Elderman
Наверное злобный Билли Гейтс, сидящий внутри моего компьютера, испугался и разрешил выполнятся этой функции. А ещё говорят, что расположение планет может влиять на работу компьютера ;-))))))))))))
Но самый прикол в том, что я в своём приложении (где я наткнулся на этот косяк), уже всё сделал через GetAclInformation, GetAce, LookupAccountSid и т.п. Ну ладно, всё хорошо, что хорошо кончается ;-))))))
[Win32] Пожалуйста, проверил19.07.02 21:11 Автор: Cyril <sc> Статус: Member
> У кого Delphi5 или 6 могут напрямую ввести кусок вот такого > кода: > >
> implementation
> Uses AclAPI, AccCtrl, WinSvc;
>
> procedure TForm1.Button1Click(Sender: TObject);
>
> Type
> TExplicitAccessArray = Array[0..0] Of EXPLICIT_ACCESS;
> PExplicitAccessArray = ^TExplicitAccessArray;
>
> Function GetEAListFromService(ServiceKeyName: String):
> PExplicitAccessArray;
>
> Var scHndl, srvHndl: THandle;
>
> Function GetServiceSD(SDFlags: DWORD):
> PSecurityDescriptor;
> Var BytesNeeded: DWord;
> Begin
> New(Result);
> BytesNeeded := 0;
> QueryServiceObjectSecurity(srvHndl, SDFlags, Result,
> 0, BytesNeeded);
> If BytesNeeded = 0 Then RaiseLastWin32Error;
> If SizeOf(Result^) <> BytesNeeded Then
> Begin
> ReallocMem(Result, BytesNeeded);
> Win32Check(QueryServiceObjectSecurity(srvHndl,
> SDFlags, Result, BytesNeeded, BytesNeeded));
> End;
> End;
>
> Var
> aSD: PSecurityDescriptor;
> pDACL: PACL;
> dPresent, dDefaulted: Bool;
> EACount, ErrCode: DWORD;
>
> Begin
> scHndl := OpenSCManager(Nil, Nil, GENERIC_EXECUTE);
> Win32Check(scHndl <> 0);
> Try
> srvHndl := OpenService(SCHndl, PChar(ServiceKeyName),
> STANDARD_RIGHTS_REQUIRED);
> Win32Check(srvHndl <> 0);
> Try
> aSD := GetServiceSD(DACL_SECURITY_INFORMATION);
> Result := Nil;
> If Not IsValidSecurityDescriptor(aSD) Then Exit;
> Try
> Win32Check(GetSecurityDescriptorDacl(aSD,
> dPresent, pDACL, dDefaulted));
> If Not dPresent Then Exit;
> ErrCode := GetExplicitEntriesFromAcl(pDACL^,
> EACount, @Result);
> If ErrCode <> ERROR_SUCCESS Then
> Application.MessageBox(PChar(Format('Error
> (%d): %s', [ErrCode, SysErrorMessage(ErrCode)])), Nil,
> mb_IconError);
> Finally
> FreeMem(aSD);
> End;
> Finally
> CloseServiceHandle(srvHndl);
> End;
> Finally
> CloseServiceHandle(scHndl);
> End;
>
> End;
>
> Var
> pEAList: PExplicitAccessArray;
> begin
> pEAList := GetEAListFromService('Messenger');
> If pEAList = Nil Then Application.MessageBox('Найден
> новый баг! Call for service ;-))', 'Microsoft снова
> обложался?', mb_IconQuestion)
> Else LocalFree(DWord(pEAList));
> end;
>
---
> > Указание по компиляции на Delphi5: > Найти в каталоге Source\Rtl\Win библиотеку AclAPI.pas. > Открыть библиотеку каким-либо текстовым редактором. > Найти строчку: ModName = 'aclapi.dll' . > Поменять на: ModName = 'advapi32.dll' . (И здесь баги! > ;-)))))))) > Скомпилировать библиотеку командной строкой: dcc32 > AclAPI.pas . > Получившийся модуль aclapi.dcu переместить в каталог > Delphi5\LIB, затерев старый файл. > Запустить Delphi5. Дальше вроде всем понятно ;-))))) > > Очень было бы неплохо, если бы кто-нибудь сваял подобное на > С — так, на всякий случай. > По-моему, налицо явный баг.
Это легко сказать. Только где? Не пойму ;-((( А винды у тебя какие ?19.07.02 17:02 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 19.07.02 17:03 Количество правок: 1
> Hi, All! > Блин, досадная трабла, не знаю как побороться. > Уже что только не переделал. > Итак, вот кусок кода (Delphi): > >
> Var
> PSec: PSecurityDescriptor;
> Count: DWORD;
> pAccessList: PEXPLICIT_ACCESS_A;
> J: Integer;
> aDACL: PACL;
> dDefaulted, dPresent: BOOL;
> Begin
> PSec := GetServiceSD(DACL_SECURITY_INFORMATION);
> Try
> //ConvertSDtoAbsolute(pSec);
> Win32Check(GetSecurityDescriptorDacl(pSec, dPresent,
> aDACL, dDefaulted));
> If Not dPresent Then Exit;
> pAccessList := Nil; Count := 0;
> J := GetExplicitEntriesFromAcl(aDacl^, Count,
> pAccessList);
dolzhen peredat1 pointer na -> Count
> If J <> ERROR_SUCCESS Then // <=== Здесь
> происходит трабла. Возвращаемый код
> // равен ошибке 87, что
> означает "Параметр задан неверно"
> Raise Exception.Create('Win32Error: ' +
> SysErrorMessage(J));
>
---
> > Что здравого можно придумать по этому поводу? Я уже > изматюгался весь. Мелкософт говорит, что > GetExplicitEntriesFromAcl сам создаст нужный буфер, который > надо потом LocalFree. > Причём неважно, из кагого SD DACL пихаешь - абсолютного или > Self-relative, всё равно ЕГГОГ 87 ;-)) > Заранее спасибо за советы, добрый All!
[Win32] В библиотеках Delphi функция описана правильно. Смотреть внутри ж-))16.07.02 23:03 Автор: HandleX <Александр М.> Статус: The Elderman
> > Hi, All! > > Блин, досадная трабла, не знаю как побороться. > > Уже что только не переделал. > > Итак, вот кусок кода (Delphi): > >
>> Var
> > PSec: PSecurityDescriptor;
> > Count: DWORD;
> > pAccessList: PEXPLICIT_ACCESS_A;
> > J: Integer;
> > aDACL: PACL;
> > dDefaulted, dPresent: BOOL;
> > Begin
> > PSec := GetServiceSD(DACL_SECURITY_INFORMATION);
> > Try
> > //ConvertSDtoAbsolute(pSec);
> > Win32Check(GetSecurityDescriptorDacl(pSec,
> dPresent,
> > aDACL, dDefaulted));
> > If Not dPresent Then Exit;
> > pAccessList := Nil; Count := 0;
> > J := GetExplicitEntriesFromAcl(aDacl^, Count,
> > pAccessList);
dolzhen peredat1 pointer na -> Count
If J <> ERROR_SUCCESS Then // <=== Здесь происходит трабла. Возвращаемый код
// равен ошибке 87, что означает "Параметр задан неверно"
---
В Delphi функция задана вот так:
function GetExplicitEntriesFromAclA(var pacl: ACL; var pcCountOfExplicitEntries: ULONG;
pListOfExplicitEntries: PEXPLICIT_ACCESS_A): DWORD; stdcall;
--- То есть получается, что pcCountOfExplicitEntries толкается в стек как указатель на Count, поскольку VAR.
Что делать, пока не знаю.
Изтрахался уже ;-)))))
[Win32] В библиотеках Delphi функция описана правильно. Смотреть внутри ж-))16.07.02 23:49 Автор: + <Mikhail> Статус: Elderman
> > > Hi, All! > > > Блин, досадная трабла, не знаю как побороться. > > > Уже что только не переделал. > > > Итак, вот кусок кода (Delphi): > > > >
> >> Var
> > > PSec: PSecurityDescriptor;
> > > Count: DWORD;
> > > pAccessList: PEXPLICIT_ACCESS_A;
> > > J: Integer;
> > > aDACL: PACL;
> > > dDefaulted, dPresent: BOOL;
> > > Begin
> > > PSec :=
> GetServiceSD(DACL_SECURITY_INFORMATION);
> > > Try
> > > //ConvertSDtoAbsolute(pSec);
> > >
> Win32Check(GetSecurityDescriptorDacl(pSec,
> > dPresent,
> > > aDACL, dDefaulted));
> > > If Not dPresent Then Exit;
> > > pAccessList := Nil; Count := 0;
> > > J := GetExplicitEntriesFromAcl(aDacl^,
> Count,
> > > pAccessList);
> dolzhen peredat1 pointer na -> Count
> If J <> ERROR_SUCCESS Then // <===
> Здесь происходит трабла. Возвращаемый код
> // равен ошибке 87, что
> означает "Параметр задан неверно"
>
---
> > В Delphi функция задана вот так: >
> function GetExplicitEntriesFromAclA(var pacl: ACL; var
> pcCountOfExplicitEntries: ULONG;
> pListOfExplicitEntries: PEXPLICIT_ACCESS_A): DWORD;
> stdcall;
>
--- > То есть получается, что pcCountOfExplicitEntries толкается > в стек как указатель на Count, поскольку VAR. > Что делать, пока не знаю. > Изтрахался уже ;-))))) Pochemuto pAccessList - zadeclarirovan kak pointer,
a Count - kak DWORD? Tebe ne kazhetsia chto Count dolzhen byt pointer to DWORD?
Count: DWORD;
pAccessList: PEXPLICIT_ACCESS_A;
[Win32] Всё равно правильно ;-)))))))))))))17.07.02 00:24 Автор: HandleX <Александр М.> Статус: The Elderman
--- > > То есть получается, что pcCountOfExplicitEntries > толкается > > в стек как указатель на Count, поскольку VAR. > > Что делать, пока не знаю. > > Изтрахался уже ;-))))) > > Pochemuto pAccessList - zadeclarirovan kak pointer, > a Count - kak DWORD? Tebe ne kazhetsia chto Count dolzhen > byt pointer to DWORD? > > Count: DWORD; > pAccessList: PEXPLICIT_ACCESS_A; >
Ну нравится так Борландовским деклараторам ;-))) Или декларастам ;-))) А может даже и декларирам, что ближе всего ;-)))))))))))
Вот, к примеру, две процедуры (или «функции, которые возвращают значение VOID») — это для утомлённых C++ ;-))))
Procedure Increment(Var Value: DWORD); StdCall;
Begin
Value := Value + 1;
End;
Procedure Increment1(pValue: PDWORD); StdCall;
Begin
pValue^ := pValue^ + 1;
End;
---
Вызывать их можно вот так:
Program Test1;
Var Val: DWORD;
Begin
Val := 0;
Increment(Val);
Increment1(@Val);
End.
---
Видно, что в первом случае гораздо легче как писать процедуры/функции, так и вызывать их. Не нужно всяких крышечек (^) и прочих штук вроде оператора @. Плюс контроль типов работает. А физически что в первом, что во втором случае в стек толкается указатель на переменную. Прогресс, мля! ;-))))) А только список Trustee из DACL всё равно надо как-то вытаскивать ;-((((((
[Win32] Посмотри в отладчике, правильно ли параметры передаются17.07.02 16:40 Автор: Cyril <sc> Статус: Member
[Win32] Правильно. Код внутри. Всем спасибо. Кранты и вашим приложениям тоже в Win2k. Про это тоже внутри.18.07.02 22:04 Автор: HandleX <Александр М.> Статус: The Elderman
Вроде всё в порядке.
Конечно, нулевые параметры я поставил для примера.
А вот что пишет MSDN по этому поводу:
INFO: The GetExplicitEntriesFromAcl() Function Returns the Incorrect Number of ACEs
ID: Q260307
The GetExplicitEntriesFromAcl function does not return any access control entries (ACEs) that are marked with the INHERITED_ACE flag.
MORE INFORMATION
The INHERITED_ACE flag is new for Windows 2000. The flag indicates that the ACE was propagated by a parent object.
To obtain all ACEs, including ACEs that are marked with the INHERITED_ACE flag, the following low-level security functions should be used instead of GetExplictEntriesFromAcl:
GetAclInformation
GetAce
LookupAccountSid
Additional query words:
Keywords : kbAPI kbKernBase kbWinOS2000 kbSDKPlatform kbSDKWin32 kbDSupport kbGrpKernBase
Version : winnt:
Platform : winnt
Issue type : kbinfo
Technology : kbvcSearch
---
Так что можете перелопачивать свои проекты. Удачи ;-))))))))
Однако прикол ещё жёстче. Видать эта функция в Win2k не поддерживает ещё чего-то. Я извлекал DACL из дексриптора безопасности сервиса Win2k.
Проверял — флаг INHERITED_ACE в ACE'ах не выставлен. А всё равно не работает!
Я в другую нитку отправил исходник, где не работает эта функция. Посмотрите, кому это интересно.