Peter Laman wrote:
After some msdn searhing, I came up with the following to determine the
effective access rights on a file:
function CheckAccessRights(const UserName, Filename: string): ACCESS_MASK;
var
DACL: PACL;
SecDesc: PSECURITY_DESCRIPTOR;
User: TRUSTEE;
ActualUser: string;
begin
DACL := nil;
SecDesc := nil;
Win32Check(GetNamedSecurityInfo(PChar(FileName), SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
nil, nil, @DACL, nil, SecDesc) = ERROR_SUCCESS);
try
if Assigned(DACL) then
begin
FillChar(User, SizeOf(User), 0);
User.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
User.TrusteeForm := TRUSTEE_IS_NAME;
User.TrusteeType := TRUSTEE_IS_USER;
if Length(UserName) > 0 then
ActualUser := PChar(UserName)
else
ActualUser := PChar(LoggedOnUser);
User.ptstrName := PChar(ActualUser);
Win32Check(GetEffectiveRightsFromAcl(DACL^, User, Result) =
ERROR_SUCCESS);
end
else
Result := 0;
finally
Win32Check(LocalFree(Cardinal(SecDesc)) = 0);
end;
end;
The call to GetEffectiveRightsFromAcl(DACL^, User, Result) results in an
exception "System Error. Code: 998. Invalid access to memory location".
What's going wrong here?
I tried your code, and it seems to work for me. I made two changes,
which I don't think are relevant, but I'll describe them anyway. First,
I had to type-cast "@DACL" in the first call since Borland misdeclared
the function and you probably don't use the "typed @ operator" compiler
option. Second, I did away with the LoggedOnUser stuff since I don't
have that function and it's easier to test this function without
worrying about what ActualUser is.
Perhaps the error message is wrong. When you pass a False value to
Win32Check, it generates its error message based on the result from
GetLastError. But the security functions say nothing about using
GetLastError. Instead, they say their return values _are_ the error code.
Instead of Win32Check, try this:
procedure SecurityCheck(ErrCode: DWord);
begin
if ErrCode <> Error_Success then RaiseLastOSError(ErrCode);
end;
If your version of Delphi doesn't have a one-argument RaiseLastOSError,
then implement it like this:
procedure RaiseLastOSError(ErrCode: DWord);
begin
SetLastError(ErrCode);
SysUtils.RaiseLastOSError;
end;
None of this will actually fix the problem, but it might get you a more
accurate error message, so diagnosing the problem might become easier.
--
Rob
__________________________________________________
Delphi-Talk mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi-talk