summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--ext/win32ole/win32ole.c2
-rw-r--r--ext/win32ole/win32ole_variant.c45
-rw-r--r--test/win32ole/test_win32ole_variant.rb28
4 files changed, 80 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index e004ec5cb2..0615dd79e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Sep 6 16:38:08 2014 Masaki Suketa <masaki.suketa@nifty.ne.jp>
+
+ * ext/win32ole/win32ole_variant.c (ole_val2variant_err,
+ ole_val2variantdata, Init_win32ole_variant): support VT_ERROR
+ variant with error code. add WIN32OLE_VARIANT::NoParam.
+ * test/win32ole/test_win32ole_variant.rb(test_c_noparam,
+ test_vt_error_noparam): ditto.
+ * ext/win32ole/win32ole.c: ditto.
+
Sat Sep 6 11:08:52 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (arg_ambiguous_gen): fix warning message, "even" does
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index fee197dbce..3e037c52d8 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -26,7 +26,7 @@
const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
#endif
-#define WIN32OLE_VERSION "1.8.0"
+#define WIN32OLE_VERSION "1.8.1"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
diff --git a/ext/win32ole/win32ole_variant.c b/ext/win32ole/win32ole_variant.c
index 21de9b7264..b0cc5ee5df 100644
--- a/ext/win32ole/win32ole_variant.c
+++ b/ext/win32ole/win32ole_variant.c
@@ -2,6 +2,7 @@
static void olevariant_free(struct olevariantdata *pvar);
static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar);
+static void ole_val2variant_err(VALUE val, VARIANT *var);
static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt);
static VALUE folevariant_s_allocate(VALUE klass);
static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt);
@@ -83,6 +84,13 @@ ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar)
ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
}
#endif
+ } else if ( (vt & ~VT_BYREF) == VT_ERROR) {
+ ole_val2variant_err(val, &(pvar->realvar));
+ if (vt & VT_BYREF) {
+ ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
+ } else {
+ hr = VariantCopy(&(pvar->var), &(pvar->realvar));
+ }
} else {
if (val == Qnil) {
V_VT(&(pvar->var)) = vt;
@@ -122,6 +130,24 @@ ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar)
}
static void
+ole_val2variant_err(VALUE val, VARIANT *var)
+{
+ VALUE v = val;
+ if (rb_obj_is_kind_of(v, cWIN32OLE_VARIANT)) {
+ v = folevariant_value(v);
+ }
+ if (TYPE(v) != T_FIXNUM && TYPE(v) != T_BIGNUM && v != Qnil) {
+ rb_raise(eWIN32OLERuntimeError, "failed to convert VT_ERROR VARIANT:`%"PRIsVALUE"'", rb_inspect(v));
+ }
+ V_VT(var) = VT_ERROR;
+ if (v != Qnil) {
+ V_ERROR(var) = NUM2LONG(val);
+ } else {
+ V_ERROR(var) = 0;
+ }
+}
+
+static void
ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt)
{
V_VT(var) = vt;
@@ -654,15 +680,28 @@ Init_win32ole_variant()
/*
* represents VT_EMPTY OLE object.
*/
- rb_define_const(cWIN32OLE_VARIANT, "Empty", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY)));
+ rb_define_const(cWIN32OLE_VARIANT, "Empty",
+ rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY)));
/*
* represents VT_NULL OLE object.
*/
- rb_define_const(cWIN32OLE_VARIANT, "Null", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL)));
+ rb_define_const(cWIN32OLE_VARIANT, "Null",
+ rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL)));
/*
* represents Nothing of VB.NET or VB.
*/
- rb_define_const(cWIN32OLE_VARIANT, "Nothing", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH)));
+ rb_define_const(cWIN32OLE_VARIANT, "Nothing",
+ rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH)));
+
+ /*
+ * represents VT_ERROR variant with DISP_E_PARAMNOTFOUND.
+ * This constants is used for not specified parameter.
+ *
+ * fso = WIN32OLE.new("Scripting.FileSystemObject")
+ * fso.openTextFile(filename, WIN32OLE_VARIANT::NoParam, false)
+ */
+ rb_define_const(cWIN32OLE_VARIANT, "NoParam",
+ rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, INT2NUM(DISP_E_PARAMNOTFOUND), INT2FIX(VT_ERROR)));
}
diff --git a/test/win32ole/test_win32ole_variant.rb b/test/win32ole/test_win32ole_variant.rb
index a4edc0891c..8f53dbebac 100644
--- a/test/win32ole/test_win32ole_variant.rb
+++ b/test/win32ole/test_win32ole_variant.rb
@@ -679,6 +679,34 @@ if defined?(WIN32OLE_VARIANT)
assert_nil(WIN32OLE_VARIANT::Null.value)
end
+ def test_c_noparam
+ # DISP_E_PARAMNOTFOUND
+ assert_equal(-2147352572, WIN32OLE_VARIANT::NoParam.value)
+ end
+
+ def test_vt_error_noparam
+ v = WIN32OLE_VARIANT.new(-1, WIN32OLE::VARIANT::VT_ERROR)
+ assert_equal(-1, v.value)
+ fso = WIN32OLE.new("Scripting.FileSystemObject")
+ exc = assert_raise(WIN32OLERuntimeError) {
+ fso.openTextFile("NonExistingFile", v, false)
+ }
+ assert_match(/Type mismatch/i, exc.message)
+ exc = assert_raise(WIN32OLERuntimeError) {
+ fso.openTextFile("NonExistingFile", WIN32OLE_VARIANT::NoParam, false)
+ }
+ # 800A0035 is 'file not found' error.
+ assert_match(/800A0035/, exc.message)
+
+ # -2147352572 is DISP_E_PARAMNOTFOUND
+ v = WIN32OLE_VARIANT.new(-2147352572, WIN32OLE::VARIANT::VT_ERROR)
+ exc = assert_raise(WIN32OLERuntimeError) {
+ fso.openTextFile("NonExistingFile", WIN32OLE_VARIANT::NoParam, false)
+ }
+ # 800A0035 is 'file not found' error code.
+ assert_match(/800A0035/, exc.message)
+ end
+
end
end