[PATCH 3/5] wmic: Output Unicode text with BOM when redirected.

Hans Leidekker hans at codeweavers.com
Mon Oct 8 08:53:10 CDT 2018


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 programs/wmic/main.c | 57 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/programs/wmic/main.c b/programs/wmic/main.c
index b2ec7e22f1..f01aad7702 100644
--- a/programs/wmic/main.c
+++ b/programs/wmic/main.c
@@ -124,32 +124,17 @@ static WCHAR *find_prop( IWbemClassObject *class, const WCHAR *prop )
 static int output_string( HANDLE handle, const WCHAR *msg, ... )
 {
     va_list va_args;
-    int wlen;
-    DWORD count, ret;
+    int len;
+    DWORD count;
     WCHAR buffer[8192];
 
     va_start( va_args, msg );
-    vsprintfW( buffer, msg, va_args );
+    len = vsnprintfW( buffer, ARRAY_SIZE(buffer), msg, va_args );
     va_end( va_args );
 
-    wlen = strlenW( buffer );
-    ret = WriteConsoleW( handle, buffer, wlen, &count, NULL );
-    if (!ret)
-    {
-        DWORD len;
-        char *msgA;
-
-        /* On Windows WriteConsoleW() fails if the output is redirected. So fall
-         * back to WriteFile(), assuming the console encoding is still the right
-         * one in that case.
-         */
-        len = WideCharToMultiByte( GetConsoleOutputCP(), 0, buffer, wlen, NULL, 0, NULL, NULL );
-        if (!(msgA = HeapAlloc( GetProcessHeap(), 0, len * sizeof(char) ))) return 0;
-
-        WideCharToMultiByte( GetConsoleOutputCP(), 0, buffer, wlen, msgA, len, NULL, NULL );
-        WriteFile( handle, msgA, len, &count, FALSE );
-        HeapFree( GetProcessHeap(), 0, msgA );
-    }
+    if (!WriteConsoleW( handle, buffer, len, &count, NULL ))
+        WriteFile( handle, buffer, len * sizeof(WCHAR), &count, FALSE );
+
     return count;
 }
 
@@ -162,13 +147,37 @@ static int output_error( int msg )
     return output_string( GetStdHandle(STD_ERROR_HANDLE), fmtW, buffer );
 }
 
+static int output_header( const WCHAR *prop )
+{
+    static const WCHAR bomW[] = {0xfeff}, fmtW[] = {'%','s','\r','\n',0};
+    int len;
+    DWORD count;
+    WCHAR buffer[8192];
+
+    len = snprintfW( buffer, ARRAY_SIZE(buffer), fmtW, prop );
+
+    if (!WriteConsoleW( GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, &count, NULL )) /* redirected */
+    {
+        WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), bomW, sizeof(bomW), &count, FALSE );
+        WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), buffer, len * sizeof(WCHAR), &count, FALSE );
+        count += sizeof(bomW);
+    }
+
+    return count;
+}
+
+static int output_line( const WCHAR *str )
+{
+    static const WCHAR fmtW[] = {'%','s','\r','\n',0};
+    return output_string( GetStdHandle(STD_OUTPUT_HANDLE), fmtW, str );
+}
+
 static int query_prop( const WCHAR *class, const WCHAR *propname )
 {
     static const WCHAR select_allW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
     static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
     static const WCHAR wqlW[] = {'W','Q','L',0};
     static const WCHAR newlineW[] = {'\r','\n',0};
-    static const WCHAR fmtW[] = {'%','s','\r','\n',0};
     HRESULT hr;
     IWbemLocator *locator = NULL;
     IWbemServices *services = NULL;
@@ -218,13 +227,13 @@ static int query_prop( const WCHAR *class, const WCHAR *propname )
                 output_error( STRING_INVALID_QUERY );
                 goto done;
             }
-            output_string( GetStdHandle(STD_OUTPUT_HANDLE), fmtW, prop );
+            output_header( prop );
             first = FALSE;
         }
         if (IWbemClassObject_Get( obj, prop, 0, &v, NULL, NULL ) == WBEM_S_NO_ERROR)
         {
             VariantChangeType( &v, &v, 0, VT_BSTR );
-            output_string( GetStdHandle(STD_OUTPUT_HANDLE), fmtW, V_BSTR( &v ) );
+            output_line( V_BSTR( &v ) );
             VariantClear( &v );
         }
         IWbemClassObject_Release( obj );
-- 
2.11.0




More information about the wine-devel mailing list