Commit 0ce4826e authored by Thomas Mertes's avatar Thomas Mertes Committed by Alexandre Julliard

Implemented RtlRandom, RtlAreAllAccessesGranted,

RtlAreAnyAccessesGranted, RtlCopyLuid, RtlEqualLuid, RtlMapGenericMask and RtlCopyLuidAndAttributesArray. Documentation updates for RtlExtendedMagicDivide, RtlUniform, RtlUnicodeStringToAnsiString, RtlAppendAsciizToString, RtlAppendStringToString, RtlAppendUnicodeToString and RtlAppendUnicodeStringToString.
parent e434d89b
......@@ -183,56 +183,57 @@ LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b )
/******************************************************************************
* RtlExtendedMagicDivide (NTDLL.@)
*
* This function computes (a * b) >> (64 + shift)
* Allows replacing a division by a longlong constant with a multiplication by
* the inverse constant.
*
* RETURNS
* (a * b) >> (64 + shift)
* (dividend * inverse_divisor) >> (64 + shift)
*
* NOTES
* This allows replacing a division by a longlong constant
* by a multiplication by the inverse constant.
* If the divisor of a division is constant, the constants inverse_divisor and
* shift must be chosen such that inverse_divisor = 2^(64 + shift) / divisor.
* Then we have RtlExtendedMagicDivide(dividend,inverse_divisor,shift) ==
* dividend * inverse_divisor / 2^(64 + shift) == dividend / divisor.
*
* If 'c' is the constant divisor, the constants 'b' and 'shift'
* must be chosen such that b = 2^(64+shift) / c.
* Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
*
* The Parameter b although defined as LONGLONG is used as ULONGLONG.
* The Parameter inverse_divisor although defined as LONGLONG is used as
* ULONGLONG.
*/
#define LOWER_32(A) ((A) & 0xffffffff)
#define UPPER_32(A) ((A) >> 32)
LONGLONG WINAPI RtlExtendedMagicDivide(
LONGLONG a, /* [I] Dividend to be divided by the constant divisor */
LONGLONG b, /* [I] Constant computed manually as 2^(64+shift) / divisor */
INT shift) /* [I] Constant shift chosen to make b as big as possible for 64 bits */
LONGLONG dividend, /* [I] Dividend to be divided by the constant divisor */
LONGLONG inverse_divisor, /* [I] Constant computed manually as 2^(64+shift) / divisor */
INT shift) /* [I] Constant shift chosen to make inverse_divisor as big as possible for 64 bits */
{
ULONGLONG a_high;
ULONGLONG a_low;
ULONGLONG b_high;
ULONGLONG b_low;
ULONGLONG dividend_high;
ULONGLONG dividend_low;
ULONGLONG inverse_divisor_high;
ULONGLONG inverse_divisor_low;
ULONGLONG ah_bl;
ULONGLONG al_bh;
LONGLONG result;
int positive;
if (a < 0) {
a_high = UPPER_32((ULONGLONG) -a);
a_low = LOWER_32((ULONGLONG) -a);
if (dividend < 0) {
dividend_high = UPPER_32((ULONGLONG) -dividend);
dividend_low = LOWER_32((ULONGLONG) -dividend);
positive = 0;
} else {
a_high = UPPER_32((ULONGLONG) a);
a_low = LOWER_32((ULONGLONG) a);
dividend_high = UPPER_32((ULONGLONG) dividend);
dividend_low = LOWER_32((ULONGLONG) dividend);
positive = 1;
} /* if */
b_high = UPPER_32((ULONGLONG) b);
b_low = LOWER_32((ULONGLONG) b);
inverse_divisor_high = UPPER_32((ULONGLONG) inverse_divisor);
inverse_divisor_low = LOWER_32((ULONGLONG) inverse_divisor);
ah_bl = a_high * b_low;
al_bh = a_low * b_high;
ah_bl = dividend_high * inverse_divisor_low;
al_bh = dividend_low * inverse_divisor_high;
result = (LONGLONG) ((a_high * b_high +
result = (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(a_low * b_low))) >> shift);
UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) +
UPPER_32(dividend_low * inverse_divisor_low))) >> shift);
if (positive) {
return result;
......
......@@ -286,8 +286,8 @@
@ stdcall RtlAppendUnicodeToString(ptr wstr)
@ stub RtlApplyRXact
@ stub RtlApplyRXactNoFlush
@ stub RtlAreAllAccessesGranted
@ stub RtlAreAnyAccessesGranted
@ stdcall RtlAreAllAccessesGranted(long long)
@ stdcall RtlAreAnyAccessesGranted(long long)
@ stdcall RtlAreBitsClear(ptr long long)
@ stdcall RtlAreBitsSet(ptr long long)
@ stdcall RtlAssert(ptr ptr long long)
......@@ -298,7 +298,7 @@
@ stdcall RtlClearBits(ptr long long)
@ stdcall RtlCompactHeap(long long)
@ stdcall RtlCompareMemory(ptr ptr long)
@ stdcall RtlCompareMemoryUlong(ptr ptr long)
@ stdcall RtlCompareMemoryUlong(ptr long long)
@ stdcall RtlCompareString(ptr ptr long)
@ stdcall RtlCompareUnicodeString (ptr ptr long)
@ stub RtlCompressBuffer
......@@ -310,8 +310,8 @@
@ stdcall RtlConvertSidToUnicodeString(ptr ptr long)
@ stub RtlConvertUiListToApiList
@ stdcall -ret64 RtlConvertUlongToLargeInteger(long)
@ stub RtlCopyLuid
@ stub RtlCopyLuidAndAttributesArray
@ stdcall RtlCopyLuid(ptr ptr)
@ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr)
@ stub RtlCopySecurityDescriptor
@ stdcall RtlCopySid(long ptr ptr)
@ stub RtlCopySidAndAttributesArray
......@@ -363,7 +363,7 @@
@ stub RtlEnumerateGenericTableWithoutSplaying
@ stdcall RtlEqualComputerName(ptr ptr)
@ stdcall RtlEqualDomainName(ptr ptr)
@ stub RtlEqualLuid
@ stdcall RtlEqualLuid(ptr ptr)
@ stdcall RtlEqualPrefixSid(ptr ptr)
@ stdcall RtlEqualSid (long long)
@ stdcall RtlEqualString(ptr ptr long)
......@@ -461,7 +461,7 @@
@ stdcall RtlLockHeap(long)
@ stub RtlLookupElementGenericTable
@ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr)
@ stub RtlMapGenericMask
@ stdcall RtlMapGenericMask(long ptr)
@ stdcall RtlMoveMemory(ptr ptr long)
@ stdcall RtlMultiByteToUnicodeN(ptr long ptr ptr long)
@ stdcall RtlMultiByteToUnicodeSize(ptr str long)
......@@ -493,7 +493,7 @@
@ stdcall RtlQueryTimeZoneInformation(ptr)
@ stdcall RtlRaiseException(ptr)
@ stdcall RtlRaiseStatus(long)
@ stub RtlRandom
@ stdcall RtlRandom(ptr)
@ stdcall RtlReAllocateHeap(long long ptr long)
@ stub RtlRealPredecessor
@ stub RtlRealSuccessor
......
......@@ -741,24 +741,36 @@ __ASM_GLOBAL_FUNC(NTDLL_RtlUshortByteSwap,
* seed [O] The seed of the Random function
*
* RETURNS
* It returns a random number uniformly distributed over [0..MAXLONG].
* It returns a random number uniformly distributed over [0..MAXLONG-1].
*
* NOTES
* Generates an uniform random number using a modified version of
* D.H. Lehmer's 1948 algorithm. The original algorithm would be:
* Generates an uniform random number using D.H. Lehmer's 1948 algorithm.
* In our case the algorithm is:
*
* result = (*seed * 0x7fffffed + 0x7fffffc3) % MAXLONG;
*
* result = *seed * 0xffffffed + 0x7fffffc3;
* *seed = result;
*
* DIFFERENCES
* The native documentation states that the random number is
* uniformly distributed over [0..MAXLONG]. In reality the native
* function and our function return a random number uniformly
* distributed over [0..MAXLONG-1].
*/
ULONG WINAPI RtlUniform (PULONG seed)
{
ULONG result;
/*
* Instead of the algorithm stated above, we use the algorithm
* below, which is totally equivalent (see the tests), but does
* not use a division and therefore is faster.
*/
result = *seed * 0xffffffed + 0x7fffffc3;
if (result == 0xffffffff || result == 0x7ffffffe) {
result = (result + 2) & MAXLONG;
} else if (result == 0x7fffffff) {
result = (result + 1) & MAXLONG;
result = 0;
} else if ((result & 0x80000000) == 0) {
result = result + (~result & 1);
} else {
......@@ -767,3 +779,160 @@ ULONG WINAPI RtlUniform (PULONG seed)
*seed = result;
return result;
}
/*************************************************************************
* RtlRandom [NTDLL.@]
*
* Generates a random number
*
* PARAMS
* seed [O] The seed of the Random function
*
* RETURNS
* It returns a random number distributed over [0..MAXLONG-1].
*/
ULONG WINAPI RtlRandom (PULONG seed)
{
static ULONG saved_value[128] =
{ /* 0 */ 0x4c8bc0aa, 0x4c022957, 0x2232827a, 0x2f1e7626, 0x7f8bdafb, 0x5c37d02a, 0x0ab48f72, 0x2f0c4ffa,
/* 8 */ 0x290e1954, 0x6b635f23, 0x5d3885c0, 0x74b49ff8, 0x5155fa54, 0x6214ad3f, 0x111e9c29, 0x242a3a09,
/* 16 */ 0x75932ae1, 0x40ac432e, 0x54f7ba7a, 0x585ccbd5, 0x6df5c727, 0x0374dad1, 0x7112b3f1, 0x735fc311,
/* 24 */ 0x404331a9, 0x74d97781, 0x64495118, 0x323e04be, 0x5974b425, 0x4862e393, 0x62389c1d, 0x28a68b82,
/* 32 */ 0x0f95da37, 0x7a50bbc6, 0x09b0091c, 0x22cdb7b4, 0x4faaed26, 0x66417ccd, 0x189e4bfa, 0x1ce4e8dd,
/* 40 */ 0x5274c742, 0x3bdcf4dc, 0x2d94e907, 0x32eac016, 0x26d33ca3, 0x60415a8a, 0x31f57880, 0x68c8aa52,
/* 48 */ 0x23eb16da, 0x6204f4a1, 0x373927c1, 0x0d24eb7c, 0x06dd7379, 0x2b3be507, 0x0f9c55b1, 0x2c7925eb,
/* 56 */ 0x36d67c9a, 0x42f831d9, 0x5e3961cb, 0x65d637a8, 0x24bb3820, 0x4d08e33d, 0x2188754f, 0x147e409e,
/* 64 */ 0x6a9620a0, 0x62e26657, 0x7bd8ce81, 0x11da0abb, 0x5f9e7b50, 0x23e444b6, 0x25920c78, 0x5fc894f0,
/* 72 */ 0x5e338cbb, 0x404237fd, 0x1d60f80f, 0x320a1743, 0x76013d2b, 0x070294ee, 0x695e243b, 0x56b177fd,
/* 80 */ 0x752492e1, 0x6decd52f, 0x125f5219, 0x139d2e78, 0x1898d11e, 0x2f7ee785, 0x4db405d8, 0x1a028a35,
/* 88 */ 0x63f6f323, 0x1f6d0078, 0x307cfd67, 0x3f32a78a, 0x6980796c, 0x462b3d83, 0x34b639f2, 0x53fce379,
/* 96 */ 0x74ba50f4, 0x1abc2c4b, 0x5eeaeb8d, 0x335a7a0d, 0x3973dd20, 0x0462d66b, 0x159813ff, 0x1e4643fd,
/* 104 */ 0x06bc5c62, 0x3115e3fc, 0x09101613, 0x47af2515, 0x4f11ec54, 0x78b99911, 0x3db8dd44, 0x1ec10b9b,
/* 112 */ 0x5b5506ca, 0x773ce092, 0x567be81a, 0x5475b975, 0x7a2cde1a, 0x494536f5, 0x34737bb4, 0x76d9750b,
/* 120 */ 0x2a1f6232, 0x2e49644d, 0x7dddcbe7, 0x500cebdb, 0x619dab9e, 0x48c626fe, 0x1cda3193, 0x52dabe9d };
ULONG rand;
int pos;
ULONG result;
rand = (*seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
*seed = (rand * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
pos = *seed & 0x7f;
result = saved_value[pos];
saved_value[pos] = rand;
return(result);
}
/*************************************************************************
* RtlAreAllAccessesGranted [NTDLL.@]
*
* Check if all desired accesses are granted
*
* RETURNS
* TRUE: All desired accesses are granted
* FALSE: Otherwise
*/
BOOLEAN WINAPI RtlAreAllAccessesGranted(
ACCESS_MASK GrantedAccess,
ACCESS_MASK DesiredAccess)
{
return (GrantedAccess & DesiredAccess) == DesiredAccess;
}
/*************************************************************************
* RtlAreAnyAccessesGranted [NTDLL.@]
*
* Check if at least one of the desired accesses is granted
*
* RETURNS
* TRUE: At least one of the desired accesses is granted
* FALSE: Otherwise
*/
BOOLEAN WINAPI RtlAreAnyAccessesGranted(
ACCESS_MASK GrantedAccess,
ACCESS_MASK DesiredAccess)
{
return (GrantedAccess & DesiredAccess) != 0;
}
/*************************************************************************
* RtlMapGenericMask [NTDLL.@]
*
* Determine the nongeneric access rights specified by an access mask
*
* RETURNS
* Nothing.
*/
void WINAPI RtlMapGenericMask(
PACCESS_MASK AccessMask,
const GENERIC_MAPPING *GenericMapping)
{
if (*AccessMask & GENERIC_READ) {
*AccessMask |= GenericMapping->GenericRead;
} /* if */
if (*AccessMask & GENERIC_WRITE) {
*AccessMask |= GenericMapping->GenericWrite;
} /* if */
if (*AccessMask & GENERIC_EXECUTE) {
*AccessMask |= GenericMapping->GenericExecute;
} /* if */
if (*AccessMask & GENERIC_ALL) {
*AccessMask |= GenericMapping->GenericAll;
} /* if */
*AccessMask &= 0x0FFFFFFF;
}
/*************************************************************************
* RtlCopyLuid [NTDLL.@]
*
* Copies the LuidSrc to LuidDest.
*
* RETURNS
* Nothing.
*/
void WINAPI RtlCopyLuid (PLUID LuidDest, const LUID *LuidSrc)
{
*LuidDest = *LuidSrc;
}
/*************************************************************************
* RtlEqualLuid [NTDLL.@]
*
* Compares two local unique ID's.
*
* RETURNS
* TRUE: The two LUID's are equal.
* FALSE: Otherwise
*/
BOOLEAN WINAPI RtlEqualLuid (const LUID *Luid1, const LUID *Luid2)
{
return (Luid1->LowPart == Luid2->LowPart && Luid1->HighPart == Luid2->HighPart);
}
/*************************************************************************
* RtlCopyLuidAndAttributesArray [NTDLL.@]
*
* Copies an array of LUID's and attributes.
*
* RETURNS
* Nothing.
*/
void WINAPI RtlCopyLuidAndAttributesArray(
ULONG Count,
const LUID_AND_ATTRIBUTES *Src,
PLUID_AND_ATTRIBUTES Dest)
{
ULONG i;
for (i = 0; i < Count; i++) Dest[i] = Src[i];
}
......@@ -472,13 +472,21 @@ NTSTATUS WINAPI RtlOemStringToUnicodeString( UNICODE_STRING *uni,
/**************************************************************************
* RtlUnicodeStringToAnsiString (NTDLL.@)
*
* Converts an Unicode string to an Ansi string.
*
* RETURNS
* Success: STATUS_SUCCESS. ansi contains the converted string
* Failure: STATUS_BUFFER_OVERFLOW if doalloc is FALSE and ansi is too small.
* STATUS_NO_MEMORY if doalloc is TRUE and the allocation fails.
*
* NOTES
* This function always writes a terminating NUL.
* Performs a partial copy if ansi is too small.
* This function always writes a terminating '\0'.
* It performs a partial copy if ansi is too small.
*/
NTSTATUS WINAPI RtlUnicodeStringToAnsiString( STRING *ansi,
const UNICODE_STRING *uni,
BOOLEAN doalloc )
NTSTATUS WINAPI RtlUnicodeStringToAnsiString(
STRING *ansi, /* [I/O] Destination for the Ansi string */
const UNICODE_STRING *uni, /* [I] Unicode string to be converted */
BOOLEAN doalloc) /* [I] TRUE=Allocate new buffer for ansi, FALSE=Use existing buffer */
{
NTSTATUS ret = STATUS_SUCCESS;
DWORD len = RtlUnicodeStringToAnsiSize( uni );
......@@ -515,8 +523,8 @@ NTSTATUS WINAPI RtlUnicodeStringToAnsiString( STRING *ansi,
*
* RETURNS
* Success: STATUS_SUCCESS. oem contains the converted string
* Failure: STATUS_BUFFER_OVERFLOW if doalloc is FALSE and oem is too small.
* STATUS_NO_MEMORY if doalloc is TRUE and allocation fails.
* Failure: STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and oem is too small.
* STATUS_NO_MEMORY, if doalloc is TRUE and allocation fails.
*
* NOTES
* If doalloc is TRUE, the length allocated is uni->Length + 1.
......@@ -993,66 +1001,139 @@ DWORD WINAPI RtlUnicodeStringToOemSize( const UNICODE_STRING *str )
/**************************************************************************
* RtlAppendStringToString (NTDLL.@)
* RtlAppendAsciizToString (NTDLL.@)
*
* Concatenates a buffered character string and a '\0' terminated character
* string
*
* RETURNS
* Success: STATUS_SUCCESS. src is appended to dest.
* Failure: STATUS_BUFFER_TOO_SMALL, if the buffer of dest is to small
* to hold the concatenated string.
*
* NOTES
* if src is NULL dest is unchanged.
* dest is never '\0' terminated.
*/
NTSTATUS WINAPI RtlAppendStringToString( STRING *dst, const STRING *src )
NTSTATUS WINAPI RtlAppendAsciizToString(
STRING *dest, /* [I/O] Buffered character string to which src is concatenated */
LPCSTR src) /* [I] '\0' terminated character string to be concatenated */
{
unsigned int len = src->Length + dst->Length;
if (len > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy( dst->Buffer + dst->Length, src->Buffer, src->Length );
dst->Length = len;
if (src != NULL) {
unsigned int src_len = strlen(src);
unsigned int dest_len = src_len + dest->Length;
if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy(dest->Buffer + dest->Length, src, src_len);
dest->Length = dest_len;
} /* if */
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlAppendAsciizToString (NTDLL.@)
* RtlAppendStringToString (NTDLL.@)
*
* Concatenates two buffered character strings
*
* RETURNS
* Success: STATUS_SUCCESS. src is appended to dest.
* Failure: STATUS_BUFFER_TOO_SMALL, if the buffer of dest is to small
* to hold the concatenated string.
*
* NOTES
* if src->length is zero dest is unchanged.
* dest is never '\0' terminated.
*/
NTSTATUS WINAPI RtlAppendAsciizToString( STRING *dst, LPCSTR src )
NTSTATUS WINAPI RtlAppendStringToString(
STRING *dest, /* [I/O] Buffered character string to which src is concatenated */
const STRING *src) /* [I] Buffered character string to be concatenated */
{
if (src)
{
unsigned int srclen = strlen(src);
unsigned int total = srclen + dst->Length;
if (total > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy( dst->Buffer + dst->Length, src, srclen );
dst->Length = total;
}
if (src->Length != 0) {
unsigned int dest_len = src->Length + dest->Length;
if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy(dest->Buffer + dest->Length, src->Buffer, src->Length);
dest->Length = dest_len;
} /* if */
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlAppendUnicodeToString (NTDLL.@)
*
* Concatenates an buffered unicode string and a '\0' terminated unicode
* string
*
* RETURNS
* Success: STATUS_SUCCESS. src is appended to dest.
* Failure: STATUS_BUFFER_TOO_SMALL, if the buffer of dest is to small
* to hold the concatenated string.
*
* NOTES
* if src is NULL dest is unchanged.
* dest is '\0' terminated when the MaximumLength allowes it.
* When dest fits exactly in MaximumLength characters the '\0' is ommitted.
*
* DIFFERENCES
* Does not write in the src->Buffer beyond MaximumLength when
* MaximumLength is odd as the native function does.
*/
NTSTATUS WINAPI RtlAppendUnicodeToString( UNICODE_STRING *dst, LPCWSTR src )
NTSTATUS WINAPI RtlAppendUnicodeToString(
UNICODE_STRING *dest, /* [I/O] Buffered unicode string to which src is concatenated */
LPCWSTR src) /* [I] '\0' terminated unicode string to be concatenated */
{
if (src)
{
unsigned int srclen = strlenW(src) * sizeof(WCHAR);
unsigned int total = srclen + dst->Length;
if (total > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy( dst->Buffer + dst->Length/sizeof(WCHAR), src, srclen );
dst->Length = total;
if (src != NULL) {
unsigned int src_len = strlenW(src) * sizeof(WCHAR);
unsigned int dest_len = src_len + dest->Length;
if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy(dest->Buffer + dest->Length/sizeof(WCHAR), src, src_len);
dest->Length = dest_len;
/* append terminating NULL if enough space */
if (total < dst->MaximumLength) dst->Buffer[total / sizeof(WCHAR)] = 0;
}
if (dest_len + sizeof(WCHAR) <= dest->MaximumLength) {
dest->Buffer[dest_len / sizeof(WCHAR)] = 0;
} /* if */
} /* if */
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlAppendUnicodeStringToString (NTDLL.@)
*
* Concatenates two buffered unicode strings
*
* RETURNS
* Success: STATUS_SUCCESS. src is appended to dest.
* Failure: STATUS_BUFFER_TOO_SMALL, if the buffer of dest is to small
* to hold the concatenated string.
*
* NOTES
* if src->length is zero dest is unchanged.
* dest is '\0' terminated when the MaximumLength allowes it.
* When dest fits exactly in MaximumLength characters the '\0' is ommitted.
*
* DIFFERENCES
* Does not write in the src->Buffer beyond MaximumLength when
* MaximumLength is odd as the native function does.
*/
NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICODE_STRING *src )
NTSTATUS WINAPI RtlAppendUnicodeStringToString(
UNICODE_STRING *dest, /* [I/O] Buffered unicode string to which src is concatenated */
const UNICODE_STRING *src) /* [I] Buffered unicode string to be concatenated */
{
unsigned int len = src->Length + dst->Length;
if (src->Length == 0) return STATUS_SUCCESS;
if (len > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy( dst->Buffer + dst->Length/sizeof(WCHAR), src->Buffer, src->Length );
dst->Length = len;
/* append terminating NULL if enough space */
if (len < dst->MaximumLength) dst->Buffer[len / sizeof(WCHAR)] = 0;
if (src->Length != 0) {
unsigned int dest_len = src->Length + dest->Length;
if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy(dest->Buffer + dest->Length/sizeof(WCHAR), src->Buffer, src->Length);
dest->Length = dest_len;
/* append terminating NULL if enough space */
if (dest_len + sizeof(WCHAR) <= dest->MaximumLength) {
dest->Buffer[dest_len / sizeof(WCHAR)] = 0;
} /* if */
} /* if */
return STATUS_SUCCESS;
}
......
......@@ -2968,7 +2968,7 @@ typedef struct _LUID {
typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid;
DWORD Attributes;
} LUID_AND_ATTRIBUTES;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
#include "poppack.h"
/*
......
......@@ -903,6 +903,8 @@ NTSTATUS WINAPI RtlAppendAsciizToString(STRING *,LPCSTR);
NTSTATUS WINAPI RtlAppendStringToString(STRING *,const STRING *);
NTSTATUS WINAPI RtlAppendUnicodeStringToString(UNICODE_STRING *,const UNICODE_STRING *);
NTSTATUS WINAPI RtlAppendUnicodeToString(UNICODE_STRING *,LPCWSTR);
BOOLEAN WINAPI RtlAreAllAccessesGranted(ACCESS_MASK,ACCESS_MASK);
BOOLEAN WINAPI RtlAreAnyAccessesGranted(ACCESS_MASK,ACCESS_MASK);
BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP,ULONG,ULONG);
BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP,ULONG,ULONG);
......@@ -916,6 +918,8 @@ DWORD WINAPI RtlComputeCrc32(DWORD,PBYTE,INT);
NTSTATUS WINAPI RtlConvertSidToUnicodeString(PUNICODE_STRING,PSID,BOOLEAN);
LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG);
ULONGLONG WINAPI RtlConvertUlongToLargeInteger(ULONG);
void WINAPI RtlCopyLuid(PLUID,const LUID*);
void WINAPI RtlCopyLuidAndAttributesArray(ULONG,const LUID_AND_ATTRIBUTES*,PLUID_AND_ATTRIBUTES);
DWORD WINAPI RtlCopySid(DWORD,PSID,PSID);
void WINAPI RtlCopyString(STRING*,const STRING*);
void WINAPI RtlCopyUnicodeString(UNICODE_STRING*,const UNICODE_STRING*);
......@@ -943,6 +947,7 @@ NTSTATUS WINAPI RtlEnterCriticalSection(RTL_CRITICAL_SECTION *);
void WINAPI RtlEraseUnicodeString(UNICODE_STRING*);
NTSTATUS WINAPI RtlEqualComputerName(const UNICODE_STRING*,const UNICODE_STRING*);
NTSTATUS WINAPI RtlEqualDomainName(const UNICODE_STRING*,const UNICODE_STRING*);
BOOLEAN WINAPI RtlEqualLuid(const LUID*,const LUID*);
BOOL WINAPI RtlEqualPrefixSid(PSID,PSID);
BOOL WINAPI RtlEqualSid(PSID,PSID);
BOOLEAN WINAPI RtlEqualString(const STRING*,const STRING*,BOOLEAN);
......@@ -1019,6 +1024,7 @@ NTSTATUS WINAPI RtlLocalTimeToSystemTime(const LARGE_INTEGER*,PLARGE_INTEGER);
BOOLEAN WINAPI RtlLockHeap(HANDLE);
NTSTATUS WINAPI RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
void WINAPI RtlMapGenericMask(PACCESS_MASK,const GENERIC_MAPPING*);
NTSTATUS WINAPI RtlMultiByteToUnicodeN(LPWSTR,DWORD,LPDWORD,LPCSTR,DWORD);
NTSTATUS WINAPI RtlMultiByteToUnicodeSize(DWORD*,LPCSTR,UINT);
......@@ -1038,8 +1044,10 @@ BOOLEAN WINAPI RtlPrefixUnicodeString(const UNICODE_STRING*,const UNICODE_STRI
DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD,PUNICODE_STRING,PUNICODE_STRING) ;
NTSTATUS WINAPI RtlQueryTimeZoneInformation(LPTIME_ZONE_INFORMATION);
void WINAPI RtlRaiseException(PEXCEPTION_RECORD);
void WINAPI RtlRaiseStatus(NTSTATUS);
ULONG WINAPI RtlRandom(PULONG);
PVOID WINAPI RtlReAllocateHeap(HANDLE,ULONG,PVOID,ULONG);
void WINAPI RtlReleasePebLock(void);
void WINAPI RtlReleaseResource(LPRTL_RWLOCK);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment