Jacek Caban : wscript: Added IHost::Echo implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Feb 2 08:32:23 CST 2015


Module: wine
Branch: master
Commit: d6f527af14d0e9f9ea629024433e3735da439194
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d6f527af14d0e9f9ea629024433e3735da439194

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Jan 29 12:56:22 2015 +0100

wscript: Added IHost::Echo implementation.

---

 programs/cscript/Makefile.in |   2 +-
 programs/wscript/Makefile.in |   2 +-
 programs/wscript/host.c      | 124 +++++++++++++++++++++++++++++++++++++++++--
 programs/wscript/wscript.h   |  15 ++++++
 4 files changed, 138 insertions(+), 5 deletions(-)

diff --git a/programs/cscript/Makefile.in b/programs/cscript/Makefile.in
index 0a47509..b3fee31 100644
--- a/programs/cscript/Makefile.in
+++ b/programs/cscript/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = cscript.exe
 APPMODE   = -mwindows -municode
-IMPORTS   = uuid shell32 oleaut32 ole32 advapi32
+IMPORTS   = uuid shell32 oleaut32 ole32 user32 advapi32
 EXTRADEFS = -DCSCRIPT_BUILD
 PARENTSRC = ../wscript
 
diff --git a/programs/wscript/Makefile.in b/programs/wscript/Makefile.in
index 879daf5..07d8832 100644
--- a/programs/wscript/Makefile.in
+++ b/programs/wscript/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = wscript.exe
 APPMODE   = -mwindows -municode
-IMPORTS   = uuid shell32 oleaut32 ole32 advapi32
+IMPORTS   = uuid shell32 oleaut32 ole32 user32 advapi32
 
 RC_SRCS = \
 	rsrc.rc
diff --git a/programs/wscript/host.c b/programs/wscript/host.c
index 55d4010..893d006 100644
--- a/programs/wscript/host.c
+++ b/programs/wscript/host.c
@@ -30,6 +30,8 @@
 #include <wine/debug.h>
 #include <wine/unicode.h>
 
+WINE_DEFAULT_DEBUG_CHANNEL(wscript);
+
 #define BUILDVERSION 16535
 
 static const WCHAR wshNameW[] = {'W','i','n','d','o','w','s',' ','S','c','r','i','p','t',' ','H','o','s','t',0};
@@ -42,7 +44,59 @@ VARIANT_BOOL wshInteractive =
     VARIANT_FALSE;
 #endif
 
