kernel32: Move string normalization functions to ntdll.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-11-21 10:43:46 +01:00
parent c9f15c20f9
commit fd588a22b7
8 changed files with 126 additions and 73 deletions

View File

@ -980,7 +980,7 @@
@ stdcall -import IsDebuggerPresent()
@ stub -i386 IsLSCallback
# @ stub IsNLSDefinedString
@ stdcall IsNormalizedString(long wstr long)
@ stdcall -import IsNormalizedString(long wstr long)
@ stdcall -import IsProcessInJob(long long ptr)
@ stdcall -import IsProcessorFeaturePresent(long)
@ stub -i386 IsSLCallback
@ -1105,7 +1105,7 @@
# @ stub NlsUpdateLocale
# @ stub NlsUpdateSystemLocale
# @ stub NlsWriteEtwEvent
@ stdcall NormalizeString(long wstr long ptr long)
@ stdcall -import NormalizeString(long wstr long ptr long)
# @ stub NotifyMountMgr
@ stub NotifyNLSUserCache
# @ stub NotifyUILanguageChange

View File

@ -3535,72 +3535,6 @@ BOOL WINAPI EnumSystemGeoID(GEOCLASS geoclass, GEOID parent, GEO_ENUMPROC enumpr
return TRUE;
}
/******************************************************************************
* NormalizeString (KERNEL32.@)
*/
INT WINAPI NormalizeString(NORM_FORM form, const WCHAR *src, INT src_len, WCHAR *dst, INT dst_len)
{
int flags = 0, compose = 0;
unsigned int res, buf_len;
WCHAR *buf = NULL;
TRACE("%x %s %d %p %d\n", form, debugstr_wn(src, src_len), src_len, dst, dst_len);
if (src_len == -1) src_len = strlenW(src) + 1;
if (form == NormalizationKC || form == NormalizationKD) flags |= WINE_DECOMPOSE_COMPAT;
if (form == NormalizationC || form == NormalizationKC) compose = 1;
if (compose || dst_len) flags |= WINE_DECOMPOSE_REORDER;
if (!compose && dst_len)
{
res = wine_decompose_string( flags, src, src_len, dst, dst_len );
if (!res)
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
goto done;
}
buf = dst;
}
else
{
buf_len = src_len * 4;
do
{
WCHAR *old_buf = buf;
buf = heap_realloc( buf, buf_len );
if (!buf)
{
heap_free( old_buf );
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
res = wine_decompose_string( flags, src, src_len, buf, buf_len );
buf_len *= 2;
} while (!res);
}
if (compose)
{
res = wine_compose_string( buf, res );
if (dst_len >= res) memcpy( dst, buf, res * sizeof(WCHAR) );
}
done:
if (buf != dst) heap_free( buf );
return res;
}
/******************************************************************************
* IsNormalizedString (KERNEL32.@)
*/
BOOL WINAPI IsNormalizedString(NORM_FORM NormForm, LPCWSTR lpString, INT cwLength)
{
FIXME("%x %p %d\n", NormForm, lpString, cwLength);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
enum {
BASE = 36,

View File

@ -85,6 +85,8 @@ static LANGID (WINAPI *pSetThreadUILanguage)(LANGID);
static LANGID (WINAPI *pGetThreadUILanguage)(VOID);
static INT (WINAPI *pNormalizeString)(NORM_FORM, LPCWSTR, INT, LPWSTR, INT);
static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCWSTR, INT, BOOL);
static NTSTATUS (WINAPI *pRtlNormalizeString)(ULONG, LPCWSTR, INT, LPWSTR, INT*);
static NTSTATUS (WINAPI *pRtlIsNormalizedString)(ULONG, LPCWSTR, INT, BOOLEAN*);
static void InitFunctionPointers(void)
{
@ -126,6 +128,8 @@ static void InitFunctionPointers(void)
mod = GetModuleHandleA("ntdll");
X(RtlUpcaseUnicodeChar);
X(RtlLocaleNameToLcid);
X(RtlNormalizeString);
X(RtlIsNormalizedString);
#undef X
}
@ -5838,7 +5842,6 @@ static void test_NormalizeString(void)
struct test_data_normal {
const WCHAR *str;
const WCHAR *expected[4];
BOOL todo[4];
};
static const struct test_data_normal test_arr[] =
{
@ -5869,6 +5872,7 @@ static void test_NormalizeString(void)
const struct test_data_normal *ptest = test_arr;
const int norm_forms[] = { NormalizationC, NormalizationD, NormalizationKC, NormalizationKD };
WCHAR dst[80];
NTSTATUS status;
int dstlen;
if (!pNormalizeString)
@ -5876,6 +5880,7 @@ static void test_NormalizeString(void)
win_skip("NormalizeString is not available.\n");
return;
}
if (!pRtlNormalizeString) win_skip("RtlNormalizeString is not available.\n");
dstlen = pNormalizeString( NormalizationD, ptest->str, -1, dst, 1 );
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Should have failed with ERROR_INSUFFICIENT_BUFFER\n");
@ -5899,7 +5904,6 @@ static void test_NormalizeString(void)
ok(dstlen == lstrlenW( dst )+1, "%s:%d: Copied length differed: was %d, should be %d\n",
wine_dbgstr_w(ptest->str), i, dstlen, lstrlenW( dst )+1);
str_cmp = wcsncmp( ptest->expected[i], dst, dstlen+1 );
todo_wine_if(ptest->todo[i])
ok( str_cmp == 0, "%s:%d: string incorrect got %s expect %s\n", wine_dbgstr_w(ptest->str), i,
wine_dbgstr_w(dst), wine_dbgstr_w(ptest->expected[i]) );
}
@ -5912,10 +5916,29 @@ todo_wine_if(ptest->todo[i])
ok(dstlen == lstrlenW( dst ), "%s:%d: Copied length differed: was %d, should be %d\n",
wine_dbgstr_w(ptest->str), i, dstlen, lstrlenW( dst ));
str_cmp = wcsncmp( ptest->expected[i], dst, dstlen );
todo_wine_if(ptest->todo[i])
ok( str_cmp == 0, "%s:%d: string incorrect got %s expect %s\n", wine_dbgstr_w(ptest->str), i,
wine_dbgstr_w(dst), wine_dbgstr_w(ptest->expected[i]) );
}
if (pRtlNormalizeString)
{
BOOLEAN ret = FALSE;
dstlen = 0;
status = pRtlNormalizeString( norm_forms[i], ptest->str, lstrlenW(ptest->str), NULL, &dstlen );
ok( !status, "%s:%d: failed %x\n", wine_dbgstr_w(ptest->str), i, status );
memset(dst, 0, sizeof(dst));
status = pRtlNormalizeString( norm_forms[i], ptest->str, lstrlenW(ptest->str), dst, &dstlen );
ok( !status, "%s:%d: failed %x\n", wine_dbgstr_w(ptest->str), i, status );
ok(dstlen == lstrlenW( dst ), "%s:%d: Copied length differed: was %d, should be %d\n",
wine_dbgstr_w(ptest->str), i, dstlen, lstrlenW( dst ));
str_cmp = wcsncmp( ptest->expected[i], dst, dstlen );
ok( str_cmp == 0, "%s:%d: string incorrect got %s expect %s\n", wine_dbgstr_w(ptest->str), i,
wine_dbgstr_w(dst), wine_dbgstr_w(ptest->expected[i]) );
status = pRtlIsNormalizedString( norm_forms[i], dst, dstlen, &ret );
todo_wine ok( !status, "%s:%d: failed %x\n", wine_dbgstr_w(ptest->str), i, status );
todo_wine ok( ret, "%s:%d: not normalized\n", wine_dbgstr_w(ptest->str), i );
}
}
ptest++;
}

