From 25758f18d9257ca5ab1a2f44079f29897b89da9b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 1 Jun 2003 18:14:24 +0000 Subject: [PATCH] Implemented RtlExtendedMagicDivide() and RtlSelfRelativeToAbsoluteSD(). Patch by Marc Schuetz. svn path=/trunk/; revision=4815 --- reactos/lib/ntdll/rtl/largeint.c | 77 +++++++++++++++++++++++++++++--- reactos/lib/ntdll/rtl/sd.c | 52 ++++++++++++++++++++- 2 files changed, 120 insertions(+), 9 deletions(-) diff --git a/reactos/lib/ntdll/rtl/largeint.c b/reactos/lib/ntdll/rtl/largeint.c index 324a6a94541..882649aee8a 100644 --- a/reactos/lib/ntdll/rtl/largeint.c +++ b/reactos/lib/ntdll/rtl/largeint.c @@ -1,4 +1,4 @@ -/* $Id: largeint.c,v 1.10 2002/12/08 15:57:39 robd Exp $ +/* $Id: largeint.c,v 1.11 2003/06/01 18:14:24 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -119,15 +119,78 @@ RtlExtendedLargeIntegerDivide ( return RC; } -LARGE_INTEGER -STDCALL -RtlExtendedMagicDivide(LARGE_INTEGER Dividend, - LARGE_INTEGER MagicDivisor, - CCHAR ShiftCount) + +/****************************************************************************** + * RtlExtendedMagicDivide + * + * Allows replacing a division by a longlong constant with a multiplication by + * the inverse constant. + * + * RETURNS + * (Dividend * MagicDivisor) >> (64 + ShiftCount) + * + * NOTES + * If the divisor of a division is constant, the constants MagicDivisor and + * shift must be chosen such that + * MagicDivisor = 2^(64 + ShiftCount) / Divisor. + * + * Then we have RtlExtendedMagicDivide(Dividend,MagicDivisor,ShiftCount) == + * Dividend * MagicDivisor / 2^(64 + ShiftCount) == Dividend / Divisor. + * + * The Parameter MagicDivisor although defined as LONGLONG is used as + * ULONGLONG. + */ + +#define LOWER_32(A) ((A) & 0xffffffff) +#define UPPER_32(A) ((A) >> 32) + +LARGE_INTEGER STDCALL +RtlExtendedMagicDivide (LARGE_INTEGER Dividend, + LARGE_INTEGER MagicDivisor, + CCHAR ShiftCount) { - UNIMPLEMENTED; + ULONGLONG dividend_high; + ULONGLONG dividend_low; + ULONGLONG inverse_divisor_high; + ULONGLONG inverse_divisor_low; + ULONGLONG ah_bl; + ULONGLONG al_bh; + LARGE_INTEGER result; + BOOLEAN positive; + + if (Dividend.QuadPart < 0) + { + dividend_high = UPPER_32((ULONGLONG) -Dividend.QuadPart); + dividend_low = LOWER_32((ULONGLONG) -Dividend.QuadPart); + positive = FALSE; + } + else + { + dividend_high = UPPER_32((ULONGLONG) Dividend.QuadPart); + dividend_low = LOWER_32((ULONGLONG) Dividend.QuadPart); + positive = TRUE; + } + inverse_divisor_high = UPPER_32((ULONGLONG) MagicDivisor.QuadPart); + inverse_divisor_low = LOWER_32((ULONGLONG) MagicDivisor.QuadPart); + + ah_bl = dividend_high * inverse_divisor_low; + al_bh = dividend_low * inverse_divisor_high; + + result.QuadPart = + (LONGLONG) ((dividend_high * inverse_divisor_high + + UPPER_32(ah_bl) + + UPPER_32(al_bh) + + UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) + + UPPER_32(dividend_low * inverse_divisor_low))) >> ShiftCount); + if (!positive) + { + result.QuadPart = -result.QuadPart; + } + + return result; } + LARGE_INTEGER STDCALL RtlLargeIntegerAdd ( diff --git a/reactos/lib/ntdll/rtl/sd.c b/reactos/lib/ntdll/rtl/sd.c index a4b0d651921..b8a45c68756 100644 --- a/reactos/lib/ntdll/rtl/sd.c +++ b/reactos/lib/ntdll/rtl/sd.c @@ -1,4 +1,4 @@ -/* $Id: sd.c,v 1.9 2002/09/08 10:23:06 chorns Exp $ +/* $Id: sd.c,v 1.10 2003/06/01 18:14:24 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -641,6 +641,7 @@ RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, return(STATUS_SUCCESS); } + NTSTATUS STDCALL RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD, PSECURITY_DESCRIPTOR AbsSD, @@ -654,7 +655,54 @@ RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD, PSID Group, PDWORD GroupSize) { - UNIMPLEMENTED; + ULONG TotalSize; + ULONG OwnerLength; + ULONG GroupLength; + ULONG DaclLength; + ULONG SaclLength; + PSID pOwner; + PSID pGroup; + PACL pDacl; + PACL pSacl; + + if (!(RelSD->Control & SE_SELF_RELATIVE)) + return STATUS_BAD_DESCRIPTOR_FORMAT; + + RtlpQuerySecurityDescriptor (RelSD, + &pOwner, + &OwnerLength, + &pGroup, + &GroupLength, + &pDacl, + &DaclLength, + &pSacl, + &SaclLength); + + if (OwnerLength > *OwnerSize || + GroupLength > *GroupSize || + DaclLength > *DaclSize || + SaclLength > *SaclSize) + return STATUS_BUFFER_TOO_SMALL; + + memmove (Owner, pOwner, OwnerLength); + memmove (Group, pGroup, GroupLength); + memmove (Dacl, pDacl, DaclLength); + memmove (Sacl, pSacl, SaclLength); + + memmove (AbsSD, RelSD, sizeof (SECURITY_DESCRIPTOR)); + + AbsSD->Control &= ~SE_SELF_RELATIVE; + AbsSD->Owner = Owner; + AbsSD->Group = Group; + AbsSD->Dacl = Dacl; + AbsSD->Sacl = Sacl; + + *OwnerSize = OwnerLength; + *GroupSize = GroupLength; + *DaclSize = DaclLength; + *SaclSize = SaclLength; + + return STATUS_SUCCESS; } /* EOF */