-WINE_DEFAULT_DEBUG_CHANNEL(wscript);
+static HRESULT to_string(VARIANT *src, BSTR *dst)
+{
+    VARIANT v;
+    HRESULT hres;
+
+    static const WCHAR nullW[] = {'n','u','l','l',0};
+
+    if(V_VT(src) == VT_NULL) {
+        *dst = SysAllocString(nullW);
+        return *dst ? S_OK : E_OUTOFMEMORY;
+    }
+
+    V_VT(&v) = VT_EMPTY;
+    hres = VariantChangeType(&v, src, 0, VT_BSTR);
+    if(FAILED(hres)) {
+        WARN("Could not convert argument %s to string\n", debugstr_variant(src));
+        return hres;
+    }
+
+    *dst = V_BSTR(&v);
+    return S_OK;
+}
+
+static void print_string(const WCHAR *string)
+{
+    DWORD count, ret, len, lena;
+    char *buf;
+
+    if(wshInteractive) {
+        static const WCHAR windows_script_hostW[] =
+            {'W','i','n','d','o','w','s',' ','S','c','r','i','p','t',' ','H','o','s','t',0};
+        MessageBoxW(NULL, string, windows_script_hostW, MB_OK);
+        return;
+    }
+
+    len = strlenW(string);
+    ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), string, len, &count, NULL);
+    if(ret) {
+        static const WCHAR crnlW[] = {'\r','\n'};
+        WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), crnlW, sizeof(crnlW)/sizeof(*crnlW), &count, NULL);
+        return;
+    }
+
+    lena = WideCharToMultiByte(GetConsoleOutputCP(), 0, string, len, NULL, 0, NULL, NULL);
+    buf = heap_alloc(len);
+    if(!buf)
+        return;
+
+    WideCharToMultiByte(GetConsoleOutputCP(), 0, string, len, buf, lena, NULL, NULL);
+    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, lena, &count, FALSE);
+    heap_free(buf);
+    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\r\n", 2, &count, FALSE);
+}
 
 static HRESULT WINAPI Host_QueryInterface(IHost *iface, REFIID riid, void **ppv)
 {
@@ -263,8 +317,72 @@ static HRESULT WINAPI Host_CreateObject(IHost *iface, BSTR ProgID, BSTR Prefix,
 
 static HRESULT WINAPI Host_Echo(IHost *iface, SAFEARRAY *args)
 {
-    WINE_FIXME("(%p)\n", args);
-    return E_NOTIMPL;
+    WCHAR *output = NULL, *ptr;
+    unsigned argc, i, len;
+    int ubound, lbound;
+    VARIANT *argv;
+    BSTR *strs;
+    HRESULT hres;
+
+    TRACE("(%p)\n", args);
+
+    if(SafeArrayGetDim(args) != 1) {
+        FIXME("Unsupported args dim %d\n", SafeArrayGetDim(args));
+        return E_NOTIMPL;
+    }
+
+    SafeArrayGetLBound(args, 1, &lbound);
+    SafeArrayGetUBound(args, 1, &ubound);
+
+    hres = SafeArrayAccessData(args, (void**)&argv);
+    if(FAILED(hres))
+        return hres;
+
+    argc = ubound-lbound+1;
+    strs = heap_alloc_zero(argc*sizeof(*strs));
+    if(!strs) {
+        SafeArrayUnaccessData(args);
+        return E_OUTOFMEMORY;
+    }
+
+    /* Len of spaces between arguments. */
+    len = argc-1;
+
+    for(i=0; i < argc; i++) {
+        hres = to_string(argv+i, strs+i);
+        if(FAILED(hres))
+            break;
+
+        len += SysStringLen(strs[i]);
+    }
+
+    SafeArrayUnaccessData(args);
+    if(SUCCEEDED(hres)) {
+        ptr = output = heap_alloc((len+1)*sizeof(WCHAR));
+        if(output) {
+            for(i=0; i < argc; i++) {
+                if(i)
+                    *ptr++ = ' ';
+                len = SysStringLen(strs[i]);
+                memcpy(ptr, strs[i], len*sizeof(WCHAR));
+                ptr += len;
+            }
+            *ptr = 0;
+        }else {
+            hres = E_OUTOFMEMORY;
+        }
+    }
+
+    for(i=0; i < argc; i++)
+        SysFreeString(strs[i]);
+    heap_free(strs);
+    if(FAILED(hres))
+        return hres;
+
+    print_string(output);
+
+    heap_free(output);
+    return S_OK;
 }
 
 static HRESULT WINAPI Host_GetObject(IHost *iface, BSTR Pathname, BSTR ProgID,
diff --git a/programs/wscript/wscript.h b/programs/wscript/wscript.h
index d624a2d..2a64b34 100644
--- a/programs/wscript/wscript.h
+++ b/programs/wscript/wscript.h
@@ -33,3 +33,18 @@ extern WCHAR **argums;
 extern int numOfArgs;
 
 extern VARIANT_BOOL wshInteractive;
+
+static inline void * __WINE_ALLOC_SIZE(1) heap_alloc(size_t len)
+{
+    return HeapAlloc(GetProcessHeap(), 0, len);
+}
+
+static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t len)
+{
+    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
+
+static inline BOOL heap_free(void *mem)
+{
+    return HeapFree(GetProcessHeap(), 0, mem);
+}




More information about the wine-cvs mailing list