1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Test for MultiByteToWideChar
5  * PROGRAMMERS:     Mike "tamlin" Nordell
6  *                  Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7  */
8 
9 #include "precomp.h"
10 
11 /* NOTE: Tested on Win10. We follow Win10 in this function.
12          Win10 might alter its design in future. */
13 
14 /* TODO: Russian, French, Korean etc. codepages */
15 
16 #define CP932   932     /* Japanese Shift_JIS (SJIS) codepage */
17 
18 /* "Japanese" in Japanese UTF-8 */
19 static const char UTF8_Japanese[] = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E";
20 /* "Japanese" in Japanese Shift_JIS */
21 static const char SJIS_Japanese[] = "\x93\xFA\x96\x7B\x8C\xEA";
22 
23 #define MAX_BUFFER  10
24 
25 /* test entry */
26 typedef struct ENTRY
27 {
28     int LineNo;
29     int Return;
30     DWORD Error;
31     UINT CodePage;
32     DWORD Flags;
33     const char *Src;
34     int SrcLen;
35     int DestLen;
36     WCHAR CheckDest[MAX_BUFFER];
37     int CheckLen;
38     BOOL SamePointer;
39 } ENTRY;
40 
41 static const ENTRY Entries[] =
42 {
43     /* without buffer */
44     { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "a", 1 },
45     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", 2 },
46     { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2 },
47     /* negative length */
48     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", -1 },
49     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", -2 },
50     { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", -1 },
51     { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", -3 },
52     /* with buffer */
53     { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "a", 1, 1, {'a', 0x7F7F}, 2 },
54     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "a", 2, 4, {'a', 0, 0x7F7F}, 3 },
55     { __LINE__, 2, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2, 4, {'a', 0, 0x7F7F}, 3 },
56     /* short buffer */
57     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "a", 2, 1, {'a', 0x7F7F}, 2 },
58     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "a", 2, 1, {'a', 0x7F7F}, 2 },
59     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "a", 2, 1, {'a', 0x7F7F}, 2 },
60     /* same pointer */
61     { __LINE__, 0, ERROR_INVALID_PARAMETER, CP_UTF8, 0, "", 1, 1, { 0x7F7F }, 1, TRUE },
62     { __LINE__, 0, ERROR_INVALID_PARAMETER, CP_UTF8, MB_ERR_INVALID_CHARS, "", 1, 1, { 0x7F7F }, 1, TRUE },
63     /* invalid UTF-8 sequences without buffer */
64     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xC0", 2 },
65     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4 },
66     { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3 },
67     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4 },
68     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2 },
69     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4 },
70     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3 },
71     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4 },
72     /* invalid UTF-8 sequences with buffer */
73     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xC0", 2, 4, {0xFFFD, 0, 0x7F7F}, 3},
74     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xC0\xC0\x80", 4, 5, {0xFFFD, 0xFFFD, 0xFFFD, 0, 0x7F7F}, 5 },
75     { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xE0\xC0", 3, 4, {0xFFFD, 0xFFFD, 0, 0x7F7F}, 4 },
76     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xE0\x20\xC0", 4, 5, {0xFFFD, 0x0020, 0xFFFD, 0, 0x7F7F}, 5 },
77     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2, 4, {0xFFFD, 0, 0x7F7F}, 3 },
78     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4, 5, {0xFFFD, 0xFFFD, 0xFFFD, 0, 0x7F7F}, 5 },
79     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3, 4, {0xFFFD, 0xFFFD, 0, 0x7F7F}, 4 },
80     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4, 5, {0xFFFD, 0x0020, 0xFFFD, 0, 0x7F7F}, 5 },
81     /* invalid UTF-8 sequences with short buffer */
82     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xC0", 2, 1, {0xFFFD, 0x7F7F}, 2},
83     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xC0\xC0\x80", 4, 1, {0xFFFD, 0x7F7F}, 2 },
84     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xE0\xC0", 3, 1, {0xFFFD, 0x7F7F}, 2 },
85     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xE0\x20\xC0", 4, 1, {0xFFFD, 0x7F7F}, 2 },
86     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", 2, 1, {0xFFFD, 0x7F7F}, 2 },
87     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", 4, 1, {0xFFFD, 0x7F7F}, 2 },
88     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", 3, 1, {0xFFFD, 0x7F7F}, 2 },
89     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", 4, 1, {0xFFFD, 0x7F7F}, 2 },
90     /* Japanese UTF-8 without buffer */
91     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese) },
92     { __LINE__, 4, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, sizeof(UTF8_Japanese) },
93     /* Japanese UTF-8 with buffer */
94     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
95     { __LINE__, 4, 0xBEAF, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, sizeof(UTF8_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
96     /* Japanese UTF-8 with short buffer */
97     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, UTF8_Japanese, sizeof(UTF8_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
98     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, sizeof(UTF8_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
99     /* Japanese UTF-8 truncated source */
100     { __LINE__, 1, 0xBEAF, CP_UTF8, 0, UTF8_Japanese, 1, 4, {0xFFFD, 0x7F7F}, 2 },
101     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese, 1, 4, {0xFFFD, 0x7F7F}, 2 },
102     /* Japanese CP932 without buffer */
103     { __LINE__, 4, 0xBEAF, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese) },
104     { __LINE__, 4, 0xBEAF, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, sizeof(SJIS_Japanese) },
105     /* Japanese CP932 with buffer */
106     { __LINE__, 4, 0xBEAF, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
107     { __LINE__, 4, 0xBEAF, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, sizeof(SJIS_Japanese), 4, {0x65E5, 0x672C, 0x8A9E, 0, 0x7F7F}, 5 },
108     /* Japanese CP932 with short buffer */
109     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP932, 0, SJIS_Japanese, sizeof(SJIS_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
110     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, sizeof(SJIS_Japanese), 1, {0x65E5, 0x7F7F}, 2 },
111     /* Japanese CP932 truncated source */
112     { __LINE__, 1, 0xBEAF, CP932, 0, SJIS_Japanese, 1, 4, {0x30FB, 0x7F7F}, 2 },
113     { __LINE__, 0, ERROR_NO_UNICODE_TRANSLATION, CP932, MB_ERR_INVALID_CHARS, SJIS_Japanese, 1, 4, {0x7F7F, 0x7F7F}, 2 },
114     /* invalid 5-byte UTF-8 sequences */
115     { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 },
116     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 },
117     { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 },
118     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 },
119     { __LINE__, 5, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 },
120     { __LINE__, 6, 0xBEAF, CP_UTF8, 0, "\xF8\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 6 },
121     /* invalid 6-byte UTF-8 sequences */
122     { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 },
123     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 },
124     { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 },
125     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 },
126     { __LINE__, 5, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 },
127     { __LINE__, 6, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 7 },
128     { __LINE__, 7, 0xBEAF, CP_UTF8, 0, "\xFC\xA3\xA3\xA3\xA3\xA3", 7, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 7 },
129     /* invalid 7-byte UTF-8 sequences */
130     { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 },
131     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 },
132     { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 },
133     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 },
134     { __LINE__, 5, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 },
135     { __LINE__, 6, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 7 },
136     { __LINE__, 7, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 7, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 8 },
137     { __LINE__, 8, 0xBEAF, CP_UTF8, 0, "\xFE\xA3\xA3\xA3\xA3\xA3\xA3", 8, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0}, 8 },
138     /* invalid UTF-8 sequences */
139     { __LINE__, 1, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 1, 8, {0xFFFD, 0x7F7F}, 2 },
140     { __LINE__, 2, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 2, 8, {0xFFFD, 0xFFFD, 0x7F7F}, 3 },
141     { __LINE__, 3, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 3, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 4 },
142     { __LINE__, 4, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 4, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 5 },
143     { __LINE__, 5, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 5, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 6 },
144     { __LINE__, 6, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 6, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 7 },
145     { __LINE__, 7, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 7, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 8 },
146     { __LINE__, 8, 0xBEAF, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 8, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 9 },
147     { __LINE__, 0, ERROR_INSUFFICIENT_BUFFER, CP_UTF8, 0, "\xFF\xA3\xA3\xA3\xA3\xA3\xA3\xA3", 9, 8, {0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x7F7F}, 9 },
148 };
149 
150 static void TestEntry(const ENTRY *pEntry)
151 {
152     int ret, i;
153     WCHAR Buffer[MAX_BUFFER];
154     DWORD Error;
155 
156     FillMemory(Buffer, sizeof(Buffer), 0x7F);
157     SetLastError(0xBEAF);
158 
159     if (pEntry->DestLen == 0)
160     {
161         /* dest is NULL */
162         ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags, pEntry->Src,
163                                   pEntry->SrcLen, NULL, 0);
164     }
165     else
166     {
167         ok(pEntry->DestLen >= pEntry->CheckLen - 1,
168            "Line %d: DestLen was shorter than (CheckLen - 1)\n", pEntry->LineNo);
169 
170         if (pEntry->SamePointer)
171         {
172             /* src ptr == dest ptr */
173             ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags,
174                                       (const char *)Buffer, pEntry->SrcLen,
175                                       Buffer, pEntry->DestLen);
176         }
177         else
178         {
179             /* src ptr != dest ptr */
180             ret = MultiByteToWideChar(pEntry->CodePage, pEntry->Flags,
181                                       pEntry->Src, pEntry->SrcLen,
182                                       Buffer, pEntry->DestLen);
183         }
184     }
185 
186     Error = GetLastError();
187 
188     /* check ret */
189     ok(ret == pEntry->Return, "Line %d: ret expected %d, got %d\n",
190        pEntry->LineNo, pEntry->Return, ret);
191 
192     /* check error code */
193     ok(Error == pEntry->Error,
194        "Line %d: Wrong last error. Expected %lu, got %lu\n",
195        pEntry->LineNo, pEntry->Error, Error);
196 
197     if (pEntry->DestLen)
198     {
199         /* check buffer */
200         for (i = 0; i < pEntry->CheckLen; ++i)
201         {
202             ok(Buffer[i] == pEntry->CheckDest[i], "Line %d: Buffer[%d] expected %d, got %d\n",
203                pEntry->LineNo, i, pEntry->CheckDest[i], Buffer[i]);
204         }
205     }
206 }
207 
208 typedef NTSTATUS (WINAPI* RTLGETVERSION)(PRTL_OSVERSIONINFOW);
209 
210 static RTL_OSVERSIONINFOW *GetRealOSVersion(void)
211 {
212     static RTL_OSVERSIONINFOW osvi = { 0 };
213     RTL_OSVERSIONINFOW *ptr = NULL;
214     HINSTANCE hNTDLL = LoadLibraryW(L"ntdll.dll");
215     RTLGETVERSION fn;
216     if (hNTDLL)
217     {
218         fn = (RTLGETVERSION)GetProcAddress(hNTDLL, "RtlGetVersion");
219         if (fn)
220         {
221             osvi.dwOSVersionInfoSize = sizeof(osvi);
222             if (fn(&osvi) == STATUS_SUCCESS)
223             {
224                 ptr = &osvi;
225             }
226         }
227         FreeLibrary(hNTDLL);
228     }
229     return ptr;
230 }
231 
232 static BOOL IsWin10Plus(void)
233 {
234     RTL_OSVERSIONINFOW *info = GetRealOSVersion();
235     if (!info)
236         return FALSE;
237 
238     return info->dwMajorVersion >= 10;
239 }
240 
241 static BOOL IsReactOS(void)
242 {
243     WCHAR szWinDir[MAX_PATH];
244     GetWindowsDirectoryW(szWinDir, _countof(szWinDir));
245     return (wcsstr(szWinDir, L"ReactOS") != NULL);
246 }
247 
248 START_TEST(MultiByteToWideChar)
249 {
250     size_t i;
251 
252     if (!IsWin10Plus() && !IsReactOS())
253     {
254         trace("This test is designed for Windows 10+ and ReactOS.\n"
255               "It is expected to report some failures on older Windows versions.\n");
256 #if 0
257         skip("\n");
258         return;
259 #endif
260     }
261 
262     for (i = 0; i < _countof(Entries); ++i)
263     {
264         TestEntry(&Entries[i]);
265     }
266 }
267