main.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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(CP_ACP, 0, str, wlen, NULL, 0, NULL, NULL);
  36. msgA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
  37. if (!msgA) return;
  38. WideCharToMultiByte(CP_ACP, 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 WINAPIV output_string(int msg, ...)
  44. {
  45. WCHAR out[8192];
  46. va_list arguments;
  47. int len;
  48. va_start(arguments, msg);
  49. len = FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE, NULL, msg, 0, out, ARRAY_SIZE(out), &arguments);
  50. va_end(arguments);
  51. if (len == 0 && GetLastError() != NO_ERROR)
  52. WINE_FIXME("Could not format string: le=%u, msg=%d\n", GetLastError(), msg);
  53. else
  54. output_write(out, len);
  55. return 0;
  56. }
  57. static BOOL output_error_string(DWORD error)
  58. {
  59. LPWSTR pBuffer;
  60. if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
  61. FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  62. NULL, error, 0, (LPWSTR)&pBuffer, 0, NULL))
  63. {
  64. output_write(pBuffer, lstrlenW(pBuffer));
  65. LocalFree(pBuffer);
  66. return TRUE;
  67. }
  68. return FALSE;
  69. }
  70. static int create_hardlink(int argc, WCHAR *argv[])
  71. {
  72. if (argc != 5)
  73. {
  74. output_string(STRING_HARDLINK_CREATE_USAGE);
  75. return 1;
  76. }
  77. if (CreateHardLinkW(argv[3], argv[4], NULL))
  78. return 0;
  79. output_error_string(GetLastError());
  80. return 1;
  81. }
  82. static int hardlink(int argc, WCHAR *argv[])
  83. {
  84. int ret = 0;
  85. if (argc > 2)
  86. {
  87. if (!wcsicmp(argv[2], L"create"))
  88. return create_hardlink(argc, argv);
  89. else
  90. {
  91. FIXME("unsupported parameter %s\n", debugstr_w(argv[2]));
  92. ret = 1;
  93. }
  94. }
  95. output_string(STRING_HARDLINK_USAGE);
  96. return ret;
  97. }
  98. int __cdecl wmain(int argc, WCHAR *argv[])
  99. {
  100. int i, ret = 0;
  101. TRACE("Command line:");
  102. for (i = 0; i < argc; i++)
  103. TRACE(" %s", debugstr_w(argv[i]));
  104. TRACE("\n");
  105. if (argc > 1)
  106. {
  107. if (!wcsicmp(argv[1], L"hardlink"))
  108. return hardlink(argc, argv);
  109. else
  110. {
  111. FIXME("unsupported command %s\n", debugstr_w(argv[1]));
  112. ret = 1;
  113. }
  114. }
  115. output_string(STRING_USAGE);
  116. return ret;
  117. }