2002-11-12 03:18:10 +01:00
/* Unit test suite for Rtl string functions
*
* Copyright 2002 Robert Shearman
2003-02-19 04:40:14 +01:00
* Copyright 2003 Thomas Mertes
2002-11-12 03:18:10 +01:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2002-11-12 03:18:10 +01:00
*
* NOTES
* We use function pointers here as there is no import library for NTDLL on
* windows .
*/
2003-01-16 01:11:32 +01:00
# include <stdlib.h>
2003-12-12 06:56:44 +01:00
# define INITGUID
2004-08-14 02:42:12 +02:00
# include "ntdll_test.h"
2003-01-16 01:11:32 +01:00
# include "winnls.h"
2003-12-12 06:56:44 +01:00
# include "guiddef.h"
2002-11-12 03:18:10 +01:00
2013-07-16 10:52:39 +02:00
# define HASH_STRING_ALGORITHM_X65599 1
# define HASH_STRING_ALGORITHM_INVALID 0xffffffff
2002-11-12 03:18:10 +01:00
/* Function ptrs for ntdll calls */
static HMODULE hntdll = 0 ;
2003-05-06 20:28:02 +02:00
static NTSTATUS ( WINAPI * pRtlAnsiStringToUnicodeString ) ( PUNICODE_STRING , PCANSI_STRING , BOOLEAN ) ;
2003-04-08 02:56:01 +02:00
static NTSTATUS ( WINAPI * pRtlAppendAsciizToString ) ( STRING * , LPCSTR ) ;
static NTSTATUS ( WINAPI * pRtlAppendStringToString ) ( STRING * , const STRING * ) ;
2003-03-22 01:21:35 +01:00
static NTSTATUS ( WINAPI * pRtlAppendUnicodeStringToString ) ( UNICODE_STRING * , const UNICODE_STRING * ) ;
2003-05-06 20:28:02 +02:00
static NTSTATUS ( WINAPI * pRtlAppendUnicodeToString ) ( UNICODE_STRING * , LPCWSTR ) ;
2003-10-06 23:03:32 +02:00
static NTSTATUS ( WINAPI * pRtlCharToInteger ) ( PCSZ , ULONG , int * ) ;
2003-02-19 04:40:14 +01:00
static VOID ( WINAPI * pRtlCopyString ) ( STRING * , const STRING * ) ;
static BOOLEAN ( WINAPI * pRtlCreateUnicodeString ) ( PUNICODE_STRING , LPCWSTR ) ;
2003-05-06 20:28:02 +02:00
static BOOLEAN ( WINAPI * pRtlCreateUnicodeStringFromAsciiz ) ( PUNICODE_STRING , LPCSTR ) ;
2003-03-22 01:21:35 +01:00
static NTSTATUS ( WINAPI * pRtlDowncaseUnicodeString ) ( UNICODE_STRING * , const UNICODE_STRING * , BOOLEAN ) ;
2010-04-21 11:00:26 +02:00
static NTSTATUS ( WINAPI * pRtlDuplicateUnicodeString ) ( int , UNICODE_STRING * , UNICODE_STRING * ) ;
2003-02-19 04:40:14 +01:00
static BOOLEAN ( WINAPI * pRtlEqualUnicodeString ) ( const UNICODE_STRING * , const UNICODE_STRING * , BOOLEAN ) ;
2003-05-06 20:28:02 +02:00
static NTSTATUS ( WINAPI * pRtlFindCharInUnicodeString ) ( int , const UNICODE_STRING * , const UNICODE_STRING * , USHORT * ) ;
2003-02-19 04:40:14 +01:00
static VOID ( WINAPI * pRtlFreeAnsiString ) ( PSTRING ) ;
2009-12-06 16:02:55 +01:00
static VOID ( WINAPI * pRtlFreeUnicodeString ) ( PUNICODE_STRING ) ;
2003-02-19 04:40:14 +01:00
static VOID ( WINAPI * pRtlInitAnsiString ) ( PSTRING , LPCSTR ) ;
static VOID ( WINAPI * pRtlInitString ) ( PSTRING , LPCSTR ) ;
static VOID ( WINAPI * pRtlInitUnicodeString ) ( PUNICODE_STRING , LPCWSTR ) ;
2003-05-06 20:28:02 +02:00
static NTSTATUS ( WINAPI * pRtlInitUnicodeStringEx ) ( PUNICODE_STRING , LPCWSTR ) ;
2003-02-19 04:40:14 +01:00
static NTSTATUS ( WINAPI * pRtlIntegerToChar ) ( ULONG , ULONG , ULONG , PCHAR ) ;
static NTSTATUS ( WINAPI * pRtlIntegerToUnicodeString ) ( ULONG , ULONG , UNICODE_STRING * ) ;
2010-04-21 11:00:26 +02:00
static NTSTATUS ( WINAPI * pRtlMultiAppendUnicodeStringBuffer ) ( UNICODE_STRING * , LONG , UNICODE_STRING * ) ;
2003-02-19 04:40:14 +01:00
static NTSTATUS ( WINAPI * pRtlUnicodeStringToAnsiString ) ( STRING * , const UNICODE_STRING * , BOOLEAN ) ;
static NTSTATUS ( WINAPI * pRtlUnicodeStringToInteger ) ( const UNICODE_STRING * , int , int * ) ;
static WCHAR ( WINAPI * pRtlUpcaseUnicodeChar ) ( WCHAR ) ;
static NTSTATUS ( WINAPI * pRtlUpcaseUnicodeString ) ( UNICODE_STRING * , const UNICODE_STRING * , BOOLEAN ) ;
static CHAR ( WINAPI * pRtlUpperChar ) ( CHAR ) ;
static NTSTATUS ( WINAPI * pRtlUpperString ) ( STRING * , const STRING * ) ;
2010-04-21 11:00:26 +02:00
static NTSTATUS ( WINAPI * pRtlValidateUnicodeString ) ( LONG , UNICODE_STRING * ) ;
2003-12-12 06:56:44 +01:00
static NTSTATUS ( WINAPI * pRtlGUIDFromString ) ( const UNICODE_STRING * , GUID * ) ;
static NTSTATUS ( WINAPI * pRtlStringFromGUID ) ( const GUID * , UNICODE_STRING * ) ;
2007-10-17 02:35:02 +02:00
static BOOLEAN ( WINAPI * pRtlIsTextUnicode ) ( LPVOID , INT , INT * ) ;
2013-07-16 10:52:39 +02:00
static NTSTATUS ( WINAPI * pRtlHashUnicodeString ) ( PCUNICODE_STRING , BOOLEAN , ULONG , ULONG * ) ;
2014-03-29 16:14:23 +01:00
static NTSTATUS ( WINAPI * pRtlUnicodeToUTF8N ) ( CHAR * , ULONG , ULONG * , const WCHAR * , ULONG ) ;
2014-03-29 16:25:25 +01:00
static NTSTATUS ( WINAPI * pRtlUTF8ToUnicodeN ) ( WCHAR * , ULONG , ULONG * , const CHAR * , ULONG ) ;
2003-02-19 04:40:14 +01:00
2002-12-19 22:15:41 +01:00
/*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/
/*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/
/*static VOID (WINAPI *pRtlEraseUnicodeString)(UNICODE_STRING *);*/
/*static LONG (WINAPI *pRtlCompareString)(const STRING *,const STRING *,BOOLEAN);*/
/*static LONG (WINAPI *pRtlCompareUnicodeString)(const UNICODE_STRING *,const UNICODE_STRING *,BOOLEAN);*/
/*static BOOLEAN (WINAPI *pRtlEqualString)(const STRING *,const STRING *,BOOLEAN);*/
/*static BOOLEAN (WINAPI *pRtlPrefixString)(const STRING *, const STRING *, BOOLEAN);*/
/*static BOOLEAN (WINAPI *pRtlPrefixUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);*/
/*static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(PUNICODE_STRING, const STRING *, BOOLEAN);*/
/*static NTSTATUS (WINAPI *pRtlUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
/*static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/
/*static NTSTATUS (WINAPI *pRtlOemToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/
/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToMultiByteN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/
/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToOemN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/
/*static UINT (WINAPI *pRtlOemToUnicodeSize)(const STRING *);*/
/*static DWORD (WINAPI *pRtlAnsiStringToUnicodeSize)(const STRING *);*/
2003-02-19 04:40:14 +01:00
2002-11-12 03:18:10 +01:00
2003-10-04 05:04:45 +02:00
static WCHAR * AtoW ( const char * p )
2003-01-16 01:11:32 +01:00
{
WCHAR * buffer ;
DWORD len = MultiByteToWideChar ( CP_ACP , 0 , p , - 1 , NULL , 0 ) ;
2009-05-13 10:32:38 +02:00
buffer = HeapAlloc ( GetProcessHeap ( ) , 0 , len * sizeof ( WCHAR ) ) ;
2003-01-16 01:11:32 +01:00
MultiByteToWideChar ( CP_ACP , 0 , p , - 1 , buffer , len ) ;
return buffer ;
}
2003-02-19 04:40:14 +01:00
static void InitFunctionPtrs ( void )
2002-11-12 03:18:10 +01:00
{
2003-02-19 04:40:14 +01:00
hntdll = LoadLibraryA ( " ntdll.dll " ) ;
2004-02-07 02:03:17 +01:00
ok ( hntdll ! = 0 , " LoadLibrary failed \n " ) ;
2003-02-19 04:40:14 +01:00
if ( hntdll ) {
2003-05-06 20:28:02 +02:00
pRtlAnsiStringToUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlAnsiStringToUnicodeString " ) ;
2003-04-08 02:56:01 +02:00
pRtlAppendAsciizToString = ( void * ) GetProcAddress ( hntdll , " RtlAppendAsciizToString " ) ;
pRtlAppendStringToString = ( void * ) GetProcAddress ( hntdll , " RtlAppendStringToString " ) ;
2003-03-22 01:21:35 +01:00
pRtlAppendUnicodeStringToString = ( void * ) GetProcAddress ( hntdll , " RtlAppendUnicodeStringToString " ) ;
2003-05-06 20:28:02 +02:00
pRtlAppendUnicodeToString = ( void * ) GetProcAddress ( hntdll , " RtlAppendUnicodeToString " ) ;
2003-02-19 04:40:14 +01:00
pRtlCharToInteger = ( void * ) GetProcAddress ( hntdll , " RtlCharToInteger " ) ;
pRtlCopyString = ( void * ) GetProcAddress ( hntdll , " RtlCopyString " ) ;
pRtlCreateUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlCreateUnicodeString " ) ;
2003-05-06 20:28:02 +02:00
pRtlCreateUnicodeStringFromAsciiz = ( void * ) GetProcAddress ( hntdll , " RtlCreateUnicodeStringFromAsciiz " ) ;
2003-03-22 01:21:35 +01:00
pRtlDowncaseUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlDowncaseUnicodeString " ) ;
2003-05-06 20:28:02 +02:00
pRtlDuplicateUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlDuplicateUnicodeString " ) ;
2003-02-19 04:40:14 +01:00
pRtlEqualUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlEqualUnicodeString " ) ;
2003-05-06 20:28:02 +02:00
pRtlFindCharInUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlFindCharInUnicodeString " ) ;
2003-02-19 04:40:14 +01:00
pRtlFreeAnsiString = ( void * ) GetProcAddress ( hntdll , " RtlFreeAnsiString " ) ;
2009-12-06 16:02:55 +01:00
pRtlFreeUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlFreeUnicodeString " ) ;
2002-11-12 03:18:10 +01:00
pRtlInitAnsiString = ( void * ) GetProcAddress ( hntdll , " RtlInitAnsiString " ) ;
pRtlInitString = ( void * ) GetProcAddress ( hntdll , " RtlInitString " ) ;
pRtlInitUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlInitUnicodeString " ) ;
2003-05-06 20:28:02 +02:00
pRtlInitUnicodeStringEx = ( void * ) GetProcAddress ( hntdll , " RtlInitUnicodeStringEx " ) ;
2003-02-19 04:40:14 +01:00
pRtlIntegerToChar = ( void * ) GetProcAddress ( hntdll , " RtlIntegerToChar " ) ;
pRtlIntegerToUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlIntegerToUnicodeString " ) ;
2003-05-06 20:28:02 +02:00
pRtlMultiAppendUnicodeStringBuffer = ( void * ) GetProcAddress ( hntdll , " RtlMultiAppendUnicodeStringBuffer " ) ;
2003-02-19 04:40:14 +01:00
pRtlUnicodeStringToAnsiString = ( void * ) GetProcAddress ( hntdll , " RtlUnicodeStringToAnsiString " ) ;
2002-11-12 03:18:10 +01:00
pRtlUnicodeStringToInteger = ( void * ) GetProcAddress ( hntdll , " RtlUnicodeStringToInteger " ) ;
2003-02-19 04:40:14 +01:00
pRtlUpcaseUnicodeChar = ( void * ) GetProcAddress ( hntdll , " RtlUpcaseUnicodeChar " ) ;
pRtlUpcaseUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlUpcaseUnicodeString " ) ;
pRtlUpperChar = ( void * ) GetProcAddress ( hntdll , " RtlUpperChar " ) ;
pRtlUpperString = ( void * ) GetProcAddress ( hntdll , " RtlUpperString " ) ;
2003-05-06 20:28:02 +02:00
pRtlValidateUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlValidateUnicodeString " ) ;
2003-12-12 06:56:44 +01:00
pRtlGUIDFromString = ( void * ) GetProcAddress ( hntdll , " RtlGUIDFromString " ) ;
pRtlStringFromGUID = ( void * ) GetProcAddress ( hntdll , " RtlStringFromGUID " ) ;
2007-10-17 02:35:02 +02:00
pRtlIsTextUnicode = ( void * ) GetProcAddress ( hntdll , " RtlIsTextUnicode " ) ;
2013-07-16 10:52:39 +02:00
pRtlHashUnicodeString = ( void * ) GetProcAddress ( hntdll , " RtlHashUnicodeString " ) ;
2014-03-29 16:14:23 +01:00
pRtlUnicodeToUTF8N = ( void * ) GetProcAddress ( hntdll , " RtlUnicodeToUTF8N " ) ;
2014-03-29 16:25:25 +01:00
pRtlUTF8ToUnicodeN = ( void * ) GetProcAddress ( hntdll , " RtlUTF8ToUnicodeN " ) ;
2005-06-13 12:03:33 +02:00
}
2002-11-12 03:18:10 +01:00
}
static void test_RtlInitString ( void )
{
2003-04-08 02:56:01 +02:00
static const char teststring [ ] = " Some Wild String " ;
STRING str ;
str . Length = 0 ;
str . MaximumLength = 0 ;
str . Buffer = ( void * ) 0xdeadbeef ;
pRtlInitString ( & str , teststring ) ;
2004-02-07 02:03:17 +01:00
ok ( str . Length = = sizeof ( teststring ) - sizeof ( char ) , " Length uninitialized \n " ) ;
ok ( str . MaximumLength = = sizeof ( teststring ) , " MaximumLength uninitialized \n " ) ;
ok ( str . Buffer = = teststring , " Buffer not equal to teststring \n " ) ;
ok ( strcmp ( str . Buffer , " Some Wild String " ) = = 0 , " Buffer written to \n " ) ;
2003-04-08 02:56:01 +02:00
pRtlInitString ( & str , NULL ) ;
2004-02-07 02:03:17 +01:00
ok ( str . Length = = 0 , " Length uninitialized \n " ) ;
ok ( str . MaximumLength = = 0 , " MaximumLength uninitialized \n " ) ;
ok ( str . Buffer = = NULL , " Buffer not equal to NULL \n " ) ;
2003-04-08 02:56:01 +02:00
/* pRtlInitString(NULL, teststring); */
2002-11-12 03:18:10 +01:00
}
2003-02-19 04:40:14 +01:00
2002-11-12 03:18:10 +01:00
static void test_RtlInitUnicodeString ( void )
{
# define STRINGW {'S','o','m','e',' ','W','i','l','d',' ','S','t','r','i','n','g',0}
static const WCHAR teststring [ ] = STRINGW ;
2003-04-08 02:56:01 +02:00
static const WCHAR originalstring [ ] = STRINGW ;
2002-11-12 03:18:10 +01:00
# undef STRINGW
2003-04-08 02:56:01 +02:00
UNICODE_STRING uni ;
uni . Length = 0 ;
uni . MaximumLength = 0 ;
uni . Buffer = ( void * ) 0xdeadbeef ;
pRtlInitUnicodeString ( & uni , teststring ) ;
2004-02-07 02:03:17 +01:00
ok ( uni . Length = = sizeof ( teststring ) - sizeof ( WCHAR ) , " Length uninitialized \n " ) ;
ok ( uni . MaximumLength = = sizeof ( teststring ) , " MaximumLength uninitialized \n " ) ;
ok ( uni . Buffer = = teststring , " Buffer not equal to teststring \n " ) ;
ok ( lstrcmpW ( uni . Buffer , originalstring ) = = 0 , " Buffer written to \n " ) ;
2003-04-08 02:56:01 +02:00
pRtlInitUnicodeString ( & uni , NULL ) ;
2004-02-07 02:03:17 +01:00
ok ( uni . Length = = 0 , " Length uninitialized \n " ) ;
ok ( uni . MaximumLength = = 0 , " MaximumLength uninitialized \n " ) ;
ok ( uni . Buffer = = NULL , " Buffer not equal to NULL \n " ) ;
2003-04-08 02:56:01 +02:00
/* pRtlInitUnicodeString(NULL, teststring); */
2002-11-12 03:18:10 +01:00
}
2003-02-19 04:40:14 +01:00
2003-05-06 20:28:02 +02:00
# define TESTSTRING2_LEN 1000000
/* #define TESTSTRING2_LEN 32766 */
static void test_RtlInitUnicodeStringEx ( void )
{
2004-04-20 03:12:17 +02:00
static const WCHAR teststring [ ] = { ' S ' , ' o ' , ' m ' , ' e ' , ' ' , ' W ' , ' i ' , ' l ' , ' d ' , ' ' , ' S ' , ' t ' , ' r ' , ' i ' , ' n ' , ' g ' , 0 } ;
2003-05-06 20:28:02 +02:00
WCHAR * teststring2 ;
UNICODE_STRING uni ;
NTSTATUS result ;
2013-07-22 11:02:04 +02:00
if ( ! pRtlInitUnicodeStringEx )
{
win_skip ( " RtlInitUnicodeStringEx is not available \n " ) ;
return ;
}
2009-05-13 10:32:38 +02:00
teststring2 = HeapAlloc ( GetProcessHeap ( ) , 0 , ( TESTSTRING2_LEN + 1 ) * sizeof ( WCHAR ) ) ;
2003-05-06 20:28:02 +02:00
memset ( teststring2 , ' X ' , TESTSTRING2_LEN * sizeof ( WCHAR ) ) ;
teststring2 [ TESTSTRING2_LEN ] = ' \0 ' ;
uni . Length = 12345 ;
uni . MaximumLength = 12345 ;
uni . Buffer = ( void * ) 0xdeadbeef ;
result = pRtlInitUnicodeStringEx ( & uni , teststring ) ;
ok ( result = = STATUS_SUCCESS ,
2006-10-13 23:33:02 +02:00
" pRtlInitUnicodeStringEx(&uni, 0) returns %x, expected 0 \n " ,
2005-11-28 17:32:54 +01:00
result ) ;
2003-05-06 20:28:02 +02:00
ok ( uni . Length = = 32 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . Length , 32 ) ;
ok ( uni . MaximumLength = = 34 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . MaximumLength , 34 ) ;
ok ( uni . Buffer = = teststring ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p \n " ,
2003-05-06 20:28:02 +02:00
uni . Buffer , teststring ) ;
uni . Length = 12345 ;
uni . MaximumLength = 12345 ;
uni . Buffer = ( void * ) 0xdeadbeef ;
pRtlInitUnicodeString ( & uni , teststring ) ;
ok ( uni . Length = = 32 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . Length , 32 ) ;
ok ( uni . MaximumLength = = 34 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . MaximumLength , 34 ) ;
ok ( uni . Buffer = = teststring ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p \n " ,
2003-05-06 20:28:02 +02:00
uni . Buffer , teststring ) ;
uni . Length = 12345 ;
uni . MaximumLength = 12345 ;
uni . Buffer = ( void * ) 0xdeadbeef ;
result = pRtlInitUnicodeStringEx ( & uni , teststring2 ) ;
ok ( result = = STATUS_NAME_TOO_LONG ,
2006-10-13 23:33:02 +02:00
" pRtlInitUnicodeStringEx(&uni, 0) returns %x, expected %x \n " ,
2003-05-06 20:28:02 +02:00
result , STATUS_NAME_TOO_LONG ) ;
2008-05-14 21:34:35 +02:00
ok ( uni . Length = = 12345 | |
uni . Length = = 0 , /* win2k3 */
" pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected 12345 or 0 \n " ,
uni . Length ) ;
ok ( uni . MaximumLength = = 12345 | |
uni . MaximumLength = = 0 , /* win2k3 */
" pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected 12345 or 0 \n " ,
uni . MaximumLength ) ;
ok ( uni . Buffer = = ( void * ) 0xdeadbeef | |
uni . Buffer = = teststring2 , /* win2k3 */
" pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %x or %p \n " ,
uni . Buffer , 0xdeadbeef , teststring2 ) ;
2003-05-06 20:28:02 +02:00
uni . Length = 12345 ;
uni . MaximumLength = 12345 ;
uni . Buffer = ( void * ) 0xdeadbeef ;
pRtlInitUnicodeString ( & uni , teststring2 ) ;
2007-01-04 17:55:58 +01:00
ok ( uni . Length = = 33920 /* <= Win2000 */ | | uni . Length = = 65532 /* >= Win XP */ ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u \n " ,
2007-01-04 17:55:58 +01:00
uni . Length , 65532 ) ;
ok ( uni . MaximumLength = = 33922 /* <= Win2000 */ | | uni . MaximumLength = = 65534 /* >= Win XP */ ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u \n " ,
2007-01-04 17:55:58 +01:00
uni . MaximumLength , 65534 ) ;
2003-05-06 20:28:02 +02:00
ok ( uni . Buffer = = teststring2 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p \n " ,
2003-05-06 20:28:02 +02:00
uni . Buffer , teststring2 ) ;
ok ( memcmp ( uni . Buffer , teststring2 , ( TESTSTRING2_LEN + 1 ) * sizeof ( WCHAR ) ) = = 0 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) changes Buffer \n " ) ;
2003-05-06 20:28:02 +02:00
uni . Length = 12345 ;
uni . MaximumLength = 12345 ;
uni . Buffer = ( void * ) 0xdeadbeef ;
result = pRtlInitUnicodeStringEx ( & uni , 0 ) ;
ok ( result = = STATUS_SUCCESS ,
2006-10-13 23:33:02 +02:00
" pRtlInitUnicodeStringEx(&uni, 0) returns %x, expected 0 \n " ,
2005-11-28 17:32:54 +01:00
result ) ;
2003-05-06 20:28:02 +02:00
ok ( uni . Length = = 0 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . Length , 0 ) ;
ok ( uni . MaximumLength = = 0 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . MaximumLength , 0 ) ;
ok ( uni . Buffer = = NULL ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p \n " ,
2003-05-06 20:28:02 +02:00
uni . Buffer , NULL ) ;
uni . Length = 12345 ;
uni . MaximumLength = 12345 ;
uni . Buffer = ( void * ) 0xdeadbeef ;
pRtlInitUnicodeString ( & uni , 0 ) ;
ok ( uni . Length = = 0 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . Length , 0 ) ;
ok ( uni . MaximumLength = = 0 ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u \n " ,
2003-05-06 20:28:02 +02:00
uni . MaximumLength , 0 ) ;
ok ( uni . Buffer = = NULL ,
2004-02-07 02:03:17 +01:00
" pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p \n " ,
2003-05-06 20:28:02 +02:00
uni . Buffer , NULL ) ;
2007-10-20 21:38:35 +02:00
2009-05-13 10:32:38 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , teststring2 ) ;
2003-05-06 20:28:02 +02:00
}
typedef struct {
int add_nul ;
int source_Length ;
int source_MaximumLength ;
int source_buf_size ;
2003-10-04 05:04:45 +02:00
const char * source_buf ;
2003-05-06 20:28:02 +02:00
int dest_Length ;
int dest_MaximumLength ;
int dest_buf_size ;
2003-10-04 05:04:45 +02:00
const char * dest_buf ;
2003-05-06 20:28:02 +02:00
int res_Length ;
int res_MaximumLength ;
int res_buf_size ;
2003-10-04 05:04:45 +02:00
const char * res_buf ;
2003-05-06 20:28:02 +02:00
NTSTATUS result ;
} dupl_ustr_t ;
static const dupl_ustr_t dupl_ustr [ ] = {
{ 0 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 32 , 32 , 32 , " This is a string " , STATUS_SUCCESS } ,
{ 0 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 32 , 32 , 32 , " This is a string " , STATUS_SUCCESS } ,
{ 0 , 32 , 30 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 0 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , NULL , 32 , 32 , 32 , " This is a string " , STATUS_SUCCESS } ,
{ 0 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , NULL , 32 , 32 , 32 , " This is a string " , STATUS_SUCCESS } ,
{ 0 , 32 , 30 , 34 , " This is a string " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 1 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 1 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 1 , 32 , 30 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 1 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , NULL , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 1 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , NULL , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 1 , 32 , 30 , 34 , " This is a string " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 2 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 2 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 2 , 32 , 30 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 2 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 2 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 2 , 32 , 30 , 34 , " This is a string " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 3 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 3 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 3 , 32 , 30 , 32 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 3 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , NULL , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 3 , 32 , 32 , 32 , " This is a string " , 40 , 42 , 42 , NULL , 32 , 34 , 34 , " This is a string " , STATUS_SUCCESS } ,
{ 3 , 32 , 30 , 32 , " This is a string " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 4 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 5 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 6 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 7 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 8 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 9 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 10 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 11 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 12 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 13 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 14 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 15 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 16 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ - 1 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ - 5 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ - 9 , 32 , 34 , 34 , " This is a string " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 0 , 0 , 2 , 2 , " " , 40 , 42 , 42 , " -------------------- " , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 0 , 0 , 0 , 0 , " " , 40 , 42 , 42 , " -------------------- " , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 0 , 0 , 2 , 2 , " " , 40 , 42 , 42 , NULL , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 0 , 0 , 0 , 0 , " " , 40 , 42 , 42 , NULL , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 0 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 0 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , " -------------------- " , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 0 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 0 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , NULL , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 1 , 0 , 2 , 2 , " " , 40 , 42 , 42 , " -------------------- " , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 1 , 0 , 0 , 0 , " " , 40 , 42 , 42 , " -------------------- " , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 1 , 0 , 2 , 2 , " " , 40 , 42 , 42 , NULL , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 1 , 0 , 0 , 0 , " " , 40 , 42 , 42 , NULL , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 1 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 1 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , " -------------------- " , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 1 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 1 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , NULL , 0 , 0 , 0 , NULL , STATUS_SUCCESS } ,
{ 2 , 0 , 2 , 2 , " " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 2 , 0 , 0 , 0 , " " , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 2 , 0 , 2 , 2 , " " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 2 , 0 , 0 , 0 , " " , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 2 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 2 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 2 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 2 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 3 , 0 , 2 , 2 , " " , 40 , 42 , 42 , " -------------------- " , 0 , 2 , 2 , " " , STATUS_SUCCESS } ,
{ 3 , 0 , 0 , 0 , " " , 40 , 42 , 42 , " -------------------- " , 0 , 2 , 2 , " " , STATUS_SUCCESS } ,
{ 3 , 0 , 2 , 2 , " " , 40 , 42 , 42 , NULL , 0 , 2 , 2 , " " , STATUS_SUCCESS } ,
{ 3 , 0 , 0 , 0 , " " , 40 , 42 , 42 , NULL , 0 , 2 , 2 , " " , STATUS_SUCCESS } ,
{ 3 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , " -------------------- " , 40 , 42 , 42 , " -------------------- " , STATUS_INVALID_PARAMETER } ,
{ 3 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , " -------------------- " , 0 , 2 , 2 , " " , STATUS_SUCCESS } ,
{ 3 , 0 , 2 , 2 , NULL , 40 , 42 , 42 , NULL , 40 , 42 , 0 , NULL , STATUS_INVALID_PARAMETER } ,
{ 3 , 0 , 0 , 0 , NULL , 40 , 42 , 42 , NULL , 0 , 2 , 2 , " " , STATUS_SUCCESS } ,
} ;
# define NB_DUPL_USTR (sizeof(dupl_ustr) / sizeof(*dupl_ustr))
static void test_RtlDuplicateUnicodeString ( void )
{
2003-07-19 05:06:03 +02:00
size_t pos ;
2003-05-06 20:28:02 +02:00
WCHAR source_buf [ 257 ] ;
WCHAR dest_buf [ 257 ] ;
WCHAR res_buf [ 257 ] ;
UNICODE_STRING source_str ;
UNICODE_STRING dest_str ;
UNICODE_STRING res_str ;
CHAR dest_ansi_buf [ 257 ] ;
STRING dest_ansi_str ;
NTSTATUS result ;
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-05-06 20:28:02 +02:00
2013-07-22 11:02:04 +02:00
if ( ! pRtlDuplicateUnicodeString )
{
win_skip ( " RtlDuplicateUnicodeString is not available \n " ) ;
return ;
}
2003-05-06 20:28:02 +02:00
for ( test_num = 0 ; test_num < NB_DUPL_USTR ; test_num + + ) {
source_str . Length = dupl_ustr [ test_num ] . source_Length ;
source_str . MaximumLength = dupl_ustr [ test_num ] . source_MaximumLength ;
if ( dupl_ustr [ test_num ] . source_buf ! = NULL ) {
for ( pos = 0 ; pos < dupl_ustr [ test_num ] . source_buf_size / sizeof ( WCHAR ) ; pos + + ) {
source_buf [ pos ] = dupl_ustr [ test_num ] . source_buf [ pos ] ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
source_str . Buffer = source_buf ;
} else {
source_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
dest_str . Length = dupl_ustr [ test_num ] . dest_Length ;
dest_str . MaximumLength = dupl_ustr [ test_num ] . dest_MaximumLength ;
if ( dupl_ustr [ test_num ] . dest_buf ! = NULL ) {
for ( pos = 0 ; pos < dupl_ustr [ test_num ] . dest_buf_size / sizeof ( WCHAR ) ; pos + + ) {
dest_buf [ pos ] = dupl_ustr [ test_num ] . dest_buf [ pos ] ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
dest_str . Buffer = dest_buf ;
} else {
dest_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
res_str . Length = dupl_ustr [ test_num ] . res_Length ;
res_str . MaximumLength = dupl_ustr [ test_num ] . res_MaximumLength ;
if ( dupl_ustr [ test_num ] . res_buf ! = NULL ) {
for ( pos = 0 ; pos < dupl_ustr [ test_num ] . res_buf_size / sizeof ( WCHAR ) ; pos + + ) {
res_buf [ pos ] = dupl_ustr [ test_num ] . res_buf [ pos ] ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
res_str . Buffer = res_buf ;
} else {
res_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
result = pRtlDuplicateUnicodeString ( dupl_ustr [ test_num ] . add_nul , & source_str , & dest_str ) ;
dest_ansi_str . Length = dest_str . Length / sizeof ( WCHAR ) ;
dest_ansi_str . MaximumLength = dest_ansi_str . Length + 1 ;
for ( pos = 0 ; pos < dest_ansi_str . Length ; pos + + ) {
2003-09-25 22:29:40 +02:00
dest_ansi_buf [ pos ] = ( char ) dest_buf [ pos ] ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
dest_ansi_buf [ dest_ansi_str . Length ] = ' \0 ' ;
dest_ansi_str . Buffer = dest_ansi_buf ;
ok ( result = = dupl_ustr [ test_num ] . result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlDuplicateUnicodeString(%d, source, dest) has result %x, expected %x \n " ,
2003-05-06 20:28:02 +02:00
test_num , dupl_ustr [ test_num ] . add_nul , result , dupl_ustr [ test_num ] . result ) ;
ok ( dest_str . Length = = dupl_ustr [ test_num ] . res_Length ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has Length %d, expected %d \n " ,
2003-05-06 20:28:02 +02:00
test_num , dupl_ustr [ test_num ] . add_nul , dest_str . Length , dupl_ustr [ test_num ] . res_Length ) ;
ok ( dest_str . MaximumLength = = dupl_ustr [ test_num ] . res_MaximumLength ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has MaximumLength %d, expected %d \n " ,
2003-05-06 20:28:02 +02:00
test_num , dupl_ustr [ test_num ] . add_nul , dest_str . MaximumLength , dupl_ustr [ test_num ] . res_MaximumLength ) ;
if ( result = = STATUS_INVALID_PARAMETER ) {
ok ( ( dest_str . Buffer = = NULL & & res_str . Buffer = = NULL ) | |
dest_str . Buffer = = dest_buf ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlDuplicateUnicodeString(%d, source, dest) destination buffer changed %p expected %p \n " ,
2003-05-06 20:28:02 +02:00
test_num , dupl_ustr [ test_num ] . add_nul , dest_str . Buffer , dest_buf ) ;
} else {
ok ( dest_str . Buffer ! = dest_buf ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination buffer unchanged %p \n " ,
2003-05-06 20:28:02 +02:00
test_num , dupl_ustr [ test_num ] . add_nul , dest_str . Buffer ) ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
if ( dest_str . Buffer ! = NULL & & dupl_ustr [ test_num ] . res_buf ! = NULL ) {
ok ( memcmp ( dest_str . Buffer , res_str . Buffer , dupl_ustr [ test_num ] . res_buf_size ) = = 0 ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination \" %s \" expected \" %s \" \n " ,
2003-05-06 20:28:02 +02:00
test_num , dupl_ustr [ test_num ] . add_nul , dest_ansi_str . Buffer , dupl_ustr [ test_num ] . res_buf ) ;
2009-12-08 11:34:40 +01:00
if ( result = = STATUS_SUCCESS ) pRtlFreeUnicodeString ( & dest_str ) ;
2003-05-06 20:28:02 +02:00
} else {
ok ( dest_str . Buffer = = NULL & & dupl_ustr [ test_num ] . res_buf = = NULL ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination %p expected %p \n " ,
2003-05-06 20:28:02 +02:00
test_num , dupl_ustr [ test_num ] . add_nul , dest_str . Buffer , dupl_ustr [ test_num ] . res_buf ) ;
2005-06-13 12:03:33 +02:00
}
}
2003-05-06 20:28:02 +02:00
}
2002-11-12 03:18:10 +01:00
static void test_RtlCopyString ( void )
{
2003-04-08 02:56:01 +02:00
static const char teststring [ ] = " Some Wild String " ;
2004-05-05 03:38:24 +02:00
char deststring [ ] = " " ;
2003-04-08 02:56:01 +02:00
STRING str ;
STRING deststr ;
pRtlInitString ( & str , teststring ) ;
pRtlInitString ( & deststr , deststring ) ;
pRtlCopyString ( & deststr , & str ) ;
2004-02-07 02:03:17 +01:00
ok ( strncmp ( str . Buffer , deststring , str . Length ) = = 0 , " String not copied \n " ) ;
2002-11-12 03:18:10 +01:00
}
2003-02-19 04:40:14 +01:00
static void test_RtlUpperChar ( void )
{
int ch ;
int upper_ch ;
int expected_upper_ch ;
int byte_ch ;
for ( ch = - 1 ; ch < = 1024 ; ch + + ) {
upper_ch = pRtlUpperChar ( ch ) ;
byte_ch = ch & 0xff ;
if ( byte_ch > = ' a ' & & byte_ch < = ' z ' ) {
expected_upper_ch = ( CHAR ) ( byte_ch - ' a ' + ' A ' ) ;
} else {
expected_upper_ch = ( CHAR ) byte_ch ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
ok ( upper_ch = = expected_upper_ch ,
2004-02-07 02:03:17 +01:00
" RtlUpperChar('%c'[=0x%x]) has result '%c'[=0x%x], expected '%c'[=0x%x] \n " ,
2003-02-19 04:40:14 +01:00
ch , ch , upper_ch , upper_ch , expected_upper_ch , expected_upper_ch ) ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
}
static void test_RtlUpperString ( void )
{
int i ;
CHAR ch ;
CHAR upper_ch ;
char ascii_buf [ 257 ] ;
char result_buf [ 257 ] ;
char upper_buf [ 257 ] ;
STRING ascii_str ;
STRING result_str ;
STRING upper_str ;
for ( i = 0 ; i < = 255 ; i + + ) {
ch = ( CHAR ) i ;
if ( ch > = ' a ' & & ch < = ' z ' ) {
upper_ch = ch - ' a ' + ' A ' ;
} else {
upper_ch = ch ;
}
ascii_buf [ i ] = ch ;
result_buf [ i ] = ' \0 ' ;
upper_buf [ i ] = upper_ch ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
ascii_buf [ i ] = ' \0 ' ;
result_buf [ i ] = ' \0 ' ;
upper_buf [ i ] = ' \0 ' ;
ascii_str . Length = 256 ;
ascii_str . MaximumLength = 256 ;
ascii_str . Buffer = ascii_buf ;
result_str . Length = 256 ;
result_str . MaximumLength = 256 ;
result_str . Buffer = result_buf ;
upper_str . Length = 256 ;
upper_str . MaximumLength = 256 ;
upper_str . Buffer = upper_buf ;
pRtlUpperString ( & result_str , & ascii_str ) ;
ok ( memcmp ( result_str . Buffer , upper_str . Buffer , 256 ) = = 0 ,
2004-02-07 02:03:17 +01:00
" RtlUpperString does not work as expected \n " ) ;
2003-02-19 04:40:14 +01:00
}
static void test_RtlUpcaseUnicodeChar ( void )
{
int i ;
WCHAR ch ;
WCHAR upper_ch ;
WCHAR expected_upper_ch ;
for ( i = 0 ; i < = 255 ; i + + ) {
ch = ( WCHAR ) i ;
upper_ch = pRtlUpcaseUnicodeChar ( ch ) ;
if ( ch > = ' a ' & & ch < = ' z ' ) {
expected_upper_ch = ch - ' a ' + ' A ' ;
} else if ( ch > = 0xe0 & & ch < = 0xfe & & ch ! = 0xf7 ) {
expected_upper_ch = ch - 0x20 ;
} else if ( ch = = 0xff ) {
expected_upper_ch = 0x178 ;
} else {
expected_upper_ch = ch ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
ok ( upper_ch = = expected_upper_ch ,
2004-02-07 02:03:17 +01:00
" RtlUpcaseUnicodeChar('%c'[=0x%x]) has result '%c'[=0x%x], expected: '%c'[=0x%x] \n " ,
2003-02-19 04:40:14 +01:00
ch , ch , upper_ch , upper_ch , expected_upper_ch , expected_upper_ch ) ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
}
static void test_RtlUpcaseUnicodeString ( void )
{
int i ;
WCHAR ch ;
WCHAR upper_ch ;
WCHAR ascii_buf [ 257 ] ;
WCHAR result_buf [ 257 ] ;
WCHAR upper_buf [ 257 ] ;
UNICODE_STRING ascii_str ;
UNICODE_STRING result_str ;
UNICODE_STRING upper_str ;
for ( i = 0 ; i < = 255 ; i + + ) {
ch = ( WCHAR ) i ;
if ( ch > = ' a ' & & ch < = ' z ' ) {
upper_ch = ch - ' a ' + ' A ' ;
} else if ( ch > = 0xe0 & & ch < = 0xfe & & ch ! = 0xf7 ) {
upper_ch = ch - 0x20 ;
} else if ( ch = = 0xff ) {
upper_ch = 0x178 ;
} else {
upper_ch = ch ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
ascii_buf [ i ] = ch ;
result_buf [ i ] = ' \0 ' ;
upper_buf [ i ] = upper_ch ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
ascii_buf [ i ] = ' \0 ' ;
result_buf [ i ] = ' \0 ' ;
upper_buf [ i ] = ' \0 ' ;
ascii_str . Length = 512 ;
ascii_str . MaximumLength = 512 ;
ascii_str . Buffer = ascii_buf ;
result_str . Length = 512 ;
result_str . MaximumLength = 512 ;
result_str . Buffer = result_buf ;
upper_str . Length = 512 ;
upper_str . MaximumLength = 512 ;
upper_str . Buffer = upper_buf ;
pRtlUpcaseUnicodeString ( & result_str , & ascii_str , 0 ) ;
for ( i = 0 ; i < = 255 ; i + + ) {
ok ( result_str . Buffer [ i ] = = upper_str . Buffer [ i ] ,
2004-02-07 02:03:17 +01:00
" RtlUpcaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x] \n " ,
2003-02-19 04:40:14 +01:00
ascii_str . Buffer [ i ] , ascii_str . Buffer [ i ] ,
result_str . Buffer [ i ] , result_str . Buffer [ i ] ,
upper_str . Buffer [ i ] , upper_str . Buffer [ i ] ) ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
}
2003-03-22 01:21:35 +01:00
static void test_RtlDowncaseUnicodeString ( void )
{
int i ;
WCHAR ch ;
WCHAR lower_ch ;
WCHAR source_buf [ 1025 ] ;
WCHAR result_buf [ 1025 ] ;
WCHAR lower_buf [ 1025 ] ;
UNICODE_STRING source_str ;
UNICODE_STRING result_str ;
UNICODE_STRING lower_str ;
2007-02-08 17:15:50 +01:00
for ( i = 0 ; i < 1024 ; i + + ) {
2003-03-22 01:21:35 +01:00
ch = ( WCHAR ) i ;
if ( ch > = ' A ' & & ch < = ' Z ' ) {
lower_ch = ch - ' A ' + ' a ' ;
} else if ( ch > = 0xc0 & & ch < = 0xde & & ch ! = 0xd7 ) {
lower_ch = ch + 0x20 ;
} else if ( ch > = 0x391 & & ch < = 0x3ab & & ch ! = 0x3a2 ) {
lower_ch = ch + 0x20 ;
} else {
switch ( ch ) {
case 0x178 : lower_ch = 0xff ; break ;
case 0x181 : lower_ch = 0x253 ; break ;
case 0x186 : lower_ch = 0x254 ; break ;
case 0x189 : lower_ch = 0x256 ; break ;
case 0x18a : lower_ch = 0x257 ; break ;
case 0x18e : lower_ch = 0x1dd ; break ;
case 0x18f : lower_ch = 0x259 ; break ;
case 0x190 : lower_ch = 0x25b ; break ;
case 0x193 : lower_ch = 0x260 ; break ;
case 0x194 : lower_ch = 0x263 ; break ;
case 0x196 : lower_ch = 0x269 ; break ;
case 0x197 : lower_ch = 0x268 ; break ;
case 0x19c : lower_ch = 0x26f ; break ;
case 0x19d : lower_ch = 0x272 ; break ;
case 0x19f : lower_ch = 0x275 ; break ;
case 0x1a9 : lower_ch = 0x283 ; break ;
case 0x1ae : lower_ch = 0x288 ; break ;
case 0x1b1 : lower_ch = 0x28a ; break ;
case 0x1b2 : lower_ch = 0x28b ; break ;
case 0x1b7 : lower_ch = 0x292 ; break ;
case 0x1c4 : lower_ch = 0x1c6 ; break ;
case 0x1c7 : lower_ch = 0x1c9 ; break ;
case 0x1ca : lower_ch = 0x1cc ; break ;
case 0x1f1 : lower_ch = 0x1f3 ; break ;
case 0x386 : lower_ch = 0x3ac ; break ;
case 0x388 : lower_ch = 0x3ad ; break ;
case 0x389 : lower_ch = 0x3ae ; break ;
case 0x38a : lower_ch = 0x3af ; break ;
case 0x38c : lower_ch = 0x3cc ; break ;
case 0x38e : lower_ch = 0x3cd ; break ;
case 0x38f : lower_ch = 0x3ce ; break ;
default : lower_ch = ch ; break ;
} /* switch */
2005-06-13 12:03:33 +02:00
}
2003-03-22 01:21:35 +01:00
source_buf [ i ] = ch ;
result_buf [ i ] = ' \0 ' ;
lower_buf [ i ] = lower_ch ;
2005-06-13 12:03:33 +02:00
}
2003-03-22 01:21:35 +01:00
source_buf [ i ] = ' \0 ' ;
result_buf [ i ] = ' \0 ' ;
lower_buf [ i ] = ' \0 ' ;
source_str . Length = 2048 ;
source_str . MaximumLength = 2048 ;
source_str . Buffer = source_buf ;
result_str . Length = 2048 ;
result_str . MaximumLength = 2048 ;
result_str . Buffer = result_buf ;
lower_str . Length = 2048 ;
lower_str . MaximumLength = 2048 ;
lower_str . Buffer = lower_buf ;
pRtlDowncaseUnicodeString ( & result_str , & source_str , 0 ) ;
for ( i = 0 ; i < = 1024 ; i + + ) {
ok ( result_str . Buffer [ i ] = = lower_str . Buffer [ i ] | | result_str . Buffer [ i ] = = source_str . Buffer [ i ] + 1 ,
2004-02-07 02:03:17 +01:00
" RtlDowncaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x] \n " ,
2003-03-22 01:21:35 +01:00
source_str . Buffer [ i ] , source_str . Buffer [ i ] ,
result_str . Buffer [ i ] , result_str . Buffer [ i ] ,
lower_str . Buffer [ i ] , lower_str . Buffer [ i ] ) ;
2005-06-13 12:03:33 +02:00
}
2003-03-22 01:21:35 +01:00
}
2003-04-08 02:56:01 +02:00
typedef struct {
int ansi_Length ;
int ansi_MaximumLength ;
int ansi_buf_size ;
2003-10-04 05:04:45 +02:00
const char * ansi_buf ;
2003-04-08 02:56:01 +02:00
int uni_Length ;
int uni_MaximumLength ;
int uni_buf_size ;
2003-10-04 05:04:45 +02:00
const char * uni_buf ;
2003-04-08 02:56:01 +02:00
BOOLEAN doalloc ;
int res_Length ;
int res_MaximumLength ;
int res_buf_size ;
2003-10-04 05:04:45 +02:00
const char * res_buf ;
2003-04-08 02:56:01 +02:00
NTSTATUS result ;
} ustr2astr_t ;
static const ustr2astr_t ustr2astr [ ] = {
{ 10 , 12 , 12 , " ------------ " , 0 , 0 , 0 , " " , TRUE , 0 , 1 , 1 , " " , STATUS_SUCCESS } ,
{ 10 , 12 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , TRUE , 6 , 7 , 7 , " abcdef " , STATUS_SUCCESS } ,
{ 0 , 2 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , TRUE , 6 , 7 , 7 , " abcdef " , STATUS_SUCCESS } ,
{ 10 , 12 , 12 , NULL , 12 , 12 , 12 , " abcdef " , TRUE , 6 , 7 , 7 , " abcdef " , STATUS_SUCCESS } ,
{ 0 , 0 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 6 , 0 , 0 , " " , STATUS_BUFFER_OVERFLOW } ,
{ 0 , 1 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 0 , 1 , 1 , " " , STATUS_BUFFER_OVERFLOW } ,
{ 0 , 2 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 1 , 2 , 2 , " a " , STATUS_BUFFER_OVERFLOW } ,
{ 0 , 3 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 2 , 3 , 3 , " ab " , STATUS_BUFFER_OVERFLOW } ,
{ 0 , 5 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 4 , 5 , 5 , " abcd " , STATUS_BUFFER_OVERFLOW } ,
{ 8 , 5 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 4 , 5 , 5 , " abcd " , STATUS_BUFFER_OVERFLOW } ,
{ 8 , 6 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 5 , 6 , 6 , " abcde " , STATUS_BUFFER_OVERFLOW } ,
{ 8 , 7 , 12 , " ------------ " , 12 , 12 , 12 , " abcdef " , FALSE , 6 , 7 , 7 , " abcdef " , STATUS_SUCCESS } ,
{ 8 , 7 , 12 , " ------------ " , 0 , 12 , 12 , NULL , FALSE , 0 , 7 , 0 , " " , STATUS_SUCCESS } ,
2010-11-11 00:48:44 +01:00
#if 0
2011-08-03 23:50:18 +02:00
/* crashes on Japanese and Chinese XP */
2003-04-08 02:56:01 +02:00
{ 0 , 0 , 12 , NULL , 10 , 10 , 12 , NULL , FALSE , 5 , 0 , 0 , NULL , STATUS_BUFFER_OVERFLOW } ,
2010-11-11 00:48:44 +01:00
# endif
2003-04-08 02:56:01 +02:00
} ;
# define NB_USTR2ASTR (sizeof(ustr2astr) / sizeof(*ustr2astr))
2003-05-06 20:28:02 +02:00
2003-04-08 02:56:01 +02:00
static void test_RtlUnicodeStringToAnsiString ( void )
{
2003-07-19 05:06:03 +02:00
size_t pos ;
2003-04-08 02:56:01 +02:00
CHAR ansi_buf [ 257 ] ;
WCHAR uni_buf [ 257 ] ;
STRING ansi_str ;
UNICODE_STRING uni_str ;
NTSTATUS result ;
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-04-08 02:56:01 +02:00
for ( test_num = 0 ; test_num < NB_USTR2ASTR ; test_num + + ) {
ansi_str . Length = ustr2astr [ test_num ] . ansi_Length ;
ansi_str . MaximumLength = ustr2astr [ test_num ] . ansi_MaximumLength ;
if ( ustr2astr [ test_num ] . ansi_buf ! = NULL ) {
memcpy ( ansi_buf , ustr2astr [ test_num ] . ansi_buf , ustr2astr [ test_num ] . ansi_buf_size ) ;
ansi_buf [ ustr2astr [ test_num ] . ansi_buf_size ] = ' \0 ' ;
ansi_str . Buffer = ansi_buf ;
} else {
ansi_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
uni_str . Length = ustr2astr [ test_num ] . uni_Length ;
uni_str . MaximumLength = ustr2astr [ test_num ] . uni_MaximumLength ;
if ( ustr2astr [ test_num ] . uni_buf ! = NULL ) {
for ( pos = 0 ; pos < ustr2astr [ test_num ] . uni_buf_size / sizeof ( WCHAR ) ; pos + + ) {
uni_buf [ pos ] = ustr2astr [ test_num ] . uni_buf [ pos ] ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
uni_str . Buffer = uni_buf ;
} else {
uni_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
result = pRtlUnicodeStringToAnsiString ( & ansi_str , & uni_str , ustr2astr [ test_num ] . doalloc ) ;
ok ( result = = ustr2astr [ test_num ] . result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has result %x, expected %x \n " ,
2003-04-08 02:56:01 +02:00
test_num , ustr2astr [ test_num ] . doalloc , result , ustr2astr [ test_num ] . result ) ;
ok ( ansi_str . Length = = ustr2astr [ test_num ] . res_Length ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has Length %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , ustr2astr [ test_num ] . doalloc , ansi_str . Length , ustr2astr [ test_num ] . res_Length ) ;
ok ( ansi_str . MaximumLength = = ustr2astr [ test_num ] . res_MaximumLength ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has MaximumLength %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , ustr2astr [ test_num ] . doalloc , ansi_str . MaximumLength , ustr2astr [ test_num ] . res_MaximumLength ) ;
ok ( memcmp ( ansi_str . Buffer , ustr2astr [ test_num ] . res_buf , ustr2astr [ test_num ] . res_buf_size ) = = 0 ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has ansi \" %s \" expected \" %s \" \n " ,
2003-04-08 02:56:01 +02:00
test_num , ustr2astr [ test_num ] . doalloc , ansi_str . Buffer , ustr2astr [ test_num ] . res_buf ) ;
2009-12-06 16:02:55 +01:00
if ( result = = STATUS_SUCCESS & & ustr2astr [ test_num ] . doalloc )
pRtlFreeAnsiString ( & ansi_str ) ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
}
typedef struct {
int dest_Length ;
int dest_MaximumLength ;
int dest_buf_size ;
2003-10-04 05:04:45 +02:00
const char * dest_buf ;
const char * src ;
2003-04-08 02:56:01 +02:00
int res_Length ;
int res_MaximumLength ;
int res_buf_size ;
2003-10-04 05:04:45 +02:00
const char * res_buf ;
2003-04-08 02:56:01 +02:00
NTSTATUS result ;
} app_asc2str_t ;
static const app_asc2str_t app_asc2str [ ] = {
{ 5 , 12 , 15 , " TestS01234abcde " , " tring " , 10 , 12 , 15 , " TestStringabcde " , STATUS_SUCCESS } ,
{ 5 , 11 , 15 , " TestS01234abcde " , " tring " , 10 , 11 , 15 , " TestStringabcde " , STATUS_SUCCESS } ,
{ 5 , 10 , 15 , " TestS01234abcde " , " tring " , 10 , 10 , 15 , " TestStringabcde " , STATUS_SUCCESS } ,
{ 5 , 9 , 15 , " TestS01234abcde " , " tring " , 5 , 9 , 15 , " TestS01234abcde " , STATUS_BUFFER_TOO_SMALL } ,
{ 5 , 0 , 15 , " TestS01234abcde " , " tring " , 5 , 0 , 15 , " TestS01234abcde " , STATUS_BUFFER_TOO_SMALL } ,
{ 5 , 14 , 15 , " TestS01234abcde " , " tring " , 10 , 14 , 15 , " TestStringabcde " , STATUS_SUCCESS } ,
{ 5 , 14 , 15 , " TestS01234abcde " , NULL , 5 , 14 , 15 , " TestS01234abcde " , STATUS_SUCCESS } ,
{ 5 , 14 , 15 , NULL , NULL , 5 , 14 , 15 , NULL , STATUS_SUCCESS } ,
{ 5 , 12 , 15 , " Tst \0 S01234abcde " , " tr \0 i " , 7 , 12 , 15 , " Tst \0 Str234abcde " , STATUS_SUCCESS } ,
} ;
# define NB_APP_ASC2STR (sizeof(app_asc2str) / sizeof(*app_asc2str))
2003-05-06 20:28:02 +02:00
2003-04-08 02:56:01 +02:00
static void test_RtlAppendAsciizToString ( void )
{
CHAR dest_buf [ 257 ] ;
STRING dest_str ;
NTSTATUS result ;
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-04-08 02:56:01 +02:00
for ( test_num = 0 ; test_num < NB_APP_ASC2STR ; test_num + + ) {
dest_str . Length = app_asc2str [ test_num ] . dest_Length ;
dest_str . MaximumLength = app_asc2str [ test_num ] . dest_MaximumLength ;
if ( app_asc2str [ test_num ] . dest_buf ! = NULL ) {
memcpy ( dest_buf , app_asc2str [ test_num ] . dest_buf , app_asc2str [ test_num ] . dest_buf_size ) ;
dest_buf [ app_asc2str [ test_num ] . dest_buf_size ] = ' \0 ' ;
dest_str . Buffer = dest_buf ;
} else {
dest_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
result = pRtlAppendAsciizToString ( & dest_str , app_asc2str [ test_num ] . src ) ;
ok ( result = = app_asc2str [ test_num ] . result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlAppendAsciizToString(dest, src) has result %x, expected %x \n " ,
2003-04-08 02:56:01 +02:00
test_num , result , app_asc2str [ test_num ] . result ) ;
ok ( dest_str . Length = = app_asc2str [ test_num ] . res_Length ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendAsciizToString(dest, src) dest has Length %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Length , app_asc2str [ test_num ] . res_Length ) ;
ok ( dest_str . MaximumLength = = app_asc2str [ test_num ] . res_MaximumLength ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendAsciizToString(dest, src) dest has MaximumLength %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . MaximumLength , app_asc2str [ test_num ] . res_MaximumLength ) ;
if ( dest_str . Buffer = = dest_buf ) {
ok ( memcmp ( dest_buf , app_asc2str [ test_num ] . res_buf , app_asc2str [ test_num ] . res_buf_size ) = = 0 ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendAsciizToString(dest, src) has dest \" %s \" expected \" %s \" \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_buf , app_asc2str [ test_num ] . res_buf ) ;
} else {
ok ( dest_str . Buffer = = app_asc2str [ test_num ] . res_buf ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendAsciizToString(dest, src) dest has Buffer %p expected %p \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Buffer , app_asc2str [ test_num ] . res_buf ) ;
2005-06-13 12:03:33 +02:00
}
}
2003-04-08 02:56:01 +02:00
}
typedef struct {
int dest_Length ;
int dest_MaximumLength ;
int dest_buf_size ;
2003-10-04 05:04:45 +02:00
const char * dest_buf ;
2003-04-08 02:56:01 +02:00
int src_Length ;
int src_MaximumLength ;
int src_buf_size ;
2003-10-04 05:04:45 +02:00
const char * src_buf ;
2003-04-08 02:56:01 +02:00
int res_Length ;
int res_MaximumLength ;
int res_buf_size ;
2003-10-04 05:04:45 +02:00
const char * res_buf ;
2003-04-08 02:56:01 +02:00
NTSTATUS result ;
} app_str2str_t ;
static const app_str2str_t app_str2str [ ] = {
{ 5 , 12 , 15 , " TestS01234abcde " , 5 , 5 , 7 , " tringZY " , 10 , 12 , 15 , " TestStringabcde " , STATUS_SUCCESS } ,
{ 5 , 11 , 15 , " TestS01234abcde " , 5 , 5 , 7 , " tringZY " , 10 , 11 , 15 , " TestStringabcde " , STATUS_SUCCESS } ,
{ 5 , 10 , 15 , " TestS01234abcde " , 5 , 5 , 7 , " tringZY " , 10 , 10 , 15 , " TestStringabcde " , STATUS_SUCCESS } ,
{ 5 , 9 , 15 , " TestS01234abcde " , 5 , 5 , 7 , " tringZY " , 5 , 9 , 15 , " TestS01234abcde " , STATUS_BUFFER_TOO_SMALL } ,
{ 5 , 0 , 15 , " TestS01234abcde " , 0 , 0 , 7 , " tringZY " , 5 , 0 , 15 , " TestS01234abcde " , STATUS_SUCCESS } ,
{ 5 , 14 , 15 , " TestS01234abcde " , 0 , 0 , 7 , " tringZY " , 5 , 14 , 15 , " TestS01234abcde " , STATUS_SUCCESS } ,
{ 5 , 14 , 15 , " TestS01234abcde " , 0 , 0 , 7 , NULL , 5 , 14 , 15 , " TestS01234abcde " , STATUS_SUCCESS } ,
{ 5 , 14 , 15 , NULL , 0 , 0 , 7 , NULL , 5 , 14 , 15 , NULL , STATUS_SUCCESS } ,
{ 5 , 12 , 15 , " Tst \0 S01234abcde " , 4 , 4 , 7 , " tr \0 iZY " , 9 , 12 , 15 , " Tst \0 Str \0 i4abcde " , STATUS_SUCCESS } ,
} ;
# define NB_APP_STR2STR (sizeof(app_str2str) / sizeof(*app_str2str))
2003-05-06 20:28:02 +02:00
2003-04-08 02:56:01 +02:00
static void test_RtlAppendStringToString ( void )
2003-03-22 01:21:35 +01:00
{
CHAR dest_buf [ 257 ] ;
CHAR src_buf [ 257 ] ;
2003-04-08 02:56:01 +02:00
STRING dest_str ;
STRING src_str ;
NTSTATUS result ;
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-04-08 02:56:01 +02:00
for ( test_num = 0 ; test_num < NB_APP_STR2STR ; test_num + + ) {
dest_str . Length = app_str2str [ test_num ] . dest_Length ;
dest_str . MaximumLength = app_str2str [ test_num ] . dest_MaximumLength ;
if ( app_str2str [ test_num ] . dest_buf ! = NULL ) {
memcpy ( dest_buf , app_str2str [ test_num ] . dest_buf , app_str2str [ test_num ] . dest_buf_size ) ;
dest_buf [ app_str2str [ test_num ] . dest_buf_size ] = ' \0 ' ;
dest_str . Buffer = dest_buf ;
} else {
dest_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
src_str . Length = app_str2str [ test_num ] . src_Length ;
src_str . MaximumLength = app_str2str [ test_num ] . src_MaximumLength ;
if ( app_str2str [ test_num ] . src_buf ! = NULL ) {
memcpy ( src_buf , app_str2str [ test_num ] . src_buf , app_str2str [ test_num ] . src_buf_size ) ;
src_buf [ app_str2str [ test_num ] . src_buf_size ] = ' \0 ' ;
src_str . Buffer = src_buf ;
} else {
src_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
result = pRtlAppendStringToString ( & dest_str , & src_str ) ;
ok ( result = = app_str2str [ test_num ] . result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlAppendStringToString(dest, src) has result %x, expected %x \n " ,
2003-04-08 02:56:01 +02:00
test_num , result , app_str2str [ test_num ] . result ) ;
ok ( dest_str . Length = = app_str2str [ test_num ] . res_Length ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Length , app_str2str [ test_num ] . res_Length ) ;
ok ( dest_str . MaximumLength = = app_str2str [ test_num ] . res_MaximumLength ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . MaximumLength , app_str2str [ test_num ] . res_MaximumLength ) ;
if ( dest_str . Buffer = = dest_buf ) {
ok ( memcmp ( dest_buf , app_str2str [ test_num ] . res_buf , app_str2str [ test_num ] . res_buf_size ) = = 0 ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) has dest \" %s \" expected \" %s \" \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_buf , app_str2str [ test_num ] . res_buf ) ;
} else {
ok ( dest_str . Buffer = = app_str2str [ test_num ] . res_buf ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Buffer , app_str2str [ test_num ] . res_buf ) ;
2005-06-13 12:03:33 +02:00
}
}
2003-04-08 02:56:01 +02:00
}
typedef struct {
int dest_Length ;
int dest_MaximumLength ;
int dest_buf_size ;
2003-10-04 05:04:45 +02:00
const char * dest_buf ;
const char * src ;
2003-04-08 02:56:01 +02:00
int res_Length ;
int res_MaximumLength ;
int res_buf_size ;
2003-10-04 05:04:45 +02:00
const char * res_buf ;
2003-04-08 02:56:01 +02:00
NTSTATUS result ;
} app_uni2str_t ;
static const app_uni2str_t app_uni2str [ ] = {
{ 4 , 12 , 14 , " Fake0123abcdef " , " Ustr \0 " , 8 , 12 , 14 , " FakeUstr \0 \0 cdef " , STATUS_SUCCESS } ,
{ 4 , 11 , 14 , " Fake0123abcdef " , " Ustr \0 " , 8 , 11 , 14 , " FakeUstr \0 \0 cdef " , STATUS_SUCCESS } ,
{ 4 , 10 , 14 , " Fake0123abcdef " , " Ustr \0 " , 8 , 10 , 14 , " FakeUstr \0 \0 cdef " , STATUS_SUCCESS } ,
2003-07-19 05:06:03 +02:00
/* In the following test the native function writes beyond MaximumLength
2003-04-08 02:56:01 +02:00
* { 4 , 9 , 14 , " Fake0123abcdef " , " Ustr \0 " , 8 , 9 , 14 , " FakeUstrabcdef " , STATUS_SUCCESS } ,
*/
{ 4 , 8 , 14 , " Fake0123abcdef " , " Ustr \0 " , 8 , 8 , 14 , " FakeUstrabcdef " , STATUS_SUCCESS } ,
{ 4 , 7 , 14 , " Fake0123abcdef " , " Ustr \0 " , 4 , 7 , 14 , " Fake0123abcdef " , STATUS_BUFFER_TOO_SMALL } ,
{ 4 , 0 , 14 , " Fake0123abcdef " , " Ustr \0 " , 4 , 0 , 14 , " Fake0123abcdef " , STATUS_BUFFER_TOO_SMALL } ,
{ 4 , 14 , 14 , " Fake0123abcdef " , " Ustr \0 " , 8 , 14 , 14 , " FakeUstr \0 \0 cdef " , STATUS_SUCCESS } ,
{ 4 , 14 , 14 , " Fake0123abcdef " , NULL , 4 , 14 , 14 , " Fake0123abcdef " , STATUS_SUCCESS } ,
{ 4 , 14 , 14 , NULL , NULL , 4 , 14 , 14 , NULL , STATUS_SUCCESS } ,
{ 4 , 14 , 14 , " Fake0123abcdef " , " U \0 stri \0 " , 10 , 14 , 14 , " FakeU \0 stri \0 \0 ef " , STATUS_SUCCESS } ,
{ 6 , 14 , 16 , " Te \0 \0 stabcdefghij " , " St \0 \0 ri " , 8 , 14 , 16 , " Te \0 \0 stSt \0 \0 efghij " , STATUS_SUCCESS } ,
} ;
# define NB_APP_UNI2STR (sizeof(app_uni2str) / sizeof(*app_uni2str))
2003-05-06 20:28:02 +02:00
2003-04-08 02:56:01 +02:00
static void test_RtlAppendUnicodeToString ( void )
{
WCHAR dest_buf [ 257 ] ;
UNICODE_STRING dest_str ;
NTSTATUS result ;
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-04-08 02:56:01 +02:00
for ( test_num = 0 ; test_num < NB_APP_UNI2STR ; test_num + + ) {
dest_str . Length = app_uni2str [ test_num ] . dest_Length ;
dest_str . MaximumLength = app_uni2str [ test_num ] . dest_MaximumLength ;
if ( app_uni2str [ test_num ] . dest_buf ! = NULL ) {
memcpy ( dest_buf , app_uni2str [ test_num ] . dest_buf , app_uni2str [ test_num ] . dest_buf_size ) ;
dest_buf [ app_uni2str [ test_num ] . dest_buf_size / sizeof ( WCHAR ) ] = ' \0 ' ;
dest_str . Buffer = dest_buf ;
} else {
dest_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
result = pRtlAppendUnicodeToString ( & dest_str , ( LPCWSTR ) app_uni2str [ test_num ] . src ) ;
ok ( result = = app_uni2str [ test_num ] . result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlAppendUnicodeToString(dest, src) has result %x, expected %x \n " ,
2003-04-08 02:56:01 +02:00
test_num , result , app_uni2str [ test_num ] . result ) ;
ok ( dest_str . Length = = app_uni2str [ test_num ] . res_Length ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendUnicodeToString(dest, src) dest has Length %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Length , app_uni2str [ test_num ] . res_Length ) ;
ok ( dest_str . MaximumLength = = app_uni2str [ test_num ] . res_MaximumLength ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendUnicodeToString(dest, src) dest has MaximumLength %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . MaximumLength , app_uni2str [ test_num ] . res_MaximumLength ) ;
if ( dest_str . Buffer = = dest_buf ) {
ok ( memcmp ( dest_buf , app_uni2str [ test_num ] . res_buf , app_uni2str [ test_num ] . res_buf_size ) = = 0 ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendUnicodeToString(dest, src) has dest \" %s \" expected \" %s \" \n " ,
2003-04-08 02:56:01 +02:00
test_num , ( char * ) dest_buf , app_uni2str [ test_num ] . res_buf ) ;
} else {
ok ( dest_str . Buffer = = ( WCHAR * ) app_uni2str [ test_num ] . res_buf ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendUnicodeToString(dest, src) dest has Buffer %p expected %p \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Buffer , app_uni2str [ test_num ] . res_buf ) ;
2005-06-13 12:03:33 +02:00
}
}
2003-04-08 02:56:01 +02:00
}
typedef struct {
int dest_Length ;
int dest_MaximumLength ;
int dest_buf_size ;
2003-10-04 05:04:45 +02:00
const char * dest_buf ;
2003-04-08 02:56:01 +02:00
int src_Length ;
int src_MaximumLength ;
int src_buf_size ;
2003-10-04 05:04:45 +02:00
const char * src_buf ;
2003-04-08 02:56:01 +02:00
int res_Length ;
int res_MaximumLength ;
int res_buf_size ;
2003-10-04 05:04:45 +02:00
const char * res_buf ;
2003-04-08 02:56:01 +02:00
NTSTATUS result ;
} app_ustr2str_t ;
static const app_ustr2str_t app_ustr2str [ ] = {
{ 4 , 12 , 14 , " Fake0123abcdef " , 4 , 6 , 8 , " UstrZYXW " , 8 , 12 , 14 , " FakeUstr \0 \0 cdef " , STATUS_SUCCESS } ,
{ 4 , 11 , 14 , " Fake0123abcdef " , 4 , 6 , 8 , " UstrZYXW " , 8 , 11 , 14 , " FakeUstr \0 \0 cdef " , STATUS_SUCCESS } ,
{ 4 , 10 , 14 , " Fake0123abcdef " , 4 , 6 , 8 , " UstrZYXW " , 8 , 10 , 14 , " FakeUstr \0 \0 cdef " , STATUS_SUCCESS } ,
/* In the following test the native function writes beyond MaximumLength
* { 4 , 9 , 14 , " Fake0123abcdef " , 4 , 6 , 8 , " UstrZYXW " , 8 , 9 , 14 , " FakeUstrabcdef " , STATUS_SUCCESS } ,
*/
{ 4 , 8 , 14 , " Fake0123abcdef " , 4 , 6 , 8 , " UstrZYXW " , 8 , 8 , 14 , " FakeUstrabcdef " , STATUS_SUCCESS } ,
{ 4 , 7 , 14 , " Fake0123abcdef " , 4 , 6 , 8 , " UstrZYXW " , 4 , 7 , 14 , " Fake0123abcdef " , STATUS_BUFFER_TOO_SMALL } ,
{ 4 , 0 , 14 , " Fake0123abcdef " , 0 , 0 , 8 , " UstrZYXW " , 4 , 0 , 14 , " Fake0123abcdef " , STATUS_SUCCESS } ,
{ 4 , 14 , 14 , " Fake0123abcdef " , 0 , 0 , 8 , " UstrZYXW " , 4 , 14 , 14 , " Fake0123abcdef " , STATUS_SUCCESS } ,
{ 4 , 14 , 14 , " Fake0123abcdef " , 0 , 0 , 8 , NULL , 4 , 14 , 14 , " Fake0123abcdef " , STATUS_SUCCESS } ,
{ 4 , 14 , 14 , NULL , 0 , 0 , 8 , NULL , 4 , 14 , 14 , NULL , STATUS_SUCCESS } ,
{ 6 , 14 , 16 , " Te \0 \0 stabcdefghij " , 6 , 8 , 8 , " St \0 \0 riZY " , 12 , 14 , 16 , " Te \0 \0 stSt \0 \0 ri \0 \0 ij " , STATUS_SUCCESS } ,
} ;
# define NB_APP_USTR2STR (sizeof(app_ustr2str) / sizeof(*app_ustr2str))
2003-05-06 20:28:02 +02:00
2003-04-08 02:56:01 +02:00
static void test_RtlAppendUnicodeStringToString ( void )
{
WCHAR dest_buf [ 257 ] ;
WCHAR src_buf [ 257 ] ;
2003-03-22 01:21:35 +01:00
UNICODE_STRING dest_str ;
UNICODE_STRING src_str ;
NTSTATUS result ;
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-03-22 01:21:35 +01:00
2003-04-08 02:56:01 +02:00
for ( test_num = 0 ; test_num < NB_APP_USTR2STR ; test_num + + ) {
dest_str . Length = app_ustr2str [ test_num ] . dest_Length ;
dest_str . MaximumLength = app_ustr2str [ test_num ] . dest_MaximumLength ;
if ( app_ustr2str [ test_num ] . dest_buf ! = NULL ) {
memcpy ( dest_buf , app_ustr2str [ test_num ] . dest_buf , app_ustr2str [ test_num ] . dest_buf_size ) ;
dest_buf [ app_ustr2str [ test_num ] . dest_buf_size / sizeof ( WCHAR ) ] = ' \0 ' ;
dest_str . Buffer = dest_buf ;
} else {
dest_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
src_str . Length = app_ustr2str [ test_num ] . src_Length ;
src_str . MaximumLength = app_ustr2str [ test_num ] . src_MaximumLength ;
if ( app_ustr2str [ test_num ] . src_buf ! = NULL ) {
memcpy ( src_buf , app_ustr2str [ test_num ] . src_buf , app_ustr2str [ test_num ] . src_buf_size ) ;
src_buf [ app_ustr2str [ test_num ] . src_buf_size / sizeof ( WCHAR ) ] = ' \0 ' ;
src_str . Buffer = src_buf ;
} else {
src_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-04-08 02:56:01 +02:00
result = pRtlAppendUnicodeStringToString ( & dest_str , & src_str ) ;
ok ( result = = app_ustr2str [ test_num ] . result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlAppendStringToString(dest, src) has result %x, expected %x \n " ,
2003-04-08 02:56:01 +02:00
test_num , result , app_ustr2str [ test_num ] . result ) ;
ok ( dest_str . Length = = app_ustr2str [ test_num ] . res_Length ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Length , app_ustr2str [ test_num ] . res_Length ) ;
ok ( dest_str . MaximumLength = = app_ustr2str [ test_num ] . res_MaximumLength ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . MaximumLength , app_ustr2str [ test_num ] . res_MaximumLength ) ;
if ( dest_str . Buffer = = dest_buf ) {
ok ( memcmp ( dest_buf , app_ustr2str [ test_num ] . res_buf , app_ustr2str [ test_num ] . res_buf_size ) = = 0 ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) has dest \" %s \" expected \" %s \" \n " ,
2003-04-08 02:56:01 +02:00
test_num , ( char * ) dest_buf , app_ustr2str [ test_num ] . res_buf ) ;
} else {
ok ( dest_str . Buffer = = ( WCHAR * ) app_ustr2str [ test_num ] . res_buf ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p \n " ,
2003-04-08 02:56:01 +02:00
test_num , dest_str . Buffer , app_ustr2str [ test_num ] . res_buf ) ;
2005-06-13 12:03:33 +02:00
}
}
2003-03-22 01:21:35 +01:00
}
2003-05-06 20:28:02 +02:00
typedef struct {
int flags ;
2003-10-04 05:04:45 +02:00
const char * main_str ;
const char * search_chars ;
2003-05-06 20:28:02 +02:00
USHORT pos ;
NTSTATUS result ;
} find_ch_in_ustr_t ;
static const find_ch_in_ustr_t find_ch_in_ustr [ ] = {
{ 0 , " Some Wild String " , " S " , 2 , STATUS_SUCCESS } ,
{ 0 , " This is a String " , " String " , 6 , STATUS_SUCCESS } ,
{ 1 , " This is a String " , " String " , 30 , STATUS_SUCCESS } ,
{ 2 , " This is a String " , " String " , 2 , STATUS_SUCCESS } ,
{ 3 , " This is a String " , " String " , 18 , STATUS_SUCCESS } ,
{ 0 , " This is a String " , " Wild " , 6 , STATUS_SUCCESS } ,
{ 1 , " This is a String " , " Wild " , 26 , STATUS_SUCCESS } ,
{ 2 , " This is a String " , " Wild " , 2 , STATUS_SUCCESS } ,
{ 3 , " This is a String " , " Wild " , 30 , STATUS_SUCCESS } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " " , 0 , STATUS_NOT_FOUND } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " 123 " , 0 , STATUS_NOT_FOUND } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " a " , 2 , STATUS_SUCCESS } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " 12a34 " , 2 , STATUS_SUCCESS } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " 12b34 " , 4 , STATUS_SUCCESS } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " 12y34 " , 50 , STATUS_SUCCESS } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " 12z34 " , 52 , STATUS_SUCCESS } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , " rvz " , 36 , STATUS_SUCCESS } ,
{ 0 , " abcdefghijklmmlkjihgfedcba " , " egik " , 10 , STATUS_SUCCESS } ,
{ 1 , " abcdefghijklmnopqrstuvwxyz " , " " , 0 , STATUS_NOT_FOUND } ,
{ 1 , " abcdefghijklmnopqrstuvwxyz " , " rvz " , 50 , STATUS_SUCCESS } ,
{ 1 , " abcdefghijklmnopqrstuvwxyz " , " ravy " , 48 , STATUS_SUCCESS } ,
{ 1 , " abcdefghijklmnopqrstuvwxyz " , " raxv " , 46 , STATUS_SUCCESS } ,
{ 2 , " abcdefghijklmnopqrstuvwxyz " , " " , 2 , STATUS_SUCCESS } ,
{ 2 , " abcdefghijklmnopqrstuvwxyz " , " rvz " , 2 , STATUS_SUCCESS } ,
{ 2 , " abcdefghijklmnopqrstuvwxyz " , " vaz " , 4 , STATUS_SUCCESS } ,
{ 2 , " abcdefghijklmnopqrstuvwxyz " , " ravbz " , 6 , STATUS_SUCCESS } ,
{ 3 , " abcdefghijklmnopqrstuvwxyz " , " " , 50 , STATUS_SUCCESS } ,
{ 3 , " abcdefghijklmnopqrstuvwxyz " , " 123 " , 50 , STATUS_SUCCESS } ,
{ 3 , " abcdefghijklmnopqrstuvwxyz " , " ahp " , 50 , STATUS_SUCCESS } ,
{ 3 , " abcdefghijklmnopqrstuvwxyz " , " rvz " , 48 , STATUS_SUCCESS } ,
{ 0 , NULL , " abc " , 0 , STATUS_NOT_FOUND } ,
{ 1 , NULL , " abc " , 0 , STATUS_NOT_FOUND } ,
{ 2 , NULL , " abc " , 0 , STATUS_NOT_FOUND } ,
{ 3 , NULL , " abc " , 0 , STATUS_NOT_FOUND } ,
{ 0 , " abcdefghijklmnopqrstuvwxyz " , NULL , 0 , STATUS_NOT_FOUND } ,
{ 1 , " abcdefghijklmnopqrstuvwxyz " , NULL , 0 , STATUS_NOT_FOUND } ,
{ 2 , " abcdefghijklmnopqrstuvwxyz " , NULL , 2 , STATUS_SUCCESS } ,
{ 3 , " abcdefghijklmnopqrstuvwxyz " , NULL , 50 , STATUS_SUCCESS } ,
{ 0 , NULL , NULL , 0 , STATUS_NOT_FOUND } ,
{ 1 , NULL , NULL , 0 , STATUS_NOT_FOUND } ,
{ 2 , NULL , NULL , 0 , STATUS_NOT_FOUND } ,
{ 3 , NULL , NULL , 0 , STATUS_NOT_FOUND } ,
{ 0 , " abcdabcdabcdabcdabcdabcd " , " abcd " , 2 , STATUS_SUCCESS } ,
{ 1 , " abcdabcdabcdabcdabcdabcd " , " abcd " , 46 , STATUS_SUCCESS } ,
{ 2 , " abcdabcdabcdabcdabcdabcd " , " abcd " , 0 , STATUS_NOT_FOUND } ,
{ 3 , " abcdabcdabcdabcdabcdabcd " , " abcd " , 0 , STATUS_NOT_FOUND } ,
} ;
# define NB_FIND_CH_IN_USTR (sizeof(find_ch_in_ustr) / sizeof(*find_ch_in_ustr))
static void test_RtlFindCharInUnicodeString ( void )
{
WCHAR main_str_buf [ 257 ] ;
WCHAR search_chars_buf [ 257 ] ;
UNICODE_STRING main_str ;
UNICODE_STRING search_chars ;
USHORT pos ;
NTSTATUS result ;
2006-06-13 14:03:19 +02:00
unsigned int idx ;
unsigned int test_num ;
2003-05-06 20:28:02 +02:00
2013-07-22 11:02:04 +02:00
if ( ! pRtlFindCharInUnicodeString )
{
win_skip ( " RtlFindCharInUnicodeString is not available \n " ) ;
return ;
}
2003-05-06 20:28:02 +02:00
for ( test_num = 0 ; test_num < NB_FIND_CH_IN_USTR ; test_num + + ) {
if ( find_ch_in_ustr [ test_num ] . main_str ! = NULL ) {
main_str . Length = strlen ( find_ch_in_ustr [ test_num ] . main_str ) * sizeof ( WCHAR ) ;
main_str . MaximumLength = main_str . Length + sizeof ( WCHAR ) ;
for ( idx = 0 ; idx < main_str . Length / sizeof ( WCHAR ) ; idx + + ) {
main_str_buf [ idx ] = find_ch_in_ustr [ test_num ] . main_str [ idx ] ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
main_str . Buffer = main_str_buf ;
} else {
main_str . Length = 0 ;
main_str . MaximumLength = 0 ;
main_str . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
if ( find_ch_in_ustr [ test_num ] . search_chars ! = NULL ) {
search_chars . Length = strlen ( find_ch_in_ustr [ test_num ] . search_chars ) * sizeof ( WCHAR ) ;
search_chars . MaximumLength = search_chars . Length + sizeof ( WCHAR ) ;
for ( idx = 0 ; idx < search_chars . Length / sizeof ( WCHAR ) ; idx + + ) {
search_chars_buf [ idx ] = find_ch_in_ustr [ test_num ] . search_chars [ idx ] ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
search_chars . Buffer = search_chars_buf ;
} else {
search_chars . Length = 0 ;
search_chars . MaximumLength = 0 ;
search_chars . Buffer = NULL ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
pos = 12345 ;
result = pRtlFindCharInUnicodeString ( find_ch_in_ustr [ test_num ] . flags , & main_str , & search_chars , & pos ) ;
ok ( result = = find_ch_in_ustr [ test_num ] . result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) has result %x, expected %x \n " ,
2003-05-06 20:28:02 +02:00
test_num , find_ch_in_ustr [ test_num ] . flags ,
find_ch_in_ustr [ test_num ] . main_str , find_ch_in_ustr [ test_num ] . search_chars ,
result , find_ch_in_ustr [ test_num ] . result ) ;
ok ( pos = = find_ch_in_ustr [ test_num ] . pos ,
2004-02-07 02:03:17 +01:00
" (test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) assigns %d to pos, expected %d \n " ,
2003-05-06 20:28:02 +02:00
test_num , find_ch_in_ustr [ test_num ] . flags ,
find_ch_in_ustr [ test_num ] . main_str , find_ch_in_ustr [ test_num ] . search_chars ,
pos , find_ch_in_ustr [ test_num ] . pos ) ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
}
2003-01-16 01:11:32 +01:00
typedef struct {
2003-02-19 04:40:14 +01:00
int base ;
2003-10-06 23:03:32 +02:00
const char * str ;
2003-01-16 01:11:32 +01:00
int value ;
2008-08-26 11:28:31 +02:00
NTSTATUS result , alternative ;
2003-01-16 01:11:32 +01:00
} str2int_t ;
2003-02-19 04:40:14 +01:00
static const str2int_t str2int [ ] = {
{ 0 , " 1011101100 " , 1011101100 , STATUS_SUCCESS } ,
{ 0 , " 1234567 " , 1234567 , STATUS_SUCCESS } ,
{ 0 , " -214 " , - 214 , STATUS_SUCCESS } ,
{ 0 , " +214 " , 214 , STATUS_SUCCESS } , /* The + sign is allowed also */
{ 0 , " --214 " , 0 , STATUS_SUCCESS } , /* Do not accept more than one sign */
{ 0 , " -+214 " , 0 , STATUS_SUCCESS } ,
{ 0 , " ++214 " , 0 , STATUS_SUCCESS } ,
{ 0 , " +-214 " , 0 , STATUS_SUCCESS } ,
2003-03-22 01:21:35 +01:00
{ 0 , " \001 \002 \003 \004 11 " , 11 , STATUS_SUCCESS } , /* whitespace char 1 to 4 */
{ 0 , " \005 \006 \007 \010 12 " , 12 , STATUS_SUCCESS } , /* whitespace char 5 to 8 */
{ 0 , " \011 \012 \013 \014 13 " , 13 , STATUS_SUCCESS } , /* whitespace char 9 to 12 */
{ 0 , " \015 \016 \017 \020 14 " , 14 , STATUS_SUCCESS } , /* whitespace char 13 to 16 */
{ 0 , " \021 \022 \023 \024 15 " , 15 , STATUS_SUCCESS } , /* whitespace char 17 to 20 */
{ 0 , " \025 \026 \027 \030 16 " , 16 , STATUS_SUCCESS } , /* whitespace char 21 to 24 */
{ 0 , " \031 \032 \033 \034 17 " , 17 , STATUS_SUCCESS } , /* whitespace char 25 to 28 */
{ 0 , " \035 \036 \037 \040 18 " , 18 , STATUS_SUCCESS } , /* whitespace char 29 to 32 */
2003-02-19 04:40:14 +01:00
{ 0 , " \n \r \t 214 " , 214 , STATUS_SUCCESS } ,
{ 0 , " \n \r \t +214 " , 214 , STATUS_SUCCESS } , /* Signs can be used after whitespace */
{ 0 , " \n \r \t -214 " , - 214 , STATUS_SUCCESS } ,
{ 0 , " +214 0 " , 214 , STATUS_SUCCESS } , /* Space terminates the number */
{ 0 , " 214.01 " , 214 , STATUS_SUCCESS } , /* Decimal point not accepted */
{ 0 , " 214,01 " , 214 , STATUS_SUCCESS } , /* Decimal comma not accepted */
{ 0 , " f81 " , 0 , STATUS_SUCCESS } ,
{ 0 , " 0x12345 " , 0x12345 , STATUS_SUCCESS } , /* Hex */
{ 0 , " 00x12345 " , 0 , STATUS_SUCCESS } ,
{ 0 , " 0xx12345 " , 0 , STATUS_SUCCESS } ,
{ 0 , " 1x34 " , 1 , STATUS_SUCCESS } ,
{ 0 , " -9999999999 " , - 1410065407 , STATUS_SUCCESS } , /* Big negative integer */
{ 0 , " -2147483649 " , 2147483647 , STATUS_SUCCESS } , /* Too small to fit in 32 Bits */
{ 0 , " -2147483648 " , 0x80000000L , STATUS_SUCCESS } , /* Smallest negative integer */
{ 0 , " -2147483647 " , - 2147483647 , STATUS_SUCCESS } ,
{ 0 , " -1 " , - 1 , STATUS_SUCCESS } ,
{ 0 , " 0 " , 0 , STATUS_SUCCESS } ,
{ 0 , " 1 " , 1 , STATUS_SUCCESS } ,
{ 0 , " 2147483646 " , 2147483646 , STATUS_SUCCESS } ,
{ 0 , " 2147483647 " , 2147483647 , STATUS_SUCCESS } , /* Largest signed positive integer */
{ 0 , " 2147483648 " , 0x80000000L , STATUS_SUCCESS } , /* Positive int equal to smallest negative int */
{ 0 , " 2147483649 " , - 2147483647 , STATUS_SUCCESS } ,
{ 0 , " 4294967294 " , - 2 , STATUS_SUCCESS } ,
{ 0 , " 4294967295 " , - 1 , STATUS_SUCCESS } , /* Largest unsigned integer */
{ 0 , " 4294967296 " , 0 , STATUS_SUCCESS } , /* Too big to fit in 32 Bits */
{ 0 , " 9999999999 " , 1410065407 , STATUS_SUCCESS } , /* Big positive integer */
{ 0 , " 056789 " , 56789 , STATUS_SUCCESS } , /* Leading zero and still decimal */
{ 0 , " b1011101100 " , 0 , STATUS_SUCCESS } , /* Binary (b-notation) */
{ 0 , " -b1011101100 " , 0 , STATUS_SUCCESS } , /* Negative Binary (b-notation) */
{ 0 , " b10123456789 " , 0 , STATUS_SUCCESS } , /* Binary with nonbinary digits (2-9) */
{ 0 , " 0b1011101100 " , 748 , STATUS_SUCCESS } , /* Binary (0b-notation) */
{ 0 , " -0b1011101100 " , - 748 , STATUS_SUCCESS } , /* Negative binary (0b-notation) */
{ 0 , " 0b10123456789 " , 5 , STATUS_SUCCESS } , /* Binary with nonbinary digits (2-9) */
{ 0 , " -0b10123456789 " , - 5 , STATUS_SUCCESS } , /* Negative binary with nonbinary digits (2-9) */
{ 0 , " 0b1 " , 1 , STATUS_SUCCESS } , /* one digit binary */
{ 0 , " 0b2 " , 0 , STATUS_SUCCESS } , /* empty binary */
{ 0 , " 0b " , 0 , STATUS_SUCCESS } , /* empty binary */
{ 0 , " o1234567 " , 0 , STATUS_SUCCESS } , /* Octal (o-notation) */
{ 0 , " -o1234567 " , 0 , STATUS_SUCCESS } , /* Negative Octal (o-notation) */
{ 0 , " o56789 " , 0 , STATUS_SUCCESS } , /* Octal with nonoctal digits (8 and 9) */
{ 0 , " 0o1234567 " , 01234567 , STATUS_SUCCESS } , /* Octal (0o-notation) */
{ 0 , " -0o1234567 " , - 01234567 , STATUS_SUCCESS } , /* Negative octal (0o-notation) */
{ 0 , " 0o56789 " , 0567 , STATUS_SUCCESS } , /* Octal with nonoctal digits (8 and 9) */
{ 0 , " -0o56789 " , - 0567 , STATUS_SUCCESS } , /* Negative octal with nonoctal digits (8 and 9) */
{ 0 , " 0o7 " , 7 , STATUS_SUCCESS } , /* one digit octal */
{ 0 , " 0o8 " , 0 , STATUS_SUCCESS } , /* empty octal */
{ 0 , " 0o " , 0 , STATUS_SUCCESS } , /* empty octal */
2008-04-08 23:22:43 +02:00
{ 0 , " 0d1011101100 " , 0 , STATUS_SUCCESS } , /* explicit decimal with 0d */
2003-02-19 04:40:14 +01:00
{ 0 , " x89abcdef " , 0 , STATUS_SUCCESS } , /* Hex with lower case digits a-f (x-notation) */
{ 0 , " xFEDCBA00 " , 0 , STATUS_SUCCESS } , /* Hex with upper case digits A-F (x-notation) */
{ 0 , " -xFEDCBA00 " , 0 , STATUS_SUCCESS } , /* Negative Hexadecimal (x-notation) */
{ 0 , " 0x89abcdef " , 0x89abcdef , STATUS_SUCCESS } , /* Hex with lower case digits a-f (0x-notation) */
{ 0 , " 0xFEDCBA00 " , 0xFEDCBA00 , STATUS_SUCCESS } , /* Hex with upper case digits A-F (0x-notation) */
2003-09-25 22:29:40 +02:00
{ 0 , " -0xFEDCBA00 " , 19088896 , STATUS_SUCCESS } , /* Negative Hexadecimal (0x-notation) */
2003-02-19 04:40:14 +01:00
{ 0 , " 0xabcdefgh " , 0xabcdef , STATUS_SUCCESS } , /* Hex with illegal lower case digits (g-z) */
{ 0 , " 0xABCDEFGH " , 0xABCDEF , STATUS_SUCCESS } , /* Hex with illegal upper case digits (G-Z) */
{ 0 , " 0xF " , 0xf , STATUS_SUCCESS } , /* one digit hexadecimal */
{ 0 , " 0xG " , 0 , STATUS_SUCCESS } , /* empty hexadecimal */
{ 0 , " 0x " , 0 , STATUS_SUCCESS } , /* empty hexadecimal */
2008-08-26 11:28:31 +02:00
{ 0 , " " , 0 , STATUS_SUCCESS , STATUS_INVALID_PARAMETER } , /* empty string */
2003-02-19 04:40:14 +01:00
{ 2 , " 1011101100 " , 748 , STATUS_SUCCESS } ,
{ 2 , " -1011101100 " , - 748 , STATUS_SUCCESS } ,
{ 2 , " 2 " , 0 , STATUS_SUCCESS } ,
{ 2 , " 0b1011101100 " , 0 , STATUS_SUCCESS } ,
{ 2 , " 0o1011101100 " , 0 , STATUS_SUCCESS } ,
{ 2 , " 0d1011101100 " , 0 , STATUS_SUCCESS } ,
{ 2 , " 0x1011101100 " , 0 , STATUS_SUCCESS } ,
2008-08-26 11:28:31 +02:00
{ 2 , " " , 0 , STATUS_SUCCESS , STATUS_INVALID_PARAMETER } , /* empty string */
2003-02-19 04:40:14 +01:00
{ 8 , " 1011101100 " , 136610368 , STATUS_SUCCESS } ,
{ 8 , " -1011101100 " , - 136610368 , STATUS_SUCCESS } ,
{ 8 , " 8 " , 0 , STATUS_SUCCESS } ,
{ 8 , " 0b1011101100 " , 0 , STATUS_SUCCESS } ,
{ 8 , " 0o1011101100 " , 0 , STATUS_SUCCESS } ,
{ 8 , " 0d1011101100 " , 0 , STATUS_SUCCESS } ,
{ 8 , " 0x1011101100 " , 0 , STATUS_SUCCESS } ,
2008-08-26 11:28:31 +02:00
{ 8 , " " , 0 , STATUS_SUCCESS , STATUS_INVALID_PARAMETER } , /* empty string */
2003-02-19 04:40:14 +01:00
{ 10 , " 1011101100 " , 1011101100 , STATUS_SUCCESS } ,
{ 10 , " -1011101100 " , - 1011101100 , STATUS_SUCCESS } ,
{ 10 , " 0b1011101100 " , 0 , STATUS_SUCCESS } ,
{ 10 , " 0o1011101100 " , 0 , STATUS_SUCCESS } ,
{ 10 , " 0d1011101100 " , 0 , STATUS_SUCCESS } ,
{ 10 , " 0x1011101100 " , 0 , STATUS_SUCCESS } ,
2005-04-19 11:49:38 +02:00
{ 10 , " o12345 " , 0 , STATUS_SUCCESS } , /* Octal although base is 10 */
2008-08-26 11:28:31 +02:00
{ 10 , " " , 0 , STATUS_SUCCESS , STATUS_INVALID_PARAMETER } , /* empty string */
2003-02-19 04:40:14 +01:00
{ 16 , " 1011101100 " , 286265600 , STATUS_SUCCESS } ,
{ 16 , " -1011101100 " , - 286265600 , STATUS_SUCCESS } ,
{ 16 , " G " , 0 , STATUS_SUCCESS } ,
{ 16 , " g " , 0 , STATUS_SUCCESS } ,
{ 16 , " 0b1011101100 " , 286265600 , STATUS_SUCCESS } ,
{ 16 , " 0o1011101100 " , 0 , STATUS_SUCCESS } ,
{ 16 , " 0d1011101100 " , 286265600 , STATUS_SUCCESS } ,
{ 16 , " 0x1011101100 " , 0 , STATUS_SUCCESS } ,
2008-08-26 11:28:31 +02:00
{ 16 , " " , 0 , STATUS_SUCCESS , STATUS_INVALID_PARAMETER } , /* empty string */
{ 20 , " 0 " , 0 , STATUS_INVALID_PARAMETER } , /* illegal base */
{ - 8 , " 0 " , 0 , STATUS_INVALID_PARAMETER } , /* Negative base */
2003-02-19 04:40:14 +01:00
/* { 0, NULL, 0, STATUS_SUCCESS}, */ /* NULL as string */
2003-01-16 01:11:32 +01:00
} ;
2003-02-19 04:40:14 +01:00
# define NB_STR2INT (sizeof(str2int) / sizeof(*str2int))
2003-01-16 01:11:32 +01:00
2002-11-12 03:18:10 +01:00
static void test_RtlUnicodeStringToInteger ( void )
{
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-02-19 04:40:14 +01:00
int value ;
NTSTATUS result ;
WCHAR * wstr ;
2003-04-08 02:56:01 +02:00
UNICODE_STRING uni ;
2003-01-16 01:11:32 +01:00
2003-02-19 04:40:14 +01:00
for ( test_num = 0 ; test_num < NB_STR2INT ; test_num + + ) {
wstr = AtoW ( str2int [ test_num ] . str ) ;
value = 0xdeadbeef ;
2003-01-16 01:11:32 +01:00
pRtlInitUnicodeString ( & uni , wstr ) ;
2003-02-19 04:40:14 +01:00
result = pRtlUnicodeStringToInteger ( & uni , str2int [ test_num ] . base , & value ) ;
2008-08-26 11:28:31 +02:00
ok ( result = = str2int [ test_num ] . result | |
( str2int [ test_num ] . alternative & & result = = str2int [ test_num ] . alternative ) ,
" (test %d): RtlUnicodeStringToInteger( \" %s \" , %d, [out]) has result %x, expected: %x (%x) \n " ,
test_num , str2int [ test_num ] . str , str2int [ test_num ] . base , result ,
str2int [ test_num ] . result , str2int [ test_num ] . alternative ) ;
if ( result = = STATUS_SUCCESS )
2009-05-19 15:47:47 +02:00
ok ( value = = str2int [ test_num ] . value | |
broken ( str2int [ test_num ] . str [ 0 ] = = ' \0 ' & & str2int [ test_num ] . base = = 16 ) , /* nt4 */
2008-08-26 11:28:31 +02:00
" (test %d): RtlUnicodeStringToInteger( \" %s \" , %d, [out]) assigns value %d, expected: %d \n " ,
test_num , str2int [ test_num ] . str , str2int [ test_num ] . base , value , str2int [ test_num ] . value ) ;
else
ok ( value = = 0xdeadbeef | | value = = 0 /* vista */ ,
" (test %d): RtlUnicodeStringToInteger( \" %s \" , %d, [out]) assigns value %d, expected 0 or deadbeef \n " ,
test_num , str2int [ test_num ] . str , str2int [ test_num ] . base , value ) ;
2009-05-13 10:32:38 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , wstr ) ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
wstr = AtoW ( str2int [ 1 ] . str ) ;
pRtlInitUnicodeString ( & uni , wstr ) ;
result = pRtlUnicodeStringToInteger ( & uni , str2int [ 1 ] . base , NULL ) ;
ok ( result = = STATUS_ACCESS_VIOLATION ,
2006-10-13 23:33:02 +02:00
" call failed: RtlUnicodeStringToInteger( \" %s \" , %d, NULL) has result %x \n " ,
2003-02-19 04:40:14 +01:00
str2int [ 1 ] . str , str2int [ 1 ] . base , result ) ;
result = pRtlUnicodeStringToInteger ( & uni , 20 , NULL ) ;
2008-08-26 11:28:31 +02:00
ok ( result = = STATUS_INVALID_PARAMETER | | result = = STATUS_ACCESS_VIOLATION ,
2006-10-13 23:33:02 +02:00
" call failed: RtlUnicodeStringToInteger( \" %s \" , 20, NULL) has result %x \n " ,
2003-02-19 04:40:14 +01:00
str2int [ 1 ] . str , result ) ;
uni . Length = 10 ; /* Make Length shorter (5 WCHARS instead of 7) */
result = pRtlUnicodeStringToInteger ( & uni , str2int [ 1 ] . base , & value ) ;
ok ( result = = STATUS_SUCCESS ,
2006-10-13 23:33:02 +02:00
" call failed: RtlUnicodeStringToInteger( \" 12345 \" , %d, [out]) has result %x \n " ,
2003-02-19 04:40:14 +01:00
str2int [ 1 ] . base , result ) ;
ok ( value = = 12345 ,
2004-02-07 02:03:17 +01:00
" didn't return expected value (test a): expected: %d, got: %d \n " ,
2003-02-19 04:40:14 +01:00
12345 , value ) ;
uni . Length = 5 ; /* Use odd Length (2.5 WCHARS) */
result = pRtlUnicodeStringToInteger ( & uni , str2int [ 1 ] . base , & value ) ;
2008-08-26 11:28:31 +02:00
ok ( result = = STATUS_SUCCESS | | result = = STATUS_INVALID_PARAMETER /* vista */ ,
2006-10-13 23:33:02 +02:00
" call failed: RtlUnicodeStringToInteger( \" 12 \" , %d, [out]) has result %x \n " ,
2003-02-19 04:40:14 +01:00
str2int [ 1 ] . base , result ) ;
2008-08-26 11:28:31 +02:00
if ( result = = STATUS_SUCCESS )
ok ( value = = 12 , " didn't return expected value (test b): expected: %d, got: %d \n " , 12 , value ) ;
2003-02-19 04:40:14 +01:00
uni . Length = 2 ;
result = pRtlUnicodeStringToInteger ( & uni , str2int [ 1 ] . base , & value ) ;
ok ( result = = STATUS_SUCCESS ,
2006-10-13 23:33:02 +02:00
" call failed: RtlUnicodeStringToInteger( \" 1 \" , %d, [out]) has result %x \n " ,
2003-02-19 04:40:14 +01:00
str2int [ 1 ] . base , result ) ;
ok ( value = = 1 ,
2004-02-07 02:03:17 +01:00
" didn't return expected value (test c): expected: %d, got: %d \n " ,
2003-02-19 04:40:14 +01:00
1 , value ) ;
/* w2k: uni.Length = 0 returns value 11234567 instead of 0 */
2009-05-13 10:32:38 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , wstr ) ;
2002-11-12 03:18:10 +01:00
}
2003-02-19 04:40:14 +01:00
static void test_RtlCharToInteger ( void )
{
2006-06-13 14:03:19 +02:00
unsigned int test_num ;
2003-02-19 04:40:14 +01:00
int value ;
NTSTATUS result ;
for ( test_num = 0 ; test_num < NB_STR2INT ; test_num + + ) {
/* w2k skips a leading '\0' and processes the string after */
if ( str2int [ test_num ] . str [ 0 ] ! = ' \0 ' ) {
value = 0xdeadbeef ;
result = pRtlCharToInteger ( str2int [ test_num ] . str , str2int [ test_num ] . base , & value ) ;
2008-08-26 11:28:31 +02:00
ok ( result = = str2int [ test_num ] . result | |
( str2int [ test_num ] . alternative & & result = = str2int [ test_num ] . alternative ) ,
" (test %d): call failed: RtlCharToInteger( \" %s \" , %d, [out]) has result %x, expected: %x (%x) \n " ,
test_num , str2int [ test_num ] . str , str2int [ test_num ] . base , result ,
str2int [ test_num ] . result , str2int [ test_num ] . alternative ) ;
if ( result = = STATUS_SUCCESS )
ok ( value = = str2int [ test_num ] . value ,
" (test %d): call failed: RtlCharToInteger( \" %s \" , %d, [out]) assigns value %d, expected: %d \n " ,
test_num , str2int [ test_num ] . str , str2int [ test_num ] . base , value , str2int [ test_num ] . value ) ;
else
ok ( value = = 0 | | value = = 0xdeadbeef ,
" (test %d): call failed: RtlCharToInteger( \" %s \" , %d, [out]) assigns value %d, expected 0 or deadbeef \n " ,
test_num , str2int [ test_num ] . str , str2int [ test_num ] . base , value ) ;
2005-06-13 12:03:33 +02:00
}
}
2003-02-19 04:40:14 +01:00
result = pRtlCharToInteger ( str2int [ 1 ] . str , str2int [ 1 ] . base , NULL ) ;
ok ( result = = STATUS_ACCESS_VIOLATION ,
2006-10-13 23:33:02 +02:00
" call failed: RtlCharToInteger( \" %s \" , %d, NULL) has result %x \n " ,
2003-02-19 04:40:14 +01:00
str2int [ 1 ] . str , str2int [ 1 ] . base , result ) ;
result = pRtlCharToInteger ( str2int [ 1 ] . str , 20 , NULL ) ;
ok ( result = = STATUS_INVALID_PARAMETER ,
2006-10-13 23:33:02 +02:00
" call failed: RtlCharToInteger( \" %s \" , 20, NULL) has result %x \n " ,
2003-02-19 04:40:14 +01:00
str2int [ 1 ] . str , result ) ;
}
# define STRI_BUFFER_LENGTH 35
typedef struct {
int base ;
ULONG value ;
USHORT Length ;
USHORT MaximumLength ;
2003-10-04 05:04:45 +02:00
const char * Buffer ;
2003-02-19 04:40:14 +01:00
NTSTATUS result ;
} int2str_t ;
static const int2str_t int2str [ ] = {
{ 10 , 123 , 3 , 11 , " 123 \0 ------------------------------- " , STATUS_SUCCESS } ,
{ 0 , 0x80000000U , 10 , 11 , " 2147483648 \0 ------------------------ " , STATUS_SUCCESS } , /* min signed int */
{ 0 , - 2147483647 , 10 , 11 , " 2147483649 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 0 , - 2 , 10 , 11 , " 4294967294 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 0 , - 1 , 10 , 11 , " 4294967295 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 0 , 0 , 1 , 11 , " 0 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 0 , 1 , 1 , 11 , " 1 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 0 , 12 , 2 , 11 , " 12 \0 -------------------------------- " , STATUS_SUCCESS } ,
{ 0 , 123 , 3 , 11 , " 123 \0 ------------------------------- " , STATUS_SUCCESS } ,
{ 0 , 1234 , 4 , 11 , " 1234 \0 ------------------------------ " , STATUS_SUCCESS } ,
{ 0 , 12345 , 5 , 11 , " 12345 \0 ----------------------------- " , STATUS_SUCCESS } ,
{ 0 , 123456 , 6 , 11 , " 123456 \0 ---------------------------- " , STATUS_SUCCESS } ,
{ 0 , 1234567 , 7 , 11 , " 1234567 \0 --------------------------- " , STATUS_SUCCESS } ,
{ 0 , 12345678 , 8 , 11 , " 12345678 \0 -------------------------- " , STATUS_SUCCESS } ,
{ 0 , 123456789 , 9 , 11 , " 123456789 \0 ------------------------- " , STATUS_SUCCESS } ,
{ 0 , 2147483646 , 10 , 11 , " 2147483646 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 0 , 2147483647 , 10 , 11 , " 2147483647 \0 ------------------------ " , STATUS_SUCCESS } , /* max signed int */
{ 0 , 2147483648U , 10 , 11 , " 2147483648 \0 ------------------------ " , STATUS_SUCCESS } , /* uint = -max int */
{ 0 , 2147483649U , 10 , 11 , " 2147483649 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 0 , 4294967294U , 10 , 11 , " 4294967294 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 0 , 4294967295U , 10 , 11 , " 4294967295 \0 ------------------------ " , STATUS_SUCCESS } , /* max unsigned int */
{ 2 , 0x80000000U , 32 , 33 , " 10000000000000000000000000000000 \0 -- " , STATUS_SUCCESS } , /* min signed int */
{ 2 , - 2147483647 , 32 , 33 , " 10000000000000000000000000000001 \0 -- " , STATUS_SUCCESS } ,
{ 2 , - 2 , 32 , 33 , " 11111111111111111111111111111110 \0 -- " , STATUS_SUCCESS } ,
{ 2 , - 1 , 32 , 33 , " 11111111111111111111111111111111 \0 -- " , STATUS_SUCCESS } ,
{ 2 , 0 , 1 , 33 , " 0 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 2 , 1 , 1 , 33 , " 1 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 2 , 10 , 4 , 33 , " 1010 \0 ------------------------------ " , STATUS_SUCCESS } ,
{ 2 , 100 , 7 , 33 , " 1100100 \0 --------------------------- " , STATUS_SUCCESS } ,
{ 2 , 1000 , 10 , 33 , " 1111101000 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 2 , 10000 , 14 , 33 , " 10011100010000 \0 -------------------- " , STATUS_SUCCESS } ,
{ 2 , 32767 , 15 , 33 , " 111111111111111 \0 ------------------- " , STATUS_SUCCESS } ,
2008-05-14 21:34:35 +02:00
/* { 2, 32768, 16, 33, "1000000000000000\0------------------", STATUS_SUCCESS}, broken on windows */
/* { 2, 65535, 16, 33, "1111111111111111\0------------------", STATUS_SUCCESS}, broken on windows */
2003-02-19 04:40:14 +01:00
{ 2 , 65536 , 17 , 33 , " 10000000000000000 \0 ----------------- " , STATUS_SUCCESS } ,
{ 2 , 100000 , 17 , 33 , " 11000011010100000 \0 ----------------- " , STATUS_SUCCESS } ,
{ 2 , 1000000 , 20 , 33 , " 11110100001001000000 \0 -------------- " , STATUS_SUCCESS } ,
{ 2 , 10000000 , 24 , 33 , " 100110001001011010000000 \0 ---------- " , STATUS_SUCCESS } ,
{ 2 , 100000000 , 27 , 33 , " 101111101011110000100000000 \0 ------- " , STATUS_SUCCESS } ,
{ 2 , 1000000000 , 30 , 33 , " 111011100110101100101000000000 \0 ---- " , STATUS_SUCCESS } ,
{ 2 , 1073741823 , 30 , 33 , " 111111111111111111111111111111 \0 ---- " , STATUS_SUCCESS } ,
{ 2 , 2147483646 , 31 , 33 , " 1111111111111111111111111111110 \0 --- " , STATUS_SUCCESS } ,
{ 2 , 2147483647 , 31 , 33 , " 1111111111111111111111111111111 \0 --- " , STATUS_SUCCESS } , /* max signed int */
{ 2 , 2147483648U , 32 , 33 , " 10000000000000000000000000000000 \0 -- " , STATUS_SUCCESS } , /* uint = -max int */
{ 2 , 2147483649U , 32 , 33 , " 10000000000000000000000000000001 \0 -- " , STATUS_SUCCESS } ,
{ 2 , 4294967294U , 32 , 33 , " 11111111111111111111111111111110 \0 -- " , STATUS_SUCCESS } ,
{ 2 , 4294967295U , 32 , 33 , " 11111111111111111111111111111111 \0 -- " , STATUS_SUCCESS } , /* max unsigned int */
{ 8 , 0x80000000U , 11 , 12 , " 20000000000 \0 ----------------------- " , STATUS_SUCCESS } , /* min signed int */
{ 8 , - 2147483647 , 11 , 12 , " 20000000001 \0 ----------------------- " , STATUS_SUCCESS } ,
{ 8 , - 2 , 11 , 12 , " 37777777776 \0 ----------------------- " , STATUS_SUCCESS } ,
{ 8 , - 1 , 11 , 12 , " 37777777777 \0 ----------------------- " , STATUS_SUCCESS } ,
{ 8 , 0 , 1 , 12 , " 0 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 8 , 1 , 1 , 12 , " 1 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 8 , 2147483646 , 11 , 12 , " 17777777776 \0 ----------------------- " , STATUS_SUCCESS } ,
{ 8 , 2147483647 , 11 , 12 , " 17777777777 \0 ----------------------- " , STATUS_SUCCESS } , /* max signed int */
{ 8 , 2147483648U , 11 , 12 , " 20000000000 \0 ----------------------- " , STATUS_SUCCESS } , /* uint = -max int */
{ 8 , 2147483649U , 11 , 12 , " 20000000001 \0 ----------------------- " , STATUS_SUCCESS } ,
{ 8 , 4294967294U , 11 , 12 , " 37777777776 \0 ----------------------- " , STATUS_SUCCESS } ,
{ 8 , 4294967295U , 11 , 12 , " 37777777777 \0 ----------------------- " , STATUS_SUCCESS } , /* max unsigned int */
{ 10 , 0x80000000U , 10 , 11 , " 2147483648 \0 ------------------------ " , STATUS_SUCCESS } , /* min signed int */
{ 10 , - 2147483647 , 10 , 11 , " 2147483649 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 10 , - 2 , 10 , 11 , " 4294967294 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 10 , - 1 , 10 , 11 , " 4294967295 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 10 , 0 , 1 , 11 , " 0 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 10 , 1 , 1 , 11 , " 1 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 10 , 2147483646 , 10 , 11 , " 2147483646 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 10 , 2147483647 , 10 , 11 , " 2147483647 \0 ------------------------ " , STATUS_SUCCESS } , /* max signed int */
{ 10 , 2147483648U , 10 , 11 , " 2147483648 \0 ------------------------ " , STATUS_SUCCESS } , /* uint = -max int */
{ 10 , 2147483649U , 10 , 11 , " 2147483649 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 10 , 4294967294U , 10 , 11 , " 4294967294 \0 ------------------------ " , STATUS_SUCCESS } ,
{ 10 , 4294967295U , 10 , 11 , " 4294967295 \0 ------------------------ " , STATUS_SUCCESS } , /* max unsigned int */
{ 16 , 0x80000000U , 8 , 9 , " 80000000 \0 -------------------------- " , STATUS_SUCCESS } , /* min signed int */
{ 16 , - 2147483647 , 8 , 9 , " 80000001 \0 -------------------------- " , STATUS_SUCCESS } ,
{ 16 , - 2 , 8 , 9 , " FFFFFFFE \0 -------------------------- " , STATUS_SUCCESS } ,
{ 16 , - 1 , 8 , 9 , " FFFFFFFF \0 -------------------------- " , STATUS_SUCCESS } ,
{ 16 , 0 , 1 , 9 , " 0 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 16 , 1 , 1 , 9 , " 1 \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 16 , 2147483646 , 8 , 9 , " 7FFFFFFE \0 -------------------------- " , STATUS_SUCCESS } ,
{ 16 , 2147483647 , 8 , 9 , " 7FFFFFFF \0 -------------------------- " , STATUS_SUCCESS } , /* max signed int */
{ 16 , 2147483648U , 8 , 9 , " 80000000 \0 -------------------------- " , STATUS_SUCCESS } , /* uint = -max int */
{ 16 , 2147483649U , 8 , 9 , " 80000001 \0 -------------------------- " , STATUS_SUCCESS } ,
{ 16 , 4294967294U , 8 , 9 , " FFFFFFFE \0 -------------------------- " , STATUS_SUCCESS } ,
{ 16 , 4294967295U , 8 , 9 , " FFFFFFFF \0 -------------------------- " , STATUS_SUCCESS } , /* max unsigned int */
2008-05-14 21:34:35 +02:00
/* { 2, 32768, 16, 17, "1000000000000000\0------------------", STATUS_SUCCESS}, broken on windows */
/* { 2, 32768, 16, 16, "1000000000000000-------------------", STATUS_SUCCESS}, broken on windows */
2003-02-19 04:40:14 +01:00
{ 2 , 65536 , 17 , 18 , " 10000000000000000 \0 ----------------- " , STATUS_SUCCESS } ,
{ 2 , 65536 , 17 , 17 , " 10000000000000000------------------ " , STATUS_SUCCESS } ,
{ 2 , 131072 , 18 , 19 , " 100000000000000000 \0 ---------------- " , STATUS_SUCCESS } ,
{ 2 , 131072 , 18 , 18 , " 100000000000000000----------------- " , STATUS_SUCCESS } ,
{ 16 , 0xffffffff , 8 , 9 , " FFFFFFFF \0 -------------------------- " , STATUS_SUCCESS } ,
{ 16 , 0xffffffff , 8 , 8 , " FFFFFFFF--------------------------- " , STATUS_SUCCESS } , /* No \0 term */
{ 16 , 0xffffffff , 8 , 7 , " ----------------------------------- " , STATUS_BUFFER_OVERFLOW } , /* Too short */
{ 16 , 0xa , 1 , 2 , " A \0 --------------------------------- " , STATUS_SUCCESS } ,
{ 16 , 0xa , 1 , 1 , " A---------------------------------- " , STATUS_SUCCESS } , /* No \0 term */
{ 16 , 0 , 1 , 0 , " ----------------------------------- " , STATUS_BUFFER_OVERFLOW } ,
{ 20 , 0xdeadbeef , 0 , 9 , " ----------------------------------- " , STATUS_INVALID_PARAMETER } , /* ill. base */
{ - 8 , 07654321 , 0 , 12 , " ----------------------------------- " , STATUS_INVALID_PARAMETER } , /* neg. base */
} ;
# define NB_INT2STR (sizeof(int2str) / sizeof(*int2str))
static void one_RtlIntegerToUnicodeString_test ( int test_num , const int2str_t * int2str )
2002-11-12 03:18:10 +01:00
{
2003-02-19 04:40:14 +01:00
int pos ;
WCHAR expected_str_Buffer [ STRI_BUFFER_LENGTH + 1 ] ;
UNICODE_STRING expected_unicode_string ;
STRING expected_ansi_str ;
WCHAR str_Buffer [ STRI_BUFFER_LENGTH + 1 ] ;
UNICODE_STRING unicode_string ;
STRING ansi_str ;
NTSTATUS result ;
2002-11-12 03:18:10 +01:00
2003-02-19 04:40:14 +01:00
for ( pos = 0 ; pos < STRI_BUFFER_LENGTH ; pos + + ) {
expected_str_Buffer [ pos ] = int2str - > Buffer [ pos ] ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
expected_unicode_string . Length = int2str - > Length * sizeof ( WCHAR ) ;
expected_unicode_string . MaximumLength = int2str - > MaximumLength * sizeof ( WCHAR ) ;
expected_unicode_string . Buffer = expected_str_Buffer ;
pRtlUnicodeStringToAnsiString ( & expected_ansi_str , & expected_unicode_string , 1 ) ;
for ( pos = 0 ; pos < STRI_BUFFER_LENGTH ; pos + + ) {
str_Buffer [ pos ] = ' - ' ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
unicode_string . Length = 0 ;
unicode_string . MaximumLength = int2str - > MaximumLength * sizeof ( WCHAR ) ;
unicode_string . Buffer = str_Buffer ;
result = pRtlIntegerToUnicodeString ( int2str - > value , int2str - > base , & unicode_string ) ;
pRtlUnicodeStringToAnsiString ( & ansi_str , & unicode_string , 1 ) ;
if ( result = = STATUS_BUFFER_OVERFLOW ) {
/* On BUFFER_OVERFLOW the string Buffer should be unchanged */
for ( pos = 0 ; pos < STRI_BUFFER_LENGTH ; pos + + ) {
expected_str_Buffer [ pos ] = ' - ' ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
/* w2k: The native function has two reasons for BUFFER_OVERFLOW: */
/* If the value is too large to convert: The Length is unchanged */
/* If str is too small to hold the string: Set str->Length to the length */
/* the string would have (which can be larger than the MaximumLength). */
/* To allow all this in the tests we do the following: */
if ( expected_unicode_string . Length > 32 & & unicode_string . Length = = 0 ) {
2011-08-03 23:50:18 +02:00
/* The value is too large to convert only triggered when testing native */
2003-02-19 04:40:14 +01:00
expected_unicode_string . Length = 0 ;
2005-06-13 12:03:33 +02:00
}
2003-02-19 04:40:14 +01:00
} else {
ok ( result = = int2str - > result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlIntegerToUnicodeString(%u, %d, [out]) has result %x, expected: %x \n " ,
2003-02-19 04:40:14 +01:00
test_num , int2str - > value , int2str - > base , result , int2str - > result ) ;
if ( result = = STATUS_SUCCESS ) {
ok ( unicode_string . Buffer [ unicode_string . Length / sizeof ( WCHAR ) ] = = ' \0 ' ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlIntegerToUnicodeString(%u, %d, [out]) string \" %s \" is not NULL terminated \n " ,
2003-02-19 04:40:14 +01:00
test_num , int2str - > value , int2str - > base , ansi_str . Buffer ) ;
2005-06-13 12:03:33 +02:00
}
}
2003-02-19 04:40:14 +01:00
ok ( memcmp ( unicode_string . Buffer , expected_unicode_string . Buffer , STRI_BUFFER_LENGTH * sizeof ( WCHAR ) ) = = 0 ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlIntegerToUnicodeString(%u, %d, [out]) assigns string \" %s \" , expected: \" %s \" \n " ,
2003-02-19 04:40:14 +01:00
test_num , int2str - > value , int2str - > base , ansi_str . Buffer , expected_ansi_str . Buffer ) ;
ok ( unicode_string . Length = = expected_unicode_string . Length ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlIntegerToUnicodeString(%u, %d, [out]) string has Length %d, expected: %d \n " ,
2003-02-19 04:40:14 +01:00
test_num , int2str - > value , int2str - > base , unicode_string . Length , expected_unicode_string . Length ) ;
ok ( unicode_string . MaximumLength = = expected_unicode_string . MaximumLength ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlIntegerToUnicodeString(%u, %d, [out]) string has MaximumLength %d, expected: %d \n " ,
2003-02-19 04:40:14 +01:00
test_num , int2str - > value , int2str - > base , unicode_string . MaximumLength , expected_unicode_string . MaximumLength ) ;
pRtlFreeAnsiString ( & expected_ansi_str ) ;
pRtlFreeAnsiString ( & ansi_str ) ;
}
static void test_RtlIntegerToUnicodeString ( void )
{
2003-07-19 05:06:03 +02:00
size_t test_num ;
2003-02-19 04:40:14 +01:00
2003-07-19 05:06:03 +02:00
for ( test_num = 0 ; test_num < NB_INT2STR ; test_num + + )
one_RtlIntegerToUnicodeString_test ( test_num , & int2str [ test_num ] ) ;
2003-02-19 04:40:14 +01:00
}
static void one_RtlIntegerToChar_test ( int test_num , const int2str_t * int2str )
{
NTSTATUS result ;
char dest_str [ STRI_BUFFER_LENGTH + 1 ] ;
memset ( dest_str , ' - ' , STRI_BUFFER_LENGTH ) ;
dest_str [ STRI_BUFFER_LENGTH ] = ' \0 ' ;
result = pRtlIntegerToChar ( int2str - > value , int2str - > base , int2str - > MaximumLength , dest_str ) ;
ok ( result = = int2str - > result ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlIntegerToChar(%u, %d, %d, [out]) has result %x, expected: %x \n " ,
2003-02-19 04:40:14 +01:00
test_num , int2str - > value , int2str - > base , int2str - > MaximumLength , result , int2str - > result ) ;
ok ( memcmp ( dest_str , int2str - > Buffer , STRI_BUFFER_LENGTH ) = = 0 ,
2006-10-13 23:33:02 +02:00
" (test %d): RtlIntegerToChar(%u, %d, %d, [out]) assigns string \" %s \" , expected: \" %s \" \n " ,
2003-02-19 04:40:14 +01:00
test_num , int2str - > value , int2str - > base , int2str - > MaximumLength , dest_str , int2str - > Buffer ) ;
}
static void test_RtlIntegerToChar ( void )
{
NTSTATUS result ;
2003-07-19 05:06:03 +02:00
size_t test_num ;
2003-02-19 04:40:14 +01:00
2003-07-19 05:06:03 +02:00
for ( test_num = 0 ; test_num < NB_INT2STR ; test_num + + )
one_RtlIntegerToChar_test ( test_num , & int2str [ test_num ] ) ;
2003-02-19 04:40:14 +01:00
result = pRtlIntegerToChar ( int2str [ 0 ] . value , 20 , int2str [ 0 ] . MaximumLength , NULL ) ;
ok ( result = = STATUS_INVALID_PARAMETER ,
2006-10-13 23:33:02 +02:00
" (test a): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x \n " ,
2003-02-19 04:40:14 +01:00
int2str [ 0 ] . value , 20 , int2str [ 0 ] . MaximumLength , result , STATUS_INVALID_PARAMETER ) ;
result = pRtlIntegerToChar ( int2str [ 0 ] . value , 20 , 0 , NULL ) ;
ok ( result = = STATUS_INVALID_PARAMETER ,
2006-10-13 23:33:02 +02:00
" (test b): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x \n " ,
2003-02-19 04:40:14 +01:00
int2str [ 0 ] . value , 20 , 0 , result , STATUS_INVALID_PARAMETER ) ;
result = pRtlIntegerToChar ( int2str [ 0 ] . value , int2str [ 0 ] . base , 0 , NULL ) ;
ok ( result = = STATUS_BUFFER_OVERFLOW ,
2006-10-13 23:33:02 +02:00
" (test c): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x \n " ,
2003-02-19 04:40:14 +01:00
int2str [ 0 ] . value , int2str [ 0 ] . base , 0 , result , STATUS_BUFFER_OVERFLOW ) ;
result = pRtlIntegerToChar ( int2str [ 0 ] . value , int2str [ 0 ] . base , int2str [ 0 ] . MaximumLength , NULL ) ;
ok ( result = = STATUS_ACCESS_VIOLATION ,
2006-10-13 23:33:02 +02:00
" (test d): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x \n " ,
2003-02-19 04:40:14 +01:00
int2str [ 0 ] . value , int2str [ 0 ] . base , int2str [ 0 ] . MaximumLength , result , STATUS_ACCESS_VIOLATION ) ;
}
2007-10-17 02:35:02 +02:00
static void test_RtlIsTextUnicode ( void )
{
char ascii [ ] = " A simple string " ;
2010-05-14 15:36:54 +02:00
char false_positive [ ] = { 0x41 , 0x0a , 0x0d , 0x1d } ;
WCHAR false_negative = 0x0d0a ;
2007-10-17 02:35:02 +02:00
WCHAR unicode [ ] = { ' A ' , ' ' , ' U ' , ' n ' , ' i ' , ' c ' , ' o ' , ' d ' , ' e ' , ' ' , ' s ' , ' t ' , ' r ' , ' i ' , ' n ' , ' g ' , 0 } ;
2008-06-24 18:57:11 +02:00
WCHAR unicode_no_controls [ ] = { ' A ' , ' U ' , ' n ' , ' i ' , ' c ' , ' o ' , ' d ' , ' e ' , ' s ' , ' t ' , ' r ' , ' i ' , ' n ' , ' g ' , 0 } ;
/* String with both byte-reversed and standard Unicode control characters. */
WCHAR mixed_controls [ ] = { ' \t ' , 0x9000 , 0x0d00 , ' \n ' , 0 } ;
2007-10-17 02:35:02 +02:00
WCHAR * be_unicode ;
2008-06-24 18:57:11 +02:00
WCHAR * be_unicode_no_controls ;
2008-09-03 05:57:13 +02:00
BOOLEAN res ;
2007-10-17 02:35:02 +02:00
int flags ;
int i ;
2013-07-22 11:02:04 +02:00
if ( ! pRtlIsTextUnicode )
{
win_skip ( " RtlIsTextUnicode is not available \n " ) ;
return ;
}
2007-10-17 02:49:28 +02:00
ok ( ! pRtlIsTextUnicode ( ascii , sizeof ( ascii ) , NULL ) , " ASCII text detected as Unicode \n " ) ;
2007-10-17 02:35:02 +02:00
2008-09-03 05:57:13 +02:00
res = pRtlIsTextUnicode ( unicode , sizeof ( unicode ) , NULL ) ;
ok ( res | |
broken ( res = = FALSE ) , /* NT4 */
" Text should be Unicode \n " ) ;
2007-10-17 02:35:02 +02:00
ok ( ! pRtlIsTextUnicode ( unicode , sizeof ( unicode ) - 1 , NULL ) , " Text should be Unicode \n " ) ;
flags = IS_TEXT_UNICODE_UNICODE_MASK ;
ok ( pRtlIsTextUnicode ( unicode , sizeof ( unicode ) , & flags ) , " Text should not pass a Unicode \n " ) ;
2007-10-24 07:02:38 +02:00
ok ( flags = = ( IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_CONTROLS ) ,
" Expected flags 0x6, obtained %x \n " , flags ) ;
2007-10-17 02:35:02 +02:00
flags = IS_TEXT_UNICODE_REVERSE_MASK ;
ok ( ! pRtlIsTextUnicode ( unicode , sizeof ( unicode ) , & flags ) , " Text should not pass reverse Unicode tests \n " ) ;
2007-10-24 07:02:38 +02:00
ok ( flags = = 0 , " Expected flags 0, obtained %x \n " , flags ) ;
2007-10-17 02:35:02 +02:00
flags = IS_TEXT_UNICODE_ODD_LENGTH ;
ok ( ! pRtlIsTextUnicode ( unicode , sizeof ( unicode ) - 1 , & flags ) , " Odd length test should have passed \n " ) ;
2007-10-24 07:02:38 +02:00
ok ( flags = = IS_TEXT_UNICODE_ODD_LENGTH , " Expected flags 0x200, obtained %x \n " , flags ) ;
2007-10-17 02:35:02 +02:00
be_unicode = HeapAlloc ( GetProcessHeap ( ) , 0 , sizeof ( unicode ) + sizeof ( WCHAR ) ) ;
be_unicode [ 0 ] = 0xfffe ;
for ( i = 0 ; i < sizeof ( unicode ) / sizeof ( unicode [ 0 ] ) ; i + + )
{
be_unicode [ i + 1 ] = ( unicode [ i ] > > 8 ) | ( ( unicode [ i ] & 0xff ) < < 8 ) ;
}
ok ( ! pRtlIsTextUnicode ( be_unicode , sizeof ( unicode ) + 2 , NULL ) , " Reverse endian should not be Unicode \n " ) ;
2008-06-30 18:46:38 +02:00
ok ( ! pRtlIsTextUnicode ( & be_unicode [ 1 ] , sizeof ( unicode ) , NULL ) , " Reverse endian should not be Unicode \n " ) ;
2007-10-17 02:35:02 +02:00
flags = IS_TEXT_UNICODE_REVERSE_MASK ;
ok ( ! pRtlIsTextUnicode ( & be_unicode [ 1 ] , sizeof ( unicode ) , & flags ) , " Reverse endian should be Unicode \n " ) ;
2007-10-24 07:02:38 +02:00
todo_wine
ok ( flags = = ( IS_TEXT_UNICODE_REVERSE_ASCII16 | IS_TEXT_UNICODE_REVERSE_STATISTICS | IS_TEXT_UNICODE_REVERSE_CONTROLS ) ,
" Expected flags 0x70, obtained %x \n " , flags ) ;
2007-10-17 02:35:02 +02:00
flags = IS_TEXT_UNICODE_REVERSE_MASK ;
ok ( ! pRtlIsTextUnicode ( be_unicode , sizeof ( unicode ) + 2 , & flags ) , " Reverse endian should be Unicode \n " ) ;
2007-10-24 07:02:38 +02:00
ok ( flags = = ( IS_TEXT_UNICODE_REVERSE_CONTROLS | IS_TEXT_UNICODE_REVERSE_SIGNATURE ) ,
" Expected flags 0xc0, obtained %x \n " , flags ) ;
2008-06-24 18:57:11 +02:00
/* build byte reversed unicode string with no control chars */
be_unicode_no_controls = HeapAlloc ( GetProcessHeap ( ) , 0 , sizeof ( unicode ) + sizeof ( WCHAR ) ) ;
2011-08-03 23:50:18 +02:00
ok ( be_unicode_no_controls ! = NULL , " Expected HeapAlloc to succeed. \n " ) ;
2008-06-24 18:57:11 +02:00
be_unicode_no_controls [ 0 ] = 0xfffe ;
for ( i = 0 ; i < sizeof ( unicode_no_controls ) / sizeof ( unicode_no_controls [ 0 ] ) ; i + + )
be_unicode_no_controls [ i + 1 ] = ( unicode_no_controls [ i ] > > 8 ) | ( ( unicode_no_controls [ i ] & 0xff ) < < 8 ) ;
/* The following tests verify that the tests for */
/* IS_TEXT_UNICODE_CONTROLS and IS_TEXT_UNICODE_REVERSE_CONTROLS */
/* are not mutually exclusive. Regardless of whether the strings */
/* contain an indication of endianness, the tests are still */
/* run if the flag is passed to (Rtl)IsTextUnicode. */
/* Test IS_TEXT_UNICODE_CONTROLS flag */
flags = IS_TEXT_UNICODE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( unicode_no_controls , sizeof ( unicode_no_controls ) , & flags ) , " Test should not pass on Unicode string lacking control characters. \n " ) ;
ok ( flags = = 0 , " Expected flags 0x0, obtained %x \n " , flags ) ;
flags = IS_TEXT_UNICODE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( be_unicode_no_controls , sizeof ( unicode_no_controls ) , & flags ) , " Test should not pass on byte-reversed Unicode string lacking control characters. \n " ) ;
ok ( flags = = 0 , " Expected flags 0x0, obtained %x \n " , flags ) ;
flags = IS_TEXT_UNICODE_CONTROLS ;
2008-06-30 18:46:38 +02:00
ok ( pRtlIsTextUnicode ( unicode , sizeof ( unicode ) , & flags ) , " Test should pass on Unicode string lacking control characters. \n " ) ;
ok ( flags = = IS_TEXT_UNICODE_CONTROLS , " Expected flags 0x04, obtained %x \n " , flags ) ;
2008-06-24 18:57:11 +02:00
flags = IS_TEXT_UNICODE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( be_unicode_no_controls , sizeof ( unicode_no_controls ) + 2 , & flags ) ,
" Test should not pass with standard Unicode string. \n " ) ;
ok ( flags = = 0 , " Expected flags 0x0, obtained %x \n " , flags ) ;
flags = IS_TEXT_UNICODE_CONTROLS ;
2008-06-30 18:46:38 +02:00
ok ( pRtlIsTextUnicode ( mixed_controls , sizeof ( mixed_controls ) , & flags ) , " Test should pass on a string containing control characters. \n " ) ;
ok ( flags = = IS_TEXT_UNICODE_CONTROLS , " Expected flags 0x04, obtained %x \n " , flags ) ;
2008-06-24 18:57:11 +02:00
/* Test IS_TEXT_UNICODE_REVERSE_CONTROLS flag */
flags = IS_TEXT_UNICODE_REVERSE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( be_unicode_no_controls , sizeof ( unicode_no_controls ) , & flags ) , " Test should not pass on Unicode string lacking control characters. \n " ) ;
ok ( flags = = 0 , " Expected flags 0x0, obtained %x \n " , flags ) ;
flags = IS_TEXT_UNICODE_REVERSE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( unicode_no_controls , sizeof ( unicode_no_controls ) , & flags ) , " Test should not pass on Unicode string lacking control characters. \n " ) ;
ok ( flags = = 0 , " Expected flags 0x0, obtained %x \n " , flags ) ;
flags = IS_TEXT_UNICODE_REVERSE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( unicode , sizeof ( unicode ) , & flags ) , " Test should not pass on Unicode string lacking control characters. \n " ) ;
ok ( flags = = 0 , " Expected flags 0x0, obtained %x \n " , flags ) ;
flags = IS_TEXT_UNICODE_REVERSE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( be_unicode , sizeof ( unicode ) + 2 , & flags ) ,
" Test should pass with byte-reversed Unicode string containing control characters. \n " ) ;
ok ( flags = = IS_TEXT_UNICODE_REVERSE_CONTROLS , " Expected flags 0x40, obtained %x \n " , flags ) ;
flags = IS_TEXT_UNICODE_REVERSE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( mixed_controls , sizeof ( mixed_controls ) , & flags ) , " Test should pass on a string containing byte-reversed control characters. \n " ) ;
ok ( flags = = IS_TEXT_UNICODE_REVERSE_CONTROLS , " Expected flags 0x40, obtained %x \n " , flags ) ;
/* Test with flags for both byte-reverse and standard Unicode characters */
flags = IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_REVERSE_CONTROLS ;
ok ( ! pRtlIsTextUnicode ( mixed_controls , sizeof ( mixed_controls ) , & flags ) , " Test should pass on string containing both byte-reversed and standard control characters. \n " ) ;
ok ( flags = = ( IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_REVERSE_CONTROLS ) , " Expected flags 0x44, obtained %x \n " , flags ) ;
2010-05-14 15:36:54 +02:00
flags = IS_TEXT_UNICODE_STATISTICS ;
todo_wine ok ( pRtlIsTextUnicode ( false_positive , sizeof ( false_positive ) , & flags ) , " Test should pass on false positive. \n " ) ;
ok ( ! pRtlIsTextUnicode ( & false_negative , sizeof ( false_negative ) , NULL ) , " Test should fail on 0x0d0a (MALAYALAM LETTER UU). \n " ) ;
2007-10-20 21:38:35 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , be_unicode ) ;
2008-06-24 18:57:11 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , be_unicode_no_controls ) ;
2007-10-17 02:35:02 +02:00
}
2003-12-12 06:56:44 +01:00
static const WCHAR szGuid [ ] = { ' { ' , ' 0 ' , ' 1 ' , ' 0 ' , ' 2 ' , ' 0 ' , ' 3 ' , ' 0 ' , ' 4 ' , ' - ' ,
' 0 ' , ' 5 ' , ' 0 ' , ' 6 ' , ' - ' , ' 0 ' , ' 7 ' , ' 0 ' , ' 8 ' , ' - ' , ' 0 ' , ' 9 ' , ' 0 ' , ' A ' , ' - ' ,
' 0 ' , ' B ' , ' 0 ' , ' C ' , ' 0 ' , ' D ' , ' 0 ' , ' E ' , ' 0 ' , ' F ' , ' 0 ' , ' A ' , ' } ' , ' \0 ' } ;
2006-04-09 10:31:18 +02:00
static const WCHAR szGuid2 [ ] = { ' { ' , ' 0 ' , ' 1 ' , ' 0 ' , ' 2 ' , ' 0 ' , ' 3 ' , ' 0 ' , ' 4 ' , ' - ' ,
' 0 ' , ' 5 ' , ' 0 ' , ' 6 ' , ' - ' , ' 0 ' , ' 7 ' , ' 0 ' , ' 8 ' , ' - ' , ' 0 ' , ' 9 ' , ' 0 ' , ' A ' , ' - ' ,
' 0 ' , ' B ' , ' 0 ' , ' C ' , ' 0 ' , ' D ' , ' 0 ' , ' E ' , ' 0 ' , ' F ' , ' 0 ' , ' A ' , ' ] ' , ' \0 ' } ;
2011-08-24 15:19:17 +02:00
DEFINE_GUID ( IID_Endianness , 0x01020304 , 0x0506 , 0x0708 , 0x09 , 0x0A , 0x0B ,
2003-12-12 06:56:44 +01:00
0x0C , 0x0D , 0x0E , 0x0F , 0x0A ) ;
static void test_RtlGUIDFromString ( void )
{
GUID guid ;
UNICODE_STRING str ;
NTSTATUS ret ;
2013-07-22 11:02:04 +02:00
if ( ! pRtlGUIDFromString )
{
win_skip ( " RtlGUIDFromString is not available \n " ) ;
return ;
}
2007-01-04 17:56:16 +01:00
str . Length = str . MaximumLength = sizeof ( szGuid ) - sizeof ( WCHAR ) ;
2003-12-12 06:56:44 +01:00
str . Buffer = ( LPWSTR ) szGuid ;
ret = pRtlGUIDFromString ( & str , & guid ) ;
2006-10-13 23:33:02 +02:00
ok ( ret = = 0 , " expected ret=0, got 0x%0x \n " , ret ) ;
2011-08-24 15:19:17 +02:00
ok ( IsEqualGUID ( & guid , & IID_Endianness ) , " Endianness broken \n " ) ;
2006-04-09 10:31:18 +02:00
2007-01-04 17:56:16 +01:00
str . Length = str . MaximumLength = sizeof ( szGuid2 ) - sizeof ( WCHAR ) ;
2006-04-09 10:31:18 +02:00
str . Buffer = ( LPWSTR ) szGuid2 ;
ret = pRtlGUIDFromString ( & str , & guid ) ;
ok ( ret , " expected ret!=0 \n " ) ;
2003-12-12 06:56:44 +01:00
}
static void test_RtlStringFromGUID ( void )
{
UNICODE_STRING str ;
NTSTATUS ret ;
2013-07-22 11:02:04 +02:00
if ( ! pRtlStringFromGUID )
{
win_skip ( " RtlStringFromGUID is not available \n " ) ;
return ;
}
2003-12-12 06:56:44 +01:00
str . Length = str . MaximumLength = 0 ;
str . Buffer = NULL ;
2011-08-24 15:19:17 +02:00
ret = pRtlStringFromGUID ( & IID_Endianness , & str ) ;
2006-10-13 23:33:02 +02:00
ok ( ret = = 0 , " expected ret=0, got 0x%0x \n " , ret ) ;
2011-08-24 15:19:17 +02:00
ok ( str . Buffer & & ! lstrcmpiW ( str . Buffer , szGuid ) , " Endianness broken \n " ) ;
2009-12-06 16:02:55 +01:00
pRtlFreeUnicodeString ( & str ) ;
2003-12-12 06:56:44 +01:00
}
2003-02-19 04:40:14 +01:00
2013-07-16 10:52:39 +02:00
struct hash_unicodestring_test {
WCHAR str [ 50 ] ;
BOOLEAN case_insensitive ;
ULONG hash ;
} ;
static const struct hash_unicodestring_test hash_test [ ] = {
{ { ' T ' , 0 } , FALSE , 0x00000054 } ,
{ { ' T ' , ' e ' , ' s ' , ' t ' , 0 } , FALSE , 0x766bb952 } ,
{ { ' T ' , ' e ' , ' S ' , ' t ' , 0 } , FALSE , 0x764bb172 } ,
{ { ' t ' , ' e ' , ' s ' , ' t ' , 0 } , FALSE , 0x4745d132 } ,
{ { ' t ' , ' e ' , ' s ' , ' t ' , 0 } , TRUE , 0x6689c132 } ,
{ { ' T ' , ' E ' , ' S ' , ' T ' , 0 } , TRUE , 0x6689c132 } ,
{ { ' T ' , ' E ' , ' S ' , ' T ' , 0 } , FALSE , 0x6689c132 } ,
{ { ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' , 0 } , FALSE , 0x971318c3 } ,
{ { 0 } }
} ;
static void test_RtlHashUnicodeString ( void )
{
static const WCHAR strW [ ] = { ' T ' , ' e ' , ' s ' , ' t ' , 0 , ' 1 ' , 0 } ;
const struct hash_unicodestring_test * ptr ;
UNICODE_STRING str ;
NTSTATUS status ;
ULONG hash ;
if ( ! pRtlHashUnicodeString )
{
2013-07-20 07:15:34 +02:00
win_skip ( " RtlHashUnicodeString is not available \n " ) ;
2013-07-16 10:52:39 +02:00
return ;
}
status = pRtlHashUnicodeString ( NULL , FALSE , HASH_STRING_ALGORITHM_X65599 , & hash ) ;
ok ( status = = STATUS_INVALID_PARAMETER , " got status 0x%08x \n " , status ) ;
RtlInitUnicodeString ( & str , strW ) ;
status = pRtlHashUnicodeString ( & str , FALSE , HASH_STRING_ALGORITHM_X65599 , NULL ) ;
ok ( status = = STATUS_INVALID_PARAMETER , " got status 0x%08x \n " , status ) ;
status = pRtlHashUnicodeString ( & str , FALSE , HASH_STRING_ALGORITHM_INVALID , & hash ) ;
ok ( status = = STATUS_INVALID_PARAMETER , " got status 0x%08x \n " , status ) ;
/* embedded null */
str . Buffer = ( PWSTR ) strW ;
str . Length = sizeof ( strW ) - sizeof ( WCHAR ) ;
str . MaximumLength = sizeof ( strW ) ;
status = pRtlHashUnicodeString ( & str , FALSE , HASH_STRING_ALGORITHM_X65599 , & hash ) ;
ok ( status = = STATUS_SUCCESS , " got status 0x%08x \n " , status ) ;
ok ( hash = = 0x32803083 , " got 0x%08x \n " , hash ) ;
ptr = hash_test ;
while ( * ptr - > str )
{
RtlInitUnicodeString ( & str , ptr - > str ) ;
hash = 0 ;
status = pRtlHashUnicodeString ( & str , ptr - > case_insensitive , HASH_STRING_ALGORITHM_X65599 , & hash ) ;
ok ( status = = STATUS_SUCCESS , " got status 0x%08x for %s \n " , status , wine_dbgstr_w ( ptr - > str ) ) ;
ok ( hash = = ptr - > hash , " got wrong hash 0x%08x, expected 0x%08x, for %s, mode %d \n " , hash , ptr - > hash ,
wine_dbgstr_w ( ptr - > str ) , ptr - > case_insensitive ) ;
ptr + + ;
}
}
2014-03-29 16:14:23 +01:00
struct unicode_to_utf8_test {
WCHAR unicode [ 128 ] ;
const char * expected ;
NTSTATUS status ;
} ;
static const struct unicode_to_utf8_test unicode_to_utf8 [ ] = {
{ { 0 } , " " , STATUS_SUCCESS } ,
{ { ' - ' , 0 } , " - " , STATUS_SUCCESS } ,
{ { ' h ' , ' e ' , ' l ' , ' l ' , ' o ' , 0 } , " hello " , STATUS_SUCCESS } ,
{ { ' - ' , 0x7f , ' - ' , 0x80 , ' - ' , 0xff , ' - ' , 0x100 , ' - ' , 0 } , " - \x7F - \xC2 \x80 - \xC3 \xBF - \xC4 \x80 - " , STATUS_SUCCESS } ,
{ { ' - ' , 0x7ff , ' - ' , 0x800 , ' - ' , 0 } , " - \xDF \xBF - \xE0 \xA0 \x80 - " , STATUS_SUCCESS } ,
{ { ' - ' , 0xd7ff , ' - ' , 0xe000 , ' - ' , 0 } , " - \xED \x9F \xBF - \xEE \x80 \x80 - " , STATUS_SUCCESS } ,
/* 0x10000 */
{ { ' - ' , 0xffff , ' - ' , 0xd800 , 0xdc00 , ' - ' , 0 } , " - \xEF \xBF \xBF - \xF0 \x90 \x80 \x80 - " , STATUS_SUCCESS } ,
/* 0x103ff */ /* 0x10400 */
{ { ' - ' , 0xd800 , 0xdfff , ' - ' , 0xd801 , 0xdc00 , ' - ' , 0 } , " - \xF0 \x90 \x8F \xBF - \xF0 \x90 \x90 \x80 - " , STATUS_SUCCESS } ,
/* 0x10ffff */
{ { ' - ' , 0xdbff , 0xdfff , ' - ' , 0 } , " - \xF4 \x8F \xBF \xBF - " , STATUS_SUCCESS } ,
/* standalone lead surrogates become 0xFFFD */
{ { ' - ' , 0xd800 , ' - ' , 0xdbff , ' - ' , 0 } , " - \xEF \xBF \xBD - \xEF \xBF \xBD - " , STATUS_SOME_NOT_MAPPED } ,
/* standalone trail surrogates become 0xFFFD */
{ { ' - ' , 0xdc00 , ' - ' , 0xdfff , ' - ' , 0 } , " - \xEF \xBF \xBD - \xEF \xBF \xBD - " , STATUS_SOME_NOT_MAPPED } ,
/* reverse surrogate pair */
{ { ' - ' , 0xdfff , 0xdbff , ' - ' , 0 } , " - \xEF \xBF \xBD \xEF \xBF \xBD - " , STATUS_SOME_NOT_MAPPED } ,
/* byte order marks */
{ { ' - ' , 0xfeff , ' - ' , 0xfffe , ' - ' , 0 } , " - \xEF \xBB \xBF - \xEF \xBF \xBE - " , STATUS_SUCCESS } ,
{ { 0xfeff , ' - ' , 0 } , " \xEF \xBB \xBF - " , STATUS_SUCCESS } ,
{ { 0xfffe , ' - ' , 0 } , " \xEF \xBF \xBE - " , STATUS_SUCCESS } ,
/* invalid code point */
{ { 0xffff , ' - ' , 0 } , " \xEF \xBF \xBF - " , STATUS_SUCCESS } ,
/* canonically equivalent representations -- no normalization should happen */
{ { ' - ' , 0x1e09 , ' - ' , 0 } , " - \xE1 \xB8 \x89 - " , STATUS_SUCCESS } ,
{ { ' - ' , 0x0107 , 0x0327 , ' - ' , 0 } , " - \xC4 \x87 \xCC \xA7 - " , STATUS_SUCCESS } ,
{ { ' - ' , 0x00e7 , 0x0301 , ' - ' , 0 } , " - \xC3 \xA7 \xCC \x81 - " , STATUS_SUCCESS } ,
{ { ' - ' , 0x0063 , 0x0327 , 0x0301 , ' - ' , 0 } , " - \x63 \xCC \xA7 \xCC \x81 - " , STATUS_SUCCESS } ,
{ { ' - ' , 0x0063 , 0x0301 , 0x0327 , ' - ' , 0 } , " - \x63 \xCC \x81 \xCC \xA7 - " , STATUS_SUCCESS } ,
} ;
static void utf8_expect_ ( const unsigned char * out_string , ULONG buflen , ULONG out_bytes ,
const WCHAR * in_string , ULONG in_bytes ,
NTSTATUS expect_status , int line )
{
NTSTATUS status ;
ULONG bytes_out ;
char buffer [ 128 ] ;
unsigned char * buf = ( unsigned char * ) buffer ;
unsigned int i ;
if ( buflen = = ( ULONG ) - 1 )
buflen = sizeof ( buffer ) ;
bytes_out = 0x55555555 ;
memset ( buffer , 0x55 , sizeof ( buffer ) ) ;
status = pRtlUnicodeToUTF8N (
out_string ? buffer : NULL , buflen , & bytes_out ,
in_string , in_bytes ) ;
ok_ ( __FILE__ , line ) ( status = = expect_status , " status = 0x%x \n " , status ) ;
ok_ ( __FILE__ , line ) ( bytes_out = = out_bytes , " bytes_out = %u \n " , bytes_out ) ;
if ( out_string )
{
for ( i = 0 ; i < bytes_out ; i + + )
ok_ ( __FILE__ , line ) ( buf [ i ] = = out_string [ i ] ,
" buffer[%d] = 0x%x, expected 0x%x \n " ,
i , buf [ i ] , out_string [ i ] ) ;
for ( ; i < sizeof ( buffer ) ; i + + )
ok_ ( __FILE__ , line ) ( buf [ i ] = = 0x55 ,
" buffer[%d] = 0x%x, expected 0x55 \n " ,
i , buf [ i ] ) ;
}
}
# define utf8_expect(out_string, buflen, out_bytes, in_string, in_bytes, expect_status) \
utf8_expect_ ( out_string , buflen , out_bytes , in_string , in_bytes , expect_status , __LINE__ )
static void test_RtlUnicodeToUTF8N ( void )
{
NTSTATUS status ;
ULONG bytes_out ;
ULONG bytes_out_array [ 2 ] ;
void * const invalid_pointer = ( void * ) 0x8 ;
char buffer [ 128 ] ;
const WCHAR empty_string [ ] = { 0 } ;
const WCHAR test_string [ ] = { ' A ' , 0 , ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' , ' g ' , 0 } ;
const WCHAR special_string [ ] = { ' X ' , 0x80 , 0xd800 , 0 } ;
const unsigned char special_expected [ ] = { ' X ' , 0xc2 , 0x80 , 0xef , 0xbf , 0xbd , 0 } ;
unsigned int input_len ;
const unsigned int test_count = sizeof ( unicode_to_utf8 ) / sizeof ( unicode_to_utf8 [ 0 ] ) ;
unsigned int i ;
if ( ! pRtlUnicodeToUTF8N )
{
skip ( " RtlUnicodeToUTF8N unavailable \n " ) ;
return ;
}
/* show that bytes_out is really ULONG */
memset ( bytes_out_array , 0x55 , sizeof ( bytes_out_array ) ) ;
status = pRtlUnicodeToUTF8N ( NULL , 0 , bytes_out_array , empty_string , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out_array [ 0 ] = = 0x00000000 , " Got 0x%x \n " , bytes_out_array [ 0 ] ) ;
ok ( bytes_out_array [ 1 ] = = 0x55555555 , " Got 0x%x \n " , bytes_out_array [ 1 ] ) ;
/* parameter checks */
status = pRtlUnicodeToUTF8N ( NULL , 0 , NULL , NULL , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_4 , " status = 0x%x \n " , status ) ;
status = pRtlUnicodeToUTF8N ( NULL , 0 , NULL , empty_string , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER , " status = 0x%x \n " , status ) ;
bytes_out = 0x55555555 ;
status = pRtlUnicodeToUTF8N ( NULL , 0 , & bytes_out , NULL , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_4 , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0x55555555 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUnicodeToUTF8N ( NULL , 0 , & bytes_out , invalid_pointer , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUnicodeToUTF8N ( NULL , 0 , & bytes_out , empty_string , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUnicodeToUTF8N ( NULL , 0 , & bytes_out , test_string , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUnicodeToUTF8N ( NULL , 0 , & bytes_out , empty_string , 1 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUnicodeToUTF8N ( invalid_pointer , 0 , & bytes_out , empty_string , 1 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_5 , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0x55555555 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUnicodeToUTF8N ( invalid_pointer , 8 , & bytes_out , empty_string , 1 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_5 , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0x55555555 , " bytes_out = 0x%x \n " , bytes_out ) ;
/* length output with special chars */
# define length_expect(in_chars, out_bytes, expect_status) \
utf8_expect_ ( NULL , 0 , out_bytes , \
special_string , in_chars * sizeof ( WCHAR ) , \
expect_status , __LINE__ )
length_expect ( 0 , 0 , STATUS_SUCCESS ) ;
length_expect ( 1 , 1 , STATUS_SUCCESS ) ;
length_expect ( 2 , 3 , STATUS_SUCCESS ) ;
length_expect ( 3 , 6 , STATUS_SOME_NOT_MAPPED ) ;
length_expect ( 4 , 7 , STATUS_SOME_NOT_MAPPED ) ;
# undef length_expect
/* output truncation */
# define truncate_expect(buflen, out_bytes, expect_status) \
utf8_expect_ ( special_expected , buflen , out_bytes , \
special_string , sizeof ( special_string ) , \
expect_status , __LINE__ )
truncate_expect ( 0 , 0 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 1 , 1 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 2 , 1 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 3 , 3 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 4 , 3 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 5 , 3 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 6 , 6 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 7 , 7 , STATUS_SOME_NOT_MAPPED ) ;
# undef truncate_expect
/* conversion behavior with varying input length */
for ( input_len = 0 ; input_len < = sizeof ( test_string ) ; input_len + + ) {
/* no output buffer, just length */
utf8_expect ( NULL , 0 , input_len / sizeof ( WCHAR ) ,
test_string , input_len , STATUS_SUCCESS ) ;
/* write output */
bytes_out = 0x55555555 ;
memset ( buffer , 0x55 , sizeof ( buffer ) ) ;
status = pRtlUnicodeToUTF8N (
buffer , sizeof ( buffer ) , & bytes_out ,
test_string , input_len ) ;
if ( input_len % sizeof ( WCHAR ) = = 0 ) {
ok ( status = = STATUS_SUCCESS ,
" (len %u): status = 0x%x \n " , input_len , status ) ;
ok ( bytes_out = = input_len / sizeof ( WCHAR ) ,
" (len %u): bytes_out = 0x%x \n " , input_len , bytes_out ) ;
for ( i = 0 ; i < bytes_out ; i + + ) {
ok ( buffer [ i ] = = test_string [ i ] ,
" (len %u): buffer[%d] = 0x%x, expected 0x%x \n " ,
input_len , i , buffer [ i ] , test_string [ i ] ) ;
}
for ( ; i < sizeof ( buffer ) ; i + + ) {
ok ( buffer [ i ] = = 0x55 ,
" (len %u): buffer[%d] = 0x%x \n " , input_len , i , buffer [ i ] ) ;
}
} else {
ok ( status = = STATUS_INVALID_PARAMETER_5 ,
" (len %u): status = 0x%x \n " , input_len , status ) ;
ok ( bytes_out = = 0x55555555 ,
" (len %u): bytes_out = 0x%x \n " , input_len , bytes_out ) ;
for ( i = 0 ; i < sizeof ( buffer ) ; i + + ) {
ok ( buffer [ i ] = = 0x55 ,
" (len %u): buffer[%d] = 0x%x \n " , input_len , i , buffer [ i ] ) ;
}
}
}
/* test cases for special characters */
for ( i = 0 ; i < test_count ; i + + ) {
bytes_out = 0x55555555 ;
memset ( buffer , 0x55 , sizeof ( buffer ) ) ;
status = pRtlUnicodeToUTF8N (
buffer , sizeof ( buffer ) , & bytes_out ,
unicode_to_utf8 [ i ] . unicode , lstrlenW ( unicode_to_utf8 [ i ] . unicode ) * sizeof ( WCHAR ) ) ;
ok ( status = = unicode_to_utf8 [ i ] . status ,
" (test %d): status is 0x%x, expected 0x%x \n " ,
i , status , unicode_to_utf8 [ i ] . status ) ;
ok ( bytes_out = = strlen ( unicode_to_utf8 [ i ] . expected ) ,
" (test %d): bytes_out is %u, expected %u \n " ,
i , bytes_out , lstrlenA ( unicode_to_utf8 [ i ] . expected ) ) ;
ok ( ! memcmp ( buffer , unicode_to_utf8 [ i ] . expected , bytes_out ) ,
" (test %d): got \" %.*s \" , expected \" %s \" \n " ,
i , bytes_out , buffer , unicode_to_utf8 [ i ] . expected ) ;
ok ( buffer [ bytes_out ] = = 0x55 ,
" (test %d): behind string: 0x%x \n " , i , buffer [ bytes_out ] ) ;
/* same test but include the null terminator */
bytes_out = 0x55555555 ;
memset ( buffer , 0x55 , sizeof ( buffer ) ) ;
status = pRtlUnicodeToUTF8N (
buffer , sizeof ( buffer ) , & bytes_out ,
unicode_to_utf8 [ i ] . unicode , ( lstrlenW ( unicode_to_utf8 [ i ] . unicode ) + 1 ) * sizeof ( WCHAR ) ) ;
ok ( status = = unicode_to_utf8 [ i ] . status ,
" (test %d): status is 0x%x, expected 0x%x \n " ,
i , status , unicode_to_utf8 [ i ] . status ) ;
ok ( bytes_out = = strlen ( unicode_to_utf8 [ i ] . expected ) + 1 ,
" (test %d): bytes_out is %u, expected %u \n " ,
i , bytes_out , lstrlenA ( unicode_to_utf8 [ i ] . expected ) + 1 ) ;
ok ( ! memcmp ( buffer , unicode_to_utf8 [ i ] . expected , bytes_out ) ,
" (test %d): got \" %.*s \" , expected \" %s \" \n " ,
i , bytes_out , buffer , unicode_to_utf8 [ i ] . expected ) ;
ok ( buffer [ bytes_out ] = = 0x55 ,
" (test %d): behind string: 0x%x \n " , i , buffer [ bytes_out ] ) ;
}
}
2014-03-29 16:25:25 +01:00
struct utf8_to_unicode_test {
const char * utf8 ;
WCHAR expected [ 128 ] ;
NTSTATUS status ;
} ;
static const struct utf8_to_unicode_test utf8_to_unicode [ ] = {
{ " " , { 0 } , STATUS_SUCCESS } ,
{ " - " , { ' - ' , 0 } , STATUS_SUCCESS } ,
{ " hello " , { ' h ' , ' e ' , ' l ' , ' l ' , ' o ' , 0 } , STATUS_SUCCESS } ,
/* first and last of each range */
{ " - \x7F - \xC2 \x80 - \xC3 \xBF - \xC4 \x80 - " , { ' - ' , 0x7f , ' - ' , 0x80 , ' - ' , 0xff , ' - ' , 0x100 , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " - \xDF \xBF - \xE0 \xA0 \x80 - " , { ' - ' , 0x7ff , ' - ' , 0x800 , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " - \xED \x9F \xBF - \xEE \x80 \x80 - " , { ' - ' , 0xd7ff , ' - ' , 0xe000 , ' - ' , 0 } , STATUS_SUCCESS } ,
/* 0x10000 */
{ " - \xEF \xBF \xBF - \xF0 \x90 \x80 \x80 - " , { ' - ' , 0xffff , ' - ' , 0xd800 , 0xdc00 , ' - ' , 0 } , STATUS_SUCCESS } ,
/* 0x103ff */ /* 0x10400 */
{ " - \xF0 \x90 \x8F \xBF - \xF0 \x90 \x90 \x80 - " , { ' - ' , 0xd800 , 0xdfff , ' - ' , 0xd801 , 0xdc00 , ' - ' , 0 } , STATUS_SUCCESS } ,
/* 0x10ffff */
{ " - \xF4 \x8F \xBF \xBF - " , { ' - ' , 0xdbff , 0xdfff , ' - ' , 0 } , STATUS_SUCCESS } ,
/* standalone surrogate code points */
/* 0xd800 */ /* 0xdbff */
{ " - \xED \xA0 \x80 - \xED \xAF \xBF - " , { ' - ' , 0xfffd , 0xfffd , ' - ' , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* 0xdc00 */ /* 0xdfff */
{ " - \xED \xB0 \x80 - \xED \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , ' - ' , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* UTF-8 encoded surrogate pair */
/* 0xdbff */ /* 0xdfff */
{ " - \xED \xAF \xBF \xED \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* reverse surrogate pair */
/* 0xdfff */ /* 0xdbff */
{ " - \xED \xBF \xBF \xED \xAF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* code points outside the UTF-16 range */
/* 0x110000 */
{ " - \xF4 \x90 \x80 \x80 - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* 0x1fffff */
{ " - \xF7 \xBF \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* 0x200000 */
{ " - \xFA \x80 \x80 \x80 \x80 - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* 0x3ffffff */
{ " - \xFB \xBF \xBF \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* 0x4000000 */
{ " - \xFC \x84 \x80 \x80 \x80 \x80 - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* 0x7fffffff */
{ " - \xFD \xBF \xBF \xBF \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* overlong encodings of each length for -, NUL, and the highest possible value */
{ " - \xC0 \xAD - \xC0 \x80 - \xC1 \xBF - " , { ' - ' , 0xfffd , 0xfffd , ' - ' , 0xfffd , 0xfffd , ' - ' , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xE0 \x80 \xAD - \xE0 \x80 \x80 - \xE0 \x9F \xBF - " , { ' - ' , 0xfffd , 0xfffd , ' - ' , 0xfffd , 0xfffd , ' - ' , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xF0 \x80 \x80 \xAD - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xF0 \x80 \x80 \x80 - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xF0 \x8F \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xF8 \x80 \x80 \x80 \xAD - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xF8 \x80 \x80 \x80 \x80 - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xF8 \x87 \xBF \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xFC \x80 \x80 \x80 \x80 \xAD - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xFC \x80 \x80 \x80 \x80 \x80 - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " - \xFC \x83 \xBF \xBF \xBF \xBF - " , { ' - ' , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* invalid bytes */
{ " \xFE " , { 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xFF " , { 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xFE \xBF \xBF \xBF \xBF \xBF \xBF \xBF \xBF " , { 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xFF \xBF \xBF \xBF \xBF \xBF \xBF \xBF \xBF " , { 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xFF \x80 \x80 \x80 \x80 \x80 \x80 \x80 \x80 " , { 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xFF \x40 \x80 \x80 \x80 \x80 \x80 \x80 \x80 " , { 0xfffd , 0x40 , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* lone continuation bytes */
{ " \x80 " , { 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \x80 \x80 " , { 0xfffd , 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xBF " , { 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xBF \xBF " , { 0xfffd , 0xfffd , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* incomplete sequences */
{ " \xC2 - " , { 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xE0 \xA0 - " , { 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xF0 \x90 \x80 - " , { 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xF4 \x8F \xBF - " , { 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xFA \x80 \x80 \x80 - " , { 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
{ " \xFC \x84 \x80 \x80 \x80 - " , { 0xfffd , 0xfffd , 0xfffd , 0xfffd , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* multibyte sequence followed by lone continuation byte */
{ " \xE0 \xA0 \x80 \x80 - " , { 0x800 , 0xfffd , ' - ' , 0 } , STATUS_SOME_NOT_MAPPED } ,
/* byte order marks */
{ " - \xEF \xBB \xBF - \xEF \xBF \xBE - " , { ' - ' , 0xfeff , ' - ' , 0xfffe , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " \xEF \xBB \xBF - " , { 0xfeff , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " \xEF \xBF \xBE - " , { 0xfffe , ' - ' , 0 } , STATUS_SUCCESS } ,
/* invalid code point */
/* 0xffff */
{ " \xEF \xBF \xBF - " , { 0xffff , ' - ' , 0 } , STATUS_SUCCESS } ,
/* canonically equivalent representations -- no normalization should happen */
{ " - \xE1 \xB8 \x89 - " , { ' - ' , 0x1e09 , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " - \xC4 \x87 \xCC \xA7 - " , { ' - ' , 0x0107 , 0x0327 , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " - \xC3 \xA7 \xCC \x81 - " , { ' - ' , 0x00e7 , 0x0301 , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " - \x63 \xCC \xA7 \xCC \x81 - " , { ' - ' , 0x0063 , 0x0327 , 0x0301 , ' - ' , 0 } , STATUS_SUCCESS } ,
{ " - \x63 \xCC \x81 \xCC \xA7 - " , { ' - ' , 0x0063 , 0x0301 , 0x0327 , ' - ' , 0 } , STATUS_SUCCESS } ,
} ;
static void unicode_expect_ ( const WCHAR * out_string , ULONG buflen , ULONG out_chars ,
const char * in_string , ULONG in_chars ,
NTSTATUS expect_status , int line )
{
NTSTATUS status ;
ULONG bytes_out ;
WCHAR buffer [ 128 ] ;
unsigned int i ;
if ( buflen = = ( ULONG ) - 1 )
buflen = sizeof ( buffer ) ;
bytes_out = 0x55555555 ;
memset ( buffer , 0x55 , sizeof ( buffer ) ) ;
status = pRtlUTF8ToUnicodeN (
out_string ? buffer : NULL , buflen , & bytes_out ,
in_string , in_chars ) ;
ok_ ( __FILE__ , line ) ( status = = expect_status , " status = 0x%x \n " , status ) ;
ok_ ( __FILE__ , line ) ( bytes_out = = out_chars * sizeof ( WCHAR ) ,
" bytes_out = %u, expected %u \n " , bytes_out , out_chars * ( ULONG ) sizeof ( WCHAR ) ) ;
if ( out_string )
{
for ( i = 0 ; i < bytes_out / sizeof ( WCHAR ) ; i + + )
ok_ ( __FILE__ , line ) ( buffer [ i ] = = out_string [ i ] ,
" buffer[%d] = 0x%x, expected 0x%x \n " ,
i , buffer [ i ] , out_string [ i ] ) ;
for ( ; i < sizeof ( buffer ) / sizeof ( WCHAR ) ; i + + )
ok_ ( __FILE__ , line ) ( buffer [ i ] = = 0x5555 ,
" buffer[%d] = 0x%x, expected 0x5555 \n " ,
i , buffer [ i ] ) ;
}
}
# define unicode_expect(out_string, buflen, out_chars, in_string, in_chars, expect_status) \
unicode_expect_ ( out_string , buflen , out_chars , in_string , in_chars , expect_status , __LINE__ )
static void test_RtlUTF8ToUnicodeN ( void )
{
NTSTATUS status ;
ULONG bytes_out ;
ULONG bytes_out_array [ 2 ] ;
void * const invalid_pointer = ( void * ) 0x8 ;
WCHAR buffer [ 128 ] ;
const char empty_string [ ] = " " ;
const char test_string [ ] = " A \0 abcdefg " ;
const WCHAR test_stringW [ ] = { ' A ' , 0 , ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' , ' g ' , 0 } ;
const char special_string [ ] = { ' X ' , 0xc2 , 0x80 , 0xF0 , 0x90 , 0x80 , 0x80 , 0 } ;
const WCHAR special_expected [ ] = { ' X ' , 0x80 , 0xd800 , 0xdc00 , 0 } ;
unsigned int input_len ;
const unsigned int test_count = sizeof ( utf8_to_unicode ) / sizeof ( utf8_to_unicode [ 0 ] ) ;
unsigned int i ;
if ( ! pRtlUTF8ToUnicodeN )
{
skip ( " RtlUTF8ToUnicodeN unavailable \n " ) ;
return ;
}
/* show that bytes_out is really ULONG */
memset ( bytes_out_array , 0x55 , sizeof ( bytes_out_array ) ) ;
status = pRtlUTF8ToUnicodeN ( NULL , 0 , bytes_out_array , empty_string , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out_array [ 0 ] = = 0x00000000 , " Got 0x%x \n " , bytes_out_array [ 0 ] ) ;
ok ( bytes_out_array [ 1 ] = = 0x55555555 , " Got 0x%x \n " , bytes_out_array [ 1 ] ) ;
/* parameter checks */
status = pRtlUTF8ToUnicodeN ( NULL , 0 , NULL , NULL , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_4 , " status = 0x%x \n " , status ) ;
status = pRtlUTF8ToUnicodeN ( NULL , 0 , NULL , empty_string , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER , " status = 0x%x \n " , status ) ;
bytes_out = 0x55555555 ;
status = pRtlUTF8ToUnicodeN ( NULL , 0 , & bytes_out , NULL , 0 ) ;
ok ( status = = STATUS_INVALID_PARAMETER_4 , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0x55555555 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUTF8ToUnicodeN ( NULL , 0 , & bytes_out , invalid_pointer , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUTF8ToUnicodeN ( NULL , 0 , & bytes_out , empty_string , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUTF8ToUnicodeN ( NULL , 0 , & bytes_out , test_string , 0 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = 0 , " bytes_out = 0x%x \n " , bytes_out ) ;
bytes_out = 0x55555555 ;
status = pRtlUTF8ToUnicodeN ( NULL , 0 , & bytes_out , empty_string , 1 ) ;
ok ( status = = STATUS_SUCCESS , " status = 0x%x \n " , status ) ;
ok ( bytes_out = = sizeof ( WCHAR ) , " bytes_out = 0x%x \n " , bytes_out ) ;
/* length output with special chars */
# define length_expect(in_chars, out_chars, expect_status) \
unicode_expect_ ( NULL , 0 , out_chars , special_string , in_chars , \
expect_status , __LINE__ )
length_expect ( 0 , 0 , STATUS_SUCCESS ) ;
length_expect ( 1 , 1 , STATUS_SUCCESS ) ;
length_expect ( 2 , 2 , STATUS_SOME_NOT_MAPPED ) ;
length_expect ( 3 , 2 , STATUS_SUCCESS ) ;
length_expect ( 4 , 3 , STATUS_SOME_NOT_MAPPED ) ;
length_expect ( 5 , 3 , STATUS_SOME_NOT_MAPPED ) ;
length_expect ( 6 , 3 , STATUS_SOME_NOT_MAPPED ) ;
length_expect ( 7 , 4 , STATUS_SUCCESS ) ;
length_expect ( 8 , 5 , STATUS_SUCCESS ) ;
# undef length_expect
/* output truncation */
# define truncate_expect(buflen, out_chars, expect_status) \
unicode_expect_ ( special_expected , buflen , out_chars , \
special_string , sizeof ( special_string ) , \
expect_status , __LINE__ )
truncate_expect ( 0 , 0 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 1 , 0 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 2 , 1 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 3 , 1 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 4 , 2 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 5 , 2 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 6 , 3 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 7 , 3 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 8 , 4 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 9 , 4 , STATUS_BUFFER_TOO_SMALL ) ;
truncate_expect ( 10 , 5 , STATUS_SUCCESS ) ;
# undef truncate_expect
/* conversion behavior with varying input length */
for ( input_len = 0 ; input_len < = sizeof ( test_string ) ; input_len + + ) {
/* no output buffer, just length */
unicode_expect ( NULL , 0 , input_len ,
test_string , input_len , STATUS_SUCCESS ) ;
/* write output */
unicode_expect ( test_stringW , - 1 , input_len ,
test_string , input_len , STATUS_SUCCESS ) ;
}
/* test cases for special characters */
for ( i = 0 ; i < test_count ; i + + ) {
bytes_out = 0x55555555 ;
memset ( buffer , 0x55 , sizeof ( buffer ) ) ;
status = pRtlUTF8ToUnicodeN (
buffer , sizeof ( buffer ) , & bytes_out ,
utf8_to_unicode [ i ] . utf8 , strlen ( utf8_to_unicode [ i ] . utf8 ) ) ;
ok ( status = = utf8_to_unicode [ i ] . status ,
" (test %d): status is 0x%x, expected 0x%x \n " ,
i , status , utf8_to_unicode [ i ] . status ) ;
ok ( bytes_out = = lstrlenW ( utf8_to_unicode [ i ] . expected ) * sizeof ( WCHAR ) ,
" (test %d): bytes_out is %u, expected %u \n " ,
i , bytes_out , lstrlenW ( utf8_to_unicode [ i ] . expected ) * ( ULONG ) sizeof ( WCHAR ) ) ;
ok ( ! memcmp ( buffer , utf8_to_unicode [ i ] . expected , bytes_out ) ,
" (test %d): got %s, expected %s \n " ,
i , wine_dbgstr_wn ( buffer , bytes_out / sizeof ( WCHAR ) ) , wine_dbgstr_w ( utf8_to_unicode [ i ] . expected ) ) ;
ok ( buffer [ bytes_out ] = = 0x5555 ,
" (test %d): behind string: 0x%x \n " , i , buffer [ bytes_out ] ) ;
/* same test but include the null terminator */
bytes_out = 0x55555555 ;
memset ( buffer , 0x55 , sizeof ( buffer ) ) ;
status = pRtlUTF8ToUnicodeN (
buffer , sizeof ( buffer ) , & bytes_out ,
utf8_to_unicode [ i ] . utf8 , strlen ( utf8_to_unicode [ i ] . utf8 ) + 1 ) ;
ok ( status = = utf8_to_unicode [ i ] . status ,
" (test %d): status is 0x%x, expected 0x%x \n " ,
i , status , utf8_to_unicode [ i ] . status ) ;
ok ( bytes_out = = ( lstrlenW ( utf8_to_unicode [ i ] . expected ) + 1 ) * sizeof ( WCHAR ) ,
" (test %d): bytes_out is %u, expected %u \n " ,
i , bytes_out , ( lstrlenW ( utf8_to_unicode [ i ] . expected ) + 1 ) * ( ULONG ) sizeof ( WCHAR ) ) ;
ok ( ! memcmp ( buffer , utf8_to_unicode [ i ] . expected , bytes_out ) ,
" (test %d): got %s, expected %s \n " ,
i , wine_dbgstr_wn ( buffer , bytes_out / sizeof ( WCHAR ) ) , wine_dbgstr_w ( utf8_to_unicode [ i ] . expected ) ) ;
ok ( buffer [ bytes_out ] = = 0x5555 ,
" (test %d): behind string: 0x%x \n " , i , buffer [ bytes_out ] ) ;
}
}
2003-02-19 04:40:14 +01:00
START_TEST ( rtlstr )
{
InitFunctionPtrs ( ) ;
if ( pRtlInitAnsiString ) {
test_RtlInitString ( ) ;
test_RtlInitUnicodeString ( ) ;
test_RtlCopyString ( ) ;
test_RtlUnicodeStringToInteger ( ) ;
test_RtlCharToInteger ( ) ;
test_RtlIntegerToUnicodeString ( ) ;
test_RtlIntegerToChar ( ) ;
test_RtlUpperChar ( ) ;
test_RtlUpperString ( ) ;
2003-04-08 02:56:01 +02:00
test_RtlUnicodeStringToAnsiString ( ) ;
test_RtlAppendAsciizToString ( ) ;
test_RtlAppendStringToString ( ) ;
test_RtlAppendUnicodeToString ( ) ;
2003-03-22 01:21:35 +01:00
test_RtlAppendUnicodeStringToString ( ) ;
2005-06-13 12:03:33 +02:00
}
2003-05-06 20:28:02 +02:00
2013-07-22 11:02:04 +02:00
test_RtlInitUnicodeStringEx ( ) ;
test_RtlDuplicateUnicodeString ( ) ;
test_RtlFindCharInUnicodeString ( ) ;
test_RtlGUIDFromString ( ) ;
test_RtlStringFromGUID ( ) ;
test_RtlIsTextUnicode ( ) ;
2005-06-13 12:03:33 +02:00
if ( 0 )
{
test_RtlUpcaseUnicodeChar ( ) ;
test_RtlUpcaseUnicodeString ( ) ;
test_RtlDowncaseUnicodeString ( ) ;
}
2013-07-16 10:52:39 +02:00
test_RtlHashUnicodeString ( ) ;
2014-03-29 16:14:23 +01:00
test_RtlUnicodeToUTF8N ( ) ;
2014-03-29 16:25:25 +01:00
test_RtlUTF8ToUnicodeN ( ) ;
2002-11-12 03:18:10 +01:00
}