View File

@ -862,7 +862,7 @@
# @ stub IsGlobalizationUserSettingsKeyRedirected
@ stdcall IsInternetESCEnabled()
@ stub IsNLSDefinedString
@ stdcall IsNormalizedString(long wstr long) kernel32.IsNormalizedString
@ stdcall IsNormalizedString(long wstr long)
# @ stub IsProcessCritical
@ stdcall IsProcessInJob(long long ptr)
@ stdcall IsProcessorFeaturePresent(long)
@ -972,7 +972,7 @@
@ stub NlsUpdateSystemLocale
@ stub NlsValidateLocale
@ stub NlsWriteEtwEvent
@ stdcall NormalizeString(long wstr long ptr long) kernel32.NormalizeString
@ stdcall NormalizeString(long wstr long ptr long)
@ stub NotifyMountMgr
@ stub NotifyRedirectedStringChange
@ stdcall ObjectCloseAuditAlarmW(wstr ptr long)

View File

@ -1083,6 +1083,28 @@ LANGID WINAPI DECLSPEC_HOTPATCH GetUserDefaultUILanguage(void)
}
/******************************************************************************
* IsNormalizedString (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH IsNormalizedString( NORM_FORM form, const WCHAR *str, INT len )
{
BOOLEAN res;
if (!set_ntstatus( RtlIsNormalizedString( form, str, len, &res ))) res = FALSE;
return res;
}
/******************************************************************************
* NormalizeString (kernelbase.@)
*/
INT WINAPI DECLSPEC_HOTPATCH NormalizeString(NORM_FORM form, const WCHAR *src, INT src_len,
WCHAR *dst, INT dst_len)
{
set_ntstatus( RtlNormalizeString( form, src, src_len, dst, &dst_len ));
return dst_len;
}
/******************************************************************************
* ResolveLocaleName (kernelbase.@)
*/

View File

