/* * Console output functions (Unicode) * * Copyright 2015 The Wine Project, Hugh McMaster, Jonathan Vollebregt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_WINE_OUTPUT_H #define __WINE_WINE_OUTPUT_H #include #include #include #include #include "wine/unicode.h" #include "wine/debug.h" WINE_DECLARE_DEBUG_CHANNEL(output); static inline void output_write(const WCHAR *str, unsigned int wlen) { DWORD count, ret; ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL); if (!ret) { DWORD len; char *strA; /* WriteConsole() fails on Windows if its output is redirected to a file. * If this occurs, we should call WriteFile() and use an OEM codepage. */ len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL); strA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char)); if (!strA) return; WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, strA, len, NULL, NULL); WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strA, len, &count, FALSE); HeapFree(GetProcessHeap(), 0, strA); } } static inline void output_formatmessage(const WCHAR *fmt, __ms_va_list args) { WCHAR *str; int len; SetLastError(NO_ERROR); len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, fmt, 0, 0, (LPWSTR)&str, 0, &args); if (len == 0 && GetLastError() != NO_ERROR) { WINE_FIXME_(output)("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt)); return; } output_write(str, len); LocalFree(str); } /* Prints resource strings */ static inline void __cdecl output_string(unsigned int str_id, ...) { WCHAR fmt[1024]; __ms_va_list args; if (!LoadStringW(GetModuleHandleW(NULL), str_id, fmt, sizeof(fmt)/sizeof(fmt[0]))) { WINE_FIXME_(output)("LoadString failed with %d\n", GetLastError()); return; } __ms_va_start(args, str_id); output_formatmessage(fmt, args); __ms_va_end(args); } /* Prints WCHAR arrays */ static inline void __cdecl output_printf(const WCHAR *fmt, ...) { __ms_va_list args; WCHAR buffer[1024]; __ms_va_start(args, fmt); vsnprintfW(buffer, sizeof(buffer)/sizeof(buffer[0]), fmt, args); __ms_va_end(args); output_write(buffer, lstrlenW(buffer)); } #endif /* __WINE_WINE_OUTPUT_H */