Fixed RtlIsTextUnicode prototype, and made it properly take into
account the results of the tests to determine the return value.
diff --git a/dlls/advapi32/advapi.c b/dlls/advapi32/advapi.c
index 04c8827..f6d10ce 100644
--- a/dlls/advapi32/advapi.c
+++ b/dlls/advapi32/advapi.c
@@ -30,6 +30,7 @@
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
+#include "winternl.h"
#include "winerror.h"
#include "wine/library.h"
@@ -132,6 +133,23 @@
return FALSE;
}
+
+/**************************************************************************
+ * IsTextUnicode (ADVAPI32.@)
+ *
+ * Attempt to guess whether a text buffer is Unicode.
+ *
+ * PARAMS
+ * buf [I] Text buffer to test
+ * len [I] Length of buf
+ * flags [O] Destination for test results
+ */
+BOOL WINAPI IsTextUnicode( LPCVOID buf, INT len, LPINT flags )
+{
+ return RtlIsTextUnicode( buf, len, flags );
+}
+
+
/******************************************************************************
* AbortSystemShutdownA [ADVAPI32.@]
*
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 821f6dd..c87979e 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -160,7 +160,7 @@
@ stdcall InitiateSystemShutdownExW(wstr wstr long long long long)
@ stub InstallApplication
@ stub IsProcessRestricted
-@ stdcall IsTextUnicode(ptr long ptr) ntdll.RtlIsTextUnicode
+@ stdcall IsTextUnicode(ptr long ptr)
@ stdcall IsTokenRestricted(long)
@ stdcall IsValidAcl(ptr)
@ stdcall IsValidSecurityDescriptor(ptr)
diff --git a/dlls/kernel/profile.c b/dlls/kernel/profile.c
index a17e1bc..b4936d5 100644
--- a/dlls/kernel/profile.c
+++ b/dlls/kernel/profile.c
@@ -282,15 +282,15 @@
static inline ENCODING PROFILE_DetectTextEncoding(const void * buffer, int * len)
{
- DWORD flags = IS_TEXT_UNICODE_SIGNATURE |
- IS_TEXT_UNICODE_REVERSE_SIGNATURE |
- IS_TEXT_UNICODE_ODD_LENGTH;
+ int flags = IS_TEXT_UNICODE_SIGNATURE |
+ IS_TEXT_UNICODE_REVERSE_SIGNATURE |
+ IS_TEXT_UNICODE_ODD_LENGTH;
if (*len >= sizeof(bom_utf8) && !memcmp(buffer, bom_utf8, sizeof(bom_utf8)))
{
*len = sizeof(bom_utf8);
return ENCODING_UTF8;
}
- RtlIsTextUnicode((void *)buffer, *len, &flags);
+ RtlIsTextUnicode(buffer, *len, &flags);
if (flags & IS_TEXT_UNICODE_SIGNATURE)
{
*len = sizeof(WCHAR);
diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c
index 7447ea1..cbe0e3c 100644
--- a/dlls/ntdll/rtlstr.c
+++ b/dlls/ntdll/rtlstr.c
@@ -1495,13 +1495,6 @@
/*
MISC
*/
-/* Tests that we currently implement */
-#define ITU_IMPLEMENTED_TESTS \
- (IS_TEXT_UNICODE_SIGNATURE | \
- IS_TEXT_UNICODE_REVERSE_SIGNATURE | \
- IS_TEXT_UNICODE_ODD_LENGTH | \
- IS_TEXT_UNICODE_STATISTICS | \
- IS_TEXT_UNICODE_NULL_BYTES)
/**************************************************************************
* RtlIsTextUnicode (NTDLL.@)
@@ -1514,59 +1507,60 @@
* pf [O] Destination for test results
*
* RETURNS
- * The length of the string if all tests were passed, 0 otherwise.
+ * TRUE if the buffer is likely Unicode, FALSE otherwise.
*
* FIXME
* Should implement more tests.
*/
-DWORD WINAPI RtlIsTextUnicode(
- LPVOID buf,
- DWORD len,
- DWORD *pf)
+BOOLEAN WINAPI RtlIsTextUnicode( LPCVOID buf, INT len, INT *pf )
{
- LPWSTR s = buf;
- DWORD flags = -1, out_flags = 0;
+ const WCHAR *s = buf;
+ int i;
+ unsigned int flags = ~0U, out_flags = 0;
- if (!len)
- goto out;
- if (pf)
- flags = *pf;
- /*
- * Apply various tests to the text string. According to the
- * docs, each test "passed" sets the corresponding flag in
- * the output flags. But some of the tests are mutually
- * exclusive, so I don't see how you could pass all tests ...
- */
+ if (len < sizeof(WCHAR))
+ {
+ /* FIXME: MSDN documents IS_TEXT_UNICODE_BUFFER_TOO_SMALL but there is no such thing... */
+ if (pf) *pf = 0;
+ return FALSE;
+ }
+ if (pf)
+ flags = *pf;
+ /*
+ * Apply various tests to the text string. According to the
+ * docs, each test "passed" sets the corresponding flag in
+ * the output flags. But some of the tests are mutually
+ * exclusive, so I don't see how you could pass all tests ...
+ */
- /* Check for an odd length ... pass if even. */
- if ((flags & IS_TEXT_UNICODE_ODD_LENGTH) && (len & 1))
- out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
+ /* Check for an odd length ... pass if even. */
+ if (len & 1) out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
- /* Check for the special byte order unicode marks. */
- if ((flags & IS_TEXT_UNICODE_SIGNATURE) && *s == 0xFEFF)
- out_flags |= IS_TEXT_UNICODE_SIGNATURE;
+ len /= sizeof(WCHAR);
+ /* Windows only checks the first 256 characters */
+ if (len > 256) len = 256;
- if ((flags & IS_TEXT_UNICODE_REVERSE_SIGNATURE) && *s == 0xFFFE)
- out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE;
+ /* Check for the special byte order unicode marks. */
+ if (*s == 0xFEFF) out_flags |= IS_TEXT_UNICODE_SIGNATURE;
+ if (*s == 0xFFFE) out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE;
/* apply some statistical analysis */
if (flags & IS_TEXT_UNICODE_STATISTICS)
{
- DWORD i, stats = 0;
+ int stats = 0;
/* FIXME: checks only for ASCII characters in the unicode stream */
- for (i = 0; i < len / sizeof(WCHAR); i++)
+ for (i = 0; i < len; i++)
{
if (s[i] <= 255) stats++;
}
- if (stats > len / sizeof(WCHAR) / 2)
+ if (stats > len / 2)
out_flags |= IS_TEXT_UNICODE_STATISTICS;
}
/* Check for unicode NULL chars */
if (flags & IS_TEXT_UNICODE_NULL_BYTES)
{
- DWORD i;
- for (i = 0; i < len / sizeof(WCHAR); i++)
+ for (i = 0; i < len; i++)
{
if (!s[i])
{
@@ -1576,16 +1570,19 @@
}
}
- /*
- * Check whether the string passed all of the tests.
- */
- flags &= ITU_IMPLEMENTED_TESTS;
- if ((out_flags & flags) != flags)
- len = 0;
-out:
- if (pf)
- *pf = out_flags;
- return len;
+ if (pf)
+ {
+ out_flags &= *pf;
+ *pf = out_flags;
+ }
+ /* check for flags that indicate it's definitely not valid Unicode */
+ if (out_flags & (IS_TEXT_UNICODE_REVERSE_MASK | IS_TEXT_UNICODE_NOT_UNICODE_MASK)) return FALSE;
+ /* now check for invalid ASCII, and assume Unicode if so */
+ if (out_flags & IS_TEXT_UNICODE_NOT_ASCII_MASK) return TRUE;
+ /* now check for Unicode flags */
+ if (out_flags & IS_TEXT_UNICODE_UNICODE_MASK) return TRUE;
+ /* no flags set */
+ return FALSE;
}
diff --git a/include/winbase.h b/include/winbase.h
index 19c2bcc..67b76d8 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1520,7 +1520,7 @@
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD);
BOOL WINAPI InitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE);
BOOL WINAPI IsSystemResumeAutomatic(void);
-BOOL WINAPI IsTextUnicode(CONST LPVOID lpBuffer, int cb, LPINT lpi);
+BOOL WINAPI IsTextUnicode(LPCVOID,INT,LPINT);
BOOL WINAPI IsTokenRestricted(HANDLE);
BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
BOOL WINAPI IsValidSid(PSID);
diff --git a/include/winternl.h b/include/winternl.h
index 731589c..0c420bc 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1743,7 +1743,7 @@
NTSTATUS WINAPI RtlIntegerToUnicodeString(ULONG,ULONG,UNICODE_STRING *);
ULONG WINAPI RtlIsDosDeviceName_U(PCWSTR);
BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3(const UNICODE_STRING*,POEM_STRING,PBOOLEAN);
-DWORD WINAPI RtlIsTextUnicode(LPVOID,DWORD,DWORD *);
+BOOLEAN WINAPI RtlIsTextUnicode(LPCVOID,INT,INT *);
BOOLEAN WINAPI RtlIsValidHandle(const RTL_HANDLE_TABLE *, const RTL_HANDLE *);
BOOLEAN WINAPI RtlIsValidIndexHandle(const RTL_HANDLE_TABLE *, ULONG Index, RTL_HANDLE **);