ReactOS  0.4.14-dev-815-ge410a12
ConsoleCP.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: GPLv2+ - See COPYING in the top level directory
4  * PURPOSE: Test for i18n console test
5  * PROGRAMMERS: Katayama Hirofumi MZ
6  */
7 
8 #include "precomp.h"
9 
10 #define okCURSOR(hCon, c) do { \
11  CONSOLE_SCREEN_BUFFER_INFO __sbi; \
12  BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \
13  __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \
14  ok(expect, "Expected cursor at (%d,%d), got (%d,%d)\n", \
15  (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \
16 } while (0)
17 
18 #define ATTR \
19  (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
20 
21 static const WCHAR u0414[] = {0x0414, 0}; /* Д */
22 static const WCHAR u9580[] = {0x9580, 0}; /* 門 */
23 static const WCHAR space[] = {L' ', 0};
24 static const WCHAR ideograph_space = (WCHAR)0x3000; /* fullwidth space */
25 static const WCHAR s_str[] = {L'A', 0x9580, 'B', 0};
29 
30 static BOOL IsCJKCodePage(void)
31 {
32  switch (GetOEMCP())
33  {
34  case 936: // Chinese PRC
35  case 932: // Japanese
36  case 949: // Korean
37  case 1361: // Korean (Johab)
38  case 950: // Taiwan
39  return TRUE;
40  }
41  return FALSE;
42 }
43 
44 /* Russian Code Page 855 */
45 // NOTE that CP 866 can also be used
46 static void test_cp855(HANDLE hConOut)
47 {
48  BOOL ret;
49  DWORD oldcp;
50  int n;
51  DWORD len;
52  COORD c;
54  int count;
55  WCHAR str[32];
56  WORD attr;
57 
58  if (!IsValidCodePage(855))
59  {
60  skip("Codepage 855 not available\n");
61  return;
62  }
63 
64  /* Set code page */
65  oldcp = GetConsoleOutputCP();
66  SetLastError(0xdeadbeef);
67  ret = SetConsoleOutputCP(855);
68  if (!ret)
69  {
70  skip("SetConsoleOutputCP failed with last error %lu\n", GetLastError());
71  return;
72  }
73 
74  /* Get info */
75  ret = GetConsoleScreenBufferInfo(hConOut, &csbi);
76  ok(ret, "GetConsoleScreenBufferInfo failed\n");
77  trace("csbi.dwSize.X:%d, csbi.dwSize.Y:%d\n", csbi.dwSize.X, csbi.dwSize.Y);
78  count = 200;
79 
80  /* "\u0414" */
81  {
82  /* Output u0414 "count" times at (0,0) */
83  c.X = c.Y = 0;
84  SetConsoleCursorPosition(hConOut, c);
85  okCURSOR(hConOut, c);
86  for (n = 0; n < count; ++n)
87  {
88  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
89  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
90  }
91 
92  /* Check cursor */
93  len = count; /* u0414 is normal width in Russian */
94  c.X = (SHORT)(len % csbi.dwSize.X);
95  c.Y = (SHORT)(len / csbi.dwSize.X);
96  okCURSOR(hConOut, c);
97 
98  /* Read characters at (0,0) */
99  c.X = c.Y = 0;
100  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
101  ok(ret, "ReadConsoleOutputCharacterW failed\n");
102  ok(len == 6, "len was: %ld\n", len);
103  ok(str[0] == 0x414, "str[0] was: 0x%04X\n", str[0]);
104  ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]);
105  ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]);
106 
107  /* Check cursor */
108  c.X = 1;
109  c.Y = 0;
110  ret = SetConsoleCursorPosition(hConOut, c);
111  ok(ret, "SetConsoleCursorPosition failed\n");
112  okCURSOR(hConOut, c);
113 
114  /* Fill by space */
115  c.X = c.Y = 0;
116  FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
117 
118  /* Output u0414 "count" times at (1,0) */
119  c.X = 1;
120  c.Y = 0;
121  SetConsoleCursorPosition(hConOut, c);
122  okCURSOR(hConOut, c);
123  for (n = 0; n < count; ++n)
124  {
125  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
126  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
127  }
128 
129  /* Check cursor */
130  len = 1 + count;
131  c.X = (SHORT)(len % csbi.dwSize.X);
132  c.Y = (SHORT)(len / csbi.dwSize.X);
133  okCURSOR(hConOut, c);
134 
135  /* Read characters at (0,0) */
136  c.X = c.Y = 0;
137  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
138  ok(ret, "ReadConsoleOutputCharacterW failed\n");
139  ok(len == 6, "len was: %ld\n", len);
140  ok(str[0] == L' ', "str[0] was: 0x%04X\n", str[0]);
141  ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]);
142  ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]);
143  }
144 
145  /* "\u9580" */
146  {
147  /* Output u9580 "count" times at (0,0) */
148  c.X = c.Y = 0;
149  SetConsoleCursorPosition(hConOut, c);
150  okCURSOR(hConOut, c);
151  for (n = 0; n < count; ++n)
152  {
153  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
154  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
155  }
156 
157  /* Check cursor */
158  len = count; /* u9580 is normal width in Russian */
159  c.X = (SHORT)(len % csbi.dwSize.X);
160  c.Y = (SHORT)(len / csbi.dwSize.X);
161  okCURSOR(hConOut, c);
162 
163  /* Check cursor */
164  c.X = 1;
165  c.Y = 0;
166  ret = SetConsoleCursorPosition(hConOut, c);
167  ok(ret, "SetConsoleCursorPosition failed\n");
168  okCURSOR(hConOut, c);
169 
170  /* Fill by space */
171  c.X = c.Y = 0;
172  ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
173  ok(ret, "FillConsoleOutputCharacterW failed\n");
174  ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len);
175 
176  /* Output u9580 "count" times at (1,0) */
177  c.X = 1;
178  c.Y = 0;
179  SetConsoleCursorPosition(hConOut, c);
180  okCURSOR(hConOut, c);
181  for (n = 0; n < count; ++n)
182  {
183  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
184  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
185  }
186 
187  /* Check cursor */
188  len = 1 + count;
189  c.X = (SHORT)(len % csbi.dwSize.X);
190  c.Y = (SHORT)(len / csbi.dwSize.X);
191  okCURSOR(hConOut, c);
192 
193  /* Fill by ideograph space */
194  c.X = c.Y = 0;
195  ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len);
196  ok(ret, "FillConsoleOutputCharacterW failed\n");
197  ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len);
198 
199  /* Read characters at (0,0) */
200  c.X = c.Y = 0;
201  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
202  ok(ret, "ReadConsoleOutputCharacterW failed\n");
203  ok(len == 6, "len was: %ld\n", len);
204  ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]);
205  ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]);
206  ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]);
207 
208  /* Read attr at (0,0) */
209  c.X = c.Y = 0;
210  ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len);
211  ok(ret, "ReadConsoleOutputAttribute failed\n");
212  ok(attr == ATTR, "attr was: %d\n", attr);
213  ok(len == 1, "len was %ld\n", len);
214 
215  /* Read characters at (1,0) */
216  c.X = 1;
217  c.Y = 0;
218  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
219  ok(ret, "ReadConsoleOutputCharacterW failed\n");
220  ok(len == 6, "len was: %ld\n", len);
221  ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]);
222  ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]);
223  ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]);
224 
225  /* Output u9580 "count" once at (1,0) */
226  c.X = 1;
227  c.Y = 0;
228  SetConsoleCursorPosition(hConOut, c);
229  okCURSOR(hConOut, c);
230  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
231  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
232 
233  /* Read attr (1,0) */
234  c.X = 1;
235  c.Y = 0;
236  ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len);
237  ok(ret, "ReadConsoleOutputAttribute failed\n");
238  ok(attr == ATTR, "attr was: %d\n", attr);
239  ok(len == 1, "len was %ld\n", len);
240 
241  /* Check cursor */
242  c.X = 2;
243  c.Y = 0;
244  okCURSOR(hConOut, c);
245 
246  /* Read characters at (0,0) */
247  c.X = c.Y = 0;
248  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
249  ok(ret, "ReadConsoleOutputCharacterW failed\n");
250  ok(len == 6, "len was: %ld\n", len);
251  ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]);
252  ok(str[1] == 0x9580 || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]);
253  ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]);
254  }
255 
256  /* Restore code page */
257  SetConsoleOutputCP(oldcp);
258 }
259 
260 /* Japanese Code Page 932 */
261 static void test_cp932(HANDLE hConOut)
262 {
263  BOOL ret;
264  DWORD oldcp;
265  int n;
266  DWORD len;
267  COORD c, buffSize;
269  int count;
270  WCHAR str[32];
271  WORD attr, attrs[16];
272  CHAR_INFO buff[16];
273  SMALL_RECT sr;
274 
275  if (!IsValidCodePage(932))
276  {
277  skip("Codepage 932 not available\n");
278  return;
279  }
280 
281  /* Set code page */
282  oldcp = GetConsoleOutputCP();
283  SetLastError(0xdeadbeef);
284  ret = SetConsoleOutputCP(932);
285  if (!ret)
286  {
287  skip("SetConsoleOutputCP failed with last error %lu\n", GetLastError());
288  return;
289  }
290 
291  /* Get info */
292  ret = GetConsoleScreenBufferInfo(hConOut, &csbi);
293  ok(ret, "GetConsoleScreenBufferInfo failed\n");
294  trace("csbi.dwSize.X:%d, csbi.dwSize.Y:%d\n", csbi.dwSize.X, csbi.dwSize.Y);
295  count = 200;
296 
297  /* "\u0414" */
298  {
299  /* Output u0414 "count" times at (0,0) */
300  c.X = c.Y = 0;
301  SetConsoleCursorPosition(hConOut, c);
302  okCURSOR(hConOut, c);
303  for (n = 0; n < count; ++n)
304  {
305  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
306  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
307  }
308 
309  /* Check cursor */
310  GetConsoleScreenBufferInfo(hConOut, &csbi);
311  len = count * 2; /* u0414 is fullwidth in Japanese */
312  c.X = (SHORT)(len % csbi.dwSize.X);
313  c.Y = (SHORT)(len / csbi.dwSize.X);
314  okCURSOR(hConOut, c);
315 
316  /* Read characters at (0,0) */
317  c.X = c.Y = 0;
318  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
319  ok(ret, "ReadConsoleOutputCharacterW failed\n");
320  ok(len == 3, "len was: %ld\n", len);
321  ok(str[0] == 0x414, "str[0] was: 0x%04X\n", str[0]);
322  ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]);
323  ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]);
324 
325  /* Check cursor */
326  c.X = 1;
327  c.Y = 0;
328  ret = SetConsoleCursorPosition(hConOut, c);
329  ok(ret, "SetConsoleCursorPosition failed\n");
330  okCURSOR(hConOut, c);
331 
332  /* Fill by space */
333  c.X = c.Y = 0;
334  FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
335 
336  /* Output u0414 "count" times at (1,0) */
337  c.X = 1;
338  c.Y = 0;
339  SetConsoleCursorPosition(hConOut, c);
340  okCURSOR(hConOut, c);
341  for (n = 0; n < count; ++n)
342  {
343  ret = WriteConsoleW(hConOut, u0414, lstrlenW(u0414), &len, NULL);
344  ok(ret && len == lstrlenW(u0414), "WriteConsoleW failed\n");
345  }
346 
347  /* Check cursor */
348  len = csbi.dwSize.X + (count - (csbi.dwSize.X - 1) / 2) * 2;
349  c.X = (SHORT)(len % csbi.dwSize.X);
350  c.Y = (SHORT)(len / csbi.dwSize.X);
351  okCURSOR(hConOut, c);
352 
353  /* Read characters at (0,0) */
354  c.X = 0;
355  c.Y = 0;
356  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
357  ok(ret, "ReadConsoleOutputCharacterW failed\n");
358  ok(len == 4, "len was: %ld\n", len);
359  ok(str[0] == L' ', "str[0] was: 0x%04X\n", str[0]);
360  ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]);
361  ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]);
362  }
363 
364  /* "\u9580" */
365  {
366  /* Output u9580 "count" times at (0,0) */
367  c.X = c.Y = 0;
368  SetConsoleCursorPosition(hConOut, c);
369  okCURSOR(hConOut, c);
370  for (n = 0; n < count; ++n)
371  {
372  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
373  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
374  }
375 
376  /* Check cursor */
377  len = count * 2; /* u9580 is fullwidth in Japanese */
378  c.X = (SHORT)(len % csbi.dwSize.X);
379  c.Y = (SHORT)(len / csbi.dwSize.X);
380  okCURSOR(hConOut, c);
381 
382  /* Check cursor */
383  c.X = 1;
384  c.Y = 0;
385  ret = SetConsoleCursorPosition(hConOut, c);
386  ok(ret, "SetConsoleCursorPosition failed\n");
387  okCURSOR(hConOut, c);
388 
389  /* Fill by space */
390  c.X = c.Y = 0;
391  ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len);
392  ok(ret, "FillConsoleOutputCharacterW failed\n");
393  ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len);
394 
395  /* Output u9580 "count" times at (1,0) */
396  c.X = 1;
397  c.Y = 0;
398  SetConsoleCursorPosition(hConOut, c);
399  okCURSOR(hConOut, c);
400  for (n = 0; n < count; ++n)
401  {
402  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
403  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
404  }
405 
406  /* Check cursor */
407  len = csbi.dwSize.X + (count - (csbi.dwSize.X - 1) / 2) * 2;
408  c.X = (SHORT)(len % csbi.dwSize.X);
409  c.Y = (SHORT)(len / csbi.dwSize.X);
410  okCURSOR(hConOut, c);
411 
412  /* Fill by ideograph space */
413  c.X = c.Y = 0;
414  ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len);
415  ok(ret, "FillConsoleOutputCharacterW failed\n");
416  if (s_bIs8Plus)
417  ok(len == csbi.dwSize.X * csbi.dwSize.Y / 2, "len was: %ld\n", len);
418  else
419  ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len);
420 
421  /* Read characters at (0,0) */
422  c.X = c.Y = 0;
423  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
424  ok(ret, "ReadConsoleOutputCharacterW failed\n");
425  ok(len == 3, "len was: %ld\n", len);
426  ok(str[0] == ideograph_space, "str[0] was: 0x%04X\n", str[0]);
427  ok(str[1] == ideograph_space, "str[1] was: 0x%04X\n", str[1]);
428  ok(str[2] == ideograph_space, "str[2] was: 0x%04X\n", str[2]);
429 
430  /* Read attr */
431  ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len);
432  ok(ret, "ReadConsoleOutputAttribute failed\n");
433  ok(attr == ATTR, "attr was: %d\n", attr);
434  ok(len == 1, "len was %ld\n", len);
435 
436  /* Output u9580 "count" once at (1,0) */
437  c.X = 1;
438  c.Y = 0;
439  SetConsoleCursorPosition(hConOut, c);
440  okCURSOR(hConOut, c);
441  ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL);
442  ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n");
443 
444  /* Read attr */
445  ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len);
446  ok(ret, "ReadConsoleOutputAttribute failed\n");
447  ok(attr == ATTR, "attr was: %d\n", attr);
448  ok(len == 1, "len was %ld\n", len);
449 
450  /* Check cursor */
451  c.X = 3;
452  c.Y = 0;
453  okCURSOR(hConOut, c);
454 
455  /* Read characters */
456  c.X = c.Y = 0;
457  ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len);
458  ok(ret, "ReadConsoleOutputCharacterW failed\n");
459  if (s_bIs8Plus)
460  {
461  ok(len == 3, "len was: %ld\n", len);
462  ok(str[0] == 0x3000, "str[0] was: 0x%04X\n", str[0]);
463  ok(str[1] == 0x9580, "str[1] was: 0x%04X\n", str[1]);
464  ok(str[2] == 0x3000, "str[2] was: 0x%04X\n", str[2]);
465  }
466  else
467  {
468  ok(len == 4, "len was: %ld\n", len);
469  ok(str[0] == L' ', "str[0] was: 0x%04X\n", str[0]);
470  ok(str[1] == 0x9580, "str[1] was: 0x%04X\n", str[1]);
471  ok(str[2] == L' ', "str[2] was: 0x%04X\n", str[2]);
472  }
473  }
474 
475  /* COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE for u0414 */
476  {
477  /* set cursor */
478  c.X = c.Y = 0;
479  SetConsoleCursorPosition(hConOut, c);
480  okCURSOR(hConOut, c);
481 
482  /* fill by 'A' */
483  ret = FillConsoleOutputCharacterW(hConOut, L'A', csbi.dwSize.X * 2, c, &len);
484  ok_int(ret, 1);
485  ok_long(len, csbi.dwSize.X * 2);
486 
487  /* reset buff */
488  buffSize.X = ARRAYSIZE(buff);
489  buffSize.Y = 1;
490  memset(buff, 0x7F, sizeof(buff));
491 
492  /* read output */
493  c.X = c.Y = 0;
494  ZeroMemory(&sr, sizeof(sr));
495  sr.Right = buffSize.X - 1;
496  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
497  ok_int(ret, 1);
498  ok_int(sr.Left, 0);
499  ok_int(sr.Top, 0);
500  ok_int(sr.Right, buffSize.X - 1);
501  ok_int(sr.Bottom, 0);
502 
503  /* check buff */
504  ok_int(buff[0].Char.UnicodeChar, L'A');
505  ok_int(buff[0].Attributes, ATTR);
506 
507  /* read attr */
508  ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len);
509  ok_int(ret, 1);
510  ok_int(attr, ATTR);
511  ok_long(len, 1);
512 
513  /* read char */
514  c.X = c.Y = 0;
515  memset(str, 0x7F, sizeof(str));
516  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
517  ok_int(ret, 1);
518  ok_int(str[0], L'A');
519  ok_int(str[1], L'A');
520  ok_int(str[2], L'A');
521  ok_int(str[3], L'A');
522 
523  /* set cursor */
524  c.X = c.Y = 0;
525  SetConsoleCursorPosition(hConOut, c);
526  okCURSOR(hConOut, c);
527 
528  /* write u0414 */
529  ret = WriteConsoleW(hConOut, u0414, 1, &len, NULL);
530  ok_int(ret, 1);
531  ok_long(len, 1);
532 
533  /* reset buff */
534  buffSize.X = ARRAYSIZE(buff);
535  buffSize.Y = 1;
536  memset(buff, 0x7F, sizeof(buff));
537 
538  /* read output */
539  c.X = c.Y = 0;
540  ZeroMemory(&sr, sizeof(sr));
541  sr.Right = buffSize.X - 1;
542  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
543  ok_int(ret, 1);
544  ok_int(sr.Left, 0);
545  ok_int(sr.Top, 0);
546  ok_int(sr.Right, buffSize.X - 1);
547  ok_int(sr.Bottom, 0);
548 
549  /* check buff */
550  if (s_bIs8Plus)
551  {
552  ok_int(buff[0].Char.UnicodeChar, 0x0414);
554  ok_int(buff[1].Char.UnicodeChar, 0x0414);
556  }
557  else
558  {
559  ok_int(buff[0].Char.UnicodeChar, 0x0414);
560  ok_int(buff[0].Attributes, ATTR);
561  ok_int(buff[1].Char.UnicodeChar, L'A');
562  ok_int(buff[1].Attributes, ATTR);
563  }
564  ok_int(buff[2].Char.UnicodeChar, L'A');
565  ok_int(buff[2].Attributes, ATTR);
566  ok_int(buff[3].Char.UnicodeChar, L'A');
567  ok_int(buff[3].Attributes, ATTR);
568 
569  /* read attr */
570  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
571  ok_int(ret, 1);
572  ok_long(len, ARRAYSIZE(attrs));
573  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
574  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
575  ok_int(attrs[2], ATTR);
576  ok_int(attrs[3], ATTR);
577 
578  /* read char */
579  c.X = c.Y = 0;
580  memset(str, 0x7F, sizeof(str));
581  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
582  ok_int(ret, 1);
583  ok_int(str[0], 0x0414);
584  ok_int(str[1], L'A');
585  ok_int(str[2], L'A');
586  if (s_bIs8Plus)
587  ok_int(str[3], 0);
588  else
589  ok_int(str[3], 0x7F7F);
590 
591  /* set cursor */
592  c.X = 1;
593  c.Y = 0;
594  SetConsoleCursorPosition(hConOut, c);
595  okCURSOR(hConOut, c);
596 
597  /* write u0414 */
598  ret = WriteConsoleW(hConOut, u0414, 1, &len, NULL);
599  ok_int(ret, 1);
600  ok_long(len, 1);
601 
602  /* read output */
603  c.X = c.Y = 0;
604  ZeroMemory(&sr, sizeof(sr));
605  sr.Right = buffSize.X - 1;
606  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
607  ok_int(ret, 1);
608  ok_int(sr.Left, 0);
609  ok_int(sr.Top, 0);
610  ok_int(sr.Right, buffSize.X - 1);
611  ok_int(sr.Bottom, 0);
612 
613  /* check buff */
614  if (s_bIs8Plus)
615  {
616  ok_int(buff[0].Char.UnicodeChar, 0x0414);
618  ok_int(buff[1].Char.UnicodeChar, 0x0414);
620  ok_int(buff[2].Char.UnicodeChar, 0x0414);
622  }
623  else
624  {
625  ok_int(buff[0].Char.UnicodeChar, L' ');
626  ok_int(buff[0].Attributes, ATTR);
627  ok_int(buff[1].Char.UnicodeChar, 0x0414);
628  ok_int(buff[1].Attributes, ATTR);
629  ok_int(buff[2].Char.UnicodeChar, L'A');
630  ok_int(buff[2].Attributes, ATTR);
631  }
632  ok_int(buff[3].Char.UnicodeChar, L'A');
633  ok_int(buff[3].Attributes, ATTR);
634 
635  /* read attr */
636  c.X = c.Y = 0;
637  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
638  ok_int(ret, 1);
639  ok_long(len, ARRAYSIZE(attrs));
640  if (s_bIs8Plus)
641  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
642  else
643  ok_int(attrs[0], ATTR);
644  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
645  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
646  ok_int(attrs[3], ATTR);
647 
648  /* read char */
649  c.X = c.Y = 0;
650  memset(str, 0x7F, sizeof(str));
651  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
652  ok_int(ret, 1);
653  if (s_bIs8Plus)
654  {
655  ok_int(str[0], 0x0414);
656  ok_int(str[1], 0x0414);
657  ok_int(str[2], L'A');
658  ok_int(str[3], 0);
659  }
660  else
661  {
662  ok_int(str[0], L' ');
663  ok_int(str[1], 0x0414);
664  ok_int(str[2], L'A');
665  ok_int(str[3], 0x7F7F);
666  }
667 
668  /* set cursor */
669  c.X = csbi.dwSize.X - 1;
670  c.Y = 0;
671  SetConsoleCursorPosition(hConOut, c);
672  okCURSOR(hConOut, c);
673 
674  /* write u0414 */
675  WriteConsoleW(hConOut, u0414, 1, &len, NULL);
676  ok_int(ret, 1);
677  ok_long(len, 1);
678 
679  /* reset buff */
680  buffSize.X = ARRAYSIZE(buff);
681  buffSize.Y = 1;
682  memset(buff, 0x7F, sizeof(buff));
683 
684  /* read output */
685  c.X = c.Y = 0;
686  sr.Left = csbi.dwSize.X - 2;
687  sr.Top = 0;
688  sr.Right = csbi.dwSize.X - 1;
689  sr.Bottom = 0;
690  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
691  ok_int(ret, 1);
692  ok_int(sr.Left, csbi.dwSize.X - 2);
693  ok_int(sr.Top, 0);
694  ok_int(sr.Right, csbi.dwSize.X - 1);
695  ok_int(sr.Bottom, 0);
696 
697  /* check buff */
698  ok_int(buff[0].Char.UnicodeChar, L'A');
699  ok_int(buff[0].Attributes, ATTR);
700  ok_int(buff[1].Char.UnicodeChar, L'A');
701  ok_int(buff[1].Attributes, ATTR);
702 
703  /* read attrs */
704  c.X = csbi.dwSize.X - 2;
705  c.Y = 0;
706  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
707  ok_int(ret, 1);
708  ok_long(len, ARRAYSIZE(attrs));
709  ok_int(attrs[0], ATTR);
710  ok_int(attrs[1], ATTR);
711 
712  /* read char */
713  ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len);
714  ok_int(ret, 1);
715  ok_int(str[0], L'A');
716  ok_int(str[1], L'A');
717 
718  /* fill by 'A' */
719  c.X = c.Y = 0;
720  ret = FillConsoleOutputCharacterW(hConOut, L'A', 10, c, &len);
721  ok_int(ret, 1);
722  ok_long(len, 10);
723 
724  /* fill by u0414 */
725  c.X = 1;
726  c.Y = 0;
727  ret = FillConsoleOutputCharacterW(hConOut, 0x0414, 1, c, &len);
728  c.X = c.Y = 0;
729  ok_int(ret, 1);
730  ok_long(len, 1);
731 
732  /* reset buff */
733  buffSize.X = ARRAYSIZE(buff);
734  buffSize.Y = 1;
735  memset(buff, 0x7F, sizeof(buff));
736 
737  /* read output */
738  c.X = c.Y = 0;
739  sr.Left = 0;
740  sr.Top = 0;
741  sr.Right = 4;
742  sr.Bottom = 0;
743  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
744  ok_int(ret, 1);
745  ok_int(sr.Left, 0);
746  ok_int(sr.Top, 0);
747  ok_int(sr.Right, 4);
748  ok_int(sr.Bottom, 0);
749 
750  /* check buff */
751  ok_int(buff[0].Char.UnicodeChar, 'A');
752  ok_int(buff[0].Attributes, ATTR);
753  if (s_bIs8Plus)
754  {
755  ok_int(buff[1].Char.UnicodeChar, 0x0414);
757  ok_int(buff[2].Char.UnicodeChar, 0x0414);
759  }
760  else
761  {
762  ok_int(buff[1].Char.UnicodeChar, L' ');
763  ok_int(buff[1].Attributes, ATTR);
764  ok_int(buff[2].Char.UnicodeChar, 'A');
765  ok_int(buff[2].Attributes, ATTR);
766  }
767  ok_int(buff[3].Char.UnicodeChar, 'A');
768  ok_int(buff[3].Attributes, ATTR);
769  ok_int(buff[4].Char.UnicodeChar, 'A');
770  ok_int(buff[4].Attributes, ATTR);
771 
772  /* read attrs */
773  c.X = 0;
774  c.Y = 0;
775  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
776  ok_int(ret, 1);
777  ok_long(len, 4);
778  ok_int(attrs[0], ATTR);
779  if (s_bIs8Plus)
780  {
781  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
782  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
783  }
784  else
785  {
786  ok_int(attrs[1], ATTR);
787  ok_int(attrs[2], ATTR);
788  }
789  ok_int(attrs[3], ATTR);
790  }
791 
792  /* COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE for u9580 */
793  {
794  /* set cursor */
795  c.X = c.Y = 0;
796  SetConsoleCursorPosition(hConOut, c);
797  okCURSOR(hConOut, c);
798 
799  /* fill by 'A' */
800  ret = FillConsoleOutputCharacterW(hConOut, L'A', csbi.dwSize.X * 2, c, &len);
801  ok_int(ret, 1);
802  ok_long(len, csbi.dwSize.X * 2);
803 
804  /* reset buff */
805  buffSize.X = ARRAYSIZE(buff);
806  buffSize.Y = 1;
807  memset(buff, 0x7F, sizeof(buff));
808 
809  /* read output */
810  c.X = c.Y = 0;
811  ZeroMemory(&sr, sizeof(sr));
812  sr.Right = buffSize.X - 1;
813  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
814  ok_int(ret, 1);
815  ok_int(sr.Left, 0);
816  ok_int(sr.Top, 0);
817  ok_int(sr.Right, buffSize.X - 1);
818  ok_int(sr.Bottom, 0);
819 
820  /* check buff */
821  ok_int(buff[0].Char.UnicodeChar, L'A');
822  ok_int(buff[0].Attributes, ATTR);
823 
824  /* read attr */
825  ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len);
826  ok_int(ret, 1);
827  ok_int(attr, ATTR);
828  ok_long(len, 1);
829 
830  /* read char */
831  memset(str, 0x7F, sizeof(str));
832  ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len);
833  ok_int(ret, 1);
834  ok_int(str[0], L'A');
835  ok_int(str[1], L'A');
836 
837  /* set cursor */
838  c.X = 0;
839  c.Y = 0;
840  SetConsoleCursorPosition(hConOut, c);
841  okCURSOR(hConOut, c);
842 
843  /* write u9580 */
844  ret = WriteConsoleW(hConOut, u9580, 1, &len, NULL);
845  ok_int(ret, 1);
846  ok_long(len, 1);
847 
848  /* reset buff */
849  buffSize.X = ARRAYSIZE(buff);
850  buffSize.Y = 1;
851  memset(buff, 0x7F, sizeof(buff));
852 
853  /* read output */
854  c.X = c.Y = 0;
855  ZeroMemory(&sr, sizeof(sr));
856  sr.Right = buffSize.X - 1;
857  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
858  ok_int(ret, 1);
859  ok_int(sr.Left, 0);
860  ok_int(sr.Top, 0);
861  ok_int(sr.Right, buffSize.X - 1);
862  ok_int(sr.Bottom, 0);
863 
864  /* check buff */
865  if (s_bIs8Plus)
866  {
867  ok_int(buff[0].Char.UnicodeChar, 0x9580);
869  ok_int(buff[1].Char.UnicodeChar, 0x9580);
871  }
872  else
873  {
874  ok_int(buff[0].Char.UnicodeChar, 0x9580);
875  ok_int(buff[0].Attributes, ATTR);
876  ok_int(buff[1].Char.UnicodeChar, L'A');
877  ok_int(buff[1].Attributes, ATTR);
878  }
879  ok_int(buff[2].Char.UnicodeChar, L'A');
880  ok_int(buff[2].Attributes, ATTR);
881  ok_int(buff[3].Char.UnicodeChar, L'A');
882  ok_int(buff[3].Attributes, ATTR);
883 
884  /* read attr */
885  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
886  ok_int(ret, 1);
887  ok_long(len, ARRAYSIZE(attrs));
888 
889  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
890  ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE);
891  ok_int(attrs[2], ATTR);
892  ok_int(attrs[3], ATTR);
893 
894  /* read char */
895  c.X = c.Y = 0;
896  memset(str, 0x7F, sizeof(str));
897  ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len);
898  ok_int(ret, 1);
899  ok_int(str[0], 0x9580);
900  ok_int(str[1], L'A');
901  ok_int(str[2], L'A');
902  if (s_bIs8Plus)
903  ok_int(str[3], 0);
904  else
905  ok_int(str[3], 0x7F7F);
906 
907  /* set cursor */
908  c.X = 1;
909  c.Y = 0;
910  SetConsoleCursorPosition(hConOut, c);
911  okCURSOR(hConOut, c);
912 
913  /* write u9580 */
914  ret = WriteConsoleW(hConOut, u9580, 1, &len, NULL);
915  ok_int(ret, 1);
916  ok_long(len, 1);
917 
918  /* read output */
919  c.X = c.Y = 0;
920  ZeroMemory(&sr, sizeof(sr));
921  sr.Right = buffSize.X - 1;
922  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
923  ok_int(ret, 1);
924  ok_int(sr.Left, 0);
925  ok_int(sr.Top, 0);
926  ok_int(sr.Right, buffSize.X - 1);
927  ok_int(sr.Bottom, 0);
928 
929  /* check buff */
930  if (s_bIs8Plus)
931  {
932  ok_int(buff[0].Char.UnicodeChar, 0x9580);
934  ok_int(buff[1].Char.UnicodeChar, 0x9580);
936  ok_int(buff[2].Char.UnicodeChar, 0x9580);
938  }
939  else
940  {
941  ok_int(buff[0].Char.UnicodeChar, L' ');
942  ok_int(buff[0].Attributes, ATTR);
943  ok_int(buff[1].Char.UnicodeChar, 0x9580);
944  ok_int(buff[1].Attributes, ATTR);
945  ok_int(buff[2].Char.UnicodeChar, L'A');
946  ok_int(buff[2].Attributes, ATTR);
947  }
948  ok_int(buff[3].Char.UnicodeChar, L'A');
949  ok_int(buff[3].Attributes, ATTR);
950 
951  /* read attr */
952  c.X = c.Y = 0;
953  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
954  ok_int(ret, 1);
955  ok_long(len, ARRAYSIZE(attrs));
956 
957  if (s_bIs8Plus)
958  {
959  ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE);
960  }
961  else
962  {
963  ok_int(attrs[0], ATTR);
964  }
965  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
966  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
967  ok_int(attrs[3], ATTR);
968 
969  /* set cursor */
970  c.X = csbi.dwSize.X - 1;
971  c.Y = 0;
972  SetConsoleCursorPosition(hConOut, c);
973  okCURSOR(hConOut, c);
974 
975  /* write u9580 */
976  WriteConsoleW(hConOut, u9580, 1, &len, NULL);
977  ok_int(ret, 1);
978  ok_long(len, 1);
979 
980  /* reset buff */
981  buffSize.X = ARRAYSIZE(buff);
982  buffSize.Y = 1;
983  memset(buff, 0x7F, sizeof(buff));
984 
985  /* read output */
986  c.X = c.Y = 0;
987  sr.Left = csbi.dwSize.X - 2;
988  sr.Top = 0;
989  sr.Right = csbi.dwSize.X - 1;
990  sr.Bottom = 0;
991  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
992  ok_int(ret, 1);
993  ok_int(sr.Left, csbi.dwSize.X - 2);
994  ok_int(sr.Top, 0);
995  ok_int(sr.Right, csbi.dwSize.X - 1);
996  ok_int(sr.Bottom, 0);
997 
998  /* check buff */
999  ok_int(buff[0].Char.UnicodeChar, 'A');
1000  ok_int(buff[0].Attributes, ATTR);
1001  ok_int(buff[1].Char.UnicodeChar, 'A');
1002  ok_int(buff[1].Attributes, ATTR);
1003 
1004  /* read attr */
1005  c.X = csbi.dwSize.X - 2;
1006  c.Y = 0;
1007  ret = ReadConsoleOutputAttribute(hConOut, attrs, ARRAYSIZE(attrs), c, &len);
1008  ok_int(ret, 1);
1009  ok_long(len, ARRAYSIZE(attrs));
1010  ok_int(attrs[0], ATTR);
1011  ok_int(attrs[1], ATTR);
1012 
1013  /* read char */
1014  memset(str, 0x7F, sizeof(str));
1015  ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len);
1016  ok_int(ret, 1);
1017  ok_int(str[0], L'A');
1018  ok_int(str[1], L'A');
1019 
1020  /* fill by 'A' */
1021  c.X = c.Y = 0;
1022  ret = FillConsoleOutputCharacterW(hConOut, L'A', 10, c, &len);
1023  ok_int(ret, 1);
1024  ok_long(len, 10);
1025 
1026  /* fill by u9580 */
1027  c.X = 1;
1028  c.Y = 0;
1029  ret = FillConsoleOutputCharacterW(hConOut, 0x9580, 1, c, &len);
1030  c.X = c.Y = 0;
1031  ok_int(ret, 1);
1032  ok_long(len, 1);
1033 
1034  /* reset buff */
1035  buffSize.X = ARRAYSIZE(buff);
1036  buffSize.Y = 1;
1037  memset(buff, 0x7F, sizeof(buff));
1038 
1039  /* read output */
1040  c.X = c.Y = 0;
1041  sr.Left = 0;
1042  sr.Top = 0;
1043  sr.Right = 4;
1044  sr.Bottom = 0;
1045  ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1046  ok_int(ret, 1);
1047  ok_int(sr.Left, 0);
1048  ok_int(sr.Top, 0);
1049  ok_int(sr.Right, 4);
1050  ok_int(sr.Bottom, 0);
1051 
1052  /* check buff */
1053  ok_int(buff[0].Char.UnicodeChar, 'A');
1054  ok_int(buff[0].Attributes, ATTR);
1055  if (s_bIs8Plus)
1056  {
1057  ok_int(buff[1].Char.UnicodeChar, 0x9580);
1059  ok_int(buff[2].Char.UnicodeChar, 0x9580);
1061  }
1062  else
1063  {
1064  ok_int(buff[1].Char.UnicodeChar, L' ');
1065  ok_int(buff[1].Attributes, ATTR);
1066  ok_int(buff[2].Char.UnicodeChar, 'A');
1067  ok_int(buff[2].Attributes, ATTR);
1068  }
1069  ok_int(buff[3].Char.UnicodeChar, 'A');
1070  ok_int(buff[3].Attributes, ATTR);
1071  ok_int(buff[4].Char.UnicodeChar, 'A');
1072  ok_int(buff[4].Attributes, ATTR);
1073 
1074  /* read attrs */
1075  c.X = 0;
1076  c.Y = 0;
1077  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1078  ok_int(ret, 1);
1079  ok_long(len, 4);
1080  ok_int(attrs[0], ATTR);
1081  if (s_bIs8Plus)
1082  {
1083  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1084  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1085  }
1086  else
1087  {
1088  ok_int(attrs[1], ATTR);
1089  ok_int(attrs[2], ATTR);
1090  }
1091  ok_int(attrs[3], ATTR);
1092  }
1093 
1094  /* FillConsoleOutputAttribute and WriteConsoleOutput */
1095  {
1096  c.X = c.Y = 0;
1097  SetConsoleCursorPosition(hConOut, c);
1098  okCURSOR(hConOut, c);
1099  for (n = 0; n < count; ++n)
1100  {
1101  ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL);
1102  ok_int(ret, 1);
1103  ok_long(len, 1);
1104  }
1105 
1106  /* fill attrs */
1107  c.X = c.Y = 0;
1108  SetConsoleCursorPosition(hConOut, c);
1109  okCURSOR(hConOut, c);
1110  ret = FillConsoleOutputAttribute(hConOut, 0xFFFF, 2, c, &len);
1111  ok_int(ret, 1);
1112  ok_long(len, 2);
1113 
1114  /* read attrs */
1115  memset(attrs, 0x7F, sizeof(attrs));
1116  ret = ReadConsoleOutputAttribute(hConOut, attrs, 3, c, &len);
1117  ok_int(ret, 1);
1118  ok_long(len, 3);
1119  if (s_bIs8Plus)
1120  {
1121  ok_int(attrs[0], 0xDCFF);
1122  ok_int(attrs[1], 0xDCFF);
1123  }
1124  else
1125  {
1126  ok_int(attrs[0], 0xFCFF);
1127  ok_int(attrs[1], 0xFCFF);
1128  }
1129  ok_int(attrs[2], ATTR);
1130 
1131  /* fill attrs */
1132  c.X = c.Y = 0;
1133  SetConsoleCursorPosition(hConOut, c);
1134  okCURSOR(hConOut, c);
1135  ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len);
1136  ok_int(ret, 1);
1137  ok_long(len, 4);
1138 
1139  /* write */
1140  c.X = c.Y = 0;
1141  sr.Left = 0;
1142  sr.Top = 0;
1143  sr.Right = 4;
1144  sr.Bottom = 0;
1145  buff[0].Char.UnicodeChar = L' ';
1146  buff[0].Attributes = ATTR;
1147  buff[1].Char.UnicodeChar = 0x9580;
1148  buff[1].Attributes = ATTR | COMMON_LVB_LEADING_BYTE;
1149  buff[2].Char.UnicodeChar = 0x9580;
1150  buff[2].Attributes = ATTR | COMMON_LVB_TRAILING_BYTE;
1151  buff[3].Char.UnicodeChar = L'A';
1152  buff[3].Attributes = ATTR;
1153  buff[4].Char.UnicodeChar = L' ';
1154  buff[4].Attributes = 0xFFFF;
1155  buffSize.X = 4;
1156  buffSize.Y = 1;
1157  ret = WriteConsoleOutputW(hConOut, buff, buffSize, c, &sr);
1158  ok_int(ret, 1);
1159  ok_int(sr.Left, 0);
1160  ok_int(sr.Top, 0);
1161  ok_int(sr.Right, 3);
1162  ok_int(sr.Bottom, 0);
1163 
1164  /* read attrs */
1165  memset(attrs, 0x7F, sizeof(attrs));
1166  ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len);
1167  ok_int(ret, 1);
1168  ok_long(len, 6);
1169  ok_int(attrs[0], ATTR);
1170  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1171  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1172  ok_int(attrs[3], ATTR);
1173  ok_int(attrs[4], ATTR);
1174  ok_int(attrs[5], ATTR);
1175  }
1176 
1177  /* WriteConsoleOutputCharacterW and WriteConsoleOutputAttribute */
1178  {
1179  c.X = c.Y = 0;
1180  SetConsoleCursorPosition(hConOut, c);
1181  okCURSOR(hConOut, c);
1182  for (n = 0; n < count; ++n)
1183  {
1184  ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL);
1185  ok_int(ret, 1);
1186  ok_long(len, 1);
1187  }
1188 
1189  /* write attrs */
1190  attrs[0] = ATTR;
1191  attrs[1] = 0xFFFF;
1192  attrs[2] = ATTR;
1193  attrs[3] = 0;
1194  ret = WriteConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1195  ok_int(ret, 1);
1196  ok_long(len, 4);
1197 
1198  /* read attrs */
1199  memset(attrs, 0x7F, sizeof(attrs));
1200  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1201  ok_int(ret, 1);
1202  ok_long(len, 4);
1203  ok_int(attrs[0], ATTR);
1204  if (s_bIs8Plus)
1205  ok_int(attrs[1], 0xDCFF);
1206  else
1207  ok_int(attrs[1], 0xFCFF);
1208  ok_int(attrs[2], ATTR);
1209  ok_int(attrs[3], 0);
1210 
1211  /* fill attr */
1212  ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len);
1213  ok_int(ret, 1);
1214  ok_long(len, 4);
1215 
1216  /* write char */
1217  ret = WriteConsoleOutputCharacterW(hConOut, s_str, 4, c, &len);
1218  ok_int(ret, 1);
1219  ok_long(len, 4);
1220 
1221  /* read attrs */
1222  memset(attrs, 0x7F, sizeof(attrs));
1223  ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len);
1224  ok_int(ret, 1);
1225  ok_long(len, 4);
1226  ok_int(attrs[0], ATTR);
1227  ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE);
1228  ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE);
1229  ok_int(attrs[3], ATTR);
1230  }
1231 
1232  /* Restore code page */
1233  SetConsoleOutputCP(oldcp);
1234 }
1235 
1236 START_TEST(ConsoleCP)
1237 {
1238  HANDLE hConIn, hConOut;
1239  OSVERSIONINFOA osver = { sizeof(osver) };
1240 
1241  // https://github.com/reactos/reactos/pull/2131#issuecomment-563189380
1242  GetVersionExA(&osver);
1243  s_bIs8Plus = (osver.dwMajorVersion > 6) ||
1244  (osver.dwMajorVersion == 6 && osver.dwMinorVersion >= 2);
1245 
1246  FreeConsole();
1247  ok(AllocConsole(), "Couldn't alloc console\n");
1248 
1249  hConIn = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1250  hConOut = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1251  ok(hConIn != INVALID_HANDLE_VALUE, "Opening ConIn\n");
1252  ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n");
1253 
1255  {
1256  if (!IsCJKCodePage())
1257  test_cp855(hConOut);
1258  else
1259  skip("Russian testcase is skipped because of CJK\n");
1260  }
1261  else
1262  {
1263  skip("Russian locale is not installed\n");
1264  }
1265 
1267  {
1268  if (IsCJKCodePage())
1269  test_cp932(hConOut);
1270  else
1271  skip("Japanese testcase is skipped because of not CJK\n");
1272  }
1273  else
1274  {
1275  skip("Japanese locale is not installed\n");
1276  }
1277 
1278  CloseHandle(hConIn);
1279  CloseHandle(hConOut);
1280  FreeConsole();
1281  ok(AllocConsole(), "Couldn't alloc console\n");
1282 }
static const WCHAR u0414[]
Definition: ConsoleCP.c:21
static BOOL IsCJKCodePage(void)
Definition: ConsoleCP.c:30
#define ATTR
Definition: ConsoleCP.c:18
#define MAKELCID(lgid, srtid)
BOOL WINAPI SetConsoleOutputCP(IN UINT wCodepage)
Definition: console.c:666
#define TRUE
Definition: types.h:120
BOOL WINAPI AllocConsole(VOID)
Definition: console.c:48
ULONG dwMajorVersion
Definition: rtltypes.h:234
#define CloseHandle
Definition: compat.h:406
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:1571
BOOL WINAPI FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: console.c:496
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1449
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:1340
GLdouble n
Definition: glext.h:7729
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
DWORD LCID
Definition: nls.h:13
#define ok_long(expression, result)
Definition: atltest.h:133
#define lstrlenW
Definition: compat.h:415
#define LCID_INSTALLED
Definition: winnls.h:198
BOOL WINAPI WriteConsoleOutputCharacterW(HANDLE hConsoleOutput, IN LPCWSTR lpCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: console.c:422
static void test_cp855(HANDLE hConOut)
Definition: ConsoleCP.c:46
#define LANG_JAPANESE
Definition: nls.h:76
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:2453
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
#define ok_int(expression, result)
Definition: atltest.h:134
BOOL WINAPI SetConsoleCursorPosition(IN HANDLE hConsoleOutput, IN COORD dwCursorPosition)
Definition: console.c:612
static BOOL s_bIs8Plus
Definition: ConsoleCP.c:28
BOOL WINAPI GetVersionExA(IN LPOSVERSIONINFOA lpVersionInformation)
Definition: version.c:69
#define OPEN_EXISTING
Definition: compat.h:434
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:566
SHORT Left
Definition: blue.h:32
ULONG X
Definition: bl.h:1340
BOOL WINAPI FreeConsole(VOID)
Definition: console.c:127
#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:1424
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:417
#define LANG_RUSSIAN
Definition: nls.h:113
Definition: cookie.c:201
SHORT Top
Definition: blue.h:33
static const WCHAR ideograph_space
Definition: ConsoleCP.c:24
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: lang.c:1548
int ret
__u8 attr
Definition: mkdosfs.c:359
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR s_str[]
Definition: ConsoleCP.c:25
GLenum GLsizei len
Definition: glext.h:6722
ULONG dwMinorVersion
Definition: rtltypes.h:235
#define GENERIC_READ
Definition: compat.h:124
Definition: bl.h:1338
START_TEST(ConsoleCP)
Definition: ConsoleCP.c:1236
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1479
static LCID lcidRussian
Definition: ConsoleCP.c:27
#define ok(value,...)
Definition: atltest.h:57
static void test_cp932(HANDLE hConOut)
Definition: ConsoleCP.c:261
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput, OUT LPWSTR lpCharacter, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfCharsRead)
Definition: readwrite.c:1382
static const WCHAR u9580[]
Definition: ConsoleCP.c:22
#define skip(...)
Definition: atltest.h:64
#define okCURSOR(hCon, c)
Definition: ConsoleCP.c:10
#define COMMON_LVB_LEADING_BYTE
Definition: wincon.h:48
#define c
Definition: ke_i.h:80
#define MAKELANGID(p, s)
Definition: nls.h:15
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN CONST WORD *lpAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: readwrite.c:1655
#define COMMON_LVB_TRAILING_BYTE
Definition: wincon.h:49
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:407
SHORT Right
Definition: blue.h:34
ULONG Y
Definition: bl.h:1341
#define memset(x, y, z)
Definition: compat.h:39
static unsigned char buff[32768]
Definition: fatten.c:17
static LCID lcidJapanese
Definition: ConsoleCP.c:26
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput, IN WCHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1676
UINT WINAPI GetOEMCP(VOID)
Definition: nls.c:2195