diff --git a/reactos/base/applications/cmdutils/wscript/CMakeLists.txt b/reactos/base/applications/cmdutils/wscript/CMakeLists.txt index 1009ff023ab..a38899b0e34 100644 --- a/reactos/base/applications/cmdutils/wscript/CMakeLists.txt +++ b/reactos/base/applications/cmdutils/wscript/CMakeLists.txt @@ -11,7 +11,7 @@ add_typelib(ihost.idl) set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ihost.tlb) target_link_libraries(wscript uuid wine) set_module_type(wscript win32gui UNICODE) -add_importlibs(wscript shell32 oleaut32 ole32 advapi32 msvcrt kernel32 ntdll) +add_importlibs(wscript shell32 oleaut32 ole32 user32 advapi32 msvcrt kernel32 ntdll) add_dependencies(wscript stdole2 wscript_idlheader) add_pch(wscript wscript.h SOURCE) add_cd_file(TARGET wscript DESTINATION reactos/system32 FOR all) diff --git a/reactos/base/applications/cmdutils/wscript/host.c b/reactos/base/applications/cmdutils/wscript/host.c index 64519ad52db..e8da80fe2a2 100644 --- a/reactos/base/applications/cmdutils/wscript/host.c +++ b/reactos/base/applications/cmdutils/wscript/host.c @@ -30,6 +30,60 @@ VARIANT_BOOL wshInteractive = VARIANT_FALSE; #endif +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) { WINE_TRACE("(%s %p)\n", wine_dbgstr_guid(riid), ppv); @@ -249,8 +303,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; + LONG 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/reactos/base/applications/cmdutils/wscript/main.c b/reactos/base/applications/cmdutils/wscript/main.c index 0923c33cecc..f8f6122c2f2 100644 --- a/reactos/base/applications/cmdutils/wscript/main.c +++ b/reactos/base/applications/cmdutils/wscript/main.c @@ -174,7 +174,7 @@ static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWin return S_OK; } -static IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = { +static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = { ActiveScriptSiteWindow_QueryInterface, ActiveScriptSiteWindow_AddRef, ActiveScriptSiteWindow_Release, diff --git a/reactos/base/applications/cmdutils/wscript/wscript.h b/reactos/base/applications/cmdutils/wscript/wscript.h index 7a861613818..2c863f99ed5 100644 --- a/reactos/base/applications/cmdutils/wscript/wscript.h +++ b/reactos/base/applications/cmdutils/wscript/wscript.h @@ -51,4 +51,19 @@ 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); +} + #endif /* _WSCRIPT_H_ */ diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 8323ec0a4c7..13b6f16243a 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -240,7 +240,7 @@ reactos/base/applications/cmdutils/cscript # Synced to Wine-1.7.27 reactos/base/applications/cmdutils/reg # Synced to Wine-1.7.27 reactos/base/applications/cmdutils/taskkill # Synced to Wine-1.7.27 reactos/base/applications/cmdutils/wmic # Synced to Wine-1.7.27 -reactos/base/applications/cmdutils/wscript # Synced to Wine-1.7.27 +reactos/base/applications/cmdutils/wscript # Synced to WineStaging-1.7.37 reactos/base/applications/cmdutils/xcopy # Synced to Wine-1.7.27 reactos/base/applications/games/winmine # Forked at Wine-1_3_5 reactos/base/applications/extrac32 # Synced to Wine-1.7.27