main.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright 2016 Austin English
  3. * Copyright 2016 Michael Müller
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  18. */
  19. #include <windows.h>
  20. #include <wine/debug.h>
  21. #include "resources.h"
  22. WINE_DEFAULT_DEBUG_CHANNEL(fsutil);
  23. static void output_write(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 = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
  37. if (!msgA) return;
  38. WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
  39. WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
  40. HeapFree(GetProcessHeap(), 0, msgA);
  41. }
  42. }
  43. static int output_vprintf(const WCHAR* fmt, __ms_va_list va_args)
  44. {
  45. WCHAR str[8192];
  46. int len;
  47. SetLastError(NO_ERROR);
  48. len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt, 0, 0, str,
  49. sizeof(str)/sizeof(*str), &va_args);
  50. if (len == 0 && GetLastError() != NO_ERROR)
  51. WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
  52. else
  53. output_write(str, len);
  54. return 0;
  55. }
  56. static int WINAPIV output_string(int msg, ...)
  57. {
  58. WCHAR fmt[8192];
  59. __ms_va_list arguments;
  60. LoadStringW(GetModuleHandleW(NULL), msg, fmt, sizeof(fmt)/sizeof(fmt[0]));
  61. __ms_va_start(arguments, msg);
  62. output_vprintf(fmt, arguments);
  63. __ms_va_end(arguments);
  64. return 0;
  65. }
  66. static BOOL output_error_string(DWORD error)
  67. {
  68. LPWSTR pBuffer;
  69. if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
  70. FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  71. NULL, error, 0, (LPWSTR)&pBuffer, 0, NULL))
  72. {
  73. output_write(pBuffer, lstrlenW(pBuffer));
  74. LocalFree(pBuffer);
  75. return TRUE;
  76. }
  77. return FALSE;
  78. }
  79. static int create_hardlink(int argc, WCHAR *argv[])
  80. {
  81. if (argc != 5)
  82. {
  83. output_string(STRING_HARDLINK_CREATE_USAGE);
  84. return 1;
  85. }
  86. if (CreateHardLinkW(argv[3], argv[4], NULL))
  87. return 0;
  88. output_error_string(GetLastError());
  89. return 1;
  90. }
  91. static int hardlink(int argc, WCHAR *argv[])
  92. {
  93. static const WCHAR createW[]={'c','r','e','a','t','e',0};
  94. int ret;
  95. if (argc > 2)
  96. {
  97. if (!_wcsicmp(argv[2], createW))
  98. return create_hardlink(argc, argv);
  99. else
  100. {
  101. FIXME("unsupported parameter %s\n", debugstr_w(argv[2]));
  102. output_string(STRING_UNSUPPORTED_PARAM, argv[2]);
  103. ret = 1;
  104. }
  105. }
  106. output_string(STRING_HARDLINK_USAGE);
  107. return ret;
  108. }
  109. int __cdecl wmain(int argc, WCHAR *argv[])
  110. {
  111. static const WCHAR hardlinkW[]={'h','a','r','d','l','i','n','k',0};
  112. int i, ret = 0;
  113. for (i = 0; i < argc; i++)
  114. WINE_TRACE(" %s", wine_dbgstr_w(argv[i]));
  115. WINE_TRACE("\n");
  116. if (argc > 1)
  117. {
  118. if (!_wcsicmp(argv[1], hardlinkW))
  119. return hardlink(argc, argv);
  120. else
  121. {
  122. FIXME("unsupported command %s\n", debugstr_w(argv[1]));
  123. output_string(STRING_UNSUPPORTED_CMD, argv[1]);
  124. ret = 1;
  125. }
  126. }
  127. output_string(STRING_USAGE);
  128. return ret;
  129. }