hostname.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Hostname display utility
  3. *
  4. * Copyright 2008 Andrew Riedi
  5. * Copyright 2010-2011 Andrew Nguyen
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  20. */
  21. #include <stdarg.h>
  22. #include <stdio.h>
  23. #include <windef.h>
  24. #include <winbase.h>
  25. #include <wincon.h>
  26. #include <winnls.h>
  27. #include <winuser.h>
  28. #include "hostname.h"
  29. static int hostname_vprintfW(const WCHAR *msg, va_list va_args)
  30. {
  31. int wlen;
  32. DWORD count, ret;
  33. WCHAR msg_buffer[8192];
  34. wlen = vswprintf(msg_buffer, ARRAY_SIZE(msg_buffer), msg, va_args);
  35. ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
  36. if (!ret)
  37. {
  38. DWORD len;
  39. char *msgA;
  40. /* On Windows WriteConsoleW() fails if the output is redirected. So fall
  41. * back to WriteFile(), assuming the console encoding is still the right
  42. * one in that case.
  43. */
  44. len = WideCharToMultiByte(CP_ACP, 0, msg_buffer, wlen,
  45. NULL, 0, NULL, NULL);
  46. msgA = HeapAlloc(GetProcessHeap(), 0, len);
  47. if (!msgA)
  48. return 0;
  49. WideCharToMultiByte(CP_ACP, 0, msg_buffer, wlen, msgA, len, NULL, NULL);
  50. WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
  51. HeapFree(GetProcessHeap(), 0, msgA);
  52. }
  53. return count;
  54. }
  55. static int WINAPIV hostname_printfW(const WCHAR *msg, ...)
  56. {
  57. va_list va_args;
  58. int len;
  59. va_start(va_args, msg);
  60. len = hostname_vprintfW(msg, va_args);
  61. va_end(va_args);
  62. return len;
  63. }
  64. static int WINAPIV hostname_message_printfW(int msg, ...)
  65. {
  66. va_list va_args;
  67. WCHAR msg_buffer[8192];
  68. int len;
  69. LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
  70. va_start(va_args, msg);
  71. len = hostname_vprintfW(msg_buffer, va_args);
  72. va_end(va_args);
  73. return len;
  74. }
  75. static int hostname_message(int msg)
  76. {
  77. WCHAR msg_buffer[8192];
  78. LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer));
  79. return hostname_printfW(L"%s", msg_buffer);
  80. }
  81. static int display_computer_name(void)
  82. {
  83. WCHAR name[MAX_COMPUTERNAME_LENGTH + 1];
  84. DWORD size = ARRAY_SIZE(name);
  85. BOOL ret;
  86. ret = GetComputerNameW(name, &size);
  87. if (!ret)
  88. {
  89. hostname_message_printfW(STRING_CANNOT_GET_HOSTNAME, GetLastError());
  90. return 1;
  91. }
  92. hostname_printfW(L"%s\r\n", name);
  93. return 0;
  94. }
  95. int __cdecl wmain(int argc, WCHAR *argv[])
  96. {
  97. if (argc > 1)
  98. {
  99. unsigned int i;
  100. if (!wcsncmp(argv[1], L"/?", ARRAY_SIZE(L"/?") - 1))
  101. {
  102. hostname_message(STRING_USAGE);
  103. return 1;
  104. }
  105. for (i = 1; i < argc; i++)
  106. {
  107. if (argv[i][0] == '-')
  108. {
  109. switch (argv[i][1])
  110. {
  111. case 's':
  112. /* Ignore the option and continue processing. */
  113. break;
  114. case '?':
  115. hostname_message(STRING_USAGE);
  116. return 1;
  117. default:
  118. hostname_message_printfW(STRING_INVALID_OPTION, argv[i][1]);
  119. hostname_message(STRING_USAGE);
  120. return 1;
  121. }
  122. }
  123. else
  124. {
  125. hostname_message(STRING_CANNOT_SET_HOSTNAME);
  126. hostname_message(STRING_USAGE);
  127. return 1;
  128. }
  129. }
  130. }
  131. return display_computer_name();
  132. }