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