main.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright 2019 Erich E. Hoover
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  17. */
  18. #include <windows.h>
  19. #include <stdlib.h>
  20. #include "resource.h"
  21. #include "wine/debug.h"
  22. WINE_DEFAULT_DEBUG_CHANNEL(chcp);
  23. static void output_writeconsole(const WCHAR *str, DWORD wlen)
  24. {
  25. DWORD count, ret;
  26. ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL);
  27. if (!ret)
  28. {
  29. DWORD len;
  30. char *msgA;
  31. /* On Windows WriteConsoleW() fails if the output is redirected. So fall
  32. * back to WriteFile(), assuming the console encoding is still the right
  33. * one in that case.
  34. */
  35. len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL);
  36. msgA = malloc(len);
  37. WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
  38. WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
  39. free(msgA);
  40. }
  41. }
  42. static void output_formatstring(const WCHAR *fmt, va_list va_args)
  43. {
  44. WCHAR *str;
  45. DWORD len;
  46. len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
  47. fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
  48. if (!len && GetLastError() != ERROR_NO_WORK_DONE)
  49. {
  50. WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
  51. return;
  52. }
  53. output_writeconsole(str, len);
  54. LocalFree(str);
  55. }
  56. static void WINAPIV output_message(unsigned int id, ...)
  57. {
  58. WCHAR *fmt = NULL;
  59. int len;
  60. va_list va_args;
  61. if (!(len = LoadStringW(GetModuleHandleW(NULL), id, (WCHAR *)&fmt, 0)))
  62. {
  63. WINE_FIXME("LoadString failed with %d\n", GetLastError());
  64. return;
  65. }
  66. len++;
  67. fmt = malloc(len * sizeof(WCHAR));
  68. if (!fmt) return;
  69. LoadStringW(GetModuleHandleW(NULL), id, fmt, len);
  70. va_start(va_args, id);
  71. output_formatstring(fmt, va_args);
  72. va_end(va_args);
  73. free(fmt);
  74. }
  75. int __cdecl wmain(int argc, WCHAR *argv[])
  76. {
  77. int i;
  78. if (argc == 1)
  79. {
  80. output_message(STRING_ACTIVE_CODE_PAGE, GetConsoleCP());
  81. return 0;
  82. }
  83. else if (argc == 2)
  84. {
  85. int codepage, success;
  86. if (!lstrcmpW(argv[1], L"/?"))
  87. {
  88. output_message(STRING_USAGE);
  89. return 0;
  90. }
  91. codepage = _wtoi(argv[1]);
  92. success = SetConsoleCP(codepage) && SetConsoleOutputCP(codepage);
  93. if (success)
  94. output_message(STRING_ACTIVE_CODE_PAGE, codepage);
  95. else
  96. output_message(STRING_INVALID_CODE_PAGE);
  97. return !success;
  98. }
  99. WINE_FIXME("unexpected arguments:");
  100. for (i = 0; i < argc; i++)
  101. WINE_FIXME(" %s", wine_dbgstr_w(argv[i]));
  102. WINE_FIXME("\n");
  103. return 0;
  104. }