* Import from Wine 1.5.26.
svn path=/trunk/; revision=59018
add_subdirectory(userenv)
add_subdirectory(usp10)
add_subdirectory(uxtheme)
+add_subdirectory(vbscript)
add_subdirectory(version)
add_subdirectory(windowscodecs)
add_subdirectory(winhttp)
--- /dev/null
+
+add_definitions(-D__ROS_LONG64__)
+add_idl_headers(vbscript_wine_test_idlheader vbsregexp55.idl)
+
+list(APPEND SOURCE
+ createobj.c
+ run.c
+ vbscript.c
+ testlist.c
+ rsrc.rc)
+
+list(APPEND vbscript_winetest_rc_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/api.vbs
+ ${CMAKE_CURRENT_SOURCE_DIR}/lang.vbs
+ ${CMAKE_CURRENT_SOURCE_DIR}/regexp.vbs)
+
+set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS "${vbscript_winetest_rc_deps}")
+
+add_executable(vbscript_winetest ${SOURCE})
+target_link_libraries(vbscript_winetest wine)
+set_module_type(vbscript_winetest win32cui)
+add_importlibs(vbscript_winetest ole32 oleaut32 advapi32 msvcrt kernel32 ntdll)
+add_dependencies(vbscript_winetest vbscript_wine_test_idlheader)
+add_cd_file(TARGET vbscript_winetest DESTINATION reactos/bin FOR all)
--- /dev/null
+'
+' Copyright 2011 Jacek Caban for CodeWeavers
+'
+' This library is free software; you can redistribute it and/or
+' modify it under the terms of the GNU Lesser General Public
+' License as published by the Free Software Foundation; either
+' version 2.1 of the License, or (at your option) any later version.
+'
+' This library is distributed in the hope that it will be useful,
+' but WITHOUT ANY WARRANTY; without even the implied warranty of
+' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+' Lesser General Public License for more details.
+'
+' You should have received a copy of the GNU Lesser General Public
+' License along with this library; if not, write to the Free Software
+' Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+'
+
+Option Explicit
+
+Dim x
+
+Class EmptyClass
+End Class
+
+Call ok(vbSunday = 1, "vbSunday = " & vbSunday)
+Call ok(getVT(vbSunday) = "VT_I2", "getVT(vbSunday) = " & getVT(vbSunday))
+Call ok(vbMonday = 2, "vbMonday = " & vbMonday)
+Call ok(getVT(vbMonday) = "VT_I2", "getVT(vbMonday) = " & getVT(vbMonday))
+Call ok(vbTuesday = 3, "vbTuesday = " & vbTuesday)
+Call ok(getVT(vbTuesday) = "VT_I2", "getVT(vbTuesday) = " & getVT(vbTuesday))
+Call ok(vbWednesday = 4, "vbWednesday = " & vbWednesday)
+Call ok(getVT(vbWednesday) = "VT_I2", "getVT(vbWednesday) = " & getVT(vbWednesday))
+Call ok(vbThursday = 5, "vbThursday = " & vbThursday)
+Call ok(getVT(vbThursday) = "VT_I2", "getVT(vbThursday) = " & getVT(vbThursday))
+Call ok(vbFriday = 6, "vbFriday = " & vbFriday)
+Call ok(getVT(vbFriday) = "VT_I2", "getVT(vbFriday) = " & getVT(vbFriday))
+Call ok(vbSaturday = 7, "vbSaturday = " & vbSaturday)
+Call ok(getVT(vbSaturday) = "VT_I2", "getVT(vbSaturday) = " & getVT(vbSaturday))
+
+Sub TestConstant(name, val, exval)
+ Call ok(val = exval, name & " = " & val & " expected " & exval)
+ Call ok(getVT(val) = "VT_I2*", "getVT(" & name & ") = " & getVT(val))
+End Sub
+
+Sub TestConstantI4(name, val, exval)
+ Call ok(val = exval, name & " = " & val & " expected " & exval)
+ Call ok(getVT(val) = "VT_I4*", "getVT(" & name & ") = " & getVT(val))
+End Sub
+
+Sub TestConstantBSTR(name, val, exval)
+ Call ok(val = exval, name & " = " & val & " expected " & exval)
+ Call ok(getVT(val) = "VT_BSTR*", "getVT(" & name & ") = " & getVT(val))
+End Sub
+
+TestConstant "vbEmpty", vbEmpty, 0
+TestConstant "vbNull", vbNull, 1
+TestConstant "vbLong", vbLong, 3
+TestConstant "vbSingle", vbSingle, 4
+TestConstant "vbDouble", vbDouble, 5
+TestConstant "vbCurrency", vbCurrency, 6
+TestConstant "vbDate", vbDate, 7
+TestConstant "vbString", vbString, 8
+TestConstant "vbObject", vbObject, 9
+TestConstant "vbError", vbError, 10
+TestConstant "vbBoolean", vbBoolean, 11
+TestConstant "vbVariant", vbVariant, 12
+TestConstant "vbDataObject", vbDataObject, 13
+TestConstant "vbDecimal", vbDecimal, 14
+TestConstant "vbByte", vbByte, 17
+TestConstant "vbArray", vbArray, 8192
+TestConstant "vbCritical", vbCritical, 16
+TestConstant "vbQuestion", vbQuestion, 32
+TestConstant "vbExclamation", vbExclamation, 48
+TestConstant "vbInformation", vbInformation, 64
+TestConstant "vbDefaultButton1", vbDefaultButton1, 0
+TestConstant "vbDefaultButton2", vbDefaultButton2, 256
+TestConstant "vbDefaultButton3", vbDefaultButton3, 512
+TestConstant "vbDefaultButton4", vbDefaultButton4, 768
+TestConstant "vbApplicationModal", vbApplicationModal, 0
+TestConstant "vbSystemModal", vbSystemModal, 4096
+TestConstant "vbUseSystem", vbUseSystem, 0
+TestConstant "vbUseSystemDayOfWeek", vbUseSystemDayOfWeek, 0
+TestConstant "vbFirstJan1", vbFirstJan1, 1
+TestConstant "vbFirstFourDays", vbFirstFourDays, 2
+TestConstant "vbFirstFullWeek", vbFirstFullWeek, 3
+TestConstant "vbTrue", vbTrue, -1
+TestConstant "vbFalse", vbFalse, 0
+TestConstantI4 "vbMsgBoxHelpButton", vbMsgBoxHelpButton, 16384
+TestConstantI4 "vbMsgBoxSetForeground", vbMsgBoxSetForeground, 65536
+TestConstantI4 "vbMsgBoxRight", vbMsgBoxRight, 524288
+TestConstantI4 "vbMsgBoxRtlReading", vbMsgBoxRtlReading, 1048576
+TestConstant "vbUseDefault", vbUseDefault, -2
+TestConstant "vbBinaryCompare", vbBinaryCompare, 0
+TestConstant "vbTextCompare", vbTextCompare, 1
+TestConstant "vbDatabaseCompare", vbDatabaseCompare, 2
+TestConstant "vbGeneralDate", vbGeneralDate, 0
+TestConstant "vbLongDate", vbLongDate, 1
+TestConstant "vbShortDate", vbShortDate, 2
+TestConstant "vbLongTime", vbLongTime, 3
+TestConstant "vbShortTime", vbShortTime, 4
+TestConstantI4 "vbObjectError", vbObjectError, &h80040000&
+TestConstantI4 "vbBlack", vbBlack, 0
+TestConstantI4 "vbBlue", vbBlue, &hff0000&
+TestConstantI4 "vbCyan", vbCyan, &hffff00&
+TestConstantI4 "vbGreen", vbGreen, &h00ff00&
+TestConstantI4 "vbMagenta", vbMagenta, &hff00ff&
+TestConstantI4 "vbRed", vbRed, &h0000ff&
+TestConstantI4 "vbWhite", vbWhite, &hffffff&
+TestConstantI4 "vbYellow", vbYellow, &h00ffff&
+TestConstantBSTR "vbCr", vbCr, Chr(13)
+TestConstantBSTR "vbCrLf", vbCrLf, Chr(13)&Chr(10)
+TestConstantBSTR "vbNewLine", vbNewLine, Chr(13)&Chr(10)
+TestConstantBSTR "vbFormFeed", vbFormFeed, Chr(12)
+TestConstantBSTR "vbLf", vbLf, Chr(10)
+TestConstantBSTR "vbNullChar", vbNullChar, Chr(0)
+TestConstantBSTR "vbNullString", vbNullString, ""
+TestConstantBSTR "vbTab", vbTab, chr(9)
+TestConstantBSTR "vbVerticalTab", vbVerticalTab, chr(11)
+
+Sub TestCStr(arg, exval)
+ dim x
+ x = CStr(arg)
+ Call ok(getVT(x) = "VT_BSTR*", "getVT(x) = " & getVT(x))
+ Call ok(x = exval, "CStr(" & arg & ") = " & x)
+End Sub
+
+TestCStr "test", "test"
+TestCStr 3, "3"
+if isEnglishLang then TestCStr 3.5, "3.5"
+if isEnglishLang then TestCStr true, "True"
+
+Call ok(getVT(Chr(120)) = "VT_BSTR", "getVT(Chr(120)) = " & getVT(Chr(120)))
+Call ok(getVT(Chr(255)) = "VT_BSTR", "getVT(Chr(255)) = " & getVT(Chr(255)))
+Call ok(Chr(120) = "x", "Chr(120) = " & Chr(120))
+Call ok(Chr(0) <> "", "Chr(0) = """"")
+
+Call ok(isObject(new EmptyClass), "isObject(new EmptyClass) is not true?")
+Set x = new EmptyClass
+Call ok(isObject(x), "isObject(x) is not true?")
+Call ok(isObject(Nothing), "isObject(Nothing) is not true?")
+Call ok(not isObject(true), "isObject(true) is true?")
+Call ok(not isObject(4), "isObject(4) is true?")
+Call ok(not isObject("x"), "isObject(""x"") is true?")
+Call ok(not isObject(Null), "isObject(Null) is true?")
+
+Call ok(not isEmpty(new EmptyClass), "isEmpty(new EmptyClass) is true?")
+Set x = new EmptyClass
+Call ok(not isEmpty(x), "isEmpty(x) is true?")
+x = empty
+Call ok(isEmpty(x), "isEmpty(x) is not true?")
+Call ok(isEmpty(empty), "isEmpty(empty) is not true?")
+Call ok(not isEmpty(Nothing), "isEmpty(Nothing) is not true?")
+Call ok(not isEmpty(true), "isEmpty(true) is true?")
+Call ok(not isEmpty(4), "isEmpty(4) is true?")
+Call ok(not isEmpty("x"), "isEmpty(""x"") is true?")
+Call ok(not isEmpty(Null), "isEmpty(Null) is true?")
+
+Call ok(not isNull(new EmptyClass), "isNull(new EmptyClass) is true?")
+Set x = new EmptyClass
+Call ok(not isNull(x), "isNull(x) is true?")
+x = null
+Call ok(isNull(x), "isNull(x) is not true?")
+Call ok(not isNull(empty), "isNull(empty) is true?")
+Call ok(not isNull(Nothing), "isNull(Nothing) is true?")
+Call ok(not isNull(true), "isNull(true) is true?")
+Call ok(not isNull(4), "isNull(4) is true?")
+Call ok(not isNull("x"), "isNull(""x"") is true?")
+Call ok(isNull(Null), "isNull(Null) is not true?")
+
+Call ok(getVT(err) = "VT_DISPATCH", "getVT(err) = " & getVT(err))
+
+Sub TestHex(x, ex)
+ Call ok(hex(x) = ex, "hex(" & x & ") = " & hex(x) & " expected " & ex)
+End Sub
+
+TestHex 0, "0"
+TestHex 6, "6"
+TestHex 16, "10"
+TestHex &hdeadbeef&, "DEADBEEF"
+TestHex -1, "FFFF"
+TestHex -16, "FFF0"
+TestHex -934859845, "C8472BBB"
+TestHex empty, "0"
+
+Call ok(getVT(hex(null)) = "VT_NULL", "getVT(hex(null)) = " & getVT(hex(null)))
+Call ok(getVT(hex(empty)) = "VT_BSTR", "getVT(hex(empty)) = " & getVT(hex(empty)))
+
+x = InStr(1, "abcd", "bc")
+Call ok(x = 2, "InStr returned " & x)
+
+x = InStr("abcd", "bc")
+Call ok(x = 2, "InStr returned " & x)
+
+x = InStr("abc", "bc")
+Call ok(x = 2, "InStr returned " & x)
+
+x = InStr("abcbc", "bc")
+Call ok(x = 2, "InStr returned " & x)
+
+x = InStr("bcabc", "bc")
+Call ok(x = 1, "InStr returned " & x)
+
+x = InStr(3, "abcd", "bc")
+Call ok(x = 0, "InStr returned " & x)
+
+x = InStr("abcd", "bcx")
+Call ok(x = 0, "InStr returned " & x)
+
+x = InStr(5, "abcd", "bc")
+Call ok(x = 0, "InStr returned " & x)
+
+x = "abcd"
+x = InStr(x, "bc")
+Call ok(x = 2, "InStr returned " & x)
+
+x = InStr("abcd", null)
+Call ok(isNull(x), "InStr returned " & x)
+x = InStr(null, "abcd")
+Call ok(isNull(x), "InStr returned " & x)
+x = InStr(2, null, "abcd")
+Call ok(isNull(x), "InStr returned " & x)
+
+x = InStr(1.3, "abcd", "bc")
+Call ok(x = 2, "InStr returned " & x)
+
+x = InStr(2.3, "abcd", "bc")
+Call ok(x = 2, "InStr returned " & x)
+
+x = InStr(2.6, "abcd", "bc")
+Call ok(x = 0, "InStr returned " & x)
+
+Sub TestMid(str, start, len, ex)
+ x = Mid(str, start, len)
+ Call ok(x = ex, "Mid(" & str & ", " & start & ", " & len & ") = " & x & " expected " & ex)
+End Sub
+
+Sub TestMid2(str, start, ex)
+ x = Mid(str, start)
+ Call ok(x = ex, "Mid(" & str & ", " & start & ") = " & x & " expected " & ex)
+End Sub
+
+TestMid "test", 2, 2, "es"
+TestMid "test", 2, 4, "est"
+TestMid "test", 1, 2, "te"
+TestMid "test", 1, 0, ""
+TestMid "test", 1, 0, ""
+TestMid "test", 5, 2, ""
+TestMid2 "test", 1, "test"
+TestMid2 "test", 2, "est"
+TestMid2 "test", 4, "t"
+TestMid2 "test", 5, ""
+
+Sub TestUCase(str, ex)
+ x = UCase(str)
+ Call ok(x = ex, "UCase(" & str & ") = " & x & " expected " & ex)
+End Sub
+
+TestUCase "test", "TEST"
+TestUCase "123aBC?", "123ABC?"
+TestUCase "", ""
+TestUCase 1, "1"
+if isEnglishLang then TestUCase true, "TRUE"
+TestUCase 0.123, doubleAsString(0.123)
+TestUCase Empty, ""
+Call ok(getVT(UCase(Null)) = "VT_NULL", "getVT(UCase(Null)) = " & getVT(UCase(Null)))
+
+Sub TestLCase(str, ex)
+ x = LCase(str)
+ Call ok(x = ex, "LCase(" & str & ") = " & x & " expected " & ex)
+End Sub
+
+TestLCase "test", "test"
+TestLCase "123aBC?", "123abc?"
+TestLCase "", ""
+TestLCase 1, "1"
+if isEnglishLang then TestLCase true, "true"
+TestLCase 0.123, doubleAsString(0.123)
+TestLCase Empty, ""
+Call ok(getVT(LCase(Null)) = "VT_NULL", "getVT(LCase(Null)) = " & getVT(LCase(Null)))
+
+Call ok(Len("abc") = 3, "Len(abc) = " & Len("abc"))
+Call ok(Len("") = 0, "Len() = " & Len(""))
+Call ok(Len(1) = 1, "Len(1) = " & Len(1))
+Call ok(isNull(Len(null)), "Len(null) = " & Len(null))
+Call ok(Len(empty) = 0, "Len(empty) = " & Len(empty))
+
+Call ok(Space(1) = " ", "Space(1) = " & Space(1) & """")
+Call ok(Space(0) = "", "Space(0) = " & Space(0) & """")
+Call ok(Space(false) = "", "Space(false) = " & Space(false) & """")
+Call ok(Space(5) = " ", "Space(5) = " & Space(5) & """")
+Call ok(Space(5.2) = " ", "Space(5.2) = " & Space(5.2) & """")
+Call ok(Space(5.8) = " ", "Space(5.8) = " & Space(5.8) & """")
+Call ok(Space(5.5) = " ", "Space(5.5) = " & Space(5.5) & """")
+
+Sub TestStrReverse(str, ex)
+ Call ok(StrReverse(str) = ex, "StrReverse(" & str & ") = " & StrReverse(str))
+End Sub
+
+TestStrReverse "test", "tset"
+TestStrReverse "", ""
+TestStrReverse 123, "321"
+if isEnglishLang then TestStrReverse true, "eurT"
+
+Sub TestLeft(str, len, ex)
+ Call ok(Left(str, len) = ex, "Left(" & str & ", " & len & ") = " & Left(str, len))
+End Sub
+
+TestLeft "test", 2, "te"
+TestLeft "test", 5, "test"
+TestLeft "test", 0, ""
+TestLeft 123, 2, "12"
+if isEnglishLang then TestLeft true, 2, "Tr"
+
+Sub TestRight(str, len, ex)
+ Call ok(Right(str, len) = ex, "Right(" & str & ", " & len & ") = " & Right(str, len))
+End Sub
+
+TestRight "test", 2, "st"
+TestRight "test", 5, "test"
+TestRight "test", 0, ""
+TestRight 123, 2, "23"
+if isEnglishLang then TestRight true, 2, "ue"
+
+Sub TestTrim(str, exstr)
+ Call ok(Trim(str) = exstr, "Trim(" & str & ") = " & Trim(str))
+End Sub
+
+TestTrim " test ", "test"
+TestTrim "test ", "test"
+TestTrim " test", "test"
+TestTrim "test", "test"
+TestTrim "", ""
+TestTrim 123, "123"
+if isEnglishLang then TestTrim true, "True"
+
+Sub TestLTrim(str, exstr)
+ Call ok(LTrim(str) = exstr, "LTrim(" & str & ") = " & LTrim(str))
+End Sub
+
+TestLTrim " test ", "test "
+TestLTrim "test ", "test "
+TestLTrim " test", "test"
+TestLTrim "test", "test"
+TestLTrim "", ""
+TestLTrim 123, "123"
+if isEnglishLang then TestLTrim true, "True"
+
+Sub TestRound(val, exval, vt)
+ Call ok(Round(val) = exval, "Round(" & val & ") = " & Round(val))
+ Call ok(getVT(Round(val)) = vt, "getVT(Round(" & val & ")) = " & getVT(Round(val)))
+End Sub
+
+Sub TestRTrim(str, exstr)
+ Call ok(RTrim(str) = exstr, "RTrim(" & str & ") = " & RTrim(str))
+End Sub
+
+TestRTrim " test ", " test"
+TestRTrim "test ", "test"
+TestRTrim " test", " test"
+TestRTrim "test", "test"
+TestRTrim "", ""
+TestRTrim 123, "123"
+if isEnglishLang then TestRTrim true, "True"
+
+TestRound 3, 3, "VT_I2"
+TestRound 3.3, 3, "VT_R8"
+TestRound 3.8, 4, "VT_R8"
+TestRound 3.5, 4, "VT_R8"
+TestRound -3.3, -3, "VT_R8"
+TestRound -3.5, -4, "VT_R8"
+TestRound "2", 2, "VT_R8"
+TestRound true, true, "VT_BOOL"
+TestRound false, false, "VT_BOOL"
+
+if isEnglishLang then
+ Call ok(WeekDayName(1) = "Sunday", "WeekDayName(1) = " & WeekDayName(1))
+ Call ok(WeekDayName(3) = "Tuesday", "WeekDayName(3) = " & WeekDayName(3))
+ Call ok(WeekDayName(7) = "Saturday", "WeekDayName(7) = " & WeekDayName(7))
+ Call ok(WeekDayName(1.1) = "Sunday", "WeekDayName(1.1) = " & WeekDayName(1.1))
+ Call ok(WeekDayName(1, false) = "Sunday", "WeekDayName(1, false) = " & WeekDayName(1, false))
+ Call ok(WeekDayName(1, true) = "Sun", "WeekDayName(1, true) = " & WeekDayName(1, true))
+ Call ok(WeekDayName(1, 10) = "Sun", "WeekDayName(1, 10) = " & WeekDayName(1, 10))
+ Call ok(WeekDayName(1, true, 0) = "Sun", "WeekDayName(1, true, 0) = " & WeekDayName(1, true, 0))
+ Call ok(WeekDayName(1, true, 2) = "Mon", "WeekDayName(1, true, 2) = " & WeekDayName(1, true, 2))
+ Call ok(WeekDayName(1, true, 7) = "Sat", "WeekDayName(1, true, 7) = " & WeekDayName(1, true, 7))
+ Call ok(WeekDayName(1, true, 7.1) = "Sat", "WeekDayName(1, true, 7.1) = " & WeekDayName(1, true, 7.1))
+
+ Call ok(MonthName(1) = "January", "MonthName(1) = " & MonthName(1))
+ Call ok(MonthName(12) = "December", "MonthName(12) = " & MonthName(12))
+ Call ok(MonthName(1, 0) = "January", "MonthName(1, 0) = " & MonthName(1, 0))
+ Call ok(MonthName(12, false) = "December", "MonthName(12, false) = " & MonthName(12, false))
+ Call ok(MonthName(1, 10) = "Jan", "MonthName(1, 10) = " & MonthName(1, 10))
+ Call ok(MonthName(12, true) = "Dec", "MonthName(12, true) = " & MonthName(12, true))
+end if
+
+Call ok(getVT(Now()) = "VT_DATE", "getVT(Now()) = " & getVT(Now()))
+
+Call ok(vbOKOnly = 0, "vbOKOnly = " & vbOKOnly)
+Call ok(getVT(vbOKOnly) = "VT_I2", "getVT(vbOKOnly) = " & getVT(vbOKOnly))
+Call ok(vbOKCancel = 1, "vbOKCancel = " & vbOKCancel)
+Call ok(getVT(vbOKCancel) = "VT_I2", "getVT(vbOKCancel) = " & getVT(vbOKCancel))
+Call ok(vbAbortRetryIgnore = 2, "vbAbortRetryIgnore = " & vbAbortRetryIgnore)
+Call ok(getVT(vbAbortRetryIgnore) = "VT_I2", "getVT(vbAbortRetryIgnore) = " & getVT(vbAbortRetryIgnore))
+Call ok(vbYesNoCancel = 3, "vbYesNoCancel = " & vbYesNoCancel)
+Call ok(getVT(vbYesNoCancel) = "VT_I2", "getVT(vbYesNoCancel) = " & getVT(vbYesNoCancel))
+Call ok(vbYesNo = 4, "vbYesNo = " & vbYesNo)
+Call ok(getVT(vbYesNo) = "VT_I2", "getVT(vbYesNo) = " & getVT(vbYesNo))
+Call ok(vbRetryCancel = 5, "vbRetryCancel = " & vbRetryCancel)
+Call ok(getVT(vbRetryCancel) = "VT_I2", "getVT(vbRetryCancel) = " & getVT(vbRetryCancel))
+
+Call ok(vbOK = 1, "vbOK = " & vbOK)
+Call ok(getVT(vbOK) = "VT_I2", "getVT(vbOK) = " & getVT(vbOK))
+Call ok(vbCancel = 2, "vbCancel = " & vbCancel)
+Call ok(getVT(vbCancel) = "VT_I2", "getVT(vbCancel) = " & getVT(vbCancel))
+Call ok(vbAbort = 3, "vbAbort = " & vbAbort)
+Call ok(getVT(vbAbort) = "VT_I2", "getVT(vbAbort) = " & getVT(vbAbort))
+Call ok(vbRetry = 4, "vbRetry = " & vbRetry)
+Call ok(getVT(vbRetry) = "VT_I2", "getVT(vbRetry) = " & getVT(vbRetry))
+Call ok(vbIgnore = 5, "vbIgnore = " & vbIgnore)
+Call ok(getVT(vbIgnore) = "VT_I2", "getVT(vbIgnore) = " & getVT(vbIgnore))
+Call ok(vbYes = 6, "vbYes = " & vbYes)
+Call ok(getVT(vbYes) = "VT_I2", "getVT(vbYes) = " & getVT(vbYes))
+Call ok(vbNo = 7, "vbNo = " & vbNo)
+Call ok(getVT(vbNo) = "VT_I2", "getVT(vbNo) = " & getVT(vbNo))
+
+Call reportSuccess()
--- /dev/null
+/*
+ * Copyright 2009,2011 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <winnls.h>
+#include <ole2.h>
+#include <dispex.h>
+#include <activscp.h>
+#include <objsafe.h>
+//#include <urlmon.h>
+//#include <mshtmhst.h>
+
+#include <wine/test.h>
+
+#ifdef _WIN64
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
+
+#else
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
+
+#endif
+
+extern const CLSID CLSID_VBScript;
+
+#define DEFINE_EXPECT(func) \
+ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+ expect_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+ do { \
+ ok(expect_ ##func, "unexpected call " #func "\n"); \
+ called_ ## func = TRUE; \
+ }while(0)
+
+#define CHECK_EXPECT(func) \
+ do { \
+ CHECK_EXPECT2(func); \
+ expect_ ## func = FALSE; \
+ }while(0)
+
+#define CHECK_CALLED(func) \
+ do { \
+ ok(called_ ## func, "expected " #func "\n"); \
+ expect_ ## func = called_ ## func = FALSE; \
+ }while(0)
+
+#define CLEAR_CALLED(func) \
+ expect_ ## func = called_ ## func = FALSE
+
+DEFINE_EXPECT(CreateInstance);
+DEFINE_EXPECT(ProcessUrlAction);
+DEFINE_EXPECT(QueryCustomPolicy);
+DEFINE_EXPECT(reportSuccess);
+DEFINE_EXPECT(Host_QS_SecMgr);
+DEFINE_EXPECT(Caller_QS_SecMgr);
+DEFINE_EXPECT(QI_IObjectWithSite);
+DEFINE_EXPECT(SetSite);
+
+static const WCHAR testW[] = {'t','e','s','t',0};
+
+static HRESULT QS_SecMgr_hres;
+static HRESULT ProcessUrlAction_hres;
+static DWORD ProcessUrlAction_policy;
+static HRESULT CreateInstance_hres;
+static HRESULT QueryCustomPolicy_hres;
+static DWORD QueryCustomPolicy_psize;
+static DWORD QueryCustomPolicy_policy;
+static HRESULT QI_IDispatch_hres;
+static HRESULT QI_IObjectWithSite_hres;
+static HRESULT SetSite_hres;
+
+#define TESTOBJ_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}"
+#define TESTOBJINST_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80647}"
+
+static const GUID CLSID_TestObj =
+ {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
+static const GUID CLSID_TestObjInst =
+ {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x47}};
+
+/* Defined as extern in urlmon.idl, but not exported by uuid.lib */
+const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
+ {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
+
+#define DISPID_TEST_REPORTSUCCESS 0x1000
+
+#define DISPID_GLOBAL_OK 0x2000
+
+#define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
+
+static const char *debugstr_guid(REFIID riid)
+{
+ static char buf[50];
+
+ sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
+ riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
+ riid->Data4[5], riid->Data4[6], riid->Data4[7]);
+
+ return buf;
+}
+
+static BSTR a2bstr(const char *str)
+{
+ BSTR ret;
+ int len;
+
+ len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ ret = SysAllocStringLen(NULL, len-1);
+ MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+
+ return ret;
+}
+
+static int strcmp_wa(LPCWSTR strw, const char *stra)
+{
+ CHAR buf[512];
+ WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
+ return lstrcmpA(buf, stra);
+}
+
+static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
+{
+ IServiceProvider *sp;
+ HRESULT hres;
+
+
+ CHECK_EXPECT(SetSite);
+ ok(pUnkSite != NULL, "pUnkSite == NULL\n");
+
+ hres = IUnknown_QueryInterface(pUnkSite, &IID_IServiceProvider, (void**)&sp);
+ ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
+ IServiceProvider_Release(sp);
+
+ return SetSite_hres;
+}
+
+static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static const IObjectWithSiteVtbl ObjectWithSiteVtbl = {
+ ObjectWithSite_QueryInterface,
+ ObjectWithSite_AddRef,
+ ObjectWithSite_Release,
+ ObjectWithSite_SetSite,
+ ObjectWithSite_GetSite
+};
+
+static IObjectWithSite ObjectWithSite = { &ObjectWithSiteVtbl };
+
+static IObjectWithSite *object_with_site;
+
+static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ if(IsEqualGUID(riid, &IID_IUnknown)) {
+ *ppv = iface;
+ }else if(IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, &IID_IDispatchEx)) {
+ if(FAILED(QI_IDispatch_hres))
+ return QI_IDispatch_hres;
+ *ppv = iface;
+ }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
+ CHECK_EXPECT(QI_IObjectWithSite);
+ if(FAILED(QI_IObjectWithSite_hres))
+ return QI_IObjectWithSite_hres;
+ *ppv = object_with_site;
+ }else if(IsEqualGUID(&IID_IObjectSafety, riid)) {
+ ok(0, "Unexpected IID_IObjectSafety query\n");
+ }
+
+ return *ppv ? S_OK : E_NOINTERFACE;
+}
+
+static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
+ LCID lcid, ITypeInfo **ppTInfo)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
+ LPOLESTR *rgszNames, UINT cNames,
+ LCID lcid, DISPID *rgDispId)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
+ REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+ VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
+{
+ ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Test_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+ if(!strcmp_wa(bstrName, "reportSuccess")) {
+ ok(grfdex == fdexNameCaseInsensitive, "grfdex = %x\n", grfdex);
+ *pid = DISPID_TEST_REPORTSUCCESS;
+ return S_OK;
+ }
+
+ ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+ VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+ switch(id) {
+ case DISPID_TEST_REPORTSUCCESS:
+ CHECK_EXPECT(reportSuccess);
+
+ ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+ break;
+
+ default:
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+ }
+
+ return S_OK;
+}
+
+static IDispatchExVtbl testObjVtbl = {
+ DispatchEx_QueryInterface,
+ DispatchEx_AddRef,
+ DispatchEx_Release,
+ DispatchEx_GetTypeInfoCount,
+ DispatchEx_GetTypeInfo,
+ DispatchEx_GetIDsOfNames,
+ DispatchEx_Invoke,
+ Test_GetDispID,
+ Test_InvokeEx,
+ DispatchEx_DeleteMemberByName,
+ DispatchEx_DeleteMemberByDispID,
+ DispatchEx_GetMemberProperties,
+ DispatchEx_GetMemberName,
+ DispatchEx_GetNextDispID,
+ DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx testObj = { &testObjVtbl };
+
+static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+ if(!strcmp_wa(bstrName, "ok")) {
+ ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+ *pid = DISPID_GLOBAL_OK;
+ return S_OK;
+ }
+
+ ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+ VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+ switch(id) {
+ case DISPID_GLOBAL_OK:
+ ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
+ ok(V_BOOL(pdp->rgvarg+1), "%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
+ break;
+
+ default:
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+ }
+
+ return S_OK;
+}
+
+static IDispatchExVtbl globalObjVtbl = {
+ DispatchEx_QueryInterface,
+ DispatchEx_AddRef,
+ DispatchEx_Release,
+ DispatchEx_GetTypeInfoCount,
+ DispatchEx_GetTypeInfo,
+ DispatchEx_GetIDsOfNames,
+ DispatchEx_Invoke,
+ Global_GetDispID,
+ Global_InvokeEx,
+ DispatchEx_DeleteMemberByName,
+ DispatchEx_DeleteMemberByDispID,
+ DispatchEx_GetMemberProperties,
+ DispatchEx_GetMemberName,
+ DispatchEx_GetNextDispID,
+ DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx globalObj = { &globalObjVtbl };
+
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
+{
+ if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
+ *ppv = iface;
+ return S_OK;
+ }
+
+ /* TODO: IClassFactoryEx */
+ *ppv = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
+{
+ CHECK_EXPECT(CreateInstance);
+
+ ok(!outer, "outer = %p\n", outer);
+ ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
+
+ if(SUCCEEDED(CreateInstance_hres))
+ *ppv = &testObj;
+ return CreateInstance_hres;
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
+{
+ ok(0, "unexpected call\n");
+ return S_OK;
+}
+
+static const IClassFactoryVtbl ClassFactoryVtbl = {
+ ClassFactory_QueryInterface,
+ ClassFactory_AddRef,
+ ClassFactory_Release,
+ ClassFactory_CreateInstance,
+ ClassFactory_LockServer
+};
+
+static IClassFactory activex_cf = { &ClassFactoryVtbl };
+
+static HRESULT WINAPI InternetHostSecurityManager_QueryInterface(IInternetHostSecurityManager *iface, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected call\n");
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI InternetHostSecurityManager_AddRef(IInternetHostSecurityManager *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI InternetHostSecurityManager_Release(IInternetHostSecurityManager *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI InternetHostSecurityManager_GetSecurityId(IInternetHostSecurityManager *iface, BYTE *pbSecurityId,
+ DWORD *pcbSecurityId, DWORD_PTR dwReserved)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InternetHostSecurityManager_ProcessUrlAction(IInternetHostSecurityManager *iface, DWORD dwAction,
+ BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved)
+{
+ CHECK_EXPECT(ProcessUrlAction);
+
+ ok(dwAction == URLACTION_ACTIVEX_RUN, "dwAction = %x\n", dwAction);
+ ok(pPolicy != NULL, "pPolicy == NULL\n");
+ ok(cbPolicy == sizeof(DWORD), "cbPolicy = %d\n", cbPolicy);
+ ok(pContext != NULL, "pContext == NULL\n");
+ ok(cbContext == sizeof(GUID), "cbContext = %d\n", cbContext);
+ ok(IsEqualGUID(pContext, &CLSID_TestObj), "pContext = %s\n", debugstr_guid((const IID*)pContext));
+ ok(!dwFlags, "dwFlags = %x\n", dwFlags);
+ ok(!dwReserved, "dwReserved = %x\n", dwReserved);
+
+ if(SUCCEEDED(ProcessUrlAction_hres))
+ *(DWORD*)pPolicy = ProcessUrlAction_policy;
+ return ProcessUrlAction_hres;
+}
+
+static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHostSecurityManager *iface, REFGUID guidKey,
+ BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved)
+{
+ const struct CONFIRMSAFETY *cs = (const struct CONFIRMSAFETY*)pContext;
+ DWORD *ret;
+
+ CHECK_EXPECT(QueryCustomPolicy);
+
+ ok(IsEqualGUID(&GUID_CUSTOM_CONFIRMOBJECTSAFETY, guidKey), "guidKey = %s\n", debugstr_guid(guidKey));
+
+ ok(ppPolicy != NULL, "ppPolicy == NULL\n");
+ ok(pcbPolicy != NULL, "pcbPolicy == NULL\n");
+ ok(pContext != NULL, "pContext == NULL\n");
+ ok(cbContext == sizeof(struct CONFIRMSAFETY), "cbContext = %d\n", cbContext);
+ ok(!dwReserved, "dwReserved = %x\n", dwReserved);
+
+ /* TODO: CLSID */
+ ok(cs->pUnk != NULL, "cs->pUnk == NULL\n");
+ ok(!cs->dwFlags, "dwFlags = %x\n", cs->dwFlags);
+
+ if(FAILED(QueryCustomPolicy_hres))
+ return QueryCustomPolicy_hres;
+
+ ret = CoTaskMemAlloc(QueryCustomPolicy_psize);
+ *ppPolicy = (BYTE*)ret;
+ *pcbPolicy = QueryCustomPolicy_psize;
+ memset(ret, 0, QueryCustomPolicy_psize);
+ if(QueryCustomPolicy_psize >= sizeof(DWORD))
+ *ret = QueryCustomPolicy_policy;
+
+ return QueryCustomPolicy_hres;
+}
+
+static const IInternetHostSecurityManagerVtbl InternetHostSecurityManagerVtbl = {
+ InternetHostSecurityManager_QueryInterface,
+ InternetHostSecurityManager_AddRef,
+ InternetHostSecurityManager_Release,
+ InternetHostSecurityManager_GetSecurityId,
+ InternetHostSecurityManager_ProcessUrlAction,
+ InternetHostSecurityManager_QueryCustomPolicy
+};
+
+static IInternetHostSecurityManager InternetHostSecurityManager = { &InternetHostSecurityManagerVtbl };
+
+static IServiceProvider ServiceProvider;
+
+static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected call\n");
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
+ REFGUID guidService, REFIID riid, void **ppv)
+{
+ if(IsEqualGUID(&SID_GetCaller, guidService))
+ return E_NOINTERFACE;
+
+ if(IsEqualGUID(&SID_SInternetHostSecurityManager, guidService)) {
+ if(iface == &ServiceProvider)
+ CHECK_EXPECT(Host_QS_SecMgr);
+ else
+ CHECK_EXPECT(Caller_QS_SecMgr);
+ ok(IsEqualGUID(&IID_IInternetHostSecurityManager, riid), "unexpected riid %s\n", debugstr_guid(riid));
+ if(SUCCEEDED(QS_SecMgr_hres))
+ *ppv = &InternetHostSecurityManager;
+ return QS_SecMgr_hres;
+ }
+
+ ok(0, "unexpected service %s\n", debugstr_guid(guidService));
+ return E_NOINTERFACE;
+}
+
+static IServiceProviderVtbl ServiceProviderVtbl = {
+ ServiceProvider_QueryInterface,
+ ServiceProvider_AddRef,
+ ServiceProvider_Release,
+ ServiceProvider_QueryService
+};
+
+static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
+
+static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
+{
+ if(IsEqualGUID(&IID_IUnknown, riid)) {
+ *ppv = iface;
+ }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
+ *ppv = iface;
+ }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
+ *ppv = &ServiceProvider;
+ }else {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
+{
+ *plcid = GetUserDefaultLCID();
+ return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
+ DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
+{
+ ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
+ ok(!ppti, "ppti != NULL\n");
+ ok(!strcmp_wa(pstrName, "test"), "pstrName = %s\n", wine_dbgstr_w(pstrName));
+
+ *ppiunkItem = (IUnknown*)&globalObj;
+ return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
+ const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
+ ActiveScriptSite_QueryInterface,
+ ActiveScriptSite_AddRef,
+ ActiveScriptSite_Release,
+ ActiveScriptSite_GetLCID,
+ ActiveScriptSite_GetItemInfo,
+ ActiveScriptSite_GetDocVersionString,
+ ActiveScriptSite_OnScriptTerminate,
+ ActiveScriptSite_OnStateChange,
+ ActiveScriptSite_OnScriptError,
+ ActiveScriptSite_OnEnterScript,
+ ActiveScriptSite_OnLeaveScript
+};
+
+static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
+
+static void set_safety_options(IUnknown *unk, BOOL use_sec_mgr)
+{
+ IObjectSafety *safety;
+ DWORD supported, enabled, options_all, options_set;
+ HRESULT hres;
+
+ hres = IUnknown_QueryInterface(unk, &IID_IObjectSafety, (void**)&safety);
+ ok(hres == S_OK, "Could not get IObjectSafety: %08x\n", hres);
+ if(FAILED(hres))
+ return;
+
+ options_all = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
+ if(use_sec_mgr)
+ options_set = options_all;
+ else
+ options_set = INTERFACE_USES_DISPEX;
+
+ hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, options_all, options_set);
+ ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == options_all, "supported=%x, expected %x\n", supported, options_all);
+ ok(enabled == options_set, "enabled=%x, expected %x\n", enabled, options_set);
+
+ IObjectSafety_Release(safety);
+}
+
+#define parse_script_a(p,s) _parse_script_a(__LINE__,p,s)
+static void _parse_script_a(unsigned line, IActiveScriptParse *parser, const char *script)
+{
+ BSTR str;
+ HRESULT hres;
+
+ str = a2bstr(script);
+ hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ SysFreeString(str);
+ ok_(__FILE__,line)(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+}
+
+static HRESULT parse_script_ae(IActiveScriptParse *parser, const char *script)
+{
+ BSTR str;
+ HRESULT hres;
+
+ str = a2bstr(script);
+ hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ SysFreeString(str);
+
+ return hres;
+}
+
+static IActiveScriptParse *create_script(BOOL use_sec_mgr)
+{
+ IActiveScriptParse *parser;
+ IActiveScript *script;
+ HRESULT hres;
+
+ QS_SecMgr_hres = S_OK;
+ ProcessUrlAction_hres = S_OK;
+ ProcessUrlAction_policy = URLPOLICY_ALLOW;
+ CreateInstance_hres = S_OK;
+ QueryCustomPolicy_hres = S_OK;
+ QueryCustomPolicy_psize = sizeof(DWORD);
+ QueryCustomPolicy_policy = URLPOLICY_ALLOW;
+ QI_IDispatch_hres = S_OK;
+ QI_IObjectWithSite_hres = S_OK;
+ SetSite_hres = S_OK;
+
+ hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+ &IID_IActiveScript, (void**)&script);
+ ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+ if(FAILED(hres))
+ return NULL;
+
+ set_safety_options((IUnknown*)script, use_sec_mgr);
+
+ hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+ hres = IActiveScript_AddNamedItem(script, testW,
+ SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+ ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_STARTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+ IActiveScript_Release(script);
+
+ return parser;
+}
+
+static void test_CreateObject(void)
+{
+ IActiveScriptParse *parser;
+ HRESULT hres;
+
+ parser = create_script(TRUE);
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(reportSuccess);
+ parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(reportSuccess);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.TestABC\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ QS_SecMgr_hres = E_NOINTERFACE;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(Host_QS_SecMgr);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ ProcessUrlAction_hres = E_FAIL;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ ProcessUrlAction_policy = URLPOLICY_DISALLOW;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ CreateInstance_hres = E_FAIL;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ QueryCustomPolicy_hres = E_FAIL;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ QueryCustomPolicy_psize = 6;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(reportSuccess);
+ parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(reportSuccess);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ QueryCustomPolicy_policy = URLPOLICY_DISALLOW;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+
+ QueryCustomPolicy_psize = 6;
+
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+
+ QueryCustomPolicy_policy = URLPOLICY_ALLOW;
+ QueryCustomPolicy_psize = 3;
+
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(FALSE);
+
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(reportSuccess);
+ parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(reportSuccess);
+
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(TRUE);
+ object_with_site = &ObjectWithSite;
+
+ SET_EXPECT(Host_QS_SecMgr);
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(SetSite);
+ SET_EXPECT(reportSuccess);
+ parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
+ CHECK_CALLED(Host_QS_SecMgr);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(SetSite);
+ CHECK_CALLED(reportSuccess);
+
+ SetSite_hres = E_FAIL;
+ SET_EXPECT(ProcessUrlAction);
+ SET_EXPECT(CreateInstance);
+ SET_EXPECT(QueryCustomPolicy);
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(SetSite);
+ hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ CHECK_CALLED(ProcessUrlAction);
+ CHECK_CALLED(CreateInstance);
+ CHECK_CALLED(QueryCustomPolicy);
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(SetSite);
+
+ IActiveScriptParse_Release(parser);
+}
+
+static void test_GetObject(void)
+{
+ IActiveScriptParse *parser;
+ HRESULT hres;
+
+ /* Never allowed with security manager */
+ parser = create_script(TRUE);
+ hres = parse_script_ae(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
+ ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
+ IActiveScriptParse_Release(parser);
+
+ parser = create_script(FALSE);
+
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(SetSite);
+ SET_EXPECT(reportSuccess);
+ hres = parse_script_ae(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
+ if(hres == 0x8007007e) { /* Workaround for broken win2k */
+ win_skip("got unexpected error %08x\n", hres);
+ CLEAR_CALLED(QI_IObjectWithSite);
+ CLEAR_CALLED(SetSite);
+ CLEAR_CALLED(reportSuccess);
+ IActiveScriptParse_Release(parser);
+ return;
+ }
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(SetSite);
+ CHECK_CALLED(reportSuccess);
+
+ SetSite_hres = E_FAIL;
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(SetSite);
+ hres = parse_script_ae(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
+ ok(hres == E_FAIL, "hres = %08x\n", hres);
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(SetSite);
+
+ QI_IObjectWithSite_hres = E_NOINTERFACE;
+ SET_EXPECT(QI_IObjectWithSite);
+ SET_EXPECT(reportSuccess);
+ parse_script_a(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
+ CHECK_CALLED(QI_IObjectWithSite);
+ CHECK_CALLED(reportSuccess);
+
+ IActiveScriptParse_Release(parser);
+
+ /* Invalid moniker */
+ parser = create_script(FALSE);
+ hres = parse_script_ae(parser, "Call GetObject(\"nonexistent:test\").reportSuccess()");
+ ok(hres == MK_E_SYNTAX, "hres = %08x\n", hres);
+ IActiveScriptParse_Release(parser);
+}
+
+static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
+{
+ HKEY hkey;
+ DWORD res;
+
+ if(!init) {
+ RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
+ return TRUE;
+ }
+
+ res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
+ if(res != ERROR_SUCCESS)
+ return FALSE;
+
+ if(def_value)
+ res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
+
+ RegCloseKey(hkey);
+
+ return res == ERROR_SUCCESS;
+}
+
+static BOOL init_registry(BOOL init)
+{
+ return init_key("Wine.Test\\CLSID", TESTOBJ_CLSID, init);
+}
+
+static BOOL register_activex(void)
+{
+ DWORD regid;
+ HRESULT hres;
+
+ if(!init_registry(TRUE)) {
+ init_registry(FALSE);
+ return FALSE;
+ }
+
+ hres = CoRegisterClassObject(&CLSID_TestObj, (IUnknown *)&activex_cf,
+ CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id);
+ ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
+
+ hres = CoRegisterClassObject(&CLSID_TestObjInst, (IUnknown *)&testObj,
+ CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id);
+ ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
+
+ return TRUE;
+}
+
+static BOOL check_vbscript(void)
+{
+ IActiveScriptParseProcedure2 *vbscript;
+ HRESULT hres;
+
+ hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+ &IID_IActiveScriptParseProcedure2, (void**)&vbscript);
+ if(SUCCEEDED(hres))
+ IActiveScriptParseProcedure2_Release(vbscript);
+
+ return hres == S_OK;
+}
+
+
+START_TEST(createobj)
+{
+ CoInitialize(NULL);
+
+ if(check_vbscript()) {
+ register_activex();
+
+ test_CreateObject();
+ test_GetObject();
+
+ init_registry(FALSE);
+ }else {
+ win_skip("Broken engine, probably too old\n");
+ }
+
+ CoUninitialize();
+}
--- /dev/null
+'
+' Copyright 2011 Jacek Caban for CodeWeavers
+'
+' This library is free software; you can redistribute it and/or
+' modify it under the terms of the GNU Lesser General Public
+' License as published by the Free Software Foundation; either
+' version 2.1 of the License, or (at your option) any later version.
+'
+' This library is distributed in the hope that it will be useful,
+' but WITHOUT ANY WARRANTY; without even the implied warranty of
+' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+' Lesser General Public License for more details.
+'
+' You should have received a copy of the GNU Lesser General Public
+' License along with this library; if not, write to the Free Software
+' Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+'
+
+Option Explicit
+
+dim x, y, z
+
+call ok(true, "true is not true?")
+ok true, "true is not true?"
+call ok((true), "true is not true?")
+
+ok not false, "not false but not true?"
+ok not not true, "not not true but not true?"
+
+Call ok(true = true, "true = true is false")
+Call ok(false = false, "false = false is false")
+Call ok(not (true = false), "true = false is true")
+Call ok("x" = "x", """x"" = ""x"" is false")
+Call ok(empty = empty, "empty = empty is false")
+Call ok(empty = "", "empty = """" is false")
+Call ok(0 = 0.0, "0 <> 0.0")
+Call ok(16 = &h10&, "16 <> &h10&")
+Call ok(010 = 10, "010 <> 10")
+Call ok(10. = 10, "10. <> 10")
+Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1")
+Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1")
+Call ok(--1 = 1, "--1 = " & --1)
+Call ok(-empty = 0, "-empty = " & (-empty))
+Call ok(true = -1, "! true = -1")
+Call ok(false = 0, "false <> 0")
+Call ok(&hff = 255, "&hff <> 255")
+Call ok(&Hff = 255, "&Hff <> 255")
+
+x = "xx"
+Call ok(x = "xx", "x = " & x & " expected ""xx""")
+
+Call ok(true <> false, "true <> false is false")
+Call ok(not (true <> true), "true <> true is true")
+Call ok(not ("x" <> "x"), """x"" <> ""x"" is true")
+Call ok(not (empty <> empty), "empty <> empty is true")
+Call ok(x <> "x", "x = ""x""")
+Call ok("true" <> true, """true"" = true is true")
+
+Call ok("" = true = false, """"" = true = false is false")
+Call ok(not(false = true = ""), "false = true = """" is true")
+Call ok(not (false = false <> false = false), "false = false <> false = false is true")
+Call ok(not ("" <> false = false), """"" <> false = false is true")
+
+Call ok(getVT(false) = "VT_BOOL", "getVT(false) is not VT_BOOL")
+Call ok(getVT(true) = "VT_BOOL", "getVT(true) is not VT_BOOL")
+Call ok(getVT("") = "VT_BSTR", "getVT("""") is not VT_BSTR")
+Call ok(getVT("test") = "VT_BSTR", "getVT(""test"") is not VT_BSTR")
+Call ok(getVT(Empty) = "VT_EMPTY", "getVT(Empty) is not VT_EMPTY")
+Call ok(getVT(null) = "VT_NULL", "getVT(null) is not VT_NULL")
+Call ok(getVT(0) = "VT_I2", "getVT(0) is not VT_I2")
+Call ok(getVT(1) = "VT_I2", "getVT(1) is not VT_I2")
+Call ok(getVT(0.5) = "VT_R8", "getVT(0.5) is not VT_R8")
+Call ok(getVT(0.0) = "VT_R8", "getVT(0.0) is not VT_R8")
+Call ok(getVT(2147483647) = "VT_I4", "getVT(2147483647) is not VT_I4")
+Call ok(getVT(2147483648) = "VT_R8", "getVT(2147483648) is not VT_R8")
+Call ok(getVT(&h10&) = "VT_I2", "getVT(&h10&) is not VT_I2")
+Call ok(getVT(&h10000&) = "VT_I4", "getVT(&h10000&) is not VT_I4")
+Call ok(getVT(&H10000&) = "VT_I4", "getVT(&H10000&) is not VT_I4")
+Call ok(getVT(&hffFFffFF&) = "VT_I2", "getVT(&hffFFffFF&) is not VT_I2")
+Call ok(getVT(1 & 100000) = "VT_BSTR", "getVT(1 & 100000) is not VT_BSTR")
+Call ok(getVT(-empty) = "VT_I2", "getVT(-empty) = " & getVT(-empty))
+Call ok(getVT(-null) = "VT_NULL", "getVT(-null) = " & getVT(-null))
+Call ok(getVT(y) = "VT_EMPTY*", "getVT(y) = " & getVT(y))
+Call ok(getVT(nothing) = "VT_DISPATCH", "getVT(nothing) = " & getVT(nothing))
+set x = nothing
+Call ok(getVT(x) = "VT_DISPATCH*", "getVT(x=nothing) = " & getVT(x))
+x = true
+Call ok(getVT(x) = "VT_BOOL*", "getVT(x) = " & getVT(x))
+Call ok(getVT(false or true) = "VT_BOOL", "getVT(false) is not VT_BOOL")
+x = "x"
+Call ok(getVT(x) = "VT_BSTR*", "getVT(x) is not VT_BSTR*")
+x = 0.0
+Call ok(getVT(x) = "VT_R8*", "getVT(x) = " & getVT(x))
+
+Call ok(isNullDisp(nothing), "nothing is not nulldisp?")
+
+x = "xx"
+Call ok("ab" & "cd" = "abcd", """ab"" & ""cd"" <> ""abcd""")
+Call ok("ab " & null = "ab ", """ab"" & null = " & ("ab " & null))
+Call ok("ab " & empty = "ab ", """ab"" & empty = " & ("ab " & empty))
+Call ok(1 & 100000 = "1100000", "1 & 100000 = " & (1 & 100000))
+Call ok("ab" & x = "abxx", """ab"" & x = " & ("ab"&x))
+
+if(isEnglishLang) then
+ Call ok("" & true = "True", """"" & true = " & true)
+ Call ok(true & false = "TrueFalse", "true & false = " & (true & false))
+end if
+
+call ok(true and true, "true and true is not true")
+call ok(true and not false, "true and not false is not true")
+call ok(not (false and true), "not (false and true) is not true")
+call ok(getVT(null and true) = "VT_NULL", "getVT(null and true) = " & getVT(null and true))
+
+call ok(false or true, "false or uie is false?")
+call ok(not (false or false), "false or false is not false?")
+call ok(false and false or true, "false and false or true is false?")
+call ok(true or false and false, "true or false and false is false?")
+call ok(null or true, "null or true is false")
+
+call ok(true xor false, "true xor false is false?")
+call ok(not (false xor false), "false xor false is true?")
+call ok(not (true or false xor true), "true or false xor true is true?")
+call ok(not (true xor false or true), "true xor false or true is true?")
+
+call ok(false eqv false, "false does not equal false?")
+call ok(not (false eqv true), "false equals true?")
+call ok(getVT(false eqv null) = "VT_NULL", "getVT(false eqv null) = " & getVT(false eqv null))
+
+call ok(true imp true, "true does not imp true?")
+call ok(false imp false, "false does not imp false?")
+call ok(not (true imp false), "true imp false?")
+call ok(false imp null, "false imp null is false?")
+
+Call ok(2 >= 1, "! 2 >= 1")
+Call ok(2 >= 2, "! 2 >= 2")
+Call ok(not(true >= 2), "true >= 2 ?")
+Call ok(2 > 1, "! 2 > 1")
+Call ok(false > true, "! false < true")
+Call ok(0 > true, "! 0 > true")
+Call ok(not (true > 0), "true > 0")
+Call ok(not (0 > 1 = 1), "0 > 1 = 1")
+Call ok(1 < 2, "! 1 < 2")
+Call ok(1 = 1 < 0, "! 1 = 1 < 0")
+Call ok(1 <= 2, "! 1 <= 2")
+Call ok(2 <= 2, "! 2 <= 2")
+
+Call ok(isNull(0 = null), "'(0 = null)' is not null")
+Call ok(isNull(null = 1), "'(null = 1)' is not null")
+Call ok(isNull(0 > null), "'(0 > null)' is not null")
+Call ok(isNull(null > 1), "'(null > 1)' is not null")
+Call ok(isNull(0 < null), "'(0 < null)' is not null")
+Call ok(isNull(null < 1), "'(null < 1)' is not null")
+Call ok(isNull(0 <> null), "'(0 <> null)' is not null")
+Call ok(isNull(null <> 1), "'(null <> 1)' is not null")
+Call ok(isNull(0 >= null), "'(0 >= null)' is not null")
+Call ok(isNull(null >= 1), "'(null >= 1)' is not null")
+Call ok(isNull(0 <= null), "'(0 <= null)' is not null")
+Call ok(isNull(null <= 1), "'(null <= 1)' is not null")
+
+x = 3
+Call ok(2+2 = 4, "2+2 = " & (2+2))
+Call ok(false + 6 + true = 5, "false + 6 + true <> 5")
+Call ok(getVT(2+null) = "VT_NULL", "getVT(2+null) = " & getVT(2+null))
+Call ok(2+empty = 2, "2+empty = " & (2+empty))
+Call ok(x+x = 6, "x+x = " & (x+x))
+
+Call ok(5-1 = 4, "5-1 = " & (5-1))
+Call ok(3+5-true = 9, "3+5-true <> 9")
+Call ok(getVT(2-null) = "VT_NULL", "getVT(2-null) = " & getVT(2-null))
+Call ok(2-empty = 2, "2-empty = " & (2-empty))
+Call ok(2-x = -1, "2-x = " & (2-x))
+
+Call ok(9 Mod 6 = 3, "9 Mod 6 = " & (9 Mod 6))
+Call ok(11.6 Mod 5.5 = False, "11.6 Mod 5.5 = " & (11.6 Mod 5.5 = 0.6))
+Call ok(7 Mod 4+2 = 5, "7 Mod 4+2 <> 5")
+Call ok(getVT(2 mod null) = "VT_NULL", "getVT(2 mod null) = " & getVT(2 mod null))
+Call ok(getVT(null mod 2) = "VT_NULL", "getVT(null mod 2) = " & getVT(null mod 2))
+'FIXME: Call ok(empty mod 2 = 0, "empty mod 2 = " & (empty mod 2))
+
+Call ok(5 \ 2 = 2, "5 \ 2 = " & (5\2))
+Call ok(4.6 \ 1.5 = 2, "4.6 \ 1.5 = " & (4.6\1.5))
+Call ok(4.6 \ 1.49 = 5, "4.6 \ 1.49 = " & (4.6\1.49))
+Call ok(2+3\4 = 2, "2+3\4 = " & (2+3\4))
+
+Call ok(2*3 = 6, "2*3 = " & (2*3))
+Call ok(3/2 = 1.5, "3/2 = " & (3/2))
+Call ok(5\4/2 = 2, "5\4/2 = " & (5\2/1))
+Call ok(12/3\2 = 2, "12/3\2 = " & (12/3\2))
+
+Call ok(2^3 = 8, "2^3 = " & (2^3))
+Call ok(2^3^2 = 64, "2^3^2 = " & (2^3^2))
+Call ok(-3^2 = 9, "-3^2 = " & (-3^2))
+Call ok(2*3^2 = 18, "2*3^2 = " & (2*3^2))
+
+x =_
+ 3
+x _
+ = 3
+
+x = 3
+
+if true then y = true : x = y
+ok x, "x is false"
+
+x = true : if false then x = false
+ok x, "x is false, if false called?"
+
+if not false then x = true
+ok x, "x is false, if not false not called?"
+
+if not false then x = "test" : x = true
+ok x, "x is false, if not false not called?"
+
+if false then x = y : call ok(false, "if false .. : called")
+
+if false then x = y : call ok(false, "if false .. : called") else x = "else"
+Call ok(x = "else", "else not called?")
+
+if true then x = y else y = x : Call ok(false, "in else?")
+
+if false then :
+
+if false then x = y : if true then call ok(false, "embedded if called")
+
+if false then x=1 else x=2 end if
+
+if false then
+ ok false, "if false called"
+end if
+
+x = true
+if x then
+ x = false
+end if
+Call ok(not x, "x is false, if not evaluated?")
+
+x = false
+If false Then
+ Call ok(false, "inside if false")
+Else
+ x = true
+End If
+Call ok(x, "else not called?")
+
+x = false
+If false Then
+ Call ok(false, "inside if false")
+ElseIf not True Then
+ Call ok(false, "inside elseif not true")
+Else
+ x = true
+End If
+Call ok(x, "else not called?")
+
+x = false
+If false Then
+ Call ok(false, "inside if false")
+ x = 1
+ y = 10+x
+ElseIf not False Then
+ x = true
+Else
+ Call ok(false, "inside else not true")
+End If
+Call ok(x, "elseif not called?")
+
+x = false
+If false Then
+ Call ok(false, "inside if false")
+ElseIf not False Then
+ x = true
+End If
+Call ok(x, "elseif not called?")
+
+x = false
+if 1 then x = true
+Call ok(x, "if 1 not run?")
+
+x = false
+if &h10000& then x = true
+Call ok(x, "if &h10000& not run?")
+
+x = false
+y = false
+while not (x and y)
+ if x then
+ y = true
+ end if
+ x = true
+wend
+call ok((x and y), "x or y is false after while")
+
+if false then
+' empty body
+end if
+
+if false then
+ x = false
+elseif true then
+' empty body
+end if
+
+if false then
+ x = false
+else
+' empty body
+end if
+
+while false
+wend
+
+x = false
+y = false
+do while not (x and y)
+ if x then
+ y = true
+ end if
+ x = true
+loop
+call ok((x and y), "x or y is false after while")
+
+do while false
+loop
+
+do while true
+ exit do
+ ok false, "exit do didn't work"
+loop
+
+x = false
+y = false
+do until x and y
+ if x then
+ y = true
+ end if
+ x = true
+loop
+call ok((x and y), "x or y is false after do until")
+
+do until true
+loop
+
+do until false
+ exit do
+ ok false, "exit do didn't work"
+loop
+
+x = false
+do
+ if x then exit do
+ x = true
+loop
+call ok(x, "x is false after do..loop?")
+
+x = false
+y = false
+do
+ if x then
+ y = true
+ end if
+ x = true
+loop until x and y
+call ok((x and y), "x or y is false after while")
+
+do
+loop until true
+
+do
+ exit do
+ ok false, "exit do didn't work"
+loop until false
+
+x = false
+y = false
+do
+ if x then
+ y = true
+ end if
+ x = true
+loop while not (x and y)
+call ok((x and y), "x or y is false after while")
+
+do
+loop while false
+
+do
+ exit do
+ ok false, "exit do didn't work"
+loop while true
+
+y = "for1:"
+for x = 5 to 8
+ y = y & " " & x
+next
+Call ok(y = "for1: 5 6 7 8", "y = " & y)
+
+y = "for2:"
+for x = 5 to 8 step 2
+ y = y & " " & x
+next
+Call ok(y = "for2: 5 7", "y = " & y)
+
+y = "for3:"
+x = 2
+for x = x+3 to 8
+ y = y & " " & x
+next
+Call ok(y = "for3: 5 6 7 8", "y = " & y)
+
+y = "for4:"
+for x = 5 to 4
+ y = y & " " & x
+next
+Call ok(y = "for4:", "y = " & y)
+
+y = "for5:"
+for x = 5 to 3 step true
+ y = y & " " & x
+next
+Call ok(y = "for5: 5 4 3", "y = " & y)
+
+y = "for6:"
+z = 4
+for x = 5 to z step 3-4
+ y = y & " " & x
+ z = 0
+next
+Call ok(y = "for6: 5 4", "y = " & y)
+
+y = "for7:"
+z = 1
+for x = 5 to 8 step z
+ y = y & " " & x
+ z = 2
+next
+Call ok(y = "for7: 5 6 7 8", "y = " & y)
+
+y = "for8:"
+for x = 5 to 8
+ y = y & " " & x
+ x = x+1
+next
+Call ok(y = "for8: 5 7", "y = " & y)
+
+for x = 1.5 to 1
+ Call ok(false, "for..to called when unexpected")
+next
+
+for x = 1 to 100
+ exit for
+ Call ok(false, "exit for not escaped the loop?")
+next
+
+do while true
+ for x = 1 to 100
+ exit do
+ next
+loop
+
+if null then call ok(false, "if null evaluated")
+
+while null
+ call ok(false, "while null evaluated")
+wend
+
+Call collectionObj.reset()
+y = 0
+x = 10
+for each x in collectionObj
+ y = y+1
+ Call ok(x = y, "x <> y")
+next
+Call ok(y = 3, "y = " & y)
+Call ok(getVT(x) = "VT_EMPTY*", "getVT(x) = " & getVT(x))
+
+Call collectionObj.reset()
+y = false
+for each x in collectionObj
+ if x = 2 then exit for
+ y = 1
+next
+Call ok(y = 1, "y = " & y)
+Call ok(x = 2, "x = " & x)
+
+x = false
+select case 3
+ case 2
+ Call ok(false, "unexpected case")
+ case 2
+ Call ok(false, "unexpected case")
+ case 4
+ Call ok(false, "unexpected case")
+ case "test"
+ case "another case"
+ Call ok(false, "unexpected case")
+ case 0, false, 2+1, 10
+ x = true
+ case ok(false, "unexpected case")
+ Call ok(false, "unexpected case")
+ case else
+ Call ok(false, "unexpected case")
+end select
+Call ok(x, "wrong case")
+
+x = false
+select case 3
+ case 3
+ x = true
+end select
+Call ok(x, "wrong case")
+
+x = false
+select case 2+2
+ case 3
+ Call ok(false, "unexpected case")
+ case else
+ x = true
+end select
+Call ok(x, "wrong case")
+
+y = "3"
+x = false
+select case y
+ case "3"
+ x = true
+ case 3
+ Call ok(false, "unexpected case")
+end select
+Call ok(x, "wrong case")
+
+select case 0
+ case 1
+ Call ok(false, "unexpected case")
+ case "2"
+ Call ok(false, "unexpected case")
+end select
+
+select case 0
+end select
+
+if false then
+Sub testsub
+ x = true
+End Sub
+end if
+
+x = false
+Call testsub
+Call ok(x, "x is false, testsub not called?")
+
+Sub SubSetTrue(v)
+ Call ok(not v, "v is not true")
+ v = true
+End Sub
+
+x = false
+SubSetTrue x
+Call ok(x, "x was not set by SubSetTrue")
+
+SubSetTrue false
+Call ok(not false, "false is no longer false?")
+
+Sub SubSetTrue2(ByRef v)
+ Call ok(not v, "v is not true")
+ v = true
+End Sub
+
+x = false
+SubSetTrue2 x
+Call ok(x, "x was not set by SubSetTrue")
+
+Sub TestSubArgVal(ByVal v)
+ Call ok(not v, "v is not false")
+ v = true
+ Call ok(v, "v is not true?")
+End Sub
+
+x = false
+Call TestSubArgVal(x)
+Call ok(not x, "x is true after TestSubArgVal call?")
+
+Sub TestSubMultiArgs(a,b,c,d,e)
+ Call ok(a=1, "a = " & a)
+ Call ok(b=2, "b = " & b)
+ Call ok(c=3, "c = " & c)
+ Call ok(d=4, "d = " & d)
+ Call ok(e=5, "e = " & e)
+End Sub
+
+Sub TestSubExit(ByRef a)
+ If a Then
+ Exit Sub
+ End If
+ Call ok(false, "Exit Sub not called?")
+End Sub
+
+Call TestSubExit(true)
+
+Sub TestSubExit2
+ for x = 1 to 100
+ Exit Sub
+ next
+End Sub
+Call TestSubExit2
+
+TestSubMultiArgs 1, 2, 3, 4, 5
+Call TestSubMultiArgs(1, 2, 3, 4, 5)
+
+Sub TestSubLocalVal
+ x = false
+ Call ok(not x, "local x is not false?")
+ Dim x
+ Dim a,b, c
+End Sub
+
+x = true
+y = true
+Call TestSubLocalVal
+Call ok(x, "global x is not true?")
+
+Public Sub TestPublicSub
+End Sub
+Call TestPublicSub
+
+Private Sub TestPrivateSub
+End Sub
+Call TestPrivateSub
+
+if false then
+Function testfunc
+ x = true
+End Function
+end if
+
+x = false
+Call TestFunc
+Call ok(x, "x is false, testfunc not called?")
+
+Function FuncSetTrue(v)
+ Call ok(not v, "v is not true")
+ v = true
+End Function
+
+x = false
+FuncSetTrue x
+Call ok(x, "x was not set by FuncSetTrue")
+
+FuncSetTrue false
+Call ok(not false, "false is no longer false?")
+
+Function FuncSetTrue2(ByRef v)
+ Call ok(not v, "v is not true")
+ v = true
+End Function
+
+x = false
+FuncSetTrue2 x
+Call ok(x, "x was not set by FuncSetTrue")
+
+Function TestFuncArgVal(ByVal v)
+ Call ok(not v, "v is not false")
+ v = true
+ Call ok(v, "v is not true?")
+End Function
+
+x = false
+Call TestFuncArgVal(x)
+Call ok(not x, "x is true after TestFuncArgVal call?")
+
+Function TestFuncMultiArgs(a,b,c,d,e)
+ Call ok(a=1, "a = " & a)
+ Call ok(b=2, "b = " & b)
+ Call ok(c=3, "c = " & c)
+ Call ok(d=4, "d = " & d)
+ Call ok(e=5, "e = " & e)
+End Function
+
+TestFuncMultiArgs 1, 2, 3, 4, 5
+Call TestFuncMultiArgs(1, 2, 3, 4, 5)
+
+Function TestFuncLocalVal
+ x = false
+ Call ok(not x, "local x is not false?")
+ Dim x
+End Function
+
+x = true
+y = true
+Call TestFuncLocalVal
+Call ok(x, "global x is not true?")
+
+Function TestFuncExit(ByRef a)
+ If a Then
+ Exit Function
+ End If
+ Call ok(false, "Exit Function not called?")
+End Function
+
+Call TestFuncExit(true)
+
+Function TestFuncExit2(ByRef a)
+ For x = 1 to 100
+ For y = 1 to 100
+ Exit Function
+ Next
+ Next
+ Call ok(false, "Exit Function not called?")
+End Function
+
+Call TestFuncExit2(true)
+
+Sub SubParseTest
+End Sub : x = false
+Call SubParseTest
+
+Function FuncParseTest
+End Function : x = false
+
+Function ReturnTrue
+ ReturnTrue = false
+ ReturnTrue = true
+End Function
+
+Call ok(ReturnTrue(), "ReturnTrue returned false?")
+
+Function SetVal(ByRef x, ByVal v)
+ x = v
+ SetVal = x
+ Exit Function
+End Function
+
+x = false
+ok SetVal(x, true), "SetVal returned false?"
+Call ok(x, "x is not set to true by SetVal?")
+
+Public Function TestPublicFunc
+End Function
+Call TestPublicFunc
+
+Private Function TestPrivateFunc
+End Function
+Call TestPrivateFunc
+
+' Stop has an effect only in debugging mode
+Stop
+
+set x = testObj
+Call ok(getVT(x) = "VT_DISPATCH*", "getVT(x=testObj) = " & getVT(x))
+
+Dim obj
+Set obj = New EmptyClass
+Call ok(getVT(obj) = "VT_DISPATCH*", "getVT(obj) = " & getVT(obj))
+
+Class EmptyClass
+End Class
+
+Set x = obj
+Call ok(getVT(x) = "VT_DISPATCH*", "getVT(x) = " & getVT(x))
+
+Class TestClass
+ Public publicProp
+
+ Private privateProp
+
+ Public Function publicFunction()
+ privateSub()
+ publicFunction = 4
+ End Function
+
+ Public Property Get gsProp()
+ gsProp = privateProp
+ funcCalled = "gsProp get"
+ exit property
+ Call ok(false, "exit property not returned?")
+ End Property
+
+ Public Default Property Get DefValGet
+ DefValGet = privateProp
+ funcCalled = "GetDefVal"
+ End Property
+
+ Public Property Let DefValGet(x)
+ End Property
+
+ Public publicProp2
+
+ Public Sub publicSub
+ End Sub
+
+ Public Property Let gsProp(val)
+ privateProp = val
+ funcCalled = "gsProp let"
+ exit property
+ Call ok(false, "exit property not returned?")
+ End Property
+
+ Public Property Set gsProp(val)
+ funcCalled = "gsProp set"
+ exit property
+ Call ok(false, "exit property not returned?")
+ End Property
+
+ Public Sub setPrivateProp(x)
+ privateProp = x
+ End Sub
+
+ Function getPrivateProp
+ getPrivateProp = privateProp
+ End Function
+
+ Private Sub privateSub
+ End Sub
+
+ Public Sub Class_Initialize
+ publicProp2 = 2
+ privateProp = true
+ End Sub
+End Class
+
+Call testDisp(new testClass)
+
+Set obj = New TestClass
+
+Call ok(obj.publicFunction = 4, "obj.publicFunction = " & obj.publicFunction)
+Call ok(obj.publicFunction() = 4, "obj.publicFunction() = " & obj.publicFunction())
+
+obj.publicSub()
+Call obj.publicSub
+Call obj.publicFunction()
+
+Call ok(getVT(obj.publicProp) = "VT_EMPTY", "getVT(obj.publicProp) = " & getVT(obj.publicProp))
+obj.publicProp = 3
+Call ok(obj.publicProp = 3, "obj.publicProp = " & obj.publicProp)
+obj.publicProp() = 3
+
+Call ok(obj.getPrivateProp() = true, "obj.getPrivateProp() = " & obj.getPrivateProp())
+Call obj.setPrivateProp(6)
+Call ok(obj.getPrivateProp = 6, "obj.getPrivateProp = " & obj.getPrivateProp)
+
+Dim funcCalled
+funcCalled = ""
+Call ok(obj.gsProp = 6, "obj.gsProp = " & obj.gsProp)
+Call ok(funcCalled = "gsProp get", "funcCalled = " & funcCalled)
+obj.gsProp = 3
+Call ok(funcCalled = "gsProp let", "funcCalled = " & funcCalled)
+Call ok(obj.getPrivateProp = 3, "obj.getPrivateProp = " & obj.getPrivateProp)
+Set obj.gsProp = New testclass
+Call ok(funcCalled = "gsProp set", "funcCalled = " & funcCalled)
+
+x = obj
+Call ok(x = 3, "(x = obj) = " & x)
+Call ok(funcCalled = "GetDefVal", "funcCalled = " & funcCalled)
+funcCalled = ""
+Call ok(obj = 3, "(x = obj) = " & obj)
+Call ok(funcCalled = "GetDefVal", "funcCalled = " & funcCalled)
+
+Call obj.Class_Initialize
+Call ok(obj.getPrivateProp() = true, "obj.getPrivateProp() = " & obj.getPrivateProp())
+
+x = (New testclass).publicProp
+
+Class TermTest
+ Public Sub Class_Terminate()
+ funcCalled = "terminate"
+ End Sub
+End Class
+
+Set obj = New TermTest
+funcCalled = ""
+Set obj = Nothing
+Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled)
+
+Set obj = New TermTest
+funcCalled = ""
+Call obj.Class_Terminate
+Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled)
+funcCalled = ""
+Set obj = Nothing
+Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled)
+
+Call (New testclass).publicSub()
+Call (New testclass).publicSub
+
+x = "following ':' is correct syntax" :
+x = "following ':' is correct syntax" :: :
+:: x = "also correct syntax"
+rem another ugly way for comments
+x = "rem as simplestatement" : rem rem comment
+:
+
+Set obj = new EmptyClass
+Set x = obj
+Set y = new EmptyClass
+
+Call ok(obj is x, "obj is not x")
+Call ok(x is obj, "x is not obj")
+Call ok(not (obj is y), "obj is not y")
+Call ok(not obj is y, "obj is not y")
+Call ok(not (x is Nothing), "x is 1")
+Call ok(Nothing is Nothing, "Nothing is not Nothing")
+Call ok(x is obj and true, "x is obj and true is false")
+
+Class TestMe
+ Public Sub Test(MyMe)
+ Call ok(Me is MyMe, "Me is not MyMe")
+ End Sub
+End Class
+
+Set obj = New TestMe
+Call obj.test(obj)
+
+Call ok(getVT(test) = "VT_DISPATCH", "getVT(test) = " & getVT(test))
+Call ok(Me is Test, "Me is not Test")
+
+Const c1 = 1, c2 = 2, c3 = -3
+Call ok(c1 = 1, "c1 = " & c1)
+Call ok(getVT(c1) = "VT_I2", "getVT(c1) = " & getVT(c1))
+Call ok(c3 = -3, "c3 = " & c3)
+Call ok(getVT(c3) = "VT_I2", "getVT(c3) = " & getVT(c3))
+
+Const cb = True, cs = "test", cnull = null
+Call ok(cb, "cb = " & cb)
+Call ok(getVT(cb) = "VT_BOOL", "getVT(cb) = " & getVT(cb))
+Call ok(cs = "test", "cs = " & cs)
+Call ok(getVT(cs) = "VT_BSTR", "getVT(cs) = " & getVT(cs))
+Call ok(isNull(cnull), "cnull = " & cnull)
+Call ok(getVT(cnull) = "VT_NULL", "getVT(cnull) = " & getVT(cnull))
+
+if false then Const conststr = "str"
+Call ok(conststr = "str", "conststr = " & conststr)
+Call ok(getVT(conststr) = "VT_BSTR", "getVT(conststr) = " & getVT(conststr))
+Call ok(conststr = "str", "conststr = " & conststr)
+
+Sub ConstTestSub
+ Const funcconst = 1
+ Call ok(c1 = 1, "c1 = " & c1)
+ Call ok(funcconst = 1, "funcconst = " & funcconst)
+End Sub
+
+Call ConstTestSub
+Dim funcconst
+
+' Property may be used as an identifier (although it's a keyword)
+Sub TestProperty
+ Dim Property
+ PROPERTY = true
+ Call ok(property, "property = " & property)
+
+ for property = 1 to 2
+ next
+End Sub
+
+Call TestProperty
+
+Class Property
+ Public Sub Property()
+ End Sub
+
+ Sub Test(byref property)
+ End Sub
+End Class
+
+Class Property2
+ Function Property()
+ End Function
+
+
+ Sub Test(property)
+ End Sub
+
+ Sub Test2(byval property)
+ End Sub
+End Class
+
+reportSuccess()
--- /dev/null
+'
+' Copyright 2013 Piotr Caban for CodeWeavers
+'
+' This library is free software; you can redistribute it and/or
+' modify it under the terms of the GNU Lesser General Public
+' License as published by the Free Software Foundation; either
+' version 2.1 of the License, or (at your option) any later version.
+'
+' This library is distributed in the hope that it will be useful,
+' but WITHOUT ANY WARRANTY; without even the implied warranty of
+' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+' Lesser General Public License for more details.
+'
+' You should have received a copy of the GNU Lesser General Public
+' License along with this library; if not, write to the Free Software
+' Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+'
+
+Option Explicit
+
+Dim x, matches, match, submatch
+
+Set x = CreateObject("vbscript.regexp")
+Call ok(getVT(x.Pattern) = "VT_BSTR", "getVT(RegExp.Pattern) = " & getVT(x.Pattern))
+Call ok(x.Pattern = "", "RegExp.Pattern = " & x.Pattern)
+Call ok(getVT(x.IgnoreCase) = "VT_BOOL", "getVT(RegExp.IgnoreCase) = " & getVT(x.IgnoreCase))
+Call ok(x.IgnoreCase = false, "RegExp.IgnoreCase = " & x.IgnoreCase)
+Call ok(getVT(x.Global) = "VT_BOOL", "getVT(RegExp.Global) = " & getVT(x.Global))
+Call ok(x.Global = false, "RegExp.Global = " & x.Global)
+Call ok(getVT(x.Multiline) = "VT_BOOL", "getVT(RegExp.Multiline) = " & getVT(x.Multiline))
+Call ok(x.Multiline = false, "RegExp.Multiline = " & x.Multiline)
+
+x.Pattern = "a+"
+matches = x.Test(" aabaaa")
+Call ok(matches = true, "RegExp.Test returned: " & matches)
+Set matches = x.Execute(" aabaaa")
+Call ok(getVT(matches.Count) = "VT_I4", "getVT(matches.Count) = " & getVT(matches.Count))
+Call ok(matches.Count = 1, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "aa", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 1, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 2, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+
+x.Global = true
+Set matches = x.Execute(" aabaaa")
+Call ok(matches.Count = 2, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "aa", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 1, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 2, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+Set match = matches.Item(1)
+Call ok(match.Value = "aaa", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 4, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 3, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+
+Set matches = x.Execute(" aabaaa")
+Call ok(matches.Count = 2, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "aa", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 1, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 2, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+
+x.Pattern = "^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$"
+x.Global = false
+Set matches = x.Execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+Call ok(matches.Count = 0, "matches.Count = " & matches.Count)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+
+x.Pattern = "(a|b)+|(c)"
+Set matches = x.Execute("aa")
+Call ok(matches.Count = 1, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "aa", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 0, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 2, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 2, "submatch.Count = " & submatch.Count)
+Call ok(getVT(submatch.Item(0)) = "VT_BSTR", "getVT(submatch.Item(0)) = " & getVT(submatch.Item(0)))
+Call ok(submatch.Item(0) = "a", "submatch.Item(0) = " & submatch.Item(0))
+Call ok(getVT(submatch.Item(1)) = "VT_EMPTY", "getVT(submatch.Item(1)) = " & getVT(submatch.Item(1)))
+Call ok(submatch.Item(1) = "", "submatch.Item(0) = " & submatch.Item(1))
+
+matches = x.Test(" a ")
+Call ok(matches = true, "RegExp.Test returned: " & matches)
+matches = x.Test(" a ")
+Call ok(matches = true, "RegExp.Test returned: " & matches)
+
+x.Pattern = "\[([^\[]+)\]"
+x.Global = true
+Set matches = x.Execute(" [test] ")
+Call ok(matches.Count = 1, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "[test]", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 1, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 6, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 1, "submatch.Count = " & submatch.Count)
+Call ok(submatch.Item(0) = "test", "submatch.Item(0) = " & submatch.Item(0))
+
+x.Pattern = "Ab"
+x.IgnoreCase = true
+Set matches = x.Execute("abcaBc")
+Call ok(matches.Count = 2, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "ab", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 0, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 2, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+Set match = matches.Item(1)
+Call ok(match.Value = "aB", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 3, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 2, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+
+x.Pattern = "a+b"
+x.IgnoreCase = false
+Set matches = x.Execute("aaabcabc")
+Call ok(matches.Count = 2, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "aaab", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 0, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 4, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+Set match = matches.Item(1)
+Call ok(match.Value = "ab", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 5, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 2, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+
+x.Pattern = "\\"
+Set matches = x.Execute("aaa\\cabc")
+Call ok(matches.Count = 2, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "\", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 3, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 1, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+Set match = matches.Item(1)
+Call ok(match.Value = "\", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 4, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 1, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 0, "submatch.Count = " & submatch.Count)
+
+x.Pattern = "(a)(b)cabc"
+Set matches = x.Execute("abcabc")
+Call ok(matches.Count = 1, "matches.Count = " & matches.Count)
+Set match = matches.Item(0)
+Call ok(match.Value = "abcabc", "match.Value = " & match.Value)
+Call ok(match.FirstIndex = 0, "match.FirstIndex = " & match.FirstIndex)
+Call ok(match.Length = 6, "match.Length = " & match.Length)
+Set submatch = match.SubMatches
+Call ok(submatch.Count = 2, "submatch.Count = " & submatch.Count)
+Call ok(submatch.Item(0) = "a", "submatch.Item(0) = " & submatch.Item(0))
+Call ok(submatch.Item(1) = "b", "submatch.Item(0) = " & submatch.Item(1))
+
+Call reportSuccess()
--- /dev/null
+/*
+ * Copyright 2011 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @makedep: api.vbs */
+api.vbs 40 "api.vbs"
+
+/* @makedep: lang.vbs */
+lang.vbs 40 "lang.vbs"
+
+/* @makedep: regexp.vbs */
+regexp.vbs 40 "regexp.vbs"
--- /dev/null
+/*
+ * Copyright 2011 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
+#include <ole2.h>
+#include <dispex.h>
+#include <activscp.h>
+
+#include <vbsregexp55.h>
+
+#include <wine/test.h>
+
+#ifdef _WIN64
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_64_ParseProcedureText
+
+#else
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_32_ParseProcedureText
+
+#endif
+
+extern const CLSID CLSID_VBScript;
+extern const CLSID CLSID_VBScriptRegExp;
+
+#define DEFINE_EXPECT(func) \
+ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+ expect_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+ do { \
+ ok(expect_ ##func, "unexpected call " #func "\n"); \
+ called_ ## func = TRUE; \
+ }while(0)
+
+#define CHECK_EXPECT(func) \
+ do { \
+ CHECK_EXPECT2(func); \
+ expect_ ## func = FALSE; \
+ }while(0)
+
+#define CHECK_CALLED(func) \
+ do { \
+ ok(called_ ## func, "expected " #func "\n"); \
+ expect_ ## func = called_ ## func = FALSE; \
+ }while(0)
+
+#define CLEAR_CALLED(func) \
+ expect_ ## func = called_ ## func = FALSE
+
+DEFINE_EXPECT(global_success_d);
+DEFINE_EXPECT(global_success_i);
+DEFINE_EXPECT(global_vbvar_d);
+DEFINE_EXPECT(global_vbvar_i);
+DEFINE_EXPECT(testobj_propget_d);
+DEFINE_EXPECT(testobj_propget_i);
+DEFINE_EXPECT(testobj_propput_d);
+DEFINE_EXPECT(testobj_propput_i);
+DEFINE_EXPECT(global_propargput_d);
+DEFINE_EXPECT(global_propargput_i);
+DEFINE_EXPECT(global_propargput1_d);
+DEFINE_EXPECT(global_propargput1_i);
+DEFINE_EXPECT(collectionobj_newenum_i);
+DEFINE_EXPECT(Next);
+DEFINE_EXPECT(GetWindow);
+DEFINE_EXPECT(GetUIBehavior);
+DEFINE_EXPECT(EnableModeless);
+
+#define DISPID_GLOBAL_REPORTSUCCESS 1000
+#define DISPID_GLOBAL_TRACE 1001
+#define DISPID_GLOBAL_OK 1002
+#define DISPID_GLOBAL_GETVT 1003
+#define DISPID_GLOBAL_ISENGLANG 1004
+#define DISPID_GLOBAL_VBVAR 1005
+#define DISPID_GLOBAL_TESTOBJ 1006
+#define DISPID_GLOBAL_ISNULLDISP 1007
+#define DISPID_GLOBAL_TESTDISP 1008
+#define DISPID_GLOBAL_REFOBJ 1009
+#define DISPID_GLOBAL_COUNTER 1010
+#define DISPID_GLOBAL_PROPARGPUT 1011
+#define DISPID_GLOBAL_PROPARGPUT1 1012
+#define DISPID_GLOBAL_COLLOBJ 1013
+#define DISPID_GLOBAL_DOUBLEASSTRING 1014
+
+#define DISPID_TESTOBJ_PROPGET 2000
+#define DISPID_TESTOBJ_PROPPUT 2001
+
+#define DISPID_COLLOBJ_RESET 3000
+
+static const WCHAR testW[] = {'t','e','s','t',0};
+static const WCHAR emptyW[] = {0};
+
+static BOOL strict_dispid_check, is_english, allow_ui;
+static const char *test_name = "(null)";
+static int test_counter;
+static SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_NOUIERROR;
+
+static BSTR a2bstr(const char *str)
+{
+ BSTR ret;
+ int len;
+
+ len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ ret = SysAllocStringLen(NULL, len-1);
+ MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+
+ return ret;
+}
+
+static int strcmp_wa(LPCWSTR strw, const char *stra)
+{
+ CHAR buf[512];
+ WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
+ return lstrcmpA(buf, stra);
+}
+
+static const char *debugstr_guid(REFIID riid)
+{
+ static char buf[50];
+
+ sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
+ riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
+ riid->Data4[5], riid->Data4[6], riid->Data4[7]);
+
+ return buf;
+}
+
+static const char *vt2a(VARIANT *v)
+{
+ if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
+ static char buf[64];
+ sprintf(buf, "%s*", vt2a(V_BYREF(v)));
+ return buf;
+ }
+
+ switch(V_VT(v)) {
+ case VT_EMPTY:
+ return "VT_EMPTY";
+ case VT_NULL:
+ return "VT_NULL";
+ case VT_I2:
+ return "VT_I2";
+ case VT_I4:
+ return "VT_I4";
+ case VT_R8:
+ return "VT_R8";
+ case VT_DATE:
+ return "VT_DATE";
+ case VT_BSTR:
+ return "VT_BSTR";
+ case VT_DISPATCH:
+ return "VT_DISPATCH";
+ case VT_BOOL:
+ return "VT_BOOL";
+ case VT_ARRAY|VT_VARIANT:
+ return "VT_ARRAY|VT_VARIANT";
+ default:
+ ok(0, "unknown vt %d\n", V_VT(v));
+ return NULL;
+ }
+}
+
+/* Returns true if the user interface is in English. Note that this does not
+ * presume of the formatting of dates, numbers, etc.
+ */
+static BOOL is_lang_english(void)
+{
+ static HMODULE hkernel32 = NULL;
+ static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
+ static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
+
+ if (!hkernel32)
+ {
+ hkernel32 = GetModuleHandleA("kernel32.dll");
+ pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
+ pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
+ }
+ if (pGetThreadUILanguage && PRIMARYLANGID(pGetThreadUILanguage()) != LANG_ENGLISH)
+ return FALSE;
+ if (pGetUserDefaultUILanguage && PRIMARYLANGID(pGetUserDefaultUILanguage()) != LANG_ENGLISH)
+ return FALSE;
+
+ return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
+}
+
+static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected call\n");
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
+ REFIID riid, void **ppv)
+{
+ ok(0, "unexpected service %s\n", debugstr_guid(guidService));
+ return E_NOINTERFACE;
+}
+
+static const IServiceProviderVtbl ServiceProviderVtbl = {
+ ServiceProvider_QueryInterface,
+ ServiceProvider_AddRef,
+ ServiceProvider_Release,
+ ServiceProvider_QueryService
+};
+
+static IServiceProvider caller_sp = { &ServiceProviderVtbl };
+
+static void test_disp(IDispatch *disp)
+{
+ DISPID id, public_prop_id, public_prop2_id, public_func_id, public_sub_id, defvalget_id;
+ DISPID named_args[5] = {DISPID_PROPERTYPUT};
+ VARIANT v, args[5];
+ DISPPARAMS dp = {args, named_args};
+ IDispatchEx *dispex;
+ EXCEPINFO ei = {0};
+ BSTR str;
+ HRESULT hres;
+
+ hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+ ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
+
+ str = a2bstr("publicProp");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop_id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
+
+ str = a2bstr("PUBLICPROP");
+ hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(PUBLICPROP) failed: %08x\n", hres);
+ ok(public_prop_id == id, "id = %d\n", public_prop_id);
+
+ str = a2bstr("publicPROP2");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop2_id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
+
+ str = a2bstr("defValGet");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &defvalget_id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(defValGet) failed: %08x\n", hres);
+ ok(defvalget_id == DISPID_VALUE, "id = %d\n", defvalget_id);
+
+ str = a2bstr("privateProp");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
+ SysFreeString(str);
+ ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
+ ok(id == -1, "id = %d\n", id);
+
+ str = a2bstr("class_initialize");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
+
+ hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ V_VT(args) = VT_BOOL;
+ V_BOOL(args) = VARIANT_TRUE;
+ dp.cArgs = dp.cNamedArgs = 1;
+ V_VT(&v) = VT_BOOL;
+ hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
+
+ dp.cArgs = 1;
+ hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ V_VT(args) = VT_BOOL;
+ V_BOOL(args) = VARIANT_FALSE;
+ dp.cArgs = 1;
+ V_VT(&v) = VT_BOOL;
+ hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
+ ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
+
+ str = a2bstr("publicFunction");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
+ ok(public_func_id != -1, "public_func_id = -1\n");
+
+ str = a2bstr("publicSub");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_sub_id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres);
+ ok(public_sub_id != -1, "public_func_id = -1\n");
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
+ ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
+ ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ V_VT(args) = VT_BOOL;
+ V_BOOL(args) = VARIANT_TRUE;
+ dp.cArgs = dp.cNamedArgs = 1;
+ hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
+ ok(FAILED(hres), "InvokeEx succeeded: %08x\n", hres);
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ dp.cArgs = dp.cNamedArgs = 0;
+ hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
+
+ str = a2bstr("privateSub");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
+ SysFreeString(str);
+ ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateSub) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
+ ok(id == -1, "id = %d\n", id);
+
+ str = a2bstr("dynprop");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive|fdexNameEnsure, &id);
+ ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
+ ok(id == -1, "id = %d\n", id);
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &id);
+ ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
+ ok(id == -1, "id = %d\n", id);
+ SysFreeString(str);
+
+ str = a2bstr("publicProp");
+ hres = IDispatchEx_GetDispID(dispex, str, 0x80000000|fdexNameCaseInsensitive, &public_prop_id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
+
+ id = 0xdeadbeef;
+ str = a2bstr("publicProp");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
+ ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
+
+ id = 0xdeadbeef;
+ str = a2bstr("publicprop");
+ hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
+ SysFreeString(str);
+ ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
+ ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
+
+ IDispatchEx_Release(dispex);
+}
+
+#define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
+static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
+{
+ ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
+}
+
+static IDispatchEx enumDisp;
+
+static HRESULT WINAPI EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
+{
+ if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) {
+ *ppv = iface;
+ return S_OK;
+ }
+
+ if(IsEqualGUID(riid, &IID_IDispatch)) {
+ *ppv = &enumDisp;
+ return S_OK;
+ }
+
+ ok(0, "unexpected call %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI EnumVARIANT_AddRef(IEnumVARIANT *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI EnumVARIANT_Release(IEnumVARIANT *iface)
+{
+ return 1;
+}
+
+static unsigned next_cnt;
+
+static HRESULT WINAPI EnumVARIANT_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
+{
+ if(strict_dispid_check)
+ CHECK_EXPECT2(Next);
+
+ ok(celt == 1, "celt = %d\n", celt);
+ ok(V_VT(rgVar) == VT_EMPTY, "V_VT(rgVar) = %d\n", V_VT(rgVar));
+ ok(!pCeltFetched, "pCeltFetched = %p\n", pCeltFetched);
+
+ if(next_cnt++ < 3) {
+ V_VT(rgVar) = VT_I2;
+ V_I2(rgVar) = next_cnt;
+ return S_OK;
+ }
+
+ return S_FALSE;
+}
+
+static HRESULT WINAPI EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI EnumVARIANT_Reset(IEnumVARIANT *iface)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static const IEnumVARIANTVtbl EnumVARIANTVtbl = {
+ EnumVARIANT_QueryInterface,
+ EnumVARIANT_AddRef,
+ EnumVARIANT_Release,
+ EnumVARIANT_Next,
+ EnumVARIANT_Skip,
+ EnumVARIANT_Reset,
+ EnumVARIANT_Clone
+};
+
+static IEnumVARIANT enumObj = { &EnumVARIANTVtbl };
+
+static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ if(IsEqualGUID(riid, &IID_IUnknown)
+ || IsEqualGUID(riid, &IID_IDispatch)
+ || IsEqualGUID(riid, &IID_IDispatchEx))
+ *ppv = iface;
+ else {
+ trace("QI %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
+ LCID lcid, ITypeInfo **ppTInfo)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
+ LPOLESTR *rgszNames, UINT cNames,
+ LCID lcid, DISPID *rgDispId)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
+ REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+ VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
+{
+ ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+ VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+ ok(0, "unexpected call %d\n", id);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+ if(!strcmp_wa(bstrName, "propget")) {
+ CHECK_EXPECT(testobj_propget_d);
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_TESTOBJ_PROPGET;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "propput")) {
+ CHECK_EXPECT(testobj_propput_d);
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_TESTOBJ_PROPPUT;
+ return S_OK;
+ }
+
+ ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
+ return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+ VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+ switch(id) {
+ case DISPID_TESTOBJ_PROPGET:
+ CHECK_EXPECT(testobj_propget_i);
+
+ ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgvarg, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ V_VT(pvarRes) = VT_I2;
+ V_I2(pvarRes) = 10;
+ return S_OK;
+ case DISPID_TESTOBJ_PROPPUT:
+ CHECK_EXPECT(testobj_propput_i);
+
+ ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
+ return S_OK;
+ }
+
+ ok(0, "unexpected call %d\n", id);
+ return E_FAIL;
+}
+
+static IDispatchExVtbl testObjVtbl = {
+ DispatchEx_QueryInterface,
+ DispatchEx_AddRef,
+ DispatchEx_Release,
+ DispatchEx_GetTypeInfoCount,
+ DispatchEx_GetTypeInfo,
+ DispatchEx_GetIDsOfNames,
+ DispatchEx_Invoke,
+ testObj_GetDispID,
+ testObj_InvokeEx,
+ DispatchEx_DeleteMemberByName,
+ DispatchEx_DeleteMemberByDispID,
+ DispatchEx_GetMemberProperties,
+ DispatchEx_GetMemberName,
+ DispatchEx_GetNextDispID,
+ DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx testObj = { &testObjVtbl };
+
+static HRESULT WINAPI enumDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
+{
+ return IEnumVARIANT_QueryInterface(&enumObj, riid, ppv);
+}
+
+static IDispatchExVtbl enumDispVtbl = {
+ enumDisp_QueryInterface,
+ DispatchEx_AddRef,
+ DispatchEx_Release,
+ DispatchEx_GetTypeInfoCount,
+ DispatchEx_GetTypeInfo,
+ DispatchEx_GetIDsOfNames,
+ DispatchEx_Invoke,
+ DispatchEx_GetDispID,
+ DispatchEx_InvokeEx,
+ DispatchEx_DeleteMemberByName,
+ DispatchEx_DeleteMemberByDispID,
+ DispatchEx_GetMemberProperties,
+ DispatchEx_GetMemberName,
+ DispatchEx_GetNextDispID,
+ DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx enumDisp = { &enumDispVtbl };
+
+static HRESULT WINAPI collectionObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+ if(!strcmp_wa(bstrName, "reset")) {
+ *pid = DISPID_COLLOBJ_RESET;
+ return S_OK;
+ }
+
+ ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
+ return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT WINAPI collectionObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+ VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+ switch(id) {
+ case DISPID_NEWENUM:
+ if(strict_dispid_check)
+ CHECK_EXPECT(collectionobj_newenum_i);
+
+ ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgvarg, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ V_VT(pvarRes) = VT_UNKNOWN;
+ V_UNKNOWN(pvarRes) = (IUnknown*)&enumObj;
+ return S_OK;
+ case DISPID_COLLOBJ_RESET:
+ next_cnt = 0;
+ return S_OK;
+ }
+
+ ok(0, "unexpected call %d\n", id);
+ return E_NOTIMPL;
+}
+
+static IDispatchExVtbl collectionObjVtbl = {
+ DispatchEx_QueryInterface,
+ DispatchEx_AddRef,
+ DispatchEx_Release,
+ DispatchEx_GetTypeInfoCount,
+ DispatchEx_GetTypeInfo,
+ DispatchEx_GetIDsOfNames,
+ DispatchEx_Invoke,
+ collectionObj_GetDispID,
+ collectionObj_InvokeEx,
+ DispatchEx_DeleteMemberByName,
+ DispatchEx_DeleteMemberByDispID,
+ DispatchEx_GetMemberProperties,
+ DispatchEx_GetMemberName,
+ DispatchEx_GetNextDispID,
+ DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx collectionObj = { &collectionObjVtbl };
+
+static ULONG refobj_ref;
+
+static ULONG WINAPI RefObj_AddRef(IDispatchEx *iface)
+{
+ return ++refobj_ref;
+}
+
+static ULONG WINAPI RefObj_Release(IDispatchEx *iface)
+{
+ return --refobj_ref;
+}
+
+static IDispatchExVtbl RefObjVtbl = {
+ DispatchEx_QueryInterface,
+ RefObj_AddRef,
+ RefObj_Release,
+ DispatchEx_GetTypeInfoCount,
+ DispatchEx_GetTypeInfo,
+ DispatchEx_GetIDsOfNames,
+ DispatchEx_Invoke,
+ DispatchEx_GetDispID,
+ DispatchEx_InvokeEx,
+ DispatchEx_DeleteMemberByName,
+ DispatchEx_DeleteMemberByDispID,
+ DispatchEx_GetMemberProperties,
+ DispatchEx_GetMemberName,
+ DispatchEx_GetNextDispID,
+ DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx RefObj = { &RefObjVtbl };
+
+static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+ if(!strcmp_wa(bstrName, "ok")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_OK;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "trace")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_TRACE;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "reportSuccess")) {
+ CHECK_EXPECT(global_success_d);
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_REPORTSUCCESS;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "getVT")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_GETVT;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "isEnglishLang")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_ISENGLANG;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "testObj")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_TESTOBJ;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "collectionObj")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_COLLOBJ;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "vbvar")) {
+ CHECK_EXPECT(global_vbvar_d);
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_VBVAR;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "isNullDisp")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_ISNULLDISP;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "testDisp")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_TESTDISP;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "RefObj")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_REFOBJ;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "propargput")) {
+ CHECK_EXPECT(global_propargput_d);
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_PROPARGPUT;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "propargput1")) {
+ CHECK_EXPECT(global_propargput1_d);
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_PROPARGPUT1;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "counter")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_COUNTER;
+ return S_OK;
+ }
+ if(!strcmp_wa(bstrName, "doubleAsString")) {
+ test_grfdex(grfdex, fdexNameCaseInsensitive);
+ *pid = DISPID_GLOBAL_DOUBLEASSTRING;
+ return S_OK;
+ }
+
+ if(strict_dispid_check && strcmp_wa(bstrName, "x"))
+ ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
+ return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+ VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+ switch(id) {
+ case DISPID_GLOBAL_OK: {
+ VARIANT *b;
+
+ ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ if(wFlags & INVOKE_PROPERTYGET)
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ else
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+
+ b = pdp->rgvarg+1;
+ if(V_VT(b) == (VT_BYREF|VT_VARIANT))
+ b = V_BYREF(b);
+
+ ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
+
+ ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
+ return S_OK;
+ }
+
+ case DISPID_GLOBAL_TRACE:
+ ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ if(V_VT(pdp->rgvarg) == VT_BSTR)
+ trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
+
+ return S_OK;
+
+ case DISPID_GLOBAL_REPORTSUCCESS:
+ CHECK_EXPECT(global_success_i);
+
+ ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ return S_OK;
+
+ case DISPID_GLOBAL_GETVT:
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+ ok(pei != NULL, "pei == NULL\n");
+
+ V_VT(pvarRes) = VT_BSTR;
+ V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
+ return S_OK;
+
+ case DISPID_GLOBAL_ISENGLANG:
+ ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ V_VT(pvarRes) = VT_BOOL;
+ V_BOOL(pvarRes) = is_english ? VARIANT_TRUE : VARIANT_FALSE;
+ return S_OK;
+
+ case DISPID_GLOBAL_VBVAR:
+ CHECK_EXPECT(global_vbvar_i);
+
+ ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
+ return S_OK;
+
+ case DISPID_GLOBAL_TESTOBJ:
+ ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
+
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgvarg, "rgvarg != NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ V_VT(pvarRes) = VT_DISPATCH;
+ V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
+ return S_OK;
+
+ case DISPID_GLOBAL_COLLOBJ:
+ ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
+
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgvarg, "rgvarg != NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ V_VT(pvarRes) = VT_DISPATCH;
+ V_DISPATCH(pvarRes) = (IDispatch*)&collectionObj;
+ return S_OK;
+
+ case DISPID_GLOBAL_REFOBJ:
+ ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
+
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(!pdp->rgvarg, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ IDispatchEx_AddRef(&RefObj);
+ V_VT(pvarRes) = VT_DISPATCH;
+ V_DISPATCH(pvarRes) = (IDispatch*)&RefObj;
+ return S_OK;
+
+ case DISPID_GLOBAL_ISNULLDISP: {
+ VARIANT *v;
+
+ ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ v = pdp->rgvarg;
+ if(V_VT(v) == (VT_VARIANT|VT_BYREF))
+ v = V_VARIANTREF(v);
+
+ ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ V_VT(pvarRes) = VT_BOOL;
+ V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
+ return S_OK;
+ }
+
+ case DISPID_GLOBAL_TESTDISP:
+ ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ test_disp(V_DISPATCH(pdp->rgvarg));
+ return S_OK;
+
+ case DISPID_GLOBAL_PROPARGPUT:
+ CHECK_EXPECT(global_propargput_i);
+
+ ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
+ ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
+ ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
+
+ ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
+ ok(V_I2(pdp->rgvarg+1) == 2, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
+
+ ok(V_VT(pdp->rgvarg+2) == VT_I2, "V_VT(psp->rgvargs+2) = %d\n", V_VT(pdp->rgvarg+2));
+ ok(V_I2(pdp->rgvarg+2) == 1, "V_I2(psp->rgvargs+2) = %d\n", V_I2(pdp->rgvarg+2));
+ return S_OK;
+
+ case DISPID_GLOBAL_PROPARGPUT1:
+ CHECK_EXPECT(global_propargput1_i);
+
+ ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
+ ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
+ ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+ ok(!pvarRes, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+ ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
+
+ ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
+ ok(V_I2(pdp->rgvarg+1) == 1, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
+
+ return S_OK;
+
+ case DISPID_GLOBAL_COUNTER:
+ ok(pdp != NULL, "pdp == NULL\n");
+ todo_wine ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+ ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+ ok(pei != NULL, "pei == NULL\n");
+
+ V_VT(pvarRes) = VT_I2;
+ V_I2(pvarRes) = test_counter++;
+ return S_OK;
+
+ case DISPID_GLOBAL_DOUBLEASSTRING:
+ ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(V_VT(pdp->rgvarg) == VT_R8, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
+ ok(pvarRes != NULL, "pvarRes == NULL\n");
+
+ V_VT(pvarRes) = VT_BSTR;
+ return VarBstrFromR8(V_R8(pdp->rgvarg), 0, 0, &V_BSTR(pvarRes));
+ }
+
+ ok(0, "unexpected call %d\n", id);
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+static IDispatchExVtbl GlobalVtbl = {
+ DispatchEx_QueryInterface,
+ DispatchEx_AddRef,
+ DispatchEx_Release,
+ DispatchEx_GetTypeInfoCount,
+ DispatchEx_GetTypeInfo,
+ DispatchEx_GetIDsOfNames,
+ DispatchEx_Invoke,
+ Global_GetDispID,
+ Global_InvokeEx,
+ DispatchEx_DeleteMemberByName,
+ DispatchEx_DeleteMemberByDispID,
+ DispatchEx_GetMemberProperties,
+ DispatchEx_GetMemberName,
+ DispatchEx_GetNextDispID,
+ DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx Global = { &GlobalVtbl };
+
+static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected call\n");
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *phwnd)
+{
+ if(!allow_ui)
+ CHECK_EXPECT(GetWindow);
+ *phwnd = NULL;
+ return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL fEnable)
+{
+ if(allow_ui)
+ return S_OK;
+
+ CHECK_EXPECT(EnableModeless);
+ ok(!fEnable, "fEnable = %x\n", fEnable);
+ return E_FAIL;
+}
+
+static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = {
+ ActiveScriptSiteWindow_QueryInterface,
+ ActiveScriptSiteWindow_AddRef,
+ ActiveScriptSiteWindow_Release,
+ ActiveScriptSiteWindow_GetWindow,
+ ActiveScriptSiteWindow_EnableModeless
+};
+
+static IActiveScriptSiteWindow ActiveScriptSiteWindow = { &ActiveScriptSiteWindowVtbl };
+
+static HRESULT WINAPI ActiveScriptSiteUIControl_QueryInterface(IActiveScriptSiteUIControl *iface, REFIID riid, void **ppv)
+{
+ ok(0, "unexpected call\n");
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ActiveScriptSiteUIControl_AddRef(IActiveScriptSiteUIControl *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ActiveScriptSiteUIControl_Release(IActiveScriptSiteUIControl *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSiteUIControl_GetUIBehavior(IActiveScriptSiteUIControl *iface, SCRIPTUICITEM UicItem,
+ SCRIPTUICHANDLING *pUicHandling)
+{
+ if(!allow_ui) {
+ CHECK_EXPECT(GetUIBehavior);
+ ok(UicItem == SCRIPTUICITEM_MSGBOX, "UidItem = %d\n", UicItem);
+ }
+ *pUicHandling = uic_handling;
+ return S_OK;
+}
+
+static const IActiveScriptSiteUIControlVtbl ActiveScriptSiteUIControlVtbl = {
+ ActiveScriptSiteUIControl_QueryInterface,
+ ActiveScriptSiteUIControl_AddRef,
+ ActiveScriptSiteUIControl_Release,
+ ActiveScriptSiteUIControl_GetUIBehavior
+};
+
+static IActiveScriptSiteUIControl ActiveScriptSiteUIControl = { &ActiveScriptSiteUIControlVtbl };
+
+static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ if(IsEqualGUID(&IID_IUnknown, riid))
+ *ppv = iface;
+ else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
+ *ppv = iface;
+ else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid))
+ *ppv = &ActiveScriptSiteWindow;
+ else if(IsEqualGUID(&IID_IActiveScriptSiteUIControl, riid))
+ *ppv = &ActiveScriptSiteUIControl;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
+{
+ *plcid = GetUserDefaultLCID();
+ return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
+ DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
+{
+ ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
+ ok(!ppti, "ppti != NULL\n");
+
+ if(strcmp_wa(pstrName, "test"))
+ ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
+
+ *ppiunkItem = (IUnknown*)&Global;
+ return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
+ const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
+{
+ return E_NOTIMPL;
+}
+
+#undef ACTSCPSITE_THIS
+
+static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
+ ActiveScriptSite_QueryInterface,
+ ActiveScriptSite_AddRef,
+ ActiveScriptSite_Release,
+ ActiveScriptSite_GetLCID,
+ ActiveScriptSite_GetItemInfo,
+ ActiveScriptSite_GetDocVersionString,
+ ActiveScriptSite_OnScriptTerminate,
+ ActiveScriptSite_OnStateChange,
+ ActiveScriptSite_OnScriptError,
+ ActiveScriptSite_OnEnterScript,
+ ActiveScriptSite_OnLeaveScript
+};
+
+static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
+
+static IActiveScript *create_script(void)
+{
+ IActiveScript *script;
+ HRESULT hres;
+
+ hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+ &IID_IActiveScript, (void**)&script);
+ ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+
+ return script;
+}
+
+static IActiveScript *create_and_init_script(DWORD flags)
+{
+ IActiveScriptParse *parser;
+ IActiveScript *engine;
+ HRESULT hres;
+
+ engine = create_script();
+ if(!engine)
+ return NULL;
+
+ hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+ IActiveScriptParse_Release(parser);
+
+ hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+ hres = IActiveScript_AddNamedItem(engine, testW,
+ SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
+ ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+ return engine;
+}
+
+static void close_script(IActiveScript *script)
+{
+ ULONG ref;
+ HRESULT hres;
+
+ hres = IActiveScript_Close(script);
+ ok(hres == S_OK, "Close failed: %08x\n", hres);
+
+ ref = IActiveScript_Release(script);
+ ok(!ref, "ref=%u\n", ref);
+}
+
+static HRESULT parse_script(DWORD flags, BSTR script_str, const WCHAR *delim)
+{
+ IActiveScriptParse *parser;
+ IActiveScript *engine;
+ IDispatch *script_disp;
+ LONG ref;
+ HRESULT hres;
+
+ engine = create_and_init_script(flags);
+ if(!engine)
+ return S_OK;
+
+ hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+ if (FAILED(hres))
+ {
+ IActiveScript_Release(engine);
+ return hres;
+ }
+
+ hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
+ ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
+ ok(script_disp != NULL, "script_disp == NULL\n");
+ ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
+
+ test_counter = 0;
+
+ hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, delim, 0, 0, 0, NULL, NULL);
+
+ IActiveScript_Close(engine);
+
+ IDispatch_Release(script_disp);
+ IActiveScript_Release(engine);
+
+ ref = IActiveScriptParse_Release(parser);
+ ok(!ref, "ref=%d\n", ref);
+ return hres;
+}
+
+static void parse_script_af(DWORD flags, const char *src)
+{
+ BSTR tmp;
+ HRESULT hres;
+
+ tmp = a2bstr(src);
+ hres = parse_script(flags, tmp, NULL);
+ SysFreeString(tmp);
+ ok(hres == S_OK, "parse_script failed: %08x\n", hres);
+}
+
+static HRESULT parse_script_ar(const char *src)
+{
+ BSTR tmp;
+ HRESULT hres;
+
+ tmp = a2bstr(src);
+ hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp, NULL);
+ SysFreeString(tmp);
+ return hres;
+}
+
+static void parse_script_a(const char *src)
+{
+ parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
+}
+
+#define parse_htmlscript_a(a) _parse_htmlscript_a(__LINE__,a)
+static void _parse_htmlscript_a(unsigned line, const char *src)
+{
+ BSTR tmp;
+ HRESULT hres;
+
+ static const WCHAR script_delimW[] = {'<','/','S','C','R','I','P','T','>',0};
+
+ tmp = a2bstr(src);
+ hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp, script_delimW);
+ SysFreeString(tmp);
+ ok_(__FILE__,line)(hres == S_OK, "parse_script failed: %08x\n", hres);
+}
+
+static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src)
+{
+ IDispatchEx *dispex;
+ IDispatch *disp;
+ BSTR str;
+ HRESULT hres;
+
+ static const WCHAR delimiterW[] = {'\"',0};
+
+ str = a2bstr(src);
+ hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, str, NULL, emptyW, NULL, NULL, delimiterW, 0, 0,
+ SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp);
+ SysFreeString(str);
+ ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
+ ok(disp != NULL, "disp = NULL\n");
+
+ hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+ IDispatch_Release(disp);
+ ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
+
+ return dispex;
+}
+
+
+static void test_procedures(void)
+{
+ IActiveScriptParseProcedure2 *parse_proc;
+ DISPPARAMS dp = {NULL};
+ IActiveScript *script;
+ IDispatchEx *proc;
+ EXCEPINFO ei = {0};
+ VARIANT v;
+ HRESULT hres;
+
+ script = create_and_init_script(0);
+
+ hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
+ ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
+
+ proc = parse_procedure(parse_proc, "dim x\nif true then x=false");
+
+ V_VT(&v) = VT_EMPTY;
+ hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+
+ IDispatchEx_Release(proc);
+
+ IActiveScriptParseProcedure2_Release(parse_proc);
+
+ close_script(script);
+}
+
+static void test_gc(void)
+{
+ IActiveScriptParse *parser;
+ IActiveScript *engine;
+ BSTR src;
+ HRESULT hres;
+
+ strict_dispid_check = FALSE;
+
+ engine = create_script();
+ if(!engine)
+ return;
+
+ hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+ hres = IActiveScript_AddNamedItem(engine, testW,
+ SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+ ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+ src = a2bstr(
+ "class C\n"
+ " Public ref\n"
+ " Public Sub Class_Terminate\n"
+ " Call reportSuccess()\n"
+ " End Sub\n"
+ "End Class\n"
+ "Dim x\n"
+ "set x = new C\n"
+ "set x.ref = x\n"
+ "set x = nothing\n");
+
+ hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+ SysFreeString(src);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ IActiveScript_Close(engine);
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ IActiveScript_Release(engine);
+ IActiveScriptParse_Release(parser);
+}
+
+static void test_msgbox(void)
+{
+ HRESULT hres;
+
+ uic_handling = SCRIPTUICHANDLING_NOUIDEFAULT;
+
+ SET_EXPECT(GetUIBehavior);
+ SET_EXPECT(GetWindow);
+ SET_EXPECT(EnableModeless);
+ hres = parse_script_ar("MsgBox \"testing...\"");
+ CLEAR_CALLED(GetUIBehavior);
+ CLEAR_CALLED(GetWindow);
+ CLEAR_CALLED(EnableModeless);
+ if(FAILED(hres)) {
+ win_skip("Skipping MsgBox tests, broken (probably too old) vbscript\n");
+ return;
+ }
+
+ SET_EXPECT(GetUIBehavior);
+ parse_script_a("dim r\n r=MsgBox(\"testing...\")\n Call ok(r=0, \"r=\"&r)");
+ CHECK_CALLED(GetUIBehavior);
+
+ SET_EXPECT(GetUIBehavior);
+ parse_script_a("MsgBox 10");
+ CHECK_CALLED(GetUIBehavior);
+
+ uic_handling = SCRIPTUICHANDLING_ALLOW;
+
+ SET_EXPECT(GetUIBehavior);
+ SET_EXPECT(GetWindow);
+ SET_EXPECT(EnableModeless);
+ hres = parse_script_ar("MsgBox \"testing...\"");
+ ok(FAILED(hres), "script not failed\n");
+ CHECK_CALLED(GetUIBehavior);
+ CHECK_CALLED(GetWindow);
+ CHECK_CALLED(EnableModeless);
+
+ uic_handling = SCRIPTUICHANDLING_NOUIERROR;
+
+ SET_EXPECT(GetUIBehavior);
+ hres = parse_script_ar("MsgBox \"testing...\"");
+ ok(FAILED(hres), "script not failed\n");
+ CHECK_CALLED(GetUIBehavior);
+}
+
+static HRESULT test_global_vars_ref(BOOL use_close)
+{
+ IActiveScriptParse *parser;
+ IActiveScript *engine;
+ BSTR script_str;
+ LONG ref;
+ HRESULT hres;
+
+ engine = create_script();
+ if(!engine)
+ return S_OK;
+
+ hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+ if (FAILED(hres))
+ {
+ IActiveScript_Release(engine);
+ return hres;
+ }
+
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+ hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+ ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+ refobj_ref = 0;
+
+ script_str = a2bstr("Dim x\nset x = RefObj\n");
+ hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ SysFreeString(script_str);
+
+ ok(refobj_ref, "refobj_ref = 0\n");
+
+ if(use_close) {
+ hres = IActiveScript_Close(engine);
+ ok(hres == S_OK, "Close failed: %08x\n", hres);
+ }else {
+ hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_UNINITIALIZED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+ }
+
+ ok(!refobj_ref, "refobj_ref = %d\n", refobj_ref);
+
+ IActiveScript_Release(engine);
+
+ ref = IActiveScriptParse_Release(parser);
+ ok(!ref, "ref=%d\n", ref);
+ return hres;
+}
+
+static BSTR get_script_from_file(const char *filename)
+{
+ DWORD size, len;
+ HANDLE file, map;
+ const char *file_map;
+ BSTR ret;
+
+ file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
+ if(file == INVALID_HANDLE_VALUE) {
+ trace("Could not open file: %u\n", GetLastError());
+ return NULL;
+ }
+
+ size = GetFileSize(file, NULL);
+
+ map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
+ CloseHandle(file);
+ if(map == INVALID_HANDLE_VALUE) {
+ trace("Could not create file mapping: %u\n", GetLastError());
+ return NULL;
+ }
+
+ file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
+ CloseHandle(map);
+ if(!file_map) {
+ trace("MapViewOfFile failed: %u\n", GetLastError());
+ return NULL;
+ }
+
+ len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
+ ret = SysAllocStringLen(NULL, len);
+ MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
+
+ UnmapViewOfFile(file_map);
+
+ return ret;
+}
+
+static void run_from_file(const char *filename)
+{
+ BSTR script_str;
+ HRESULT hres;
+
+ script_str = get_script_from_file(filename);
+ if(!script_str)
+ return;
+
+ strict_dispid_check = FALSE;
+ hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str, NULL);
+ SysFreeString(script_str);
+ ok(hres == S_OK, "parse_script failed: %08x\n", hres);
+}
+
+static void run_from_res(const char *name)
+{
+ const char *data;
+ DWORD size, len;
+ BSTR str;
+ HRSRC src;
+ HRESULT hres;
+
+ strict_dispid_check = FALSE;
+ test_name = name;
+
+ src = FindResourceA(NULL, name, (LPCSTR)40);
+ ok(src != NULL, "Could not find resource %s\n", name);
+
+ size = SizeofResource(NULL, src);
+ data = LoadResource(NULL, src);
+
+ len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
+ str = SysAllocStringLen(NULL, len);
+ MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str, NULL);
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ ok(hres == S_OK, "parse_script failed: %08x\n", hres);
+ SysFreeString(str);
+}
+
+static void run_tests(void)
+{
+ HRESULT hres;
+
+ strict_dispid_check = TRUE;
+
+ parse_script_a("");
+ parse_script_a("' empty ;");
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_script_a("reportSuccess");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_script_a("reportSuccess()");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_script_a("Call reportSuccess");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_script_a("test.reportSuccess()");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ SET_EXPECT(global_vbvar_d);
+ SET_EXPECT(global_vbvar_i);
+ parse_script_a("Option Explicit\nvbvar = 3");
+ CHECK_CALLED(global_vbvar_d);
+ CHECK_CALLED(global_vbvar_i);
+
+ SET_EXPECT(global_vbvar_d);
+ SET_EXPECT(global_vbvar_i);
+ parse_script_a("Option Explicit\nvbvar() = 3");
+ CHECK_CALLED(global_vbvar_d);
+ CHECK_CALLED(global_vbvar_i);
+
+ SET_EXPECT(testobj_propget_d);
+ SET_EXPECT(testobj_propget_i);
+ parse_script_a("dim x\nx = testObj.propget");
+ CHECK_CALLED(testobj_propget_d);
+ CHECK_CALLED(testobj_propget_i);
+
+ SET_EXPECT(testobj_propput_d);
+ SET_EXPECT(testobj_propput_i);
+ parse_script_a("testObj.propput = 1");
+ CHECK_CALLED(testobj_propput_d);
+ CHECK_CALLED(testobj_propput_i);
+
+ SET_EXPECT(global_propargput_d);
+ SET_EXPECT(global_propargput_i);
+ parse_script_a("propargput(counter(), counter()) = counter()");
+ CHECK_CALLED(global_propargput_d);
+ CHECK_CALLED(global_propargput_i);
+
+ SET_EXPECT(global_propargput_d);
+ SET_EXPECT(global_propargput_i);
+ parse_script_a("test.propargput(counter(), counter()) = counter()");
+ CHECK_CALLED(global_propargput_d);
+ CHECK_CALLED(global_propargput_i);
+
+ SET_EXPECT(global_propargput1_d);
+ SET_EXPECT(global_propargput1_i);
+ parse_script_a("propargput1 (counter()) = counter()");
+ CHECK_CALLED(global_propargput1_d);
+ CHECK_CALLED(global_propargput1_i);
+
+ SET_EXPECT(global_propargput1_d);
+ SET_EXPECT(global_propargput1_i);
+ parse_script_a("test.propargput1(counter()) = counter()");
+ CHECK_CALLED(global_propargput1_d);
+ CHECK_CALLED(global_propargput1_i);
+
+ parse_htmlscript_a("<!--");
+ parse_htmlscript_a(" -->");
+ parse_htmlscript_a("<!--\ndim x\nx=1\n-->\n");
+ parse_htmlscript_a("<!--\ndim x\n-->\n<!--\nx=1\n-->\n");
+
+ hres = parse_script_ar("<!--");
+ ok(FAILED(hres), "script didn't fail\n");
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ parse_htmlscript_a("<!--\n<!-- ignore this <> <>\n--> <>\nCall reportSuccess()\n-->\n");
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ next_cnt = 0;
+ SET_EXPECT(collectionobj_newenum_i);
+ SET_EXPECT(Next);
+ parse_script_a("for each x in collectionObj\nnext");
+ CHECK_CALLED(collectionobj_newenum_i);
+ CHECK_CALLED(Next);
+ ok(next_cnt == 4, "next_cnt = %d\n", next_cnt);
+
+ parse_script_a("x = 1\n Call ok(x = 1, \"x = \" & x)");
+
+ parse_script_a("x = _ \n3");
+
+ test_global_vars_ref(TRUE);
+ test_global_vars_ref(FALSE);
+
+ strict_dispid_check = FALSE;
+
+ parse_script_a("Sub testsub\n"
+ "x = 1\n"
+ "Call ok(x = 1, \"x = \" & x)\n"
+ "End Sub\n"
+ "Call testsub()");
+
+ parse_script_a("Call ok(getVT(x) = \"VT_EMPTY*\", \"getVT(x) = \" & getVT(x))\n");
+ parse_script_a("Call ok(x = \"\", \"x = \" & x)\n");
+ parse_script_a("x = y\n"
+ "Call ok(getVT(x) = \"VT_EMPTY*\", \"getVT(x) = \" & getVT(x))\n"
+ "Call ok(getVT(y) = \"VT_EMPTY*\", \"getVT(y) = \" & getVT(y))");
+ hres = parse_script_ar("x = y(\"a\")");
+ ok(FAILED(hres), "script didn't fail\n");
+
+ run_from_res("lang.vbs");
+ run_from_res("api.vbs");
+ run_from_res("regexp.vbs");
+
+ test_procedures();
+ test_gc();
+ test_msgbox();
+}
+
+static BOOL check_vbscript(void)
+{
+ IRegExp2 *regexp;
+ IUnknown *unk;
+ HRESULT hres;
+
+ hres = CoCreateInstance(&CLSID_VBScriptRegExp, NULL,
+ CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+ &IID_IUnknown, (void**)&unk);
+ if(hres == REGDB_E_CLASSNOTREG)
+ return FALSE;
+ ok(hres == S_OK, "CoCreateInstance(CLSID_VBScriptRegExp) failed: %x\n", hres);
+
+ hres = IUnknown_QueryInterface(unk, &IID_IRegExp2, (void**)®exp);
+ if(SUCCEEDED(hres))
+ IRegExp2_Release(regexp);
+ IUnknown_Release(unk);
+
+ return hres == S_OK;
+}
+
+START_TEST(run)
+{
+ int argc;
+ char **argv;
+
+ is_english = is_lang_english();
+ if(!is_english)
+ skip("Skipping some tests in non-English locale\n");
+
+ argc = winetest_get_mainargs(&argv);
+
+ CoInitialize(NULL);
+
+ if(!check_vbscript()) {
+ win_skip("Broken engine, probably too old\n");
+ }else if(argc > 2) {
+ allow_ui = TRUE;
+ uic_handling = SCRIPTUICHANDLING_ALLOW;
+ run_from_file(argv[2]);
+ }else {
+ run_tests();
+ }
+
+ CoUninitialize();
+}
--- /dev/null
+/* Automatically generated file; DO NOT EDIT!! */
+
+#define STANDALONE
+#include <wine/test.h>
+
+extern void func_createobj(void);
+extern void func_run(void);
+extern void func_vbscript(void);
+
+const struct test winetest_testlist[] =
+{
+ { "createobj", func_createobj },
+ { "run", func_run },
+ { "vbscript", func_vbscript },
+ { 0, 0 }
+};
--- /dev/null
+/*
+ * Copyright 2011 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
+#include <initguid.h>
+#include <ole2.h>
+#include <activscp.h>
+#include <objsafe.h>
+#include <dispex.h>
+
+#include <vbsregexp55.h>
+
+#include <wine/test.h>
+
+#ifdef _WIN64
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+#define IActiveScriptParseProcedure2_Release \
+ IActiveScriptParseProcedure2_64_Release
+
+#else
+
+#define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+#define IActiveScriptParseProcedure2_Release \
+ IActiveScriptParseProcedure2_32_Release
+
+#endif
+
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+
+#define DEFINE_EXPECT(func) \
+ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+ expect_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+ do { \
+ ok(expect_ ##func, "unexpected call " #func "\n"); \
+ called_ ## func = TRUE; \
+ }while(0)
+
+#define CHECK_EXPECT(func) \
+ do { \
+ CHECK_EXPECT2(func); \
+ expect_ ## func = FALSE; \
+ }while(0)
+
+#define CHECK_CALLED(func) \
+ do { \
+ ok(called_ ## func, "expected " #func "\n"); \
+ expect_ ## func = called_ ## func = FALSE; \
+ }while(0)
+
+DEFINE_EXPECT(GetLCID);
+DEFINE_EXPECT(OnStateChange_UNINITIALIZED);
+DEFINE_EXPECT(OnStateChange_STARTED);
+DEFINE_EXPECT(OnStateChange_CONNECTED);
+DEFINE_EXPECT(OnStateChange_DISCONNECTED);
+DEFINE_EXPECT(OnStateChange_CLOSED);
+DEFINE_EXPECT(OnStateChange_INITIALIZED);
+DEFINE_EXPECT(OnEnterScript);
+DEFINE_EXPECT(OnLeaveScript);
+
+DEFINE_GUID(CLSID_VBScript, 0xb54f3741, 0x5b07, 0x11cf, 0xa4,0xb0, 0x00,0xaa,0x00,0x4a,0x55,0xe8);
+DEFINE_GUID(CLSID_VBScriptRegExp, 0x3f4daca4, 0x160d, 0x11d2, 0xa8,0xe9, 0x00,0x10,0x4b,0x36,0x5c,0x9f);
+
+static BSTR a2bstr(const char *str)
+{
+ BSTR ret;
+ int len;
+
+ len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ ret = SysAllocStringLen(NULL, len-1);
+ MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+
+ return ret;
+}
+
+#define test_state(s,ss) _test_state(__LINE__,s,ss)
+static void _test_state(unsigned line, IActiveScript *script, SCRIPTSTATE exstate)
+{
+ SCRIPTSTATE state = -1;
+ HRESULT hres;
+
+ hres = IActiveScript_GetScriptState(script, &state);
+ ok_(__FILE__,line) (hres == S_OK, "GetScriptState failed: %08x\n", hres);
+ ok_(__FILE__,line) (state == exstate, "state=%d, expected %d\n", state, exstate);
+}
+
+static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ if(IsEqualGUID(&IID_IUnknown, riid))
+ *ppv = iface;
+ else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
+ *ppv = iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
+{
+ CHECK_EXPECT(GetLCID);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
+ DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
+ const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
+{
+ switch(ssScriptState) {
+ case SCRIPTSTATE_UNINITIALIZED:
+ CHECK_EXPECT(OnStateChange_UNINITIALIZED);
+ return S_OK;
+ case SCRIPTSTATE_STARTED:
+ CHECK_EXPECT(OnStateChange_STARTED);
+ return S_OK;
+ case SCRIPTSTATE_CONNECTED:
+ CHECK_EXPECT(OnStateChange_CONNECTED);
+ return S_OK;
+ case SCRIPTSTATE_DISCONNECTED:
+ CHECK_EXPECT(OnStateChange_DISCONNECTED);
+ return S_OK;
+ case SCRIPTSTATE_CLOSED:
+ CHECK_EXPECT(OnStateChange_CLOSED);
+ return S_OK;
+ case SCRIPTSTATE_INITIALIZED:
+ CHECK_EXPECT(OnStateChange_INITIALIZED);
+ return S_OK;
+ default:
+ ok(0, "unexpected call %d\n", ssScriptState);
+ }
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
+{
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
+{
+ CHECK_EXPECT(OnEnterScript);
+ return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
+{
+ CHECK_EXPECT(OnLeaveScript);
+ return S_OK;
+}
+
+static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
+ ActiveScriptSite_QueryInterface,
+ ActiveScriptSite_AddRef,
+ ActiveScriptSite_Release,
+ ActiveScriptSite_GetLCID,
+ ActiveScriptSite_GetItemInfo,
+ ActiveScriptSite_GetDocVersionString,
+ ActiveScriptSite_OnScriptTerminate,
+ ActiveScriptSite_OnStateChange,
+ ActiveScriptSite_OnScriptError,
+ ActiveScriptSite_OnEnterScript,
+ ActiveScriptSite_OnLeaveScript
+};
+
+static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
+
+static void test_safety(IActiveScript *script)
+{
+ IObjectSafety *safety;
+ DWORD supported, enabled;
+ HRESULT hres;
+
+ hres = IActiveScript_QueryInterface(script, &IID_IObjectSafety, (void**)&safety);
+ ok(hres == S_OK, "Could not get IObjectSafety: %08x\n", hres);
+ if(FAILED(hres))
+ return;
+
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, NULL);
+ ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, NULL, &enabled);
+ ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "supported=%x\n", supported);
+ ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScript, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "supported=%x\n", supported);
+ ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "supported=%x\n", supported);
+ ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+ hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER
+ |INTERFACESAFE_FOR_UNTRUSTED_CALLER,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
+ ok(hres == E_FAIL, "SetInterfaceSafetyOptions failed: %08x, expected E_FAIL\n", hres);
+
+ hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
+ ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "supported=%x\n", supported);
+ ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "enabled=%x\n", enabled);
+
+ hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0);
+ ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "supported=%x\n", supported);
+ ok(enabled == (INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER), "enabled=%x\n", enabled);
+
+ hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER, 0);
+ ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "supported=%x\n", supported);
+ ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+ hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+ INTERFACE_USES_DISPEX, 0);
+ ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+ supported = enabled = 0xdeadbeef;
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+ ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+ ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+ "supported=%x\n", supported);
+ ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+ IObjectSafety_Release(safety);
+}
+
+static IDispatchEx *get_script_dispatch(IActiveScript *script)
+{
+ IDispatchEx *dispex;
+ IDispatch *disp;
+ HRESULT hres;
+
+ disp = (void*)0xdeadbeef;
+ hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
+ ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
+ if(FAILED(hres))
+ return NULL;
+
+ hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+ IDispatch_Release(disp);
+ ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
+ return dispex;
+}
+
+static void parse_script(IActiveScriptParse *parse, const char *src)
+{
+ BSTR str;
+ HRESULT hres;
+
+ SET_EXPECT(OnEnterScript);
+ SET_EXPECT(OnLeaveScript);
+
+ str = a2bstr(src);
+ hres = IActiveScriptParse_ParseScriptText(parse, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ SysFreeString(str);
+ ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+
+ CHECK_CALLED(OnEnterScript);
+ CHECK_CALLED(OnLeaveScript);
+}
+
+#define get_disp_id(a,b,c,d) _get_disp_id(__LINE__,a,b,c,d)
+static void _get_disp_id(unsigned line, IDispatchEx *dispex, const char *name, HRESULT exhres, DISPID *id)
+{
+ DISPID id2;
+ BSTR str;
+ HRESULT hres;
+
+ str = a2bstr(name);
+ hres = IDispatchEx_GetDispID(dispex, str, 0, id);
+ ok_(__FILE__,line)(hres == exhres, "GetDispID(%s) returned %08x, expected %08x\n", name, hres, exhres);
+
+ hres = IDispatchEx_GetIDsOfNames(dispex, &IID_NULL, &str, 1, 0, &id2);
+ SysFreeString(str);
+ ok_(__FILE__,line)(hres == exhres, "GetIDsOfNames(%s) returned %08x, expected %08x\n", name, hres, exhres);
+ ok_(__FILE__,line)(*id == id2, "GetIDsOfNames(%s) id != id2\n", name);
+}
+
+static void test_no_script_dispatch(IActiveScript *script)
+{
+ IDispatch *disp;
+ HRESULT hres;
+
+ disp = (void*)0xdeadbeef;
+ hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
+ ok(hres == E_UNEXPECTED, "hres = %08x, expected E_UNEXPECTED\n", hres);
+ ok(!disp, "disp != NULL\n");
+}
+
+static IActiveScript *create_vbscript(void)
+{
+ IActiveScript *ret;
+ HRESULT hres;
+
+ hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+ &IID_IActiveScript, (void**)&ret);
+ ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+
+ return ret;
+}
+
+static void test_scriptdisp(void)
+{
+ IActiveScriptParse *parser;
+ IDispatchEx *script_disp;
+ IActiveScript *vbscript;
+ DISPID id, id2;
+ DISPPARAMS dp;
+ EXCEPINFO ei;
+ VARIANT v;
+ ULONG ref;
+ HRESULT hres;
+
+ vbscript = create_vbscript();
+
+ hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hres);
+
+ test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
+ test_safety(vbscript);
+
+ SET_EXPECT(GetLCID);
+ hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+ CHECK_CALLED(GetLCID);
+
+ test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
+
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ test_state(vbscript, SCRIPTSTATE_INITIALIZED);
+
+ SET_EXPECT(OnStateChange_CONNECTED);
+ hres = IActiveScript_SetScriptState(vbscript, SCRIPTSTATE_CONNECTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_CONNECTED);
+
+ test_state(vbscript, SCRIPTSTATE_CONNECTED);
+
+ script_disp = get_script_dispatch(vbscript);
+
+ id = 100;
+ get_disp_id(script_disp, "LCase", DISP_E_UNKNOWNNAME, &id);
+ ok(id == -1, "id = %d, expected -1\n", id);
+
+ get_disp_id(script_disp, "globalVariable", DISP_E_UNKNOWNNAME, &id);
+ parse_script(parser, "dim globalVariable\nglobalVariable = 3");
+ get_disp_id(script_disp, "globalVariable", S_OK, &id);
+
+ memset(&dp, 0, sizeof(dp));
+ memset(&ei, 0, sizeof(ei));
+ V_VT(&v) = VT_EMPTY;
+ hres = IDispatchEx_InvokeEx(script_disp, id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I2(&v) == 3, "V_I2(v) = %d\n", V_I2(&v));
+
+ get_disp_id(script_disp, "globalVariable2", DISP_E_UNKNOWNNAME, &id);
+ parse_script(parser, "globalVariable2 = 4");
+ get_disp_id(script_disp, "globalVariable2", S_OK, &id);
+
+ get_disp_id(script_disp, "globalFunction", DISP_E_UNKNOWNNAME, &id);
+ parse_script(parser, "function globalFunction()\nglobalFunction=5\nend function");
+ get_disp_id(script_disp, "globalFunction", S_OK, &id);
+
+ SET_EXPECT(OnEnterScript);
+ SET_EXPECT(OnLeaveScript);
+
+ memset(&dp, 0, sizeof(dp));
+ memset(&ei, 0, sizeof(ei));
+ V_VT(&v) = VT_EMPTY;
+ hres = IDispatchEx_InvokeEx(script_disp, id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I2(&v) == 5, "V_I2(v) = %d\n", V_I2(&v));
+
+ CHECK_CALLED(OnEnterScript);
+ CHECK_CALLED(OnLeaveScript);
+
+ SET_EXPECT(OnEnterScript);
+ SET_EXPECT(OnLeaveScript);
+
+ memset(&dp, 0, sizeof(dp));
+ memset(&ei, 0, sizeof(ei));
+ V_VT(&v) = VT_EMPTY;
+ hres = IDispatchEx_Invoke(script_disp, id, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
+ ok(V_I2(&v) == 5, "V_I2(v) = %d\n", V_I2(&v));
+
+ CHECK_CALLED(OnEnterScript);
+ CHECK_CALLED(OnLeaveScript);
+
+ get_disp_id(script_disp, "globalSub", DISP_E_UNKNOWNNAME, &id);
+ parse_script(parser, "sub globalSub()\nend sub");
+ get_disp_id(script_disp, "globalSub", S_OK, &id);
+ get_disp_id(script_disp, "globalSub", S_OK, &id2);
+ ok(id == id2, "id != id2\n");
+
+ get_disp_id(script_disp, "constVariable", DISP_E_UNKNOWNNAME, &id);
+ parse_script(parser, "const constVariable = 6");
+ get_disp_id(script_disp, "ConstVariable", S_OK, &id);
+ get_disp_id(script_disp, "Constvariable", S_OK, &id2);
+ ok(id == id2, "id != id2\n");
+
+ IDispatchEx_Release(script_disp);
+
+ IActiveScriptParse_Release(parser);
+
+ SET_EXPECT(OnStateChange_DISCONNECTED);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ SET_EXPECT(OnStateChange_CLOSED);
+ hres = IActiveScript_Close(vbscript);
+ ok(hres == S_OK, "Close failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_DISCONNECTED);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+ CHECK_CALLED(OnStateChange_CLOSED);
+
+ ref = IActiveScript_Release(vbscript);
+ ok(!ref, "ref = %d\n", ref);
+}
+
+static void test_vbscript(void)
+{
+ IActiveScriptParseProcedure2 *parse_proc;
+ IActiveScriptParse *parser;
+ IActiveScript *vbscript;
+ ULONG ref;
+ HRESULT hres;
+
+ vbscript = create_vbscript();
+
+ hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hres);
+
+ test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
+ test_safety(vbscript);
+
+ SET_EXPECT(GetLCID);
+ hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+ CHECK_CALLED(GetLCID);
+
+ test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
+
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ test_state(vbscript, SCRIPTSTATE_INITIALIZED);
+
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
+
+ SET_EXPECT(OnStateChange_CONNECTED);
+ hres = IActiveScript_SetScriptState(vbscript, SCRIPTSTATE_CONNECTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_CONNECTED);
+
+ test_state(vbscript, SCRIPTSTATE_CONNECTED);
+
+ SET_EXPECT(OnStateChange_DISCONNECTED);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ SET_EXPECT(OnStateChange_CLOSED);
+ hres = IActiveScript_Close(vbscript);
+ ok(hres == S_OK, "Close failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_DISCONNECTED);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+ CHECK_CALLED(OnStateChange_CLOSED);
+
+ test_state(vbscript, SCRIPTSTATE_CLOSED);
+ test_no_script_dispatch(vbscript);
+
+ IActiveScriptParse_Release(parser);
+
+ hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParseProcedure, (void**)&parse_proc);
+ ok(hres == E_NOINTERFACE, "Got IActiveScriptParseProcedure interface, expected E_NOTIMPL\n");
+
+ hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
+ ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 interface\n");
+ IActiveScriptParseProcedure2_Release(parse_proc);
+
+ ref = IActiveScript_Release(vbscript);
+ ok(!ref, "ref = %d\n", ref);
+}
+
+static void test_vbscript_uninitializing(void)
+{
+ IActiveScriptParse *parse;
+ IActiveScript *script;
+ IDispatchEx *dispex;
+ ULONG ref;
+ HRESULT hres;
+
+ static const WCHAR script_textW[] =
+ {'F','u','n','c','t','i','o','n',' ','f','\n','E','n','d',' ','F','u','n','c','t','i','o','n','\n',0};
+
+ script = create_vbscript();
+
+ hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+ test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+ hres = IActiveScriptParse_InitNew(parse);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+ SET_EXPECT(GetLCID);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+ CHECK_CALLED(GetLCID);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ test_state(script, SCRIPTSTATE_INITIALIZED);
+
+ hres = IActiveScriptParse_ParseScriptText(parse, script_textW, NULL, NULL, NULL, 0, 1, 0x42, NULL, NULL);
+ ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
+
+ SET_EXPECT(OnStateChange_UNINITIALIZED);
+ hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_UNINITIALIZED);
+
+ test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+ hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
+
+ SET_EXPECT(GetLCID);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+ CHECK_CALLED(GetLCID);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ SET_EXPECT(OnStateChange_CONNECTED);
+ SET_EXPECT(OnEnterScript);
+ SET_EXPECT(OnLeaveScript);
+ hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_CONNECTED);
+ CHECK_CALLED(OnEnterScript);
+ CHECK_CALLED(OnLeaveScript);
+
+ test_state(script, SCRIPTSTATE_CONNECTED);
+
+ dispex = get_script_dispatch(script);
+ ok(dispex != NULL, "dispex == NULL\n");
+ if(dispex)
+ IDispatchEx_Release(dispex);
+
+ SET_EXPECT(OnStateChange_DISCONNECTED);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ SET_EXPECT(OnStateChange_UNINITIALIZED);
+ hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_DISCONNECTED);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+ CHECK_CALLED(OnStateChange_UNINITIALIZED);
+
+ test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+ hres = IActiveScript_Close(script);
+ ok(hres == S_OK, "Close failed: %08x\n", hres);
+
+ test_state(script, SCRIPTSTATE_CLOSED);
+
+ hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+ ok(hres == E_UNEXPECTED, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x, expected E_UNEXPECTED\n", hres);
+
+ test_state(script, SCRIPTSTATE_CLOSED);
+
+ SET_EXPECT(GetLCID);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+ CHECK_CALLED(GetLCID);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ test_state(script, SCRIPTSTATE_INITIALIZED);
+
+ SET_EXPECT(OnStateChange_CLOSED);
+ hres = IActiveScript_Close(script);
+ ok(hres == S_OK, "Close failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_CLOSED);
+
+ test_state(script, SCRIPTSTATE_CLOSED);
+
+ IActiveScriptParse_Release(parse);
+
+ ref = IActiveScript_Release(script);
+ ok(!ref, "ref = %d\n", ref);
+}
+
+static void test_vbscript_release(void)
+{
+ IActiveScriptParse *parser;
+ IActiveScript *vbscript;
+ ULONG ref;
+ HRESULT hres;
+
+ vbscript = create_vbscript();
+
+ hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hres);
+
+ test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
+ test_safety(vbscript);
+
+ SET_EXPECT(GetLCID);
+ hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+ CHECK_CALLED(GetLCID);
+
+ test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
+
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ test_state(vbscript, SCRIPTSTATE_INITIALIZED);
+
+ SET_EXPECT(OnStateChange_CONNECTED);
+ hres = IActiveScript_SetScriptState(vbscript, SCRIPTSTATE_CONNECTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_CONNECTED);
+
+ test_state(vbscript, SCRIPTSTATE_CONNECTED);
+
+ IActiveScriptParse_Release(parser);
+
+ SET_EXPECT(OnStateChange_DISCONNECTED);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ SET_EXPECT(OnStateChange_CLOSED);
+ ref = IActiveScript_Release(vbscript);
+ ok(!ref, "ref = %d\n", ref);
+ CHECK_CALLED(OnStateChange_DISCONNECTED);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+ CHECK_CALLED(OnStateChange_CLOSED);
+}
+
+static void test_vbscript_simplecreate(void)
+{
+ IActiveScript *script;
+ ULONG ref;
+ HRESULT hres;
+
+ script = create_vbscript();
+
+ hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
+
+ ref = IActiveScript_Release(script);
+ ok(!ref, "ref = %d\n", ref);
+}
+
+static void test_vbscript_initializing(void)
+{
+ IActiveScriptParse *parse;
+ IActiveScript *script;
+ ULONG ref;
+ HRESULT hres;
+
+ script = create_vbscript();
+
+ hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+ test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+ SET_EXPECT(GetLCID);
+ hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+ CHECK_CALLED(GetLCID);
+
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hres = IActiveScriptParse_InitNew(parse);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
+
+ SET_EXPECT(OnStateChange_CLOSED);
+ hres = IActiveScript_Close(script);
+ ok(hres == S_OK, "Close failed: %08x\n", hres);
+ CHECK_CALLED(OnStateChange_CLOSED);
+
+ test_state(script, SCRIPTSTATE_CLOSED);
+
+ IActiveScriptParse_Release(parse);
+
+ ref = IActiveScript_Release(script);
+ ok(!ref, "ref = %d\n", ref);
+}
+
+static void test_RegExp(void)
+{
+ IRegExp2 *regexp;
+ IMatchCollection2 *mc;
+ IMatch2 *match;
+ ISubMatches *sm;
+ IEnumVARIANT *ev;
+ IUnknown *unk;
+ IDispatch *disp;
+ HRESULT hres;
+ BSTR bstr;
+ LONG count;
+ VARIANT v;
+ ULONG fetched;
+
+ hres = CoCreateInstance(&CLSID_VBScriptRegExp, NULL,
+ CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+ &IID_IUnknown, (void**)&unk);
+ if(hres == REGDB_E_CLASSNOTREG) {
+ win_skip("VBScriptRegExp is not registered\n");
+ return;
+ }
+ ok(hres == S_OK, "CoCreateInstance(CLSID_VBScriptRegExp) failed: %x\n", hres);
+
+ hres = IUnknown_QueryInterface(unk, &IID_IRegExp2, (void**)®exp);
+ if(hres == E_NOINTERFACE) {
+ win_skip("IRegExp2 interface is not available\n");
+ return;
+ }
+ ok(hres == S_OK, "QueryInterface(IID_IRegExp2) failed: %x\n", hres);
+ IUnknown_Release(unk);
+
+ hres = IRegExp2_QueryInterface(regexp, &IID_IRegExp, (void**)&unk);
+ ok(hres == S_OK, "QueryInterface(IID_IRegExp) returned %x\n", hres);
+ IUnknown_Release(unk);
+
+ hres = IRegExp2_QueryInterface(regexp, &IID_IDispatchEx, (void**)&unk);
+ ok(hres == E_NOINTERFACE, "QueryInterface(IID_IDispatchEx) returned %x\n", hres);
+
+ hres = IRegExp2_get_Pattern(regexp, &bstr);
+ ok(bstr == NULL, "bstr != NULL\n");
+ ok(hres == S_OK, "get_Pattern returned %x, expected S_OK\n", hres);
+
+ hres = IRegExp2_get_Pattern(regexp, NULL);
+ ok(hres == E_POINTER, "get_Pattern returned %x, expected E_POINTER\n", hres);
+
+ hres = IRegExp2_get_IgnoreCase(regexp, NULL);
+ ok(hres == E_POINTER, "get_IgnoreCase returned %x, expected E_POINTER\n", hres);
+
+ hres = IRegExp2_get_Global(regexp, NULL);
+ ok(hres == E_POINTER, "get_Global returned %x, expected E_POINTER\n", hres);
+
+ hres = IRegExp2_Execute(regexp, NULL, &disp);
+ ok(hres == S_OK, "Execute returned %x, expected S_OK\n", hres);
+ hres = IDispatch_QueryInterface(disp, &IID_IMatchCollection2, (void**)&mc);
+ ok(hres == S_OK, "QueryInterface(IID_IMatchCollection2) returned %x\n", hres);
+ IDispatch_Release(disp);
+
+ hres = IMatchCollection2_get_Count(mc, NULL);
+ ok(hres == E_POINTER, "get_Count returned %x, expected E_POINTER\n", hres);
+
+ hres = IMatchCollection2_get_Count(mc, &count);
+ ok(hres == S_OK, "get_Count returned %x, expected S_OK\n", hres);
+ ok(count == 1, "count = %d\n", count);
+
+ hres = IMatchCollection2_get_Item(mc, 1, &disp);
+ ok(hres == E_INVALIDARG, "get_Item returned %x, expected E_INVALIDARG\n", hres);
+
+ hres = IMatchCollection2_get_Item(mc, 1, NULL);
+ ok(hres == E_POINTER, "get_Item returned %x, expected E_POINTER\n", hres);
+
+ hres = IMatchCollection2_get_Item(mc, 0, &disp);
+ ok(hres == S_OK, "get_Item returned %x, expected S_OK\n", hres);
+ hres = IDispatch_QueryInterface(disp, &IID_IMatch2, (void**)&match);
+ ok(hres == S_OK, "QueryInterface(IID_IMatch2) returned %x\n", hres);
+ IDispatch_Release(disp);
+
+ hres = IMatch2_get_Value(match, NULL);
+ ok(hres == E_POINTER, "get_Value returned %x, expected E_POINTER\n", hres);
+
+ hres = IMatch2_get_FirstIndex(match, NULL);
+ ok(hres == E_POINTER, "get_FirstIndex returned %x, expected E_POINTER\n", hres);
+
+ hres = IMatch2_get_Length(match, NULL);
+ ok(hres == E_POINTER, "get_Length returned %x, expected E_POINTER\n", hres);
+
+ hres = IMatch2_get_SubMatches(match, NULL);
+ ok(hres == E_POINTER, "get_SubMatches returned %x, expected E_POINTER\n", hres);
+
+ hres = IMatch2_get_SubMatches(match, &disp);
+ ok(hres == S_OK, "get_SubMatches returned %x, expected S_OK\n", hres);
+ IMatch2_Release(match);
+ hres = IDispatch_QueryInterface(disp, &IID_ISubMatches, (void**)&sm);
+ ok(hres == S_OK, "QueryInterface(IID_ISubMatches) returned %x\n", hres);
+ IDispatch_Release(disp);
+
+ hres = ISubMatches_get_Item(sm, 0, &v);
+ ok(hres == E_INVALIDARG, "get_Item returned %x, expected E_INVALIDARG\n", hres);
+
+ hres = ISubMatches_get_Item(sm, 0, NULL);
+ ok(hres == E_POINTER, "get_Item returned %x, expected E_POINTER\n", hres);
+
+ hres = ISubMatches_get_Count(sm, NULL);
+ ok(hres == E_POINTER, "get_Count returned %x, expected E_POINTER\n", hres);
+ ISubMatches_Release(sm);
+
+ hres = IMatchCollection2_get__NewEnum(mc, &unk);
+ ok(hres == S_OK, "get__NewEnum returned %x, expected S_OK\n", hres);
+ hres = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&ev);
+ ok(hres == S_OK, "QueryInterface(IID_IEnumVARIANT) returned %x\n", hres);
+ IUnknown_Release(unk);
+ IMatchCollection2_Release(mc);
+
+ hres = IEnumVARIANT_Skip(ev, 2);
+ ok(hres == S_OK, "Skip returned %x\n", hres);
+
+ hres = IEnumVARIANT_Next(ev, 1, &v, &fetched);
+ ok(hres == S_FALSE, "Next returned %x, expected S_FALSE\n", hres);
+ ok(fetched == 0, "fetched = %d\n", fetched);
+
+ hres = IEnumVARIANT_Skip(ev, -1);
+ ok(hres == S_OK, "Skip returned %x\n", hres);
+
+ hres = IEnumVARIANT_Next(ev, 1, &v, &fetched);
+ ok(hres == S_OK, "Next returned %x\n", hres);
+ ok(fetched == 1, "fetched = %d\n", fetched);
+ VariantClear(&v);
+ IEnumVARIANT_Release(ev);
+
+ IRegExp2_Release(regexp);
+}
+
+static BOOL check_vbscript(void)
+{
+ IActiveScriptParseProcedure2 *vbscript;
+ HRESULT hres;
+
+ hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+ &IID_IActiveScriptParseProcedure2, (void**)&vbscript);
+ if(SUCCEEDED(hres))
+ IActiveScriptParseProcedure2_Release(vbscript);
+
+ return hres == S_OK;
+}
+
+START_TEST(vbscript)
+{
+ CoInitialize(NULL);
+
+ if(check_vbscript()) {
+ test_vbscript();
+ test_vbscript_uninitializing();
+ test_vbscript_release();
+ test_vbscript_simplecreate();
+ test_vbscript_initializing();
+ test_scriptdisp();
+ test_RegExp();
+ }else {
+ win_skip("VBScript engine not available or too old\n");
+ }
+
+ CoUninitialize();
+}
--- /dev/null
+/*
+ * Copyright 2011 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define DISPID_SUBMATCHES_COUNT 1
+
+#define DISPID_MATCHCOLLECTION_COUNT 1
+
+#define DISPID_MATCH_FIRSTINDEX 10001
+#define DISPID_MATCH_LENGTH 10002
+#define DISPID_MATCH_SUBMATCHES 10003
+
+#define DISPID_REGEXP_PATTERN 10001
+#define DISPID_REGEXP_IGNORECASE 10002
+#define DISPID_REGEXP_GLOBAL 10003
+#define DISPID_REGEXP_EXECUTE 10004
+#define DISPID_REGEXP_TEST 10005
+#define DISPID_REGEXP_REPLACE 10006
+#define DISPID_REGEXP_MULTILINE 10007
--- /dev/null
+/*
+ * Copyright 2013 Piotr Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "oaidl.idl";
+
+#include "vbscript_defs.h"
+
+[
+ helpstring("Microsoft VBScript Regular Expressions 5.5"),
+ uuid(3f4daca7-160d-11d2-a8e9-00104b365c9f),
+ version(5.5)
+]
+library VBScript_RegExp_55
+{
+ importlib("stdole2.tlb");
+
+ [
+ dual,
+ hidden,
+ nonextensible,
+ odl,
+ oleautomation,
+ uuid(3f4daca0-160d-11d2-a8e9-00104b365c9f),
+ ]
+ interface IRegExp : IDispatch
+ {
+ [id(DISPID_REGEXP_PATTERN), propget]
+ HRESULT Pattern([out, retval] BSTR *pPattern);
+
+ [id(DISPID_REGEXP_PATTERN), propput]
+ HRESULT Pattern([in] BSTR pPattern);
+
+ [id(DISPID_REGEXP_IGNORECASE), propget]
+ HRESULT IgnoreCase([out, retval] VARIANT_BOOL *pIgnoreCase);
+
+ [id(DISPID_REGEXP_IGNORECASE), propput]
+ HRESULT IgnoreCase([in] VARIANT_BOOL pIgnoreCase);
+
+ [id(DISPID_REGEXP_GLOBAL), propget]
+ HRESULT Global([out, retval] VARIANT_BOOL *pGlobal);
+
+ [id(DISPID_REGEXP_GLOBAL), propput]
+ HRESULT Global([in] VARIANT_BOOL pGlobal);
+
+ [id(DISPID_REGEXP_EXECUTE)]
+ HRESULT Execute(
+ [in] BSTR sourceString,
+ [out, retval] IDispatch **ppMatches);
+
+ [id(DISPID_REGEXP_TEST)]
+ HRESULT Test(
+ [in] BSTR sourceString,
+ [out, retval] VARIANT_BOOL *pMatch);
+
+ [id(DISPID_REGEXP_REPLACE)]
+ HRESULT Replace(
+ [in] BSTR sourceString,
+ [in] BSTR replaceString,
+ [out, retval] BSTR *pDestString);
+ }
+
+ [
+ dual,
+ hidden,
+ nonextensible,
+ odl,
+ oleautomation,
+ uuid(3f4dacb0-160d-11d2-a8e9-00104b365c9f)
+ ]
+ interface IRegExp2 : IDispatch
+ {
+ [id(DISPID_REGEXP_PATTERN), propget]
+ HRESULT Pattern([out, retval] BSTR *pPattern);
+
+ [id(DISPID_REGEXP_PATTERN), propput]
+ HRESULT Pattern([in] BSTR pPattern);
+
+ [id(DISPID_REGEXP_IGNORECASE), propget]
+ HRESULT IgnoreCase([out, retval] VARIANT_BOOL *pIgnoreCase);
+
+ [id(DISPID_REGEXP_IGNORECASE), propput]
+ HRESULT IgnoreCase([in] VARIANT_BOOL pIgnoreCase);
+
+ [id(DISPID_REGEXP_GLOBAL), propget]
+ HRESULT Global([out, retval] VARIANT_BOOL *pGlobal);
+
+ [id(DISPID_REGEXP_GLOBAL), propput]
+ HRESULT Global([in] VARIANT_BOOL pGlobal);
+
+ [id(DISPID_REGEXP_MULTILINE), propget]
+ HRESULT Multiline([out, retval] VARIANT_BOOL *pMultiline);
+
+ [id(DISPID_REGEXP_MULTILINE), propput]
+ HRESULT Multiline([in] VARIANT_BOOL pMultiline);
+
+ [id(DISPID_REGEXP_EXECUTE)]
+ HRESULT Execute(
+ [in] BSTR sourceString,
+ [out, retval] IDispatch **ppMatches);
+
+ [id(DISPID_REGEXP_TEST)]
+ HRESULT Test(
+ [in] BSTR sourceString,
+ [out, retval] VARIANT_BOOL *pMatch);
+
+ [id(DISPID_REGEXP_REPLACE)]
+ HRESULT Replace(
+ [in] BSTR sourceString,
+ [in] VARIANT replaceVar,
+ [out, retval] BSTR *pDestString);
+ }
+
+ [
+ dual,
+ hidden,
+ nonextensible,
+ odl,
+ oleautomation,
+ uuid(3f4daca1-160d-11d2-a8e9-00104b365c9f)
+ ]
+ interface IMatch : IDispatch
+ {
+ [id(DISPID_VALUE), propget]
+ HRESULT Value([out, retval] BSTR *pValue);
+
+ [id(DISPID_MATCH_FIRSTINDEX), propget]
+ HRESULT FirstIndex([out, retval] LONG *pFirstIndex);
+
+ [id(DISPID_MATCH_LENGTH), propget]
+ HRESULT Length([out, retval] LONG *pLength);
+ }
+
+ [
+ odl,
+ uuid(3f4dacb1-160d-11d2-a8e9-00104b365c9f),
+ hidden,
+ dual,
+ nonextensible,
+ oleautomation
+ ]
+ interface IMatch2 : IDispatch
+ {
+ [id(DISPID_VALUE), propget]
+ HRESULT Value([out, retval] BSTR *pValue);
+
+ [id(DISPID_MATCH_FIRSTINDEX), propget]
+ HRESULT FirstIndex([out, retval] LONG *pFirstIndex);
+
+ [id(DISPID_MATCH_LENGTH), propget]
+ HRESULT Length([out, retval] LONG *pLength);
+
+ [id(DISPID_MATCH_SUBMATCHES), propget]
+ HRESULT SubMatches([out, retval] IDispatch **ppSubMatches);
+ }
+
+ [
+ dual,
+ hidden,
+ nonextensible,
+ odl,
+ oleautomation,
+ uuid(3f4daca2-160d-11d2-a8e9-00104b365c9f)
+ ]
+ interface IMatchCollection : IDispatch
+ {
+ [id(DISPID_VALUE), propget]
+ HRESULT Item(
+ [in] LONG index,
+ [out, retval] IDispatch **ppMatch);
+
+ [id(DISPID_MATCHCOLLECTION_COUNT), propget]
+ HRESULT Count([out, retval] LONG *pCount);
+
+ [id(DISPID_NEWENUM), propget]
+ HRESULT _NewEnum([out, retval] IUnknown **ppEnum);
+ }
+
+ [
+ dual,
+ hidden,
+ nonextensible,
+ odl,
+ oleautomation,
+ uuid(3f4dacb2-160d-11d2-a8e9-00104b365c9f)
+ ]
+ interface IMatchCollection2 : IDispatch
+ {
+ [id(DISPID_VALUE), propget]
+ HRESULT Item(
+ [in] LONG index,
+ [out, retval] IDispatch **ppMatch);
+
+ [id(DISPID_MATCHCOLLECTION_COUNT), propget]
+ HRESULT Count([out, retval] LONG *pCount);
+
+ [id(DISPID_NEWENUM), propget]
+ HRESULT _NewEnum([out, retval] IUnknown **ppEnum);
+ }
+
+ [
+ dual,
+ hidden,
+ nonextensible,
+ odl,
+ oleautomation,
+ uuid(3f4dacb3-160d-11d2-a8e9-00104b365c9f)
+ ]
+ interface ISubMatches : IDispatch
+ {
+ [id(DISPID_VALUE), propget]
+ HRESULT Item(
+ [in] LONG index,
+ [out, retval] VARIANT *pSubMatch);
+
+ [id(DISPID_SUBMATCHES_COUNT), propget]
+ HRESULT Count([out, retval] LONG *pCount);
+
+ [id(DISPID_NEWENUM), propget]
+ HRESULT _NewEnum([out, retval] IUnknown **ppEnum);
+ }
+
+ [
+ uuid(3f4daca4-160d-11d2-a8e9-00104b365c9f)
+ ]
+ coclass RegExp
+ {
+ [default] interface IRegExp2;
+ }
+
+ [
+ noncreatable,
+ uuid(3f4daca5-160d-11d2-a8e9-00104b365c9f)
+ ]
+ coclass Match
+ {
+ [default] interface IMatch2;
+ }
+
+ [
+ noncreatable,
+ uuid(3f4daca6-160d-11d2-a8e9-00104b365c9f)
+ ]
+ coclass MatchCollection
+ {
+ [default] interface IMatchCollection2;
+ }
+
+ [
+ noncreatable,
+ uuid(3f4dacc0-160d-11d2-a8e9-00104b365c9f)
+ ]
+ coclass SubMatches {
+ [default] interface ISubMatches;
+ }
+}