@ -538,3 +538,73 @@ found:
TRACE( "%s -> %04x\n", debugstr_w(name), *lcid );
return STATUS_SUCCESS;
}
/******************************************************************************
* RtlIsNormalizedString (NTDLL.@)
*/
NTSTATUS WINAPI RtlIsNormalizedString( ULONG form, const WCHAR *str, INT len, BOOLEAN *res )
{
FIXME( "%x %p %d\n", form, str, len );
return STATUS_NOT_IMPLEMENTED;
}
/******************************************************************************
* RtlNormalizeString (NTDLL.@)
*/
NTSTATUS WINAPI RtlNormalizeString( ULONG form, const WCHAR *src, INT src_len, WCHAR *dst, INT *dst_len )
{
int flags = 0, compose = 0;
unsigned int res, buf_len;
WCHAR *buf = NULL;
NTSTATUS status = STATUS_SUCCESS;
TRACE( "%x %s %d %p %d\n", form, debugstr_wn(src, src_len), src_len, dst, *dst_len );
if (src_len == -1) src_len = strlenW(src) + 1;
if (form == NormalizationKC || form == NormalizationKD) flags |= WINE_DECOMPOSE_COMPAT;
if (form == NormalizationC || form == NormalizationKC) compose = 1;
if (compose || *dst_len) flags |= WINE_DECOMPOSE_REORDER;
if (!compose && *dst_len)
{
res = wine_decompose_string( flags, src, src_len, dst, *dst_len );
if (!res)
{
status = STATUS_BUFFER_TOO_SMALL;
goto done;
}
buf = dst;
}
else
{
buf_len = src_len * 4;
do
{
WCHAR *old_buf = buf;
if (!buf) buf = RtlAllocateHeap( GetProcessHeap(), 0, buf_len );
else buf = RtlReAllocateHeap( GetProcessHeap(), 0, buf, buf_len );
if (!buf)
{
RtlFreeHeap( GetProcessHeap(), 0, old_buf );
return STATUS_NO_MEMORY;
}
res = wine_decompose_string( flags, src, src_len, buf, buf_len );
buf_len *= 2;
} while (!res);
}
if (compose)
{
res = wine_compose_string( buf, res );
if (*dst_len >= res) memcpy( dst, buf, res * sizeof(WCHAR) );
}
done:
if (buf != dst) RtlFreeHeap( GetProcessHeap(), 0, buf );
*dst_len = res;
return status;
}

View File

@ -788,6 +788,7 @@
@ stub RtlIsGenericTableEmpty
# @ stub RtlIsGenericTableEmptyAvl
@ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr)
@ stdcall RtlIsNormalizedString(long wstr long ptr)
@ stdcall RtlIsProcessorFeaturePresent(long)
# @ stub RtlIsRangeAvailable
@ stdcall RtlIsTextUnicode(ptr long ptr)
@ -830,6 +831,7 @@
# @ stub RtlNewSecurityObjectEx
# @ stub RtlNewSecurityObjectWithMultipleInheritance
@ stdcall RtlNormalizeProcessParams(ptr)
@ stdcall RtlNormalizeString(long wstr long ptr ptr)
# @ stub RtlNtPathNameToDosPathName
@ stdcall RtlNtStatusToDosError(long)
@ stdcall RtlNtStatusToDosErrorNoTeb(long)

View File

@ -2769,6 +2769,7 @@ NTSYSAPI BOOL WINAPI RtlIsCriticalSectionLocked(RTL_CRITICAL_SECTION *);
NTSYSAPI BOOL WINAPI RtlIsCriticalSectionLockedByThread(RTL_CRITICAL_SECTION *);
NTSYSAPI ULONG WINAPI RtlIsDosDeviceName_U(PCWSTR);
NTSYSAPI BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3(const UNICODE_STRING*,POEM_STRING,PBOOLEAN);
NTSYSAPI NTSTATUS WINAPI RtlIsNormalizedString(ULONG,const WCHAR*,INT,BOOLEAN*);
NTSYSAPI BOOLEAN WINAPI RtlIsProcessorFeaturePresent(UINT);
NTSYSAPI BOOLEAN WINAPI RtlIsTextUnicode(LPCVOID,INT,INT *);
NTSYSAPI BOOLEAN WINAPI RtlIsValidHandle(const RTL_HANDLE_TABLE *, const RTL_HANDLE *);
@ -2787,6 +2788,7 @@ NTSYSAPI NTSTATUS WINAPI RtlMultiByteToUnicodeN(LPWSTR,DWORD,LPDWORD,LPCSTR,DWO
NTSYSAPI NTSTATUS WINAPI RtlMultiByteToUnicodeSize(DWORD*,LPCSTR,UINT);
NTSYSAPI NTSTATUS WINAPI RtlNewSecurityObject(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR*,BOOLEAN,HANDLE,PGENERIC_MAPPING);
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS WINAPI RtlNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*);
NTSYSAPI NTSTATUS WINAPI RtlNormalizeString(ULONG,const WCHAR*,INT,WCHAR*,INT*);
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS);
NTSYSAPI ULONG WINAPI RtlNtStatusToDosErrorNoTeb(NTSTATUS);
NTSYSAPI ULONG WINAPI RtlNumberOfSetBits(PCRTL_BITMAP);