[ADVAPI32_APITEST]: I wasn't alone for writing these tests!
[reactos.git] / rostests / apitests / advapi32 / IsTextUnicode.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Tests for (Rtl)IsTextUnicode.
5 * PROGRAMMERS: Hermes Belusca-Maito
6 * Dmitry Chapyshev
7 */
8
9 #include <apitest.h>
10
11 #define WIN32_NO_STATUS
12 #include <ndk/rtlfuncs.h>
13 #include <winbase.h>
14 #include <winnls.h>
15 #include <wincon.h>
16 #include <stdio.h>
17
18 PVOID LoadCodePageData(ULONG Code)
19 {
20 char filename[MAX_PATH], sysdir[MAX_PATH];
21 HANDLE hFile;
22 PVOID Data = NULL;
23 GetSystemDirectoryA(sysdir, MAX_PATH);
24
25 if (Code != -1)
26 sprintf(filename, "%s\\c_%lu.nls", sysdir, Code);
27 else
28 sprintf(filename, "%s\\l_intl.nls", sysdir);
29
30 hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
31 if (hFile != INVALID_HANDLE_VALUE)
32 {
33 DWORD dwRead;
34 DWORD dwFileSize = GetFileSize(hFile, NULL);
35 Data = malloc(dwFileSize);
36 ReadFile(hFile, Data, dwFileSize, &dwRead, NULL);
37 CloseHandle(hFile);
38 }
39 return Data;
40 }
41
42 /* https://www.microsoft.com/resources/msdn/goglobal/default.mspx */
43 void SetupLocale(ULONG AnsiCode, ULONG OemCode, ULONG Unicode)
44 {
45 NLSTABLEINFO NlsTable;
46 PVOID AnsiCodePageData;
47 PVOID OemCodePageData;
48 PVOID UnicodeCaseTableData;
49
50 AnsiCodePageData = LoadCodePageData(AnsiCode);
51 OemCodePageData = LoadCodePageData(OemCode);
52 UnicodeCaseTableData = LoadCodePageData(Unicode);
53
54 RtlInitNlsTables(AnsiCodePageData, OemCodePageData, UnicodeCaseTableData, &NlsTable);
55 RtlResetRtlTranslations(&NlsTable);
56 /* Do NOT free the buffers here, they are directly used!
57 Yes, we leak the old buffers, but this is a test anyway... */
58
59 }
60
61 START_TEST(IsTextUnicode)
62 {
63 #define INVALID_FLAG 0xFFFFFFFF
64
65 #define NEW_TEST(Buffer, Flags, ResultFlags, Success) \
66 { (PVOID)(Buffer), sizeof((Buffer)), (Flags), (ResultFlags), (Success) }
67
68 static struct
69 {
70 /* Input */
71 PVOID Buffer;
72 INT Size;
73 INT Flags;
74
75 /* Output */
76 INT ResultFlags;
77 BOOL Success;
78 } Tests[] =
79 {
80 /* ANSI string */
81
82 // 0
83 NEW_TEST("ANSI string", IS_TEXT_UNICODE_ASCII16, 0, FALSE),
84 NEW_TEST("ANSI string", IS_TEXT_UNICODE_STATISTICS, 0, FALSE),
85 NEW_TEST("ANSI string", INVALID_FLAG, 0, FALSE),
86
87 /* UNICODE strings */
88
89 // 3
90 NEW_TEST(L"a", IS_TEXT_UNICODE_ASCII16, IS_TEXT_UNICODE_ASCII16, TRUE),
91 NEW_TEST(L"a", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_ASCII16, TRUE),
92 NEW_TEST(L"a", IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_STATISTICS, TRUE),
93 NEW_TEST(L"a", INVALID_FLAG, 0, TRUE),
94
95 // 7
96 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_ASCII16, 0, FALSE),
97 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_STATISTICS, TRUE),
98 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_STATISTICS, TRUE),
99 NEW_TEST(L"UNICODE String 0", INVALID_FLAG, 0, TRUE),
100
101 // 11
102 NEW_TEST(L"\xFEFF" L"UNICODE String 1", IS_TEXT_UNICODE_ASCII16, 0, FALSE),
103 NEW_TEST(L"\xFEFF" L"UNICODE String 1", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_CONTROLS, TRUE),
104 NEW_TEST(L"\xFEFF" L"UNICODE String 1", IS_TEXT_UNICODE_STATISTICS, 0, FALSE),
105 NEW_TEST(L"\xFEFF" L"UNICODE String 1", INVALID_FLAG, 0, TRUE),
106
107 // 15
108 NEW_TEST(L"\xFFFE" L"UNICODE String 2", IS_TEXT_UNICODE_ASCII16, 0, FALSE),
109 NEW_TEST(L"\xFFFE" L"UNICODE String 2", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS, TRUE),
110 NEW_TEST(L"\xFFFE" L"UNICODE String 2", IS_TEXT_UNICODE_STATISTICS, 0, FALSE),
111 NEW_TEST(L"\xFFFE" L"UNICODE String 2", INVALID_FLAG, 0, FALSE),
112
113 // 19
114 NEW_TEST(L"UNICODE String 3 Привет!", IS_TEXT_UNICODE_ASCII16, 0, FALSE),
115 NEW_TEST(L"UNICODE String 3 Привет!", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_STATISTICS, TRUE),
116 NEW_TEST(L"UNICODE String 3 Привет!", IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_STATISTICS, TRUE),
117 NEW_TEST(L"UNICODE String 3 Привет!", INVALID_FLAG, 0, TRUE),
118
119 // 23
120 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", IS_TEXT_UNICODE_ASCII16, 0, FALSE),
121 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_CONTROLS, TRUE),
122 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", IS_TEXT_UNICODE_STATISTICS, 0, FALSE),
123 NEW_TEST(L"\xFEFF" L"UNICODE String 4 Привет!", INVALID_FLAG, 0, TRUE),
124
125 // 27
126 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", IS_TEXT_UNICODE_ASCII16, 0, FALSE),
127 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", IS_TEXT_UNICODE_UNICODE_MASK, IS_TEXT_UNICODE_CONTROLS, TRUE),
128 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", IS_TEXT_UNICODE_STATISTICS, 0, FALSE),
129 NEW_TEST(L"\xFFFE" L"UNICODE String 5 Привет!", INVALID_FLAG, 0, FALSE),
130
131 // 31
132 /* Reverse BOM */
133 NEW_TEST(L"UNICODE S" L"\xFFFE" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE),
134 /* UNICODE_NUL */
135 NEW_TEST(L"UNICODE S" L"\x0000" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE),
136 /* ASCII CRLF (packed into one word) */
137 NEW_TEST(L"UNICODE S" L"\x0A0D" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE),
138 /* Unicode 0xFFFF */
139 NEW_TEST(L"UNICODE S" L"\xFFFF" L"tring 5 Привет!", IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ILLEGAL_CHARS, FALSE),
140
141 // 35
142 NEW_TEST(L"UNICODE String 0", IS_TEXT_UNICODE_DBCS_LEADBYTE, 0, FALSE)
143 };
144
145 const char japanese_with_lead[] = "ABC" "\x83\x40" "D";
146 const char simplfied_chinese_with_lead[] = "ABC" "\xC5\xC5" "D";
147 const char korean_with_lead[] = "ABC" "\xBF\xAD" "D";
148 const char traditional_chinese_with_lead[] = "ABC" "\xB1\xC1" "D";
149
150 UINT i;
151 BOOL Success;
152 INT Result;
153
154 for (i = 0; i < ARRAYSIZE(Tests); ++i)
155 {
156 Result = Tests[i].Flags;
157 Success = IsTextUnicode(Tests[i].Buffer, Tests[i].Size, ((Result != INVALID_FLAG) ? &Result : NULL));
158 ok(Success == Tests[i].Success, "IsTextUnicode(%u) returned 0x%x, expected %s\n", i, Success, (Tests[i].Success ? "TRUE" : "FALSE"));
159 if (Result != INVALID_FLAG)
160 ok(Result == Tests[i].ResultFlags, "IsTextUnicode(%u) Result returned 0x%x, expected 0x%x\n", i, Result, Tests[i].ResultFlags);
161 }
162
163 /* Japanese */
164 SetupLocale(932, 932, -1);
165
166 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE;
167 ok(!IsTextUnicode(japanese_with_lead, sizeof(japanese_with_lead), &Result), "IsTextUnicode() returned TRUE, expected FALSE\n");
168 ok(Result == IS_TEXT_UNICODE_DBCS_LEADBYTE, "Result returned 0x%x, expected 0x%x\n", Result, IS_TEXT_UNICODE_DBCS_LEADBYTE);
169
170 /* Simplified Chinese */
171 SetupLocale(936, 936, -1);
172
173 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE;
174 ok(!IsTextUnicode(simplfied_chinese_with_lead, sizeof(simplfied_chinese_with_lead), &Result), "IsTextUnicode() returned TRUE, expected FALSE\n");
175 ok(Result == IS_TEXT_UNICODE_DBCS_LEADBYTE, "Result returned 0x%x, expected 0x%x\n", Result, IS_TEXT_UNICODE_DBCS_LEADBYTE);
176
177 /* Korean */
178 SetupLocale(949, 949, -1);
179
180 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE;
181 ok(!IsTextUnicode(korean_with_lead, sizeof(korean_with_lead), &Result), "IsTextUnicode() returned TRUE, expected FALSE\n");
182 ok(Result == IS_TEXT_UNICODE_DBCS_LEADBYTE, "Result returned 0x%x, expected 0x%x\n", Result, IS_TEXT_UNICODE_DBCS_LEADBYTE);
183
184 /* Traditional Chinese */
185 SetupLocale(950, 950, -1);
186
187 Result = IS_TEXT_UNICODE_DBCS_LEADBYTE;
188 ok(!IsTextUnicode(traditional_chinese_with_lead, sizeof(traditional_chinese_with_lead), &Result), "IsTextUnicode() returned TRUE, expected FALSE\n");
189 ok(Result == IS_TEXT_UNICODE_DBCS_LEADBYTE, "Result returned 0x%x, expected 0x%x\n", Result, IS_TEXT_UNICODE_DBCS_LEADBYTE);
190 }