ReactOS  0.4.15-dev-5459-gb85f005
ConsoleCP.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Tests for i18n console.
5  * COPYRIGHT: Copyright 2017-2020 Katayama Hirofumi MZ
6  * Copyright 2020-2022 Hermès Bélusca-Maïto
7  */
8 
9 #include "precomp.h"
10 
11 #define okCURSOR(hCon, c) \
12 do { \
13  CONSOLE_SCREEN_BUFFER_INFO __sbi; \
14  BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \
15  __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \
16  ok(expect, "Expected cursor at (%d,%d), got (%d,%d)\n", \
17  (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \
18 } while (0)
19 
20 #define ATTR (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
21 
22 static const WCHAR u0414[] = {0x0414, 0}; /* Д */
23 static const WCHAR u9580[] = {0x9580, 0}; /* 門 */
24 static const WCHAR space[] = {L' ', 0};
25 static const WCHAR ideograph_space = (WCHAR)0x3000; /* fullwidth space */
26 static const WCHAR s_str[] = {L'A', 0x9580, 'B', 0};
29 
30 static UINT s_uOEMCP;
32 
33 static BOOL IsCJKCodePage(_In_ UINT CodePage)
34 {
35  switch (CodePage)
36  {
37  case 932: // Japanese
38  case 949: // Korean
39  case 1361: // Korean (Johab)
40  case 936: // Chinese PRC
41  case 950: // Taiwan
42  return TRUE;
43  }
44  return FALSE;
45 }
46 
47 static __inline
49 {
50  switch (CodePage)
51  {
52  case 932: // Japanese (Shift-JIS)
54  case 949: // Korean (Hangul/Wansung)
55  // case 1361: // Korean (Johab)
57  case 936: // Chinese PRC (Chinese Simplified)
59  case 950: // Taiwan (Chinese Traditional)
61  default:
63  }
64 }
65 
67  _In_ const char* file,
68  _In_ int line,
69  _In_ UINT CodePage)
70 {
71  BOOL bSuccess;
72 
73  /* Validate the code page */
74  bSuccess = IsValidCodePage(CodePage);
75  if (!bSuccess)
76  {
77  skip_(file, line)("Code page %d not available\n", CodePage);
78  return FALSE;
79  }
80 
81  /* Set the new code page */
82  SetLastError(0xdeadbeef);
83  bSuccess = SetConsoleOutputCP(CodePage);
84  if (!bSuccess)
85  skip_(file, line)("SetConsoleOutputCP(%d) failed with last error %lu\n", CodePage, GetLastError());
86  return bSuccess;
87 }
88 
89 #define ChangeOutputCP(CodePage) \
90  ChangeOutputCP_(__FILE__, __LINE__, CodePage)
91 
92 
93 #define cmpThreadLangId(file, line, ExpectedLangId) \
94 do { \
95  LANGID ThreadLangId; \
96  ThreadLangId = LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale); \
97  trace_((file), (line))("Thread LangId %d, expecting %d...\n", \
98  ThreadLangId, (ExpectedLangId)); \
99  ok_((file), (line))(ThreadLangId == (ExpectedLangId), \
100  "Thread LangId %d, expected %d\n", \
101  ThreadLangId, (ExpectedLangId)); \
102 } while (0)
103 
104 static BOOL
106  _In_ const char* file,
107  _In_ int line,
108  _In_ UINT CodePage,
109  _In_ LANGID ExpectedLangId)
110 {
111  UINT newcp;
112 
113  /* Verify and set the new code page */
114  if (!ChangeOutputCP_(file, line, CodePage))
115  {
116  skip_(file, line)("Code page %d expected to be valid!\n", CodePage);
117  return FALSE;
118  }
119 
120  newcp = GetConsoleOutputCP();
121  ok_(file, line)(newcp == CodePage, "Console output CP is %d, expected %d\n", newcp, CodePage);
122 
123  /* Verify that the thread lang ID is the expected one */
124  cmpThreadLangId(file, line, ExpectedLangId);
125  return TRUE;
126 }
127 
128 #define doTest_CP_ThreadLang(...) \
129  doTest_CP_ThreadLang_(__FILE__, __LINE__, ##__VA_ARGS__)
130 
132 {
133  /* Save the initial current thread locale. It is (re)initialized after
134  * attaching to a console. Don't use GetThreadLocale() as the latter
135  * can return a replacement value in case CurrentLocale is 0. */
136  LANGID ThreadLangId = LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale);
137  UINT oldcp = GetConsoleOutputCP();
138 
139  if (IsCJKCodePage(s_uOEMCP))
140  {
141  /* We are on a CJK system */
142 
143  /* Is the console in CJK? If so, current thread should be in CJK language */
144  if (!IsCJKCodePage(oldcp))
145  {
146  skip("CJK system but console CP not in CJK\n");
147  }
148  else
149  {
150  /* Check that the thread lang ID matches what the console set */
151  LANGID LangId = MapCJKCPToLangId(oldcp);
152  cmpThreadLangId(__FILE__, __LINE__, LangId);
153  }
154 
155  /* Set the code page to OEM USA (non-CJK codepage that is supported).
156  * Verify that the thread lang ID has changed to non-CJK language. */
158 
159  /* Set the code page to the default system CJK codepage.
160  * Check that the thread lang ID matches what the console set. */
162  }
163  else
164  {
165  /* We are on a non-CJK system */
166 
167  /* Code pages: Japanese, Korean, Chinese Simplified/Traditional */
168  UINT CJKCodePages[] = {932, 949, 936, 950};
169  UINT newcp;
170  USHORT i;
171 
172  /* Switch to a different code page (OEM USA) than the current one.
173  * In such setup, the current thread lang ID should not change. */
174  newcp = (s_uOEMCP == 437 ? 850 : 437);
175  doTest_CP_ThreadLang(newcp, ThreadLangId);
176 
177  /* Try switching to a CJK codepage, if possible, but
178  * the thread lang ID should not change either... */
179 
180  /* Retry as long as no valid CJK codepage has been found */
181  for (i = 0; i < ARRAYSIZE(CJKCodePages); ++i)
182  {
183  newcp = CJKCodePages[i];
184  if (IsValidCodePage(newcp))
185  break; // Found a valid one.
186  }
187  if (i >= ARRAYSIZE(CJKCodePages))
188  {
189  /* No valid CJK code pages on the system */
190  skip("CJK system but console CP not in CJK\n");
191  }
192  else
193  {
194  /* Verify that the thread lang ID remains the same */
195  doTest_CP_ThreadLang(newcp, ThreadLangId);
196  }
197  }
198 
199  /* Restore code page */
200  SetConsoleOutputCP(oldcp);
201 }
202 
203 
204 /* Russian Code Page 855 */
205 // NOTE that CP 866 can also be used
206 static void test_cp855(HANDLE hConOut)
207 {
208  BOOL ret;
209  UINT oldcp;
210  int n;
211  DWORD len;
212  COORD c;
214  int count;
215  WCHAR str[32];
216  WORD attrs[16];
217 
218  /* Set code page */
219  oldcp = GetConsoleOutputCP();
220  if (!ChangeOutputCP(855))
221  {
222  skip("Codepage 855 not available\n");
223  return;
224  }
225 
226  /* Get info */
227  ret = GetConsoleScreenBufferInfo(hConOut, &csbi);
228  ok(ret, "GetConsoleScreenBufferInfo failed\n");
229  trace("csbi.dwSize.X:%d, csbi.dwSize.Y:%d\n", csbi.dwSize.X, csbi.dwSize.Y);
230  count = 200;
231 
232  /* "\u0414" */
233  {
234  /* Output u0414 "count" times at (0,0) */
235  c.X = c.Y = 0;
236  SetConsoleCursorPosition(hConOut, c);
237  okCURSOR(hConOut, c);
238  for (n = 0; n < count; ++n)
239  {
240  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
241  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
242  }
243 
244  /* Check cursor */
245  len = count; /* u0414 is normal width in Russian */
246  c.X = (SHORT)(len % csbi.dwSize.X);
247  c.Y = (SHORT)(len / csbi.dwSize.X);
248  okCURSOR(hConOut, c);
249 
250  /* Read characters at (0,0) */
251  c.X = c.Y = 0;
252  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
253  ok(ret, "ReadConsoleOutputCharacterW failed\n");
254  ok_long(len, 6);
255  ok_int(str[0], 0x414);
256  ok_int(str[1], 0x414);
257  ok_int(str[2], 0x414);
258 
259  /* Read attributes at (0,0) */
260  c.X = c.Y = 0;
261  ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len);
262  ok(ret, "ReadConsoleOutputAttribute failed\n");
263  ok_long(len, 6);
264  ok_int(attrs[0], ATTR);
265 
266  /* Check cursor */
267  c.X = 1;
268  c.Y = 0;
269  ret = SetConsoleCursorPosition(hConOut, c);
270  ok(ret, "SetConsoleCursorPosition failed\n");
271  okCURSOR(hConOut, c);
272 
273  /* Fill by space */
274  c.X = c.Y = 0;
275  FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
276 
277  /* Output u0414 "count" times at (1,0) */
278  c.X = 1;
279  c.Y = 0;
280  SetConsoleCursorPosition(hConOut, c);
281  okCURSOR(hConOut, c);
282  for (n = 0; n < count; ++n)
283  {
284  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
285  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
286  }
287 
288  /* Check cursor */
289  len = 1 + count;
290  c.X = (SHORT)(len % csbi.dwSize.X);
291  c.Y = (SHORT)(len / csbi.dwSize.X);
292  okCURSOR(hConOut, c);
293 
294  /* Read characters at (0,0) */
295  c.X = c.Y = 0;
296  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
297  ok(ret, "ReadConsoleOutputCharacterW failed\n");
298  ok_long(len, 6);
299  ok_int(str[0], L' ');
300  ok_int(str[1], 0x414);
301  ok_int(str[2], 0x414);
302  }
303 
304  /* "\u9580" */
305  {
306  /* Output u9580 "count" times at (0,0) */
307  c.X = c.Y = 0;
308  SetConsoleCursorPosition(hConOut, c);
309  okCURSOR(hConOut, c);
310  for (n = 0; n < count; ++n)
311  {
312  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
313  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
314  }
315 
316  /* Check cursor */
317  len = count; /* u9580 is normal width in Russian */
318  c.X = (SHORT)(len % csbi.dwSize.X);
319  c.Y = (SHORT)(len / csbi.dwSize.X);
320  okCURSOR(hConOut, c);
321 
322  /* Check cursor */
323  c.X = 1;
324  c.Y = 0;
325  ret = SetConsoleCursorPosition(hConOut, c);
326  ok(ret, "SetConsoleCursorPosition failed\n");
327  okCURSOR(hConOut, c);
328 
329  /* Fill by space */
330  c.X = c.Y = 0;
331  ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
332  ok(ret, "FillConsoleOutputCharacterW failed\n");
333  ok_long(len, csbi.dwSize.X * csbi.dwSize.Y);
334 
335  /* Output u9580 "count" times at (1,0) */
336  c.X = 1;
337  c.Y = 0;
338  SetConsoleCursorPosition(hConOut, c);
339  okCURSOR(hConOut, c);
340  for (n = 0; n < count; ++n)
341  {
342  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
343  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
344  }
345 
346  /* Check cursor */
347  len = 1 + count;
348  c.X = (SHORT)(len % csbi.dwSize.X);
349  c.Y = (SHORT)(len / csbi.dwSize.X);
350  okCURSOR(hConOut, c);
351 
352  /* Fill by ideograph space */
353  c.X = c.Y = 0;
354  ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len);
355  ok(ret, "FillConsoleOutputCharacterW failed\n");
356  ok_long(len, csbi.dwSize.X * csbi.dwSize.Y);
357 
358  /* Read characters at (0,0) */
359  c.X = c.Y = 0;
360  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
361  ok(ret, "ReadConsoleOutputCharacterW failed\n");
362  ok_long(len, 6);
363  ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]);
364  ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]);
365  ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]);
366 
367  /* Read attributes at (0,0) */
368  c.X = c.Y = 0;
369  ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len);
370  ok(ret, "ReadConsoleOutputAttribute failed\n");
371  ok_long(len, 6);
372  ok_int(attrs[0], ATTR);
373 
374  /* Read characters at (1,0) */
375  c.X = 1;
376  c.Y = 0;
377  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
378  ok(ret, "ReadConsoleOutputCharacterW failed\n");
379  ok_long(len, 6);
380  ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]);
381  ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]);
382  ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]);
383 
384  /* Output u9580 "count" once at (1,0) */
385  c.X = 1;
386  c.Y = 0;
387  SetConsoleCursorPosition(hConOut, c);
388  okCURSOR(hConOut, c);
389  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
390  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
391 
392  /* Read attributes at (1,0) */
393  c.X = 1;
394  c.Y = 0;
395  ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len);
396  ok(ret, "ReadConsoleOutputAttribute failed\n");
397  ok_long(len, 1);
398  ok_int(attrs[0], ATTR);
399 
400  /* Check cursor */
401  c.X = 2;
402  c.Y = 0;
403  okCURSOR(hConOut, c);
404 
405  /* Read characters at (0,0) */
406  c.X = c.Y = 0;
407  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
408  ok(ret, "ReadConsoleOutputCharacterW failed\n");
409  ok_long(len, 6);
410  ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]);
411  ok(str[1] == u9580[0] || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]);
412  ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]);
413  }
414 
415  /* Restore code page */
416  SetConsoleOutputCP(oldcp);
417 }
418 
419 /* Japanese Code Page 932 */
420 static void test_cp932(HANDLE hConOut)
421 {
422  BOOL ret;
423  UINT oldcp;
424  int n;
425  DWORD len;
426  COORD c, buffSize;
428  int count;
429  WCHAR str[32];
430  WORD attrs[16];
431  CHAR_INFO buff[16];
432  SMALL_RECT sr;
433 
434  /* Set code page */
435  oldcp = GetConsoleOutputCP();
436  if (!ChangeOutputCP(932))
437  {
438  skip("Codepage 932 not available\n");
439  return;
440  }
441 
442  /* Get info */
443  ret = GetConsoleScreenBufferInfo(hConOut, &csbi);
444  ok(ret, "GetConsoleScreenBufferInfo failed\n");
445  trace("csbi.dwSize.X:%d, csbi.dwSize.Y:%d\n", csbi.dwSize.X, csbi.dwSize.Y);
446  count = 200;
447 
448  /* "\u0414" */
449  {
450  /* Output u0414 "count" times at (0,0) */
451  c.X = c.Y = 0;
452  SetConsoleCursorPosition(hConOut, c);
453  okCURSOR(hConOut, c);
454  for (n = 0; n < count; ++n)
455  {
456  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
457  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
458  }
459 
460  /* Check cursor */
461  GetConsoleScreenBufferInfo(hConOut, &csbi);
462  len = count * 2; /* u0414 is fullwidth in Japanese */
463  c.X = (SHORT)(len % csbi.dwSize.X);
464  c.Y = (SHORT)(len / csbi.dwSize.X);
465  okCURSOR(hConOut, c);
466 
467  /* Read characters at (0,0) */
468  c.X = c.Y = 0;
469  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
470  ok(ret, "ReadConsoleOutputCharacterW failed\n");
471  ok_long(len, 3);
472  ok_int(str[0], 0x414);
473  ok_int(str[1], 0x414);
474  ok_int(str[2], 0x414);
475 
476  /* Read attributes at (0,0) */
477  c.X = c.Y = 0;
478  ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len);
479  ok(ret, "ReadConsoleOutputAttribute failed\n");
480  ok_long(len, 6);
481  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
482  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
483 
484  /* Check cursor */
485  c.X = 1;
486  c.Y = 0;
487  ret = SetConsoleCursorPosition(hConOut, c);
488  ok(ret, "SetConsoleCursorPosition failed\n");
489  okCURSOR(hConOut, c);
490 
491  /* Fill by space */
492  c.X = c.Y = 0;
493  FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
494 
495  /* Output u0414 "count" times at (1,0) */
496  c.X = 1;
497  c.Y = 0;
498  SetConsoleCursorPosition(hConOut, c);
499  okCURSOR(hConOut, c);
500  for (n = 0; n < count; ++n)
501  {
502  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
503  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
504  }
505 
506  /* Check cursor */
507  len = csbi.dwSize.X + (count - (csbi.dwSize.X - 1) / 2) * 2;
508  c.X = (SHORT)(len % csbi.dwSize.X);
509  c.Y = (SHORT)(len / csbi.dwSize.X);
510  okCURSOR(hConOut, c);
511 
512  /* Read characters at (0,0) */
513  c.X = 0;
514  c.Y = 0;
515  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
516  ok(ret, "ReadConsoleOutputCharacterW failed\n");
517  ok_long(len, 4);
518  ok_int(str[0], L' ');
519  ok_int(str[1], 0x414);
520  ok_int(str[2], 0x414);
521  }
522 
523  /* "\u9580" */
524  {
525  /* Output u9580 "count" times at (0,0) */
526  c.X = c.Y = 0;
527  SetConsoleCursorPosition(hConOut, c);
528  okCURSOR(hConOut, c);
529  for (n = 0; n < count; ++n)
530  {
531  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
532  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
533  }
534 
535  /* Check cursor */
536  len = count * 2; /* u9580 is fullwidth in Japanese */
537  c.X = (SHORT)(len % csbi.dwSize.X);
538  c.Y = (SHORT)(len / csbi.dwSize.X);
539  okCURSOR(hConOut, c);
540 
541  /* Check cursor */
542  c.X = 1;
543  c.Y = 0;
544  ret = SetConsoleCursorPosition(hConOut, c);
545  ok(ret, "SetConsoleCursorPosition failed\n");
546  okCURSOR(hConOut, c);
547 
548  /* Fill by space */
549  c.X = c.Y = 0;
550  ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
551  ok(ret, "FillConsoleOutputCharacterW failed\n");
552  ok_long(len, csbi.dwSize.X * csbi.dwSize.Y);
553 
554  /* Output u9580 "count" times at (1,0) */
555  c.X = 1;
556  c.Y = 0;
557  SetConsoleCursorPosition(hConOut, c);
558  okCURSOR(hConOut, c);
559  for (n = 0; n < count; ++n)
560  {
561  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
562  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
563  }
564 
565  /* Check cursor */
566  len = csbi.dwSize.X + (count - (csbi.dwSize.X - 1) / 2) * 2;
567  c.X = (SHORT)(len % csbi.dwSize.X);
568  c.Y = (SHORT)(len / csbi.dwSize.X);
569  okCURSOR(hConOut, c);
570 
571  /* Fill by ideograph space */
572  c.X = c.Y = 0;
573  ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len);
574  ok(ret, "FillConsoleOutputCharacterW failed\n");
575  if (s_bIs8Plus)
576  ok_long(len, csbi.dwSize.X * csbi.dwSize.Y / 2);
577  else
578  ok_long(len, csbi.dwSize.X * csbi.dwSize.Y);
579 
580  /* Read characters at (0,0) */
581  c.X = c.Y = 0;
582  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
583  ok(ret, "ReadConsoleOutputCharacterW failed\n");
584  ok_long(len, 3);
588 
589  /* Read attributes at (0,0) */
590  c.X = c.Y = 0;
591  ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len);
592  ok(ret, "ReadConsoleOutputAttribute failed\n");
593  ok_long(len, 6);
594  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
595  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
596  ok_int(attrs[2], ATTR | COMMON_LVB_LEADING_BYTE);
597  ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE);
598  ok_int(attrs[4], ATTR | COMMON_LVB_LEADING_BYTE);
599  ok_int(attrs[5], ATTR | COMMON_LVB_TRAILING_BYTE);
600 
601  /* Output u9580 "count" once at (1,0) */
602  c.X = 1;
603  c.Y = 0;
604  SetConsoleCursorPosition(hConOut, c);
605  okCURSOR(hConOut, c);
606  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
607  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
608 
609  /*
610  * Read attributes at (1,0) -
611  * Note that if only one attribute of a fullwidth character
612  * is retrieved, no leading/trailing byte flag is set!
613  */
614  c.X = 1;
615  c.Y = 0;
616  ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len);
617  ok(ret, "ReadConsoleOutputAttribute failed\n");
618  ok_long(len, 1);
619  ok_int(attrs[0], ATTR);
620 
621  /* Check that the same problem happens for the trailing byte */
622  c.X = 2;
623  c.Y = 0;
624  ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len);
625  ok(ret, "ReadConsoleOutputAttribute failed\n");
626  ok_long(len, 1);
627  ok_int(attrs[0], ATTR);
628 
629  /* Read attributes at (1,0) */
630  c.X = 1;
631  c.Y = 0;
632  ret = ReadConsoleOutputAttribute(hConOut, attrs, 2, c, &len);
633  ok(ret, "ReadConsoleOutputAttribute failed\n");
634  ok_long(len, 2);
635  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
636  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
637 
638  /* Read attributes at (1,0) */
639  ret = ReadConsoleOutputAttribute(hConOut, attrs, 3, c, &len);
640  ok(ret, "ReadConsoleOutputAttribute failed\n");
641  ok_long(len, 3);
642  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
643  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
644  if (s_bIs8Plus)
645  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
646  else
647  ok_int(attrs[2], ATTR);
648 
649  /* Read attributes at (0,0) */
650  c.X = c.Y = 0;
651  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
652  ok(ret, "ReadConsoleOutputAttribute failed\n");
653  ok_long(len, 4);
654  if (s_bIs8Plus)
655  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
656  else
657  ok_int(attrs[0], ATTR);
658  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
659  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
660  if (s_bIs8Plus)
661  ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE);
662  else
663  ok_int(attrs[3], ATTR);
664 
665  /* Check cursor */
666  c.X = 3;
667  c.Y = 0;
668  okCURSOR(hConOut, c);
669 
670  /* Read characters */
671  c.X = c.Y = 0;
672  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
673  ok(ret, "ReadConsoleOutputCharacterW failed\n");
674  if (s_bIs8Plus)
675  {
676  ok_long(len, 3);
678  ok_int(str[1], u9580[0]);
680  }
681  else
682  {
683  ok_long(len, 4);
684  ok_int(str[0], L' ');
685  ok_int(str[1], u9580[0]);
686  ok_int(str[2], L' ');
687  }
688  }
689 
690  /* COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE for u0414 */
691  {
692  /* set cursor */
693  c.X = c.Y = 0;
694  SetConsoleCursorPosition(hConOut, c);
695  okCURSOR(hConOut, c);
696 
697  /* fill by 'A' */
698  ret = FillConsoleOutputCharacterW(hConOut, L'A', csbi.dwSize.X * 2, c, &len);
699  ok_int(ret, 1);
700  ok_long(len, csbi.dwSize.X * 2);
701 
702  /* reset buff */
703  buffSize.X = ARRAYSIZE(buff);
704  buffSize.Y = 1;
705  memset(buff, 0x7F, sizeof(buff));
706 
707  /* read output */
708  c.X = c.Y = 0;
709  ZeroMemory(&sr, sizeof(sr));
710  sr.Right = buffSize.X - 1;
711  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
712  ok_int(ret, 1);
713  ok_int(sr.Left, 0);
714  ok_int(sr.Top, 0);
715  ok_int(sr.Right, buffSize.X - 1);
716  ok_int(sr.Bottom, 0);
717 
718  /* check buff */
719  ok_int(buff[0].Char.UnicodeChar, L'A');
720  ok_int(buff[0].Attributes, ATTR);
721 
722  /* read attr */
723  ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len);
724  ok_int(ret, 1);
725  ok_long(len, 1);
726  ok_int(attrs[0], ATTR);
727 
728  /* read char */
729  c.X = c.Y = 0;
730  memset(str, 0x7F, sizeof(str));
731  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
732  ok_int(ret, 1);
733  ok_long(len, 4);
734  ok_int(str[0], L'A');
735  ok_int(str[1], L'A');
736  ok_int(str[2], L'A');
737  ok_int(str[3], L'A');
738 
739  /* set cursor */
740  c.X = c.Y = 0;
741  SetConsoleCursorPosition(hConOut, c);
742  okCURSOR(hConOut, c);
743 
744  /* write u0414 */
745  ret = WriteConsoleW(hConOut, u0414, 1, &len, NULL);
746  ok_int(ret, 1);
747  ok_long(len, 1);
748 
749  /* reset buff */
750  buffSize.X = ARRAYSIZE(buff);
751  buffSize.Y = 1;
752  memset(buff, 0x7F, sizeof(buff));
753 
754  /* read output */
755  c.X = c.Y = 0;
756  ZeroMemory(&sr, sizeof(sr));
757  sr.Right = buffSize.X - 1;
758  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
759  ok_int(ret, 1);
760  ok_int(sr.Left, 0);
761  ok_int(sr.Top, 0);
762  ok_int(sr.Right, buffSize.X - 1);
763  ok_int(sr.Bottom, 0);
764 
765  /* check buff */
766  if (s_bIs8Plus)
767  {
768  ok_int(buff[0].Char.UnicodeChar, 0x0414);
770  ok_int(buff[1].Char.UnicodeChar, 0x0414);
772  }
773  else
774  {
775  ok_int(buff[0].Char.UnicodeChar, 0x0414);
776  ok_int(buff[0].Attributes, ATTR);
777  ok_int(buff[1].Char.UnicodeChar, L'A');
778  ok_int(buff[1].Attributes, ATTR);
779  }
780  ok_int(buff[2].Char.UnicodeChar, L'A');
781  ok_int(buff[2].Attributes, ATTR);
782  ok_int(buff[3].Char.UnicodeChar, L'A');
783  ok_int(buff[3].Attributes, ATTR);
784 
785  /* read attr */
786  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
787  ok_int(ret, 1);
788  ok_long(len, ARRAYSIZE(attrs));
789  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
790  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
791  ok_int(attrs[2], ATTR);
792  ok_int(attrs[3], ATTR);
793 
794  /* read char */
795  c.X = c.Y = 0;
796  memset(str, 0x7F, sizeof(str));
797  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
798  ok_int(ret, 1);
799  ok_long(len, 3);
800  ok_int(str[0], 0x0414);
801  ok_int(str[1], L'A');
802  ok_int(str[2], L'A');
803  if (s_bIs8Plus)
804  ok_int(str[3], 0);
805  else
806  ok_int(str[3], 0x7F7F);
807 
808  /* set cursor */
809  c.X = 1;
810  c.Y = 0;
811  SetConsoleCursorPosition(hConOut, c);
812  okCURSOR(hConOut, c);
813 
814  /* write u0414 */
815  ret = WriteConsoleW(hConOut, u0414, 1, &len, NULL);
816  ok_int(ret, 1);
817  ok_long(len, 1);
818 
819  /* read output */
820  c.X = c.Y = 0;
821  ZeroMemory(&sr, sizeof(sr));
822  sr.Right = buffSize.X - 1;
823  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
824  ok_int(ret, 1);
825  ok_int(sr.Left, 0);
826  ok_int(sr.Top, 0);
827  ok_int(sr.Right, buffSize.X - 1);
828  ok_int(sr.Bottom, 0);
829 
830  /* check buff */
831  if (s_bIs8Plus)
832  {
833  ok_int(buff[0].Char.UnicodeChar, 0x0414);
835  ok_int(buff[1].Char.UnicodeChar, 0x0414);
837  ok_int(buff[2].Char.UnicodeChar, 0x0414);
839  }
840  else
841  {
842  ok_int(buff[0].Char.UnicodeChar, L' ');
843  ok_int(buff[0].Attributes, ATTR);
844  ok_int(buff[1].Char.UnicodeChar, 0x0414);
845  ok_int(buff[1].Attributes, ATTR);
846  ok_int(buff[2].Char.UnicodeChar, L'A');
847  ok_int(buff[2].Attributes, ATTR);
848  }
849  ok_int(buff[3].Char.UnicodeChar, L'A');
850  ok_int(buff[3].Attributes, ATTR);
851 
852  /* read attr */
853  c.X = c.Y = 0;
854  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
855  ok_int(ret, 1);
856  ok_long(len, ARRAYSIZE(attrs));
857  if (s_bIs8Plus)
858  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
859  else
860  ok_int(attrs[0], ATTR);
861  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
862  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
863  ok_int(attrs[3], ATTR);
864 
865  /* read char */
866  c.X = c.Y = 0;
867  memset(str, 0x7F, sizeof(str));
868  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
869  ok_int(ret, 1);
870  ok_long(len, 3);
871  if (s_bIs8Plus)
872  {
873  ok_int(str[0], 0x0414);
874  ok_int(str[1], 0x0414);
875  ok_int(str[2], L'A');
876  ok_int(str[3], 0);
877  }
878  else
879  {
880  ok_int(str[0], L' ');
881  ok_int(str[1], 0x0414);
882  ok_int(str[2], L'A');
883  ok_int(str[3], 0x7F7F);
884  }
885 
886  /* set cursor */
887  c.X = csbi.dwSize.X - 1;
888  c.Y = 0;
889  SetConsoleCursorPosition(hConOut, c);
890  okCURSOR(hConOut, c);
891 
892  /* write u0414 */
893  WriteConsoleW(hConOut, u0414, 1, &len, NULL);
894  ok_int(ret, 1);
895  ok_long(len, 1);
896 
897  /* reset buff */
898  buffSize.X = ARRAYSIZE(buff);
899  buffSize.Y = 1;
900  memset(buff, 0x7F, sizeof(buff));
901 
902  /* read output */
903  c.X = c.Y = 0;
904  sr.Left = csbi.dwSize.X - 2;
905  sr.Top = 0;
906  sr.Right = csbi.dwSize.X - 1;
907  sr.Bottom = 0;
908  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
909  ok_int(ret, 1);
910  ok_int(sr.Left, csbi.dwSize.X - 2);
911  ok_int(sr.Top, 0);
912  ok_int(sr.Right, csbi.dwSize.X - 1);
913  ok_int(sr.Bottom, 0);
914 
915  /* check buff */
916  ok_int(buff[0].Char.UnicodeChar, L'A');
917  ok_int(buff[0].Attributes, ATTR);
918  ok_int(buff[1].Char.UnicodeChar, L'A');
919  ok_int(buff[1].Attributes, ATTR);
920 
921  /* read attrs */
922  c.X = csbi.dwSize.X - 2;
923  c.Y = 0;
924  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
925  ok_int(ret, 1);
926  ok_long(len, ARRAYSIZE(attrs));
927  ok_int(attrs[0], ATTR);
928  ok_int(attrs[1], ATTR);
929 
930  /* read char */
931  ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len);
932  ok_int(ret, 1);
933  ok_long(len, 2);
934  ok_int(str[0], L'A');
935  ok_int(str[1], L'A');
936 
937  /* fill by 'A' */
938  c.X = c.Y = 0;
939  ret = FillConsoleOutputCharacterW(hConOut, L'A', 10, c, &len);
940  ok_int(ret, 1);
941  ok_long(len, 10);
942 
943  /* fill by u0414 */
944  c.X = 1;
945  c.Y = 0;
946  ret = FillConsoleOutputCharacterW(hConOut, 0x0414, 1, c, &len);
947  c.X = c.Y = 0;
948  ok_int(ret, 1);
949  ok_long(len, 1);
950 
951  /* reset buff */
952  buffSize.X = ARRAYSIZE(buff);
953  buffSize.Y = 1;
954  memset(buff, 0x7F, sizeof(buff));
955 
956  /* read output */
957  c.X = c.Y = 0;
958  sr.Left = 0;
959  sr.Top = 0;
960  sr.Right = 4;
961  sr.Bottom = 0;
962  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
963  ok_int(ret, 1);
964  ok_int(sr.Left, 0);
965  ok_int(sr.Top, 0);
966  ok_int(sr.Right, 4);
967  ok_int(sr.Bottom, 0);
968 
969  /* check buff */
970  ok_int(buff[0].Char.UnicodeChar, L'A');
971  ok_int(buff[0].Attributes, ATTR);
972  if (s_bIs8Plus)
973  {
974  ok_int(buff[1].Char.UnicodeChar, 0x0414);
976  ok_int(buff[2].Char.UnicodeChar, 0x0414);
978  }
979  else
980  {
981  ok_int(buff[1].Char.UnicodeChar, L' ');
982  ok_int(buff[1].Attributes, ATTR);
983  ok_int(buff[2].Char.UnicodeChar, L'A');
984  ok_int(buff[2].Attributes, ATTR);
985  }
986  ok_int(buff[3].Char.UnicodeChar, L'A');
987  ok_int(buff[3].Attributes, ATTR);
988  ok_int(buff[4].Char.UnicodeChar, L'A');
989  ok_int(buff[4].Attributes, ATTR);
990 
991  /* read attrs */
992  c.X = 0;
993  c.Y = 0;
994  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
995  ok_int(ret, 1);
996  ok_long(len, 4);
997  ok_int(attrs[0], ATTR);
998  if (s_bIs8Plus)
999  {
1000  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1001  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1002  }
1003  else
1004  {
1005  ok_int(attrs[1], ATTR);
1006  ok_int(attrs[2], ATTR);
1007  }
1008  ok_int(attrs[3], ATTR);
1009  }
1010 
1011  /* COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE for u9580 */
1012  {
1013  /* set cursor */
1014  c.X = c.Y = 0;
1015  SetConsoleCursorPosition(hConOut, c);
1016  okCURSOR(hConOut, c);
1017 
1018  /* fill by 'A' */
1019  ret = FillConsoleOutputCharacterW(hConOut, L'A', csbi.dwSize.X * 2, c, &len);
1020  ok_int(ret, 1);
1021  ok_long(len, csbi.dwSize.X * 2);
1022 
1023  /* reset buff */
1024  buffSize.X = ARRAYSIZE(buff);
1025  buffSize.Y = 1;
1026  memset(buff, 0x7F, sizeof(buff));
1027 
1028  /* read output */
1029  c.X = c.Y = 0;
1030  ZeroMemory(&sr, sizeof(sr));
1031  sr.Right = buffSize.X - 1;
1032  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1033  ok_int(ret, 1);
1034  ok_int(sr.Left, 0);
1035  ok_int(sr.Top, 0);
1036  ok_int(sr.Right, buffSize.X - 1);
1037  ok_int(sr.Bottom, 0);
1038 
1039  /* check buff */
1040  ok_int(buff[0].Char.UnicodeChar, L'A');
1041  ok_int(buff[0].Attributes, ATTR);
1042 
1043  /* read attr */
1044  ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len);
1045  ok_int(ret, 1);
1046  ok_long(len, 1);
1047  ok_int(attrs[0], ATTR);
1048 
1049  /* read char */
1050  memset(str, 0x7F, sizeof(str));
1051  ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len);
1052  ok_int(ret, 1);
1053  ok_long(len, 2);
1054  ok_int(str[0], L'A');
1055  ok_int(str[1], L'A');
1056 
1057  /* set cursor */
1058  c.X = 0;
1059  c.Y = 0;
1060  SetConsoleCursorPosition(hConOut, c);
1061  okCURSOR(hConOut, c);
1062 
1063  /* write u9580 */
1064  ret = WriteConsoleW(hConOut, u9580, 1, &len, NULL);
1065  ok_int(ret, 1);
1066  ok_long(len, 1);
1067 
1068  /* reset buff */
1069  buffSize.X = ARRAYSIZE(buff);
1070  buffSize.Y = 1;
1071  memset(buff, 0x7F, sizeof(buff));
1072 
1073  /* read output */
1074  c.X = c.Y = 0;
1075  ZeroMemory(&sr, sizeof(sr));
1076  sr.Right = buffSize.X - 1;
1077  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1078  ok_int(ret, 1);
1079  ok_int(sr.Left, 0);
1080  ok_int(sr.Top, 0);
1081  ok_int(sr.Right, buffSize.X - 1);
1082  ok_int(sr.Bottom, 0);
1083 
1084  /* check buff */
1085  if (s_bIs8Plus)
1086  {
1087  ok_int(buff[0].Char.UnicodeChar, u9580[0]);
1089  ok_int(buff[1].Char.UnicodeChar, u9580[0]);
1091  }
1092  else
1093  {
1094  ok_int(buff[0].Char.UnicodeChar, u9580[0]);
1095  ok_int(buff[0].Attributes, ATTR);
1096  ok_int(buff[1].Char.UnicodeChar, L'A');
1097  ok_int(buff[1].Attributes, ATTR);
1098  }
1099  ok_int(buff[2].Char.UnicodeChar, L'A');
1100  ok_int(buff[2].Attributes, ATTR);
1101  ok_int(buff[3].Char.UnicodeChar, L'A');
1102  ok_int(buff[3].Attributes, ATTR);
1103 
1104  /* read attr */
1105  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
1106  ok_int(ret, 1);
1107  ok_long(len, ARRAYSIZE(attrs));
1108 
1109  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
1110  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
1111  ok_int(attrs[2], ATTR);
1112  ok_int(attrs[3], ATTR);
1113 
1114  /* read char */
1115  c.X = c.Y = 0;
1116  memset(str, 0x7F, sizeof(str));
1117  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
1118  ok_int(ret, 1);
1119  ok_long(len, 3);
1120  ok_int(str[0], u9580[0]);
1121  ok_int(str[1], L'A');
1122  ok_int(str[2], L'A');
1123  if (s_bIs8Plus)
1124  ok_int(str[3], 0);
1125  else
1126  ok_int(str[3], 0x7F7F);
1127 
1128  /* set cursor */
1129  c.X = 1;
1130  c.Y = 0;
1131  SetConsoleCursorPosition(hConOut, c);
1132  okCURSOR(hConOut, c);
1133 
1134  /* write u9580 */
1135  ret = WriteConsoleW(hConOut, u9580, 1, &len, NULL);
1136  ok_int(ret, 1);
1137  ok_long(len, 1);
1138 
1139  /* read output */
1140  c.X = c.Y = 0;
1141  ZeroMemory(&sr, sizeof(sr));
1142  sr.Right = buffSize.X - 1;
1143  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1144  ok_int(ret, 1);
1145  ok_int(sr.Left, 0);
1146  ok_int(sr.Top, 0);
1147  ok_int(sr.Right, buffSize.X - 1);
1148  ok_int(sr.Bottom, 0);
1149 
1150  /* check buff */
1151  if (s_bIs8Plus)
1152  {
1153  ok_int(buff[0].Char.UnicodeChar, u9580[0]);
1155  ok_int(buff[1].Char.UnicodeChar, u9580[0]);
1157  ok_int(buff[2].Char.UnicodeChar, u9580[0]);
1159  }
1160  else
1161  {
1162  ok_int(buff[0].Char.UnicodeChar, L' ');
1163  ok_int(buff[0].Attributes, ATTR);
1164  ok_int(buff[1].Char.UnicodeChar, u9580[0]);
1165  ok_int(buff[1].Attributes, ATTR);
1166  ok_int(buff[2].Char.UnicodeChar, L'A');
1167  ok_int(buff[2].Attributes, ATTR);
1168  }
1169  ok_int(buff[3].Char.UnicodeChar, L'A');
1170  ok_int(buff[3].Attributes, ATTR);
1171 
1172  /* read attr */
1173  c.X = c.Y = 0;
1174  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
1175  ok_int(ret, 1);
1176  ok_long(len, ARRAYSIZE(attrs));
1177 
1178  if (s_bIs8Plus)
1179  {
1180  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
1181  }
1182  else
1183  {
1184  ok_int(attrs[0], ATTR);
1185  }
1186  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1187  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1188  ok_int(attrs[3], ATTR);
1189 
1190  /* set cursor */
1191  c.X = csbi.dwSize.X - 1;
1192  c.Y = 0;
1193  SetConsoleCursorPosition(hConOut, c);
1194  okCURSOR(hConOut, c);
1195 
1196  /* write u9580 */
1197  WriteConsoleW(hConOut, u9580, 1, &len, NULL);
1198  ok_int(ret, 1);
1199  ok_long(len, 1);
1200 
1201  /* reset buff */
1202  buffSize.X = ARRAYSIZE(buff);
1203  buffSize.Y = 1;
1204  memset(buff, 0x7F, sizeof(buff));
1205 
1206  /* read output */
1207  c.X = c.Y = 0;
1208  sr.Left = csbi.dwSize.X - 2;
1209  sr.Top = 0;
1210  sr.Right = csbi.dwSize.X - 1;
1211  sr.Bottom = 0;
1212  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1213  ok_int(ret, 1);
1214  ok_int(sr.Left, csbi.dwSize.X - 2);
1215  ok_int(sr.Top, 0);
1216  ok_int(sr.Right, csbi.dwSize.X - 1);
1217  ok_int(sr.Bottom, 0);
1218 
1219  /* check buff */
1220  ok_int(buff[0].Char.UnicodeChar, L'A');
1221  ok_int(buff[0].Attributes, ATTR);
1222  ok_int(buff[1].Char.UnicodeChar, L'A');
1223  ok_int(buff[1].Attributes, ATTR);
1224 
1225  /* read attr */
1226  c.X = csbi.dwSize.X - 2;
1227  c.Y = 0;
1228  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
1229  ok_int(ret, 1);
1230  ok_long(len, ARRAYSIZE(attrs));
1231  ok_int(attrs[0], ATTR);
1232  ok_int(attrs[1], ATTR);
1233 
1234  /* read char */
1235  memset(str, 0x7F, sizeof(str));
1236  ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len);
1237  ok_int(ret, 1);
1238  ok_long(len, 2);
1239  ok_int(str[0], L'A');
1240  ok_int(str[1], L'A');
1241 
1242  /* fill by 'A' */
1243  c.X = c.Y = 0;
1244  ret = FillConsoleOutputCharacterW(hConOut, L'A', 10, c, &len);
1245  ok_int(ret, 1);
1246  ok_long(len, 10);
1247 
1248  /* fill by u9580 */
1249  c.X = 1;
1250  c.Y = 0;
1251  ret = FillConsoleOutputCharacterW(hConOut, u9580[0], 1, c, &len);
1252  c.X = c.Y = 0;
1253  ok_int(ret, 1);
1254  ok_long(len, 1);
1255 
1256  /* reset buff */
1257  buffSize.X = ARRAYSIZE(buff);
1258  buffSize.Y = 1;
1259  memset(buff, 0x7F, sizeof(buff));
1260 
1261  /* read output */
1262  c.X = c.Y = 0;
1263  sr.Left = 0;
1264  sr.Top = 0;
1265  sr.Right = 4;
1266  sr.Bottom = 0;
1267  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1268  ok_int(ret, 1);
1269  ok_int(sr.Left, 0);
1270  ok_int(sr.Top, 0);
1271  ok_int(sr.Right, 4);
1272  ok_int(sr.Bottom, 0);
1273 
1274  /* check buff */
1275  ok_int(buff[0].Char.UnicodeChar, L'A');
1276  ok_int(buff[0].Attributes, ATTR);
1277  if (s_bIs8Plus)
1278  {
1279  ok_int(buff[1].Char.UnicodeChar, u9580[0]);
1281  ok_int(buff[2].Char.UnicodeChar, u9580[0]);
1283  }
1284  else
1285  {
1286  ok_int(buff[1].Char.UnicodeChar, L' ');
1287  ok_int(buff[1].Attributes, ATTR);
1288  ok_int(buff[2].Char.UnicodeChar, L'A');
1289  ok_int(buff[2].Attributes, ATTR);
1290  }
1291  ok_int(buff[3].Char.UnicodeChar, L'A');
1292  ok_int(buff[3].Attributes, ATTR);
1293  ok_int(buff[4].Char.UnicodeChar, L'A');
1294  ok_int(buff[4].Attributes, ATTR);
1295 
1296  /* read attrs */
1297  c.X = 0;
1298  c.Y = 0;
1299  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1300  ok_int(ret, 1);
1301  ok_long(len, 4);
1302  ok_int(attrs[0], ATTR);
1303  if (s_bIs8Plus)
1304  {
1305  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1306  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1307  }
1308  else
1309  {
1310  ok_int(attrs[1], ATTR);
1311  ok_int(attrs[2], ATTR);
1312  }
1313  ok_int(attrs[3], ATTR);
1314  }
1315 
1316  /* FillConsoleOutputAttribute and WriteConsoleOutput */
1317  {
1318  c.X = c.Y = 0;
1319  SetConsoleCursorPosition(hConOut, c);
1320  okCURSOR(hConOut, c);
1321  for (n = 0; n < count; ++n)
1322  {
1323  ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL);
1324  ok_int(ret, 1);
1325  ok_long(len, 1);
1326  }
1327 
1328  /* fill attrs */
1329  c.X = c.Y = 0;
1330  SetConsoleCursorPosition(hConOut, c);
1331  okCURSOR(hConOut, c);
1332  ret = FillConsoleOutputAttribute(hConOut, 0xFFFF, 2, c, &len);
1333  ok_int(ret, 1);
1334  ok_long(len, 2);
1335 
1336  /* read attrs */
1337  memset(attrs, 0x7F, sizeof(attrs));
1338  ret = ReadConsoleOutputAttribute(hConOut, attrs, 3, c, &len);
1339  ok_int(ret, 1);
1340  ok_long(len, 3);
1341  if (s_bIs8Plus)
1342  {
1343  ok_int(attrs[0], 0xDCFF);
1344  ok_int(attrs[1], 0xDCFF);
1345  }
1346  else
1347  {
1348  ok_int(attrs[0], 0xFCFF);
1349  ok_int(attrs[1], 0xFCFF);
1350  }
1351  ok_int(attrs[2], ATTR);
1352 
1353  /* fill attrs */
1354  c.X = c.Y = 0;
1355  SetConsoleCursorPosition(hConOut, c);
1356  okCURSOR(hConOut, c);
1357  ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len);
1358  ok_int(ret, 1);
1359  ok_long(len, 4);
1360 
1361  /* write */
1362  c.X = c.Y = 0;
1363  sr.Left = 0;
1364  sr.Top = 0;
1365  sr.Right = 4;
1366  sr.Bottom = 0;
1367  // Check how Read/WriteConsoleOutput() handle inconsistent DBCS flags.
1368  buff[0].Char.UnicodeChar = u9580[0];
1369  buff[0].Attributes = ATTR | COMMON_LVB_LEADING_BYTE;
1370  buff[1].Char.UnicodeChar = u9580[0];
1371  buff[1].Attributes = ATTR | COMMON_LVB_LEADING_BYTE;
1372  buff[2].Char.UnicodeChar = u9580[0];
1373  buff[2].Attributes = ATTR | COMMON_LVB_TRAILING_BYTE;
1374  buff[3].Char.UnicodeChar = L'A';
1375  buff[3].Attributes = ATTR;
1376  buff[4].Char.UnicodeChar = L' ';
1377  buff[4].Attributes = 0xFFFF;
1378  buffSize.X = 4;
1379  buffSize.Y = 1;
1380  ret = WriteConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1381  ok_int(ret, 1);
1382  ok_int(sr.Left, 0);
1383  ok_int(sr.Top, 0);
1384  ok_int(sr.Right, 3);
1385  ok_int(sr.Bottom, 0);
1386 
1387  /* read output */
1388  sr.Left = 0;
1389  sr.Top = 0;
1390  sr.Right = 4;
1391  sr.Bottom = 0;
1392  memset(buff, 0x7F, sizeof(buff));
1393  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1394  ok_int(ret, 1);
1395  ok_int(sr.Left, 0);
1396  ok_int(sr.Top, 0);
1397  ok_int(sr.Right, 3);
1398  ok_int(sr.Bottom, 0);
1399 
1400  /* check buff */
1401  if (s_bIs8Plus)
1402  {
1403  ok_int(buff[0].Char.UnicodeChar, u9580[0]);
1405  ok_int(buff[1].Char.UnicodeChar, u9580[0]);
1407  ok_int(buff[2].Char.UnicodeChar, u9580[0]);
1409  ok_int(buff[3].Char.UnicodeChar, L'A');
1410  ok_int(buff[3].Attributes, ATTR);
1411  ok_int(buff[4].Char.UnicodeChar, 0x7F7F);
1412  ok_int(buff[4].Attributes, 0x7F7F);
1413  }
1414  else
1415  {
1416  ok_int(buff[0].Char.UnicodeChar, u9580[0]);
1417  ok_int(buff[0].Attributes, ATTR);
1418  ok_int(buff[1].Char.UnicodeChar, u9580[0]);
1419  ok_int(buff[1].Attributes, ATTR);
1420  ok_int(buff[2].Char.UnicodeChar, 0);
1421  ok_int(buff[2].Attributes, 0);
1422  ok_int(buff[3].Char.UnicodeChar, 0);
1423  ok_int(buff[3].Attributes, 0);
1424  ok_int(buff[4].Char.UnicodeChar, 0x7F7F);
1425  ok_int(buff[4].Attributes, 0x7F7F);
1426  }
1427 
1428  /* read attrs */
1429  c.X = c.Y = 0;
1430  memset(attrs, 0x7F, sizeof(attrs));
1431  ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len);
1432  ok_int(ret, 1);
1433  ok_long(len, 6);
1434  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
1435  if (s_bIs8Plus)
1436  {
1437  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1438  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1439  ok_int(attrs[3], ATTR);
1440  }
1441  else
1442  {
1443  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
1444  ok_int(attrs[2], ATTR | COMMON_LVB_LEADING_BYTE);
1445  ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE);
1446  }
1447  ok_int(attrs[4], ATTR);
1448  ok_int(attrs[5], ATTR);
1449  }
1450 
1451  /* WriteConsoleOutputCharacterW and WriteConsoleOutputAttribute */
1452  {
1453  c.X = c.Y = 0;
1454  SetConsoleCursorPosition(hConOut, c);
1455  okCURSOR(hConOut, c);
1456  for (n = 0; n < count; ++n)
1457  {
1458  ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL);
1459  ok_int(ret, 1);
1460  ok_long(len, 1);
1461  }
1462 
1463  /* write attrs */
1464  attrs[0] = ATTR;
1465  attrs[1] = 0xFFFF;
1466  attrs[2] = ATTR;
1467  attrs[3] = 0;
1468  ret = WriteConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1469  ok_int(ret, 1);
1470  ok_long(len, 4);
1471 
1472  /* read attrs */
1473  memset(attrs, 0x7F, sizeof(attrs));
1474  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1475  ok_int(ret, 1);
1476  ok_long(len, 4);
1477  ok_int(attrs[0], ATTR);
1478  if (s_bIs8Plus)
1479  ok_int(attrs[1], 0xDCFF);
1480  else
1481  ok_int(attrs[1], 0xFCFF);
1482  ok_int(attrs[2], ATTR);
1483  ok_int(attrs[3], 0);
1484 
1485  /* fill attr */
1486  ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len);
1487  ok_int(ret, 1);
1488  ok_long(len, 4);
1489 
1490  /* write char */
1491  ret = WriteConsoleOutputCharacterW(hConOut, s_str, 4, c, &len);
1492  ok_int(ret, 1);
1493  ok_long(len, 4);
1494 
1495  /* read attrs */
1496  memset(attrs, 0x7F, sizeof(attrs));
1497  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1498  ok_int(ret, 1);
1499  ok_long(len, 4);
1500  ok_int(attrs[0], ATTR);
1501  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1502  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1503  ok_int(attrs[3], ATTR);
1504  }
1505 
1506  /* Restore code page */
1507  SetConsoleOutputCP(oldcp);
1508 }
1509 
1510 
1511 START_TEST(ConsoleCP)
1512 {
1513  HANDLE hConIn, hConOut;
1514  OSVERSIONINFOA osver = { sizeof(osver) };
1515 
1516  // https://github.com/reactos/reactos/pull/2131#issuecomment-563189380
1517  GetVersionExA(&osver);
1518  s_bIs8Plus = (osver.dwMajorVersion > 6) ||
1519  (osver.dwMajorVersion == 6 && osver.dwMinorVersion >= 2);
1520 
1521  FreeConsole();
1522  ok(AllocConsole(), "Couldn't alloc console\n");
1523 
1524  hConIn = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1525  hConOut = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1526  ok(hConIn != INVALID_HANDLE_VALUE, "Opening ConIn\n");
1527  ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n");
1528 
1529  /* Retrieve the system OEM code page */
1530  s_uOEMCP = GetOEMCP();
1531  trace("Running on %s system (codepage %d)\n",
1532  IsCJKCodePage(s_uOEMCP) ? "CJK" : "Non-CJK",
1533  s_uOEMCP);
1534 
1535  /* Test thread lang ID syncing with console code page */
1537 
1539  {
1540  if (!IsCJKCodePage(s_uOEMCP))
1541  test_cp855(hConOut);
1542  else
1543  skip("Russian testcase is skipped because of CJK\n");
1544  }
1545  else
1546  {
1547  skip("Russian locale is not installed\n");
1548  }
1549 
1551  {
1552  if (IsCJKCodePage(s_uOEMCP))
1553  test_cp932(hConOut);
1554  else
1555  skip("Japanese testcase is skipped because of not CJK\n");
1556  }
1557  else
1558  {
1559  skip("Japanese locale is not installed\n");
1560  }
1561 
1562  CloseHandle(hConIn);
1563  CloseHandle(hConOut);
1564  FreeConsole();
1565  ok(AllocConsole(), "Couldn't alloc console\n");
1566 }
static const WCHAR u0414[]
Definition: ConsoleCP.c:22
#define ATTR
Definition: ConsoleCP.c:20
#define MAKELCID(lgid, srtid)
BOOL WINAPI SetConsoleOutputCP(IN UINT wCodepage)
Definition: console.c:695
BOOL WINAPI AllocConsole(VOID)
Definition: console.c:74
#define SUBLANG_CHINESE_TRADITIONAL
Definition: nls.h:208
ULONG dwMajorVersion
Definition: rtltypes.h:238
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputW(IN HANDLE hConsoleOutput, IN CONST CHAR_INFO *lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpWriteRegion)
Definition: readwrite.c:1569
BOOL WINAPI FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: console.c:525
#define TRUE
Definition: types.h:120
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1447
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define SUBLANG_DEFAULT
Definition: nls.h:168
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputW(IN HANDLE hConsoleOutput, OUT PCHAR_INFO lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpReadRegion)
Definition: readwrite.c:1338
GLdouble n
Definition: glext.h:7729
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1670
DWORD LCID
Definition: nls.h:13
WORD LANGID
Definition: typedefs.h:81
static BOOL IsCJKCodePage(_In_ UINT CodePage)
Definition: ConsoleCP.c:33
#define ok_long(expression, result)
Definition: atltest.h:133
#define lstrlenW
Definition: compat.h:750
static BOOLEAN bSuccess
Definition: drive.cpp:433
#define LCID_INSTALLED
Definition: winnls.h:201
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
BOOL WINAPI WriteConsoleOutputCharacterW(HANDLE hConsoleOutput, IN LPCWSTR lpCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: console.c:451
static void test_cp855(HANDLE hConOut)
Definition: ConsoleCP.c:206
#define L(x)
Definition: ntvdm.h:50
#define LANG_JAPANESE
Definition: nls.h:76
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
short SHORT
Definition: pedump.c:59
#define GENERIC_WRITE
Definition: nt_native.h:90
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2451
const WCHAR * str
#define ok_int(expression, result)
Definition: atltest.h:134
BOOL WINAPI SetConsoleCursorPosition(IN HANDLE hConsoleOutput, IN COORD dwCursorPosition)
Definition: console.c:641
#define _In_
Definition: ms_sal.h:308
Definition: parser.c:48
static BOOL s_bIs8Plus
Definition: ConsoleCP.c:31
static __inline LANGID MapCJKCPToLangId(_In_ UINT CodePage)
Definition: ConsoleCP.c:48
static BOOL doTest_CP_ThreadLang_(_In_ const char *file, _In_ int line, _In_ UINT CodePage, _In_ LANGID ExpectedLangId)
Definition: ConsoleCP.c:105
BOOL WINAPI GetVersionExA(IN LPOSVERSIONINFOA lpVersionInformation)
Definition: version.c:69
#define OPEN_EXISTING
Definition: compat.h:775
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:595
SHORT Left
Definition: blue.h:32
ULONG X
Definition: bl.h:1339
BOOL WINAPI FreeConsole(VOID)
Definition: console.c:156
#define trace
Definition: atltest.h:70
SHORT Bottom
Definition: blue.h:35
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SORT_DEFAULT
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput, OUT LPWORD lpAttribute, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfAttrsRead)
Definition: readwrite.c:1422
#define cmpThreadLangId(file, line, ExpectedLangId)
Definition: ConsoleCP.c:93
#define doTest_CP_ThreadLang(...)
Definition: ConsoleCP.c:128
const GLubyte * c
Definition: glext.h:8905
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:752
#define LANG_RUSSIAN
Definition: nls.h:113
SHORT Top
Definition: blue.h:33
#define LANG_ENGLISH
Definition: nls.h:52
static const WCHAR ideograph_space
Definition: ConsoleCP.c:25
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: lang.c:1552
int ret
static const LCID lcidJapanese
Definition: ConsoleCP.c:27
static const WCHAR s_str[]
Definition: ConsoleCP.c:26
GLenum GLsizei len
Definition: glext.h:6722
ULONG dwMinorVersion
Definition: rtltypes.h:239
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define GENERIC_READ
Definition: compat.h:135
#define SUBLANG_CHINESE_SIMPLIFIED
Definition: nls.h:209
Definition: bl.h:1337
START_TEST(ConsoleCP)
Definition: ConsoleCP.c:1511
#define SUBLANG_KOREAN
Definition: nls.h:280
static UINT s_uOEMCP
Definition: ConsoleCP.c:30
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1604
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
#define ok(value,...)
Definition: atltest.h:57
static void test_cp932(HANDLE hConOut)
Definition: ConsoleCP.c:420
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define ChangeOutputCP(CodePage)
Definition: ConsoleCP.c:89
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput, OUT LPWSTR lpCharacter, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfCharsRead)
Definition: readwrite.c:1380
static const WCHAR u9580[]
Definition: ConsoleCP.c:23
#define skip(...)
Definition: atltest.h:64
#define okCURSOR(hCon, c)
Definition: ConsoleCP.c:11
#define COMMON_LVB_LEADING_BYTE
Definition: wincon.h:48
#define LANG_CHINESE
Definition: nls.h:42
#define c
Definition: ke_i.h:80
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_KOREAN
Definition: nls.h:84
static VOID test_CP_ThreadLang(VOID)
Definition: ConsoleCP.c:131
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN CONST WORD *lpAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: readwrite.c:1653
#define COMMON_LVB_TRAILING_BYTE
Definition: wincon.h:49
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
SHORT Right
Definition: blue.h:34
static BOOL ChangeOutputCP_(_In_ const char *file, _In_ int line, _In_ UINT CodePage)
Definition: ConsoleCP.c:66
ULONG Y
Definition: bl.h:1340
#define memset(x, y, z)
Definition: compat.h:39
#define skip_(test, file, line,...)
Definition: kmt_test.h:222
static unsigned char buff[32768]
Definition: fatten.c:17
#define ok_(x1, x2)
Definition: atltest.h:61
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput, IN WCHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1674
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
static const LCID lcidRussian
Definition: ConsoleCP.c:28
Definition: fci.c:126
UINT WINAPI GetOEMCP(VOID)
Definition: nls.c:2322