Leaked source code of windows server 2003

228 lines
5.7 KiB

  1. #include "pch.h"
  2. #include <stdio.h>
  3. #include <strsafe.h>
  4. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  5. typedef BOOLEAN (WINAPI * SetThreadUILanguageFunc)(DWORD dwReserved);
  6. extern HINSTANCE g_hThisModule;
  7. HANDLE g_hStdout = NULL;
  8. BOOL g_bSetLocale = FALSE;
  9. SetThreadUILanguageFunc g_pfnSetThreadUILanguage = NULL;
  10. HRESULT MySetThreadUILanguage(DWORD dwParam)
  11. {
  12. HMODULE hKernel32Dll = NULL;
  13. HRESULT hr;
  14. if (NULL == g_pfnSetThreadUILanguage) {
  15. hKernel32Dll = LoadLibraryW(L"kernel32.dll");
  16. if (NULL == hKernel32Dll) {
  17. _JumpLastError(hr, error, "LoadLibraryW");
  18. }
  19. g_pfnSetThreadUILanguage = (SetThreadUILanguageFunc)GetProcAddress(hKernel32Dll, "SetThreadUILanguage");
  20. if (NULL == g_pfnSetThreadUILanguage) {
  21. _JumpLastError(hr, error, "GetProcAddress");
  22. }
  23. }
  24. g_pfnSetThreadUILanguage(dwParam);
  25. hr = S_OK;
  26. error:
  27. if (NULL != hKernel32Dll) {
  28. FreeLibrary(hKernel32Dll);
  29. }
  30. return hr;
  31. }
  32. HRESULT InitializeConsoleOutput() {
  33. g_hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  34. if (INVALID_HANDLE_VALUE == g_hStdout) {
  35. return HRESULT_FROM_WIN32(GetLastError());
  36. }
  37. return S_OK;
  38. }
  39. BOOL
  40. FileIsConsole(
  41. HANDLE fp
  42. )
  43. {
  44. DWORD htype;
  45. htype = GetFileType(fp);
  46. htype &= ~FILE_TYPE_REMOTE;
  47. return htype == FILE_TYPE_CHAR;
  48. }
  49. HRESULT
  50. MyWriteConsole(
  51. HANDLE fp,
  52. LPWSTR lpBuffer,
  53. DWORD cchBuffer
  54. )
  55. {
  56. HRESULT hr;
  57. LPSTR lpAnsiBuffer = NULL;
  58. //
  59. // Jump through hoops for output because:
  60. //
  61. // 1. printf() family chokes on international output (stops
  62. // printing when it hits an unrecognized character)
  63. //
  64. // 2. WriteConsole() works great on international output but
  65. // fails if the handle has been redirected (i.e., when the
  66. // output is piped to a file)
  67. //
  68. // 3. WriteFile() works great when output is piped to a file
  69. // but only knows about bytes, so Unicode characters are
  70. // printed as two Ansi characters.
  71. //
  72. if (FileIsConsole(fp))
  73. {
  74. hr = MySetThreadUILanguage(0);
  75. _JumpIfError(hr, error, "MySetThreadUILanguage");
  76. hr = WriteConsole(fp, lpBuffer, cchBuffer, &cchBuffer, NULL);
  77. _JumpIfError(hr, error, "WriteConsole");
  78. }
  79. else
  80. {
  81. lpAnsiBuffer = (LPSTR) LocalAlloc(LPTR, cchBuffer * sizeof(WCHAR));
  82. _JumpIfOutOfMemory(hr, error, lpAnsiBuffer);
  83. cchBuffer = WideCharToMultiByte(CP_OEMCP,
  84. 0,
  85. lpBuffer,
  86. cchBuffer,
  87. lpAnsiBuffer,
  88. cchBuffer * sizeof(WCHAR),
  89. NULL,
  90. NULL);
  91. if (cchBuffer != 0)
  92. {
  93. if (!WriteFile(fp, lpAnsiBuffer, cchBuffer, &cchBuffer, NULL))
  94. {
  95. hr = GetLastError();
  96. _JumpError(hr, error, "WriteFile");
  97. }
  98. }
  99. else
  100. {
  101. hr = GetLastError();
  102. _JumpError(hr, error, "WideCharToMultiByte");
  103. }
  104. }
  105. hr = S_OK;
  106. error:
  107. if (NULL != lpAnsiBuffer)
  108. LocalFree(lpAnsiBuffer);
  109. return hr;
  110. }
  111. HRESULT LocalizedWPrintf(UINT nResourceID) {
  112. DWORD dwRetval;
  113. HRESULT hr;
  114. WCHAR rgwszString[512];
  115. dwRetval = LoadStringW(g_hThisModule, nResourceID, rgwszString, ARRAYSIZE(rgwszString));
  116. if (0 == dwRetval) {
  117. _JumpLastError(hr, error, "LoadStringW");
  118. }
  119. _Verify(512 > dwRetval, hr, error); // Shouldn't fill our buffer...
  120. hr = MyWriteConsole(g_hStdout, rgwszString, dwRetval);
  121. _JumpIfError(hr, error, "MyWriteConsole");
  122. hr = S_OK; // All done!
  123. error:
  124. return hr;
  125. }
  126. HRESULT LocalizedWPrintf2(UINT nResourceID, LPWSTR pwszFormat, ...) {
  127. va_list args;
  128. WCHAR pwszBuffer[1024];
  129. HRESULT hr = LocalizedWPrintf(nResourceID);
  130. _JumpIfError(hr, error, "LocalizedWPrintf");
  131. va_start(args, pwszFormat);
  132. hr = StringCchVPrintf(pwszBuffer, ARRAYSIZE(pwszBuffer), pwszFormat, args);
  133. _JumpIfError(hr, error, "StringCchVPrintf");
  134. va_end(args);
  135. hr = MyWriteConsole(g_hStdout, pwszBuffer, wcslen(pwszBuffer));
  136. _JumpIfError(hr, error, "MyWriteConsole");
  137. hr = S_OK;
  138. error:
  139. return hr;
  140. }
  141. // Same as LocalizedWPrintf, but adds a carriage return.
  142. HRESULT LocalizedWPrintfCR(UINT nResourceID) {
  143. HRESULT hr = LocalizedWPrintf(nResourceID);
  144. wprintf(L"\n");
  145. return hr;
  146. }
  147. VOID DisplayMsg(DWORD dwSource, DWORD dwMsgId, ... )
  148. {
  149. DWORD dwLen;
  150. LPWSTR pwszDisplayBuffer = NULL;
  151. va_list ap;
  152. va_start(ap, dwMsgId);
  153. dwLen = FormatMessageW(dwSource | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  154. NULL,
  155. dwMsgId,
  156. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  157. (LPWSTR)&pwszDisplayBuffer,
  158. 0,
  159. &ap);
  160. if (dwLen && pwszDisplayBuffer) {
  161. MyWriteConsole(g_hStdout, pwszDisplayBuffer, dwLen);
  162. }
  163. if (NULL != pwszDisplayBuffer) { LocalFree(pwszDisplayBuffer); }
  164. va_end(ap);
  165. }
  166. BOOL WriteMsg(DWORD dwSource, DWORD dwMsgId, LPWSTR *ppMsg, ...)
  167. {
  168. DWORD dwLen;
  169. va_list ap;
  170. va_start(ap, ppMsg);
  171. dwLen = FormatMessageW(dwSource | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  172. NULL,
  173. dwMsgId,
  174. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  175. (LPWSTR)ppMsg,
  176. 0,
  177. &ap);
  178. va_end(ap);
  179. // 0 is the error return value of FormatMessage.
  180. return (0 != dwLen);
  181. }