Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.7 KiB

  1. //--------------------------------------------------------------------
  2. // DebugWPrintf - implementation
  3. // Copyright (C) Microsoft Corporation, 2001
  4. //
  5. // Created by: Duncan Bryce (duncanb), 11-11-2001
  6. //
  7. // Various print routines
  8. //
  9. #include "pch.h"
  10. typedef BOOLEAN (WINAPI * SetThreadUILanguageFunc)(DWORD dwReserved);
  11. extern HINSTANCE g_hThisModule;
  12. HANDLE g_hStdout = NULL;
  13. BOOL g_bSetLocale = FALSE;
  14. SetThreadUILanguageFunc g_pfnSetThreadUILanguage = NULL;
  15. //--------------------------------------------------------------------
  16. void DebugWPrintf_(const WCHAR * wszFormat, ...)
  17. {
  18. WCHAR wszBuf[1024];
  19. va_list vlArgs;
  20. va_start(vlArgs, wszFormat);
  21. _vsnwprintf(wszBuf, 1024, wszFormat, vlArgs);
  22. va_end(vlArgs);
  23. OutputDebugStringW(wszBuf);
  24. }
  25. //--------------------------------------------------------------------
  26. HRESULT MySetThreadUILanguage(DWORD dwParam)
  27. {
  28. HMODULE hKernel32Dll = NULL;
  29. HRESULT hr;
  30. if (NULL == g_pfnSetThreadUILanguage) {
  31. hKernel32Dll = LoadLibraryW(L"kernel32.dll");
  32. if (NULL == hKernel32Dll) {
  33. _JumpLastError(hr, error, "LoadLibraryW");
  34. }
  35. g_pfnSetThreadUILanguage = (SetThreadUILanguageFunc)GetProcAddress(hKernel32Dll, "SetThreadUILanguage");
  36. if (NULL == g_pfnSetThreadUILanguage) {
  37. _JumpLastError(hr, error, "GetProcAddress");
  38. }
  39. }
  40. g_pfnSetThreadUILanguage(dwParam);
  41. hr = S_OK;
  42. error:
  43. if (NULL != hKernel32Dll) {
  44. FreeLibrary(hKernel32Dll);
  45. }
  46. return hr;
  47. }
  48. //--------------------------------------------------------------------
  49. HRESULT InitializeConsoleOutput() {
  50. HRESULT hr;
  51. g_hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  52. if (INVALID_HANDLE_VALUE == g_hStdout) {
  53. _JumpLastError(hr, error, "GetStdHandle");
  54. }
  55. hr = MySetThreadUILanguage(0);
  56. _JumpIfError(hr, error, "MySetThreadUILanguage");
  57. hr = S_OK;
  58. error:
  59. return S_OK;
  60. }
  61. //--------------------------------------------------------------------
  62. BOOL FileIsConsole(
  63. HANDLE fp
  64. )
  65. {
  66. DWORD htype;
  67. htype = GetFileType(fp);
  68. htype &= ~FILE_TYPE_REMOTE;
  69. return htype == FILE_TYPE_CHAR;
  70. }
  71. //--------------------------------------------------------------------
  72. HRESULT MyWriteConsole(
  73. HANDLE fp,
  74. LPWSTR lpBuffer,
  75. DWORD cchBuffer
  76. )
  77. {
  78. HRESULT hr;
  79. LPSTR lpAnsiBuffer = NULL;
  80. //
  81. // Jump through hoops for output because:
  82. //
  83. // 1. printf() family chokes on international output (stops
  84. // printing when it hits an unrecognized character)
  85. //
  86. // 2. WriteConsole() works great on international output but
  87. // fails if the handle has been redirected (i.e., when the
  88. // output is piped to a file)
  89. //
  90. // 3. WriteFile() works great when output is piped to a file
  91. // but only knows about bytes, so Unicode characters are
  92. // printed as two Ansi characters.
  93. //
  94. if (FileIsConsole(fp))
  95. {
  96. hr = WriteConsole(fp, lpBuffer, cchBuffer, &cchBuffer, NULL);
  97. _JumpIfError(hr, error, "WriteConsole");
  98. }
  99. else
  100. {
  101. lpAnsiBuffer = (LPSTR) LocalAlloc(LPTR, cchBuffer * sizeof(WCHAR));
  102. _JumpIfOutOfMemory(hr, error, lpAnsiBuffer);
  103. cchBuffer = WideCharToMultiByte(CP_OEMCP,
  104. 0,
  105. lpBuffer,
  106. cchBuffer,
  107. lpAnsiBuffer,
  108. cchBuffer * sizeof(WCHAR),
  109. NULL,
  110. NULL);
  111. if (cchBuffer != 0)
  112. {
  113. if (!WriteFile(fp, lpAnsiBuffer, cchBuffer, &cchBuffer, NULL))
  114. {
  115. hr = GetLastError();
  116. _JumpError(hr, error, "WriteFile");
  117. }
  118. }
  119. else
  120. {
  121. hr = GetLastError();
  122. _JumpError(hr, error, "WideCharToMultiByte");
  123. }
  124. }
  125. hr = S_OK;
  126. error:
  127. if (NULL != lpAnsiBuffer)
  128. LocalFree(lpAnsiBuffer);
  129. return hr;
  130. }
  131. //--------------------------------------------------------------------
  132. VOID DisplayMsg(DWORD dwSource, DWORD dwMsgId, ... )
  133. {
  134. DWORD dwBytesWritten;
  135. DWORD dwLen;
  136. LPWSTR pwszDisplayBuffer = NULL;
  137. va_list ap;
  138. va_start(ap, dwMsgId);
  139. dwLen = FormatMessageW(dwSource | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  140. NULL,
  141. dwMsgId,
  142. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  143. (LPWSTR)&pwszDisplayBuffer,
  144. 0,
  145. &ap);
  146. if (dwLen && pwszDisplayBuffer) {
  147. MyWriteConsole(g_hStdout, pwszDisplayBuffer, dwLen);
  148. }
  149. if (NULL != pwszDisplayBuffer) { LocalFree(pwszDisplayBuffer); }
  150. va_end(ap);
  151. }