Hello
Here are implementations and documentation updates of
some ntdll functions.I have tested some of the functions
a lot on w2k (see part 2: tests).
Changelog:
* include/winnt.h, include/winternl.h,
dlls/ntdll/ntdll.spec, dlls/ntdll/rtl.c,
dlls/ntdll/rtlstr.c, dlls/ntdll/large_int.c:
Thomas Mertes <thomas.mertes@gmx.at>
Implement RtlRandom, RtlAreAllAccessesGranted,
RtlAreAnyAccessesGranted, RtlCopyLuid, RtlEqualLuid,
RtlMapGenericMasc and RtlCopyLuidAndAttributesArray.
Documentation updates for RtlExtendedMagicDivide,
RtlUniform, RtlUnicodeStringToAnsiString,
RtlAppendAsciizToString, RtlAppendStringToString,
RtlAppendUnicodeToString and
RtlAppendUnicodeStringToString.
--
+++ GMX - Mail, Messaging & more http://www.gmx.net +++
Bitte lächeln! Fotogalerie online mit GMX ohne eigene Homepage!
diff -urN wine_cvs_from_20030404/dlls/ntdll/large_int.c new_wine-20030318/dlls/ntdll/large_int.c
--- wine_cvs_from_20030404/dlls/ntdll/large_int.c Thu Apr 3 21:18:27 2003
+++ new_wine-20030318/dlls/ntdll/large_int.c Sun Apr 6 22:56:30 2003
@@ -183,56 +183,57 @@
/******************************************************************************
* 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;
diff -urN wine_cvs_from_20030404/dlls/ntdll/ntdll.spec new_wine-20030318/dlls/ntdll/ntdll.spec
--- wine_cvs_from_20030404/dlls/ntdll/ntdll.spec Fri Apr 4 00:54:01 2003
+++ new_wine-20030318/dlls/ntdll/ntdll.spec Sun Apr 6 22:56:02 2003
@@ -283,8 +283,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)
@@ -295,7 +295,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
@@ -307,8 +307,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
@@ -360,7 +360,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)
@@ -458,7 +458,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)
@@ -490,7 +490,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
diff -urN wine_cvs_from_20030404/dlls/ntdll/rtl.c new_wine-20030318/dlls/ntdll/rtl.c
--- wine_cvs_from_20030404/dlls/ntdll/rtl.c Thu Apr 3 21:18:56 2003
+++ new_wine-20030318/dlls/ntdll/rtl.c Sun Apr 6 22:56:11 2003
@@ -741,24 +741,36 @@
* 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 {
@@ -766,4 +778,166 @@
} /* if */
*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,
+ PGENERIC_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, PLUID LuidSrc)
+{
+ LuidDest->HighPart = LuidSrc->HighPart;
+ LuidDest->LowPart = LuidSrc->LowPart;
+}
+
+
+/*************************************************************************
+ * RtlEqualLuid [NTDLL.@]
+ *
+ * Compares two local unique ID's.
+ *
+ * RETURNS
+ * TRUE: The two LUID's are equal.
+ * FALSE: Otherwise
+ */
+BOOLEAN WINAPI RtlEqualLuid (PLUID Luid1, PLUID Luid2)
+{
+ return (Luid1->LowPart == Luid2->LowPart &&
+ Luid1->HighPart == Luid2->HighPart) ? TRUE : FALSE;
+}
+
+
+/*************************************************************************
+ * RtlCopyLuidAndAttributesArray [NTDLL.@]
+ *
+ * Copies an array of LUID's and attributes.
+ *
+ * RETURNS
+ * Nothing.
+ */
+void WINAPI RtlCopyLuidAndAttributesArray(
+ ULONG Count,
+ PLUID_AND_ATTRIBUTES Src,
+ PLUID_AND_ATTRIBUTES Dest)
+{
+ ULONG i;
+
+ for (i = 0; i < Count; i++) {
+ RtlCopyMemory(&Dest[i], &Src[i],
+ sizeof(LUID_AND_ATTRIBUTES));
+ } /* for */
}
diff -urN wine_cvs_from_20030404/dlls/ntdll/rtlstr.c new_wine-20030318/dlls/ntdll/rtlstr.c
--- wine_cvs_from_20030404/dlls/ntdll/rtlstr.c Fri Apr 4 00:36:36 2003
+++ new_wine-20030318/dlls/ntdll/rtlstr.c Sun Apr 6 22:56:19 2003
@@ -472,13 +472,21 @@
/**************************************************************************
* 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 @@
*
* 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 @@
/**************************************************************************
- * 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 )
-{
- 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;
+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 */
+{
+ 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 )
-{
- 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;
- }
+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->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.@)
- */
-NTSTATUS WINAPI RtlAppendUnicodeToString( UNICODE_STRING *dst, LPCWSTR src )
-{
- 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;
+ *
+ * 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 *dest, /* [I/O] Buffered unicode string to which src is concatenated */
+ LPCWSTR src) /* [I] '\0' terminated unicode string to be concatenated */
+{
+ 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.@)
- */
-NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICODE_STRING *src )
-{
- 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;
+ *
+ * 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 *dest, /* [I/O] Buffered unicode string to which src is concatenated */
+ const UNICODE_STRING *src) /* [I] Buffered unicode string to be concatenated */
+{
+ 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;
}
diff -urN wine_cvs_from_20030404/include/winnt.h new_wine-20030318/include/winnt.h
--- wine_cvs_from_20030404/include/winnt.h Wed Mar 12 21:14:35 2003
+++ new_wine-20030318/include/winnt.h Sun Apr 6 22:57:16 2003
@@ -2968,7 +2968,7 @@
typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid;
DWORD Attributes;
-} LUID_AND_ATTRIBUTES;
+} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
#include "poppack.h"
/*
diff -urN wine_cvs_from_20030404/include/winternl.h new_wine-20030318/include/winternl.h
--- wine_cvs_from_20030404/include/winternl.h Wed Mar 19 01:09:57 2003
+++ new_wine-20030318/include/winternl.h Sun Apr 6 22:57:24 2003
@@ -888,6 +888,8 @@
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);
@@ -901,6 +903,8 @@
NTSTATUS WINAPI RtlConvertSidToUnicodeString(PUNICODE_STRING,PSID,BOOLEAN);
LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG);
ULONGLONG WINAPI RtlConvertUlongToLargeInteger(ULONG);
+void WINAPI RtlCopyLuid(PLUID,PLUID);
+void WINAPI RtlCopyLuidAndAttributesArray(ULONG,PLUID_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*);
@@ -918,6 +922,7 @@
HANDLE WINAPI RtlDestroyHeap(HANDLE);
BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR,PUNICODE_STRING,DWORD,DWORD);
WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR);
+NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
void WINAPI RtlDumpResource(LPRTL_RWLOCK);
LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT,INT);
@@ -927,6 +932,7 @@
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(PLUID, PLUID);
BOOL WINAPI RtlEqualPrefixSid(PSID,PSID);
BOOL WINAPI RtlEqualSid(PSID,PSID);
BOOLEAN WINAPI RtlEqualString(const STRING*,const STRING*,BOOLEAN);
@@ -1003,6 +1009,7 @@
BOOLEAN WINAPI RtlLockHeap(HANDLE);
NTSTATUS WINAPI RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
+void WINAPI RtlMapGenericMask(PACCESS_MASK,PGENERIC_MAPPING);
NTSTATUS WINAPI RtlMultiByteToUnicodeN(LPWSTR,DWORD,LPDWORD,LPCSTR,DWORD);
NTSTATUS WINAPI RtlMultiByteToUnicodeSize(DWORD*,LPCSTR,UINT);
@@ -1022,8 +1029,10 @@
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);