From: Hugh McMaster Subject: [PATCH 2/2] attrib.exe: Use program_output.h for console writing Message-Id: Date: Tue, 17 Mar 2015 23:16:40 +1100 --- programs/attrib/attrib.c | 106 +++-------------------------------------------- 1 file changed, 5 insertions(+), 101 deletions(-) diff --git a/programs/attrib/attrib.c b/programs/attrib/attrib.c index 7e3b01e..3b5b463 100644 --- a/programs/attrib/attrib.c +++ b/programs/attrib/attrib.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "attrib.h" WINE_DEFAULT_DEBUG_CHANNEL(attrib); @@ -28,103 +29,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(attrib); static const WCHAR starW[] = {'*','\0'}; /* ========================================================================= - * Load a string from the resource file, handling any error - * Returns string retrieved from resource file - * ========================================================================= */ -static WCHAR *ATTRIB_LoadMessage(UINT id) -{ - static WCHAR msg[MAXSTRING]; - const WCHAR failedMsg[] = {'F', 'a', 'i', 'l', 'e', 'd', '!', 0}; - - if (!LoadStringW(GetModuleHandleW(NULL), id, msg, sizeof(msg)/sizeof(WCHAR))) { - WINE_FIXME("LoadString failed with %d\n", GetLastError()); - lstrcpyW(msg, failedMsg); - } - return msg; -} - -/* ========================================================================= - * Output a formatted unicode string. Ideally this will go to the console - * and hence required WriteConsoleW to output it, however if file i/o is - * redirected, it needs to be WriteFile'd using OEM (not ANSI) format - * ========================================================================= */ -static int __cdecl ATTRIB_wprintf(const WCHAR *format, ...) -{ - static WCHAR *output_bufW = NULL; - static char *output_bufA = NULL; - static BOOL toConsole = TRUE; - static BOOL traceOutput = FALSE; -#define MAX_WRITECONSOLE_SIZE 65535 - - __ms_va_list parms; - DWORD nOut; - int len; - DWORD res = 0; - - /* - * Allocate buffer to use when writing to console - * Note: Not freed - memory will be allocated once and released when - * xcopy ends - */ - - if (!output_bufW) output_bufW = HeapAlloc(GetProcessHeap(), 0, - MAX_WRITECONSOLE_SIZE*sizeof(WCHAR)); - if (!output_bufW) { - WINE_FIXME("Out of memory - could not allocate 2 x 64 KB buffers\n"); - return 0; - } - - __ms_va_start(parms, format); - SetLastError(NO_ERROR); - len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, format, 0, 0, output_bufW, - MAX_WRITECONSOLE_SIZE/sizeof(*output_bufW), &parms); - __ms_va_end(parms); - if (len == 0 && GetLastError() != NO_ERROR) { - WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(format)); - return 0; - } - - /* Try to write as unicode all the time we think it's a console */ - if (toConsole) { - res = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), - output_bufW, len, &nOut, NULL); - } - - /* If writing to console has failed (ever) we assume it's file - i/o so convert to OEM codepage and output */ - if (!res) { - BOOL usedDefaultChar = FALSE; - DWORD convertedChars; - - toConsole = FALSE; - - /* - * Allocate buffer to use when writing to file. Not freed, as above - */ - if (!output_bufA) output_bufA = HeapAlloc(GetProcessHeap(), 0, - MAX_WRITECONSOLE_SIZE); - if (!output_bufA) { - WINE_FIXME("Out of memory - could not allocate 2 x 64 KB buffers\n"); - return 0; - } - - /* Convert to OEM, then output */ - convertedChars = WideCharToMultiByte(GetConsoleOutputCP(), 0, output_bufW, - len, output_bufA, MAX_WRITECONSOLE_SIZE, - "?", &usedDefaultChar); - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), output_bufA, convertedChars, - &nOut, FALSE); - } - - /* Trace whether screen or console */ - if (!traceOutput) { - WINE_TRACE("Writing to console? (%d)\n", toConsole); - traceOutput = TRUE; - } - return nOut; -} - -/* ========================================================================= * Handle the processing for a single directory, optionally recursing into * subdirectories if needed. * Parameters: @@ -235,7 +139,7 @@ static BOOL ATTRIB_processdirectory(const WCHAR *rootdir, const WCHAR *filespec, } strcpyW(buffer, rootdir); strcatW(buffer, fd.cFileName); - ATTRIB_wprintf(fmt, flags, buffer); + WINEPROG_output_array(fmt, flags, buffer); for (count = 0; count < (sizeof(flags)/sizeof(WCHAR) - 1); count++) flags[count] = ' '; found = TRUE; } @@ -261,7 +165,7 @@ int wmain(int argc, WCHAR *argv[]) BOOL found = FALSE; if ((argc >= 2) && !strcmpW(argv[1], help_option)) { - ATTRIB_wprintf(ATTRIB_LoadMessage(STRING_HELP)); + WINEPROG_output_message(STRING_HELP); return 0; } @@ -279,7 +183,7 @@ int wmain(int argc, WCHAR *argv[]) case 'R': case 'r': attrib |= FILE_ATTRIBUTE_READONLY; break; case 'A': case 'a': attrib |= FILE_ATTRIBUTE_ARCHIVE; break; default: - ATTRIB_wprintf(ATTRIB_LoadMessage(STRING_NYI)); + WINEPROG_output_message(STRING_NYI); return 0; } switch (param[0]) { @@ -319,7 +223,7 @@ int wmain(int argc, WCHAR *argv[]) found = ATTRIB_processdirectory(curdir, name, attrib_recurse, attrib_includedirs, attrib_set, attrib_clear); if (!found) { - ATTRIB_wprintf(ATTRIB_LoadMessage(STRING_FILENOTFOUND), originalname); + WINEPROG_output_message(STRING_FILENOTFOUND, originalname); } return 0; } -- 1.9.1