Reactos

[CSCRIPT][WSCRIPT][BOOTDATA] Basic .wsf support (#6140)

Support for .wsf files with a single script block

authored by

Whindmar Saksit and committed by
GitHub
108db8f0 09965760

+582
+1
base/applications/cmdutils/cscript/CMakeLists.txt
··· 15 15 set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ihost.tlb) 16 16 target_link_libraries(cscript uuid wine) 17 17 set_module_type(cscript win32cui UNICODE) 18 + add_delay_importlibs(cscript shlwapi) 18 19 add_importlibs(cscript shell32 oleaut32 ole32 advapi32 user32 msvcrt kernel32 ntdll) 19 20 add_dependencies(cscript stdole2 cscript_idlheader) 20 21 add_pch(cscript ${wscript_folder}/precomp.h SOURCE)
+1
base/applications/cmdutils/wscript/CMakeLists.txt
··· 13 13 set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ihost.tlb) 14 14 target_link_libraries(wscript uuid wine) 15 15 set_module_type(wscript win32gui UNICODE) 16 + add_delay_importlibs(wscript shlwapi) 16 17 add_importlibs(wscript shell32 oleaut32 ole32 user32 advapi32 msvcrt kernel32 ntdll) 17 18 add_dependencies(wscript stdole2 wscript_idlheader) 18 19 add_pch(wscript precomp.h SOURCE)
+378
base/applications/cmdutils/wscript/main.c
··· 60 60 61 61 static HRESULT query_interface(REFIID,void**); 62 62 63 + #ifdef __REACTOS__ 64 + #include <commctrl.h> 65 + 66 + typedef struct { 67 + UINT itemsize, count; 68 + void *mem; 69 + } SIMPLEVECTOR; 70 + 71 + static void SVect_Free(SIMPLEVECTOR *pV) 72 + { 73 + if (pV->mem) 74 + LocalFree(pV->mem); 75 + pV->mem = NULL; 76 + } 77 + 78 + static void* SVect_Add(SIMPLEVECTOR *pV) 79 + { 80 + void *p = NULL; 81 + if (pV->mem) 82 + { 83 + p = LocalReAlloc(pV->mem, pV->itemsize * (pV->count + 1), LMEM_FIXED | LMEM_MOVEABLE); 84 + if (p) 85 + { 86 + pV->mem = p; 87 + p = (char*)p + (pV->count * pV->itemsize); 88 + pV->count++; 89 + } 90 + } 91 + else 92 + { 93 + p = pV->mem = LocalAlloc(LMEM_FIXED, pV->itemsize); 94 + if (p) 95 + { 96 + pV->count = 1; 97 + } 98 + } 99 + return p; 100 + } 101 + 102 + #define SVect_Delete(pV, pItem) ( (pV), (pItem) ) /* Should not be required for global items */ 103 + 104 + static void* SVect_Get(SIMPLEVECTOR *pV, UINT i) 105 + { 106 + return pV->mem && i < pV->count ? (char*)pV->mem + (i * pV->itemsize) : NULL; 107 + } 108 + 109 + typedef struct { 110 + BSTR name; 111 + IUnknown *punk; 112 + } GLOBAL_ITEM; 113 + 114 + SIMPLEVECTOR g_global_items = { sizeof(GLOBAL_ITEM) }; 115 + 116 + static void free_globals(void) 117 + { 118 + UINT i; 119 + for (i = 0;; ++i) 120 + { 121 + GLOBAL_ITEM *p = (GLOBAL_ITEM*)SVect_Get(&g_global_items, i); 122 + if (!p) 123 + break; 124 + IUnknown_Release(p->punk); 125 + SysFreeString(p->name); 126 + } 127 + SVect_Free(&g_global_items); 128 + } 129 + 130 + static HRESULT add_globalitem(IActiveScript *script, BSTR name, IUnknown *punk, DWORD siflags) 131 + { 132 + GLOBAL_ITEM *item; 133 + HRESULT hr; 134 + 135 + name = SysAllocString(name); 136 + if (!name) 137 + return E_OUTOFMEMORY; 138 + 139 + item = SVect_Add(&g_global_items); 140 + if (item) 141 + { 142 + item->name = name; 143 + item->punk = punk; 144 + hr = IActiveScript_AddNamedItem(script, name, siflags); 145 + if (SUCCEEDED(hr)) 146 + { 147 + IUnknown_AddRef(punk); 148 + return hr; 149 + } 150 + SVect_Delete(&g_global_items, item); 151 + } 152 + SysFreeString(name); 153 + return E_OUTOFMEMORY; 154 + } 155 + 156 + static HRESULT add_globalitem_from_clsid(IActiveScript *script, BSTR name, REFCLSID clsid, DWORD siflags) 157 + { 158 + IUnknown *punk; 159 + HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&punk); 160 + if (SUCCEEDED(hr)) 161 + { 162 + hr = add_globalitem(script, name, punk, siflags); 163 + IUnknown_Release(punk); 164 + } 165 + return hr; 166 + } 167 + 168 + static HRESULT get_globalitem_info(LPCOLESTR Name, DWORD Mask, IUnknown **ppunk, ITypeInfo **ppti, BOOL *pHandled) 169 + { 170 + HRESULT hr = S_FALSE; 171 + UINT i; 172 + for (i = 0;; ++i) 173 + { 174 + GLOBAL_ITEM *p = (GLOBAL_ITEM*)SVect_Get(&g_global_items, i); 175 + if (!p) 176 + break; 177 + if (!lstrcmpiW(Name, p->name)) 178 + { 179 + if (ppti) 180 + *ppti = NULL; 181 + if (Mask & SCRIPTINFO_IUNKNOWN) 182 + { 183 + *ppunk = p->punk; 184 + if (p->punk) 185 + { 186 + IUnknown_AddRef(p->punk); 187 + *pHandled = TRUE; 188 + } 189 + return S_OK; 190 + } 191 + break; 192 + } 193 + } 194 + return hr; 195 + } 196 + #endif 197 + 63 198 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, 64 199 REFIID riid, void **ppv) 65 200 { ··· 88 223 LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppunkItem, ITypeInfo **ppti) 89 224 { 90 225 WINE_TRACE("(%s %x %p %p)\n", wine_dbgstr_w(pstrName), dwReturnMask, ppunkItem, ppti); 226 + 227 + #ifdef __REACTOS__ 228 + { 229 + BOOL handled = FALSE; 230 + HRESULT hr = get_globalitem_info(pstrName, dwReturnMask, ppunkItem, ppti, &handled); 231 + if (handled) 232 + return hr; 233 + } 234 + #endif 91 235 92 236 if(lstrcmpW(pstrName, wshW) && lstrcmpW(pstrName, wscriptW)) 93 237 return E_FAIL; ··· 388 532 WINE_FIXME("SetScriptState failed: %08x\n", hres); 389 533 } 390 534 535 + #ifdef __REACTOS__ 536 + #include <msxml2.h> 537 + #include <shlwapi.h> 538 + 539 + static HRESULT xmldomnode_getattributevalue(IXMLDOMNode *pnode, LPCWSTR name, BSTR *pout) 540 + { 541 + IXMLDOMNamedNodeMap *pmap; 542 + HRESULT hr = E_OUTOFMEMORY; 543 + BSTR bsname = SysAllocString(name); 544 + *pout = NULL; 545 + if (bsname && SUCCEEDED(hr = IXMLDOMNode_get_attributes(pnode, &pmap))) 546 + { 547 + if (SUCCEEDED(hr = IXMLDOMNamedNodeMap_getNamedItem(pmap, bsname, &pnode))) 548 + { 549 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 550 + if (pnode) 551 + { 552 + hr = IXMLDOMNode_get_text(pnode, pout); 553 + if (SUCCEEDED(hr) && !*pout) 554 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 555 + IXMLDOMNode_Release(pnode); 556 + } 557 + } 558 + IXMLDOMNamedNodeMap_Release(pmap); 559 + } 560 + SysFreeString(bsname); 561 + return hr; 562 + } 563 + 564 + static HRESULT xmldomelem_getelembytag(IXMLDOMElement *pelem, LPCWSTR name, long index, IXMLDOMNode**ppout) 565 + { 566 + HRESULT hr = E_OUTOFMEMORY; 567 + IXMLDOMNodeList *pnl; 568 + BSTR bsname = SysAllocString(name); 569 + *ppout = NULL; 570 + if (bsname && SUCCEEDED(hr = IXMLDOMElement_getElementsByTagName(pelem, bsname, &pnl))) 571 + { 572 + hr = IXMLDOMNodeList_get_item(pnl, index, ppout); 573 + if (SUCCEEDED(hr) && !*ppout) 574 + hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS); 575 + IUnknown_Release(pnl); 576 + } 577 + SysFreeString(bsname); 578 + return hr; 579 + } 580 + 581 + static HRESULT xmldomelem_getelembytagasdomelem(IXMLDOMElement *pelem, LPCWSTR name, long index, IXMLDOMElement**ppout) 582 + { 583 + IXMLDOMNode *pnode; 584 + HRESULT hr = xmldomelem_getelembytag(pelem, name, index, &pnode); 585 + *ppout = NULL; 586 + if (SUCCEEDED(hr)) 587 + { 588 + hr = IUnknown_QueryInterface(pnode, &IID_IXMLDOMElement, (void**)ppout); 589 + IUnknown_Release(pnode); 590 + } 591 + return hr; 592 + } 593 + 594 + static void wsf_addobjectfromnode(IActiveScript *script, IXMLDOMNode *obj) 595 + { 596 + BSTR bsid, bsclsid = NULL; 597 + if (SUCCEEDED(xmldomnode_getattributevalue(obj, L"id", &bsid))) 598 + { 599 + CLSID clsid; 600 + HRESULT hr; 601 + hr = xmldomnode_getattributevalue(obj, L"clsid", &bsclsid); 602 + if (FAILED(hr) || FAILED(CLSIDFromString(bsclsid, &clsid))) 603 + { 604 + SysFreeString(bsclsid); 605 + if (SUCCEEDED(hr = xmldomnode_getattributevalue(obj, L"progid", &bsclsid))) 606 + { 607 + hr = CLSIDFromProgID(bsclsid, &clsid); 608 + SysFreeString(bsclsid); 609 + } 610 + } 611 + if (SUCCEEDED(hr)) 612 + { 613 + hr = add_globalitem_from_clsid(script, bsid, &clsid, SCRIPTITEM_ISVISIBLE); 614 + } 615 + SysFreeString(bsid); 616 + } 617 + } 618 + 619 + static HRESULT run_wsfjob(IXMLDOMElement *jobtag) 620 + { 621 + // FIXME: We are supposed to somehow handle multiple languages in the same IActiveScript. 622 + IActiveScript *script; 623 + LPCWSTR deflang = L"JScript"; 624 + IXMLDOMNode *scripttag; 625 + HRESULT hr = S_OK; 626 + if (SUCCEEDED(xmldomelem_getelembytag(jobtag, L"script", 0, &scripttag))) 627 + { 628 + CLSID clsid; 629 + IActiveScriptParse *parser; 630 + BSTR lang, code; 631 + if (FAILED(xmldomnode_getattributevalue(scripttag, L"language", &lang))) 632 + lang = NULL; 633 + hr = CLSIDFromProgID(lang ? lang : deflang, &clsid); 634 + SysFreeString(lang); 635 + 636 + if (SUCCEEDED(hr)) 637 + { 638 + hr = E_FAIL; 639 + if (create_engine(&clsid, &script, &parser)) 640 + { 641 + if (init_engine(script, parser)) 642 + { 643 + long index; 644 + for (index = 0; index < 0x7fffffff; ++index) 645 + { 646 + IXMLDOMNode *obj; 647 + if (SUCCEEDED(xmldomelem_getelembytag(jobtag, L"object", index, &obj))) 648 + { 649 + wsf_addobjectfromnode(script, obj); 650 + IUnknown_Release(obj); 651 + } 652 + else 653 + { 654 + break; 655 + } 656 + } 657 + 658 + if (SUCCEEDED(hr = IXMLDOMNode_get_text(scripttag, &code))) 659 + { 660 + hr = IActiveScriptParse_ParseScriptText(parser, code, NULL, NULL, NULL, 1, 1, 661 + SCRIPTTEXT_HOSTMANAGESSOURCE|SCRIPTITEM_ISVISIBLE, 662 + NULL, NULL); 663 + if (SUCCEEDED(hr)) 664 + { 665 + hr = IActiveScript_SetScriptState(script, SCRIPTSTATE_STARTED); 666 + IActiveScript_Close(script); 667 + } 668 + SysFreeString(code); 669 + } 670 + ITypeInfo_Release(host_ti); 671 + } 672 + IUnknown_Release(parser); 673 + IUnknown_Release(script); 674 + } 675 + } 676 + IUnknown_Release(scripttag); 677 + } 678 + return hr; 679 + } 680 + 681 + /* 682 + .WSF files can contain a single job, or multiple jobs if contained in a package. 683 + Jobs are identified by their id and if no id is specified, the first job is used. 684 + Each job can contain multiple script tags and all scripts are merged into one. 685 + 686 + <job><script language="JScript">WScript.Echo("JS");</script></job> 687 + or 688 + <package> 689 + <job><script language="JScript">WScript.Echo("JS");</script></job> 690 + </package> 691 + or 692 + <?xml version="1.0" ?> 693 + <job> 694 + <script language="JScript"><![CDATA[function JS(s) {WScript.Echo(s)}]]></script> 695 + <script language="VBScript">JS "VB2JS"</script> 696 + </job> 697 + */ 698 + static HRESULT run_wsf(LPCWSTR xmlpath) 699 + { 700 + WCHAR url[ARRAY_SIZE("file://") + max(ARRAY_SIZE(scriptFullName), MAX_PATH)]; 701 + DWORD cch = ARRAY_SIZE(url); 702 + IXMLDOMDocument *pdoc; 703 + HRESULT hr = UrlCreateFromPathW(xmlpath, url, &cch, 0), hrCom; 704 + if (FAILED(hr)) 705 + return hr; 706 + 707 + hrCom = CoInitialize(NULL); 708 + hr = CoCreateInstance(&CLSID_DOMDocument30, NULL, CLSCTX_INPROC_SERVER, 709 + &IID_IXMLDOMDocument, (void**)&pdoc); 710 + if (SUCCEEDED(hr)) 711 + { 712 + VARIANT_BOOL succ = VARIANT_FALSE; 713 + IXMLDOMElement *pdocelm; 714 + BSTR bsurl = SysAllocString(url); 715 + VARIANT v; 716 + V_VT(&v) = VT_BSTR; 717 + V_BSTR(&v) = bsurl; 718 + if (!bsurl || (hr = IXMLDOMDocument_load(pdoc, v, &succ)) > 0 || (SUCCEEDED(hr) && !succ)) 719 + { 720 + hr = E_FAIL; 721 + } 722 + if (SUCCEEDED(hr) && SUCCEEDED(hr = IXMLDOMDocument_get_documentElement(pdoc, &pdocelm))) 723 + { 724 + BSTR tagName = NULL; 725 + if (SUCCEEDED(hr = IXMLDOMElement_get_tagName(pdocelm, &tagName))) 726 + { 727 + if (lstrcmpiW(tagName, L"package") == 0) 728 + { 729 + // FIXME: Accept job id as a function parameter and find the job here 730 + IXMLDOMElement *p; 731 + if (SUCCEEDED(hr = xmldomelem_getelembytagasdomelem(pdocelm, L"job", 0, &p))) 732 + { 733 + IUnknown_Release(pdocelm); 734 + pdocelm = p; 735 + } 736 + } 737 + else if (lstrcmpiW(tagName, L"job") != 0) 738 + { 739 + hr = 0x800400C0ul; 740 + } 741 + SysFreeString(tagName); 742 + } 743 + if (SUCCEEDED(hr)) 744 + { 745 + // FIXME: Only support CDATA blocks if the xml tag is present? 746 + hr = run_wsfjob(pdocelm); 747 + } 748 + IUnknown_Release(pdocelm); 749 + } 750 + VariantClear(&v); 751 + IUnknown_Release(pdoc); 752 + } 753 + free_globals(); 754 + if (SUCCEEDED(hrCom)) 755 + CoUninitialize(); 756 + return hr; 757 + } 758 + #endif 759 + 391 760 static BOOL set_host_properties(const WCHAR *prop) 392 761 { 393 762 static const WCHAR nologoW[] = {'n','o','l','o','g','o',0}; ··· 453 822 return 1; 454 823 455 824 ext = wcsrchr(filepart, '.'); 825 + #ifdef __REACTOS__ 826 + if (ext && !lstrcmpiW(ext, L".wsf")) { 827 + return run_wsf(scriptFullName); 828 + } 829 + #endif 456 830 if(!ext || !get_engine_clsid(ext, &clsid)) { 457 831 WINE_FIXME("Could not find engine for %s\n", wine_dbgstr_w(ext)); 458 832 return 1; ··· 476 850 477 851 IActiveScript_Release(script); 478 852 IActiveScriptParse_Release(parser); 853 + 854 + #ifdef __REACTOS__ 855 + free_globals(); 856 + #endif 479 857 480 858 CoUninitialize(); 481 859
+11
boot/bootdata/hivecls.inf
··· 555 555 HKCR,"AVIFile\DefaultIcon","",0x00020000,"%SystemRoot%\system32\shell32.dll,-224" 556 556 HKCR,"AVIFile\shell\open\command","",0x00020000,"%SystemRoot%\system32\mplay32.exe ""%1""" 557 557 558 + ; WSH 559 + HKCR,".wsf","",0x00000000,"WSFFile" 560 + HKCR,".wsf","PerceivedType",0x00000000,"text" 561 + HKCR,"WSFFile","",0x00000000,%WSFFILE% 562 + HKCR,"WSFFile\DefaultIcon","",0x00020000,"%SystemRoot%\system32\shell32.dll,-153" 563 + HKCR,"WSFFile\shell\Open\command","",0x00020000,"""%SystemRoot%\system32\WScript.exe"" ""%1"" %*" 564 + HKCR,"WSFFile\shell\Open2","",0x00000000,"Open &with Command Prompt" 565 + HKCR,"WSFFile\shell\Open2\command","",0x00020000,"""%SystemRoot%\system32\CScript.exe"" ""%1"" %*" 566 + 567 + 558 568 HKCR,"CLSID",,0x00000012 559 569 560 570 ; For Shell32.dll ··· 791 801 CSSFILE="Cascading Style Sheet" 792 802 SCFFILE="ReactOS Explorer Command" 793 803 WMZFILE="Compressed Enhanced Metafile" 804 + WSFFILE="Windows Script File" 794 805 795 806 ;; For .reg files, right-click menu 796 807 MERGE="Merge"
+1
modules/rostests/apitests/CMakeLists.txt
··· 66 66 add_subdirectory(winspool) 67 67 add_subdirectory(wlanapi) 68 68 add_subdirectory(ws2_32) 69 + add_subdirectory(wscript) 69 70 add_subdirectory(zipfldr)
+10
modules/rostests/apitests/wscript/CMakeLists.txt
··· 1 + 2 + list(APPEND SOURCE 3 + wsf.c 4 + testlist.c) 5 + 6 + add_executable(wscript_apitest ${SOURCE}) 7 + target_link_libraries(wscript_apitest wine ${PSEH_LIB}) 8 + set_module_type(wscript_apitest win32cui) 9 + add_importlibs(wscript_apitest shlwapi msvcrt user32 kernel32) 10 + add_rostests_file(TARGET wscript_apitest)
+10
modules/rostests/apitests/wscript/testlist.c
··· 1 + #define STANDALONE 2 + #include <apitest.h> 3 + 4 + extern void func_wsf(void); 5 + 6 + const struct test winetest_testlist[] = 7 + { 8 + { "wsf", func_wsf }, 9 + { 0, 0 } 10 + };
+170
modules/rostests/apitests/wscript/wsf.c
··· 1 + /* 2 + * PROJECT: ReactOS API tests 3 + * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) 4 + * PURPOSE: Tests for wscript.exe 5 + * COPYRIGHT: Whindmar Saksit (whindsaks@proton.me) 6 + */ 7 + 8 + #include <apitest.h> 9 + #include <windows.h> 10 + #include <shlwapi.h> 11 + #include <stdio.h> 12 + 13 + #define MYGUID "{898AC78E-BFC7-41FF-937D-EDD01E666707}" 14 + 15 + static DWORD getregdw(HKEY hKey, LPCSTR sub, LPCSTR name, DWORD *out, DWORD defval) 16 + { 17 + LRESULT e; 18 + DWORD size = sizeof(*out); 19 + *out = 0; 20 + e = SHGetValueA(hKey, sub, name, NULL, out, &size); 21 + if (e) 22 + *out = defval; 23 + return e; 24 + } 25 + 26 + static BOOL makestringfile(LPWSTR path, SIZE_T cchpath, LPCSTR ext, LPCSTR string, const BYTE *map) 27 + { 28 + UINT cch = GetTempPathW(cchpath, path); 29 + UINT16 i = 0; 30 + if (!cch || cch > cchpath) 31 + return FALSE; 32 + while (++i) 33 + { 34 + HANDLE hFile; 35 + if (_snwprintf(path + cch, cchpath - cch, L"~%u.%hs", i, ext ? ext : "tmp") >= cchpath - cch) 36 + return FALSE; 37 + hFile = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_NEW, 0, NULL); 38 + if (hFile != INVALID_HANDLE_VALUE) 39 + { 40 + BOOL succ = TRUE; 41 + for (; *string && succ; ++string) 42 + { 43 + BYTE ch = *string; 44 + DWORD j; 45 + for (j = 0; map && map[j + 0]; j += 2) 46 + { 47 + if (ch == map[j + 0]) 48 + ch = map[j + 1]; 49 + } 50 + succ = WriteFile(hFile, &ch, 1, &j, NULL); 51 + } 52 + CloseHandle(hFile); 53 + return succ; 54 + } 55 + } 56 + return FALSE; 57 + } 58 + 59 + static DWORD runscriptfile(LPCWSTR path, LPCWSTR engine) 60 + { 61 + STARTUPINFOW si; 62 + PROCESS_INFORMATION pi; 63 + LPCWSTR exe = engine ? engine : L"wscript.exe"; 64 + WCHAR cmd[MAX_PATH * 2]; 65 + 66 + if (_snwprintf(cmd, _countof(cmd), L"\"%s\" //nologo \"%s\"", exe, path) >= _countof(cmd)) 67 + return ERROR_BUFFER_OVERFLOW; 68 + ZeroMemory(&si, sizeof(si)); 69 + si.cb = sizeof(si); 70 + if (CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) 71 + { 72 + DWORD code = ERROR_INTERNAL_ERROR; 73 + WaitForSingleObject(pi.hProcess, INFINITE); 74 + GetExitCodeProcess(pi.hProcess, &code); 75 + CloseHandle(pi.hProcess); 76 + CloseHandle(pi.hThread); 77 + return code; 78 + } 79 + return GetLastError(); 80 + } 81 + 82 + static DWORD runscript(LPCSTR ext, LPCSTR script, const BYTE *map) 83 + { 84 + DWORD code; 85 + WCHAR file[MAX_PATH]; 86 + if (!makestringfile(file, _countof(file), ext, script, map)) 87 + { 88 + skip("Unable to create script\n"); 89 + return ERROR_FILE_NOT_FOUND; 90 + } 91 + code = runscriptfile(file, NULL); 92 + DeleteFileW(file); 93 + return code; 94 + } 95 + 96 + static void test_defaultscriptisjs(void) 97 + { 98 + LPCSTR script = "" 99 + "<job>" 100 + "<script>" /* No language attribute should default to Javascript */ 101 + "var x = 42;" 102 + "WScript.Quit(x);" 103 + "</script>" 104 + "</job>"; 105 + 106 + ok(runscript("wsf", script, NULL) == 42, "Script failed\n"); 107 + } 108 + 109 + static void test_simplevb(void) 110 + { 111 + LPCSTR script = "" 112 + "<job>" 113 + "<script language=\"VBScript\">" 114 + "Dim x\n" 115 + "x = 42\n" 116 + "WScript.Quit x\n" 117 + "</script>" 118 + "</job>"; 119 + 120 + ok(runscript("wsf", script, NULL) == 42, "Script failed\n"); 121 + } 122 + 123 + static void test_defpackagejob(void) 124 + { 125 + LPCSTR script = "" 126 + "<package>" 127 + "<job id=\"PickMePlease\">" 128 + "<script language=\"VBScript\">" 129 + "WScript.Quit 42" 130 + "</script>" 131 + "</job>" 132 + "<job id=\"DontExecuteMe\">" 133 + "<script language=\"VBScript\">" 134 + "WScript.Quit 33" 135 + "</script>" 136 + "</job>" 137 + "</package>"; 138 + 139 + ok(runscript("wsf", script, NULL) == 42, "Script failed\n"); 140 + } 141 + 142 + static void test_objecttag(void) 143 + { 144 + DWORD dw; 145 + static const BYTE map[] = { '#', '\"', '$', '\\', 0, 0 }; 146 + LPCSTR script = "" 147 + "<job>" 148 + "<object id=#ws1# clsid=#{72C24DD5-D70A-438B-8A42-98424B88AFB8}# />" 149 + "<script language=#JScript#>" 150 + "var dontcare = ws1.ExpandEnvironmentStrings(#SystemRoot#);" 151 + "var p = #HKCU/Software/" MYGUID "#.replace(/$//g,'$$');" 152 + "ws2.RegWrite(p, 42, #REG_DWORD#);" 153 + "</script>" 154 + "<object id=#ws2# progid=#WScript.Shell# />" /* Placing the object tag after the script just for fun */ 155 + "</job>"; 156 + 157 + ok(runscript("wsf", script, map) == 0, "Script failed\n"); 158 + 159 + getregdw(HKEY_CURRENT_USER, "Software", MYGUID, &dw, 0); 160 + ok(dw == 42, "Value does not match\n"); 161 + SHDeleteValueA(HKEY_CURRENT_USER, "Software", MYGUID); 162 + } 163 + 164 + START_TEST(wsf) 165 + { 166 + test_defaultscriptisjs(); 167 + test_simplevb(); 168 + test_defpackagejob(); 169 + test_objecttag(); 170 + }