Andrew Eikum : oleaut32: Implement ITypeInfo2::GetCustData.

Alexandre Julliard julliard at winehq.org
Thu Aug 19 11:44:02 CDT 2010


Module: wine
Branch: master
Commit: 9d3e2f1b517594c85361c9916ba31a243a0a96cf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9d3e2f1b517594c85361c9916ba31a243a0a96cf

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Wed Aug 18 12:21:52 2010 -0500

oleaut32: Implement ITypeInfo2::GetCustData.

---

 dlls/oleaut32/tests/typelib.c |   36 ++++++++++++++-----
 dlls/oleaut32/typelib2.c      |   77 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index 9843327..0c7e9ab 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -1076,10 +1076,12 @@ static void test_CreateTypeLib(void) {
     static OLECHAR prop1W[] = {'P','r','o','p','1',0};
     static OLECHAR param1W[] = {'p','a','r','a','m','1',0};
     static OLECHAR param2W[] = {'p','a','r','a','m','2',0};
+    static OLECHAR asdfW[] = {'A','s','d','f',0};
     static OLECHAR *names1[] = {func1W, param1W, param2W};
     static OLECHAR *names2[] = {func2W, param1W, param2W};
     static OLECHAR *propname[] = {prop1W, param1W};
     static const GUID custguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}};
+    static const GUID bogusguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x71}};
 
     char filename[MAX_PATH];
     WCHAR filenameW[MAX_PATH];
@@ -1444,15 +1446,12 @@ static void test_CreateTypeLib(void) {
     ok(hres == S_OK, "got %08x\n", hres);
 
     hres = ITypeInfo2_GetCustData(ti2, NULL, NULL);
-    todo_wine
     ok(hres == E_INVALIDARG, "got %08x\n", hres);
 
     hres = ITypeInfo2_GetCustData(ti2, &custguid, NULL);
-    todo_wine
     ok(hres == E_INVALIDARG, "got %08x\n", hres);
 
     hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
-    todo_wine
     ok(hres == S_OK, "got %08x\n", hres);
 
     hres = ICreateTypeInfo2_SetCustData(createti2, NULL, NULL);
@@ -1474,12 +1473,9 @@ static void test_CreateTypeLib(void) {
     V_VT(&cust_data) = VT_EMPTY;
 
     hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
-    todo_wine
     ok(hres == S_OK, "got %08x\n", hres);
 
-    todo_wine
     ok(V_VT(&cust_data) == VT_UI4, "got %d\n", V_VT(&cust_data));
-    todo_wine
     ok(V_I4(&cust_data) == 0xdeadbeef, "got 0x%08x\n", V_I4(&cust_data));
 
     V_VT(&cust_data) = VT_UI4;
@@ -1492,14 +1488,36 @@ static void test_CreateTypeLib(void) {
     V_VT(&cust_data) = VT_EMPTY;
 
     hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
-    todo_wine
     ok(hres == S_OK, "got %08x\n", hres);
 
-    todo_wine
     ok(V_VT(&cust_data) == VT_UI4, "got %d\n", V_VT(&cust_data));
-    todo_wine
     ok(V_I4(&cust_data) == 12345678, "got 0x%08x\n", V_I4(&cust_data));
 
+    V_VT(&cust_data) = VT_BSTR;
+    V_BSTR(&cust_data) = SysAllocString(asdfW);
+
+    hres = ICreateTypeInfo2_SetCustData(createti2, &custguid, &cust_data);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    SysFreeString(V_BSTR(&cust_data));
+    V_I4(&cust_data) = 0;
+    V_VT(&cust_data) = VT_EMPTY;
+
+    hres = ITypeInfo2_GetCustData(ti2, &custguid, &cust_data);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    ok(V_VT(&cust_data) == VT_BSTR, "got %d\n", V_VT(&cust_data));
+    ok(!lstrcmpW(V_BSTR(&cust_data), asdfW), "got %s\n", wine_dbgstr_w(V_BSTR(&cust_data)));
+    SysFreeString(V_BSTR(&cust_data));
+
+    V_VT(&cust_data) = VT_UI4;
+    V_UI4(&cust_data) = 17;
+
+    hres = ITypeInfo2_GetCustData(ti2, &bogusguid, &cust_data);
+    ok(hres == S_OK, "got %08x\n", hres);
+
+    ok(V_VT(&cust_data) == VT_EMPTY, "got: %d\n", V_VT(&cust_data));
+
     ITypeInfo2_Release(ti2);
     ICreateTypeInfo2_Release(createti2);
     ICreateTypeInfo_Release(createti);
diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c
index 8009a68..d1b48ff 100644
--- a/dlls/oleaut32/typelib2.c
+++ b/dlls/oleaut32/typelib2.c
@@ -951,6 +951,64 @@ static int ctl2_find_custdata(
 }
 
 /****************************************************************************
+ *      ctl2_decode_variant
+ *
+ *  Decodes a variant
+ *
+ * RETURNS
+ *
+ *  Success: S_OK
+ *  Failure: Error code from winerror.h
+ */
+static HRESULT ctl2_decode_variant(
+        ICreateTypeLib2Impl *This, /* [I] The typelib that contains the variant */
+        int data_offs,             /* [I] Offset within the data array, or the encoded value itself */
+        VARIANT *value)            /* [O] Decoded value */
+{
+    char *encoded_data;
+    VARTYPE type;
+
+    if (data_offs & 0x80000000) {
+        /* data_offs contains the encoded value */
+        V_VT(value) = (data_offs & ~0x80000000) >> 26;
+        V_UI4(value) = data_offs & ~0xFF000000;
+        return S_OK;
+    }
+
+    encoded_data = &This->typelib_segment_data[MSFT_SEG_CUSTDATA][data_offs];
+    type = *encoded_data;
+
+    switch(type) {
+    case VT_I4:
+    case VT_R4:
+    case VT_UI4:
+    case VT_INT:
+    case VT_UINT:
+    case VT_HRESULT:
+    case VT_PTR: {
+        V_VT(value) = type;
+        V_UI4(value) = *(unsigned*)(encoded_data + 2);
+        return S_OK;
+    }
+    case VT_BSTR: {
+        unsigned len, i;
+
+        len = *(unsigned*)(encoded_data + 2);
+
+        V_VT(value) = type;
+        V_BSTR(value) = SysAllocStringByteLen(NULL, len * sizeof(OLECHAR));
+        for (i = 0; i < len; ++i)
+            V_BSTR(value)[i] = *(encoded_data + 6 + i);
+
+        return S_OK;
+    }
+    default:
+        FIXME("Don't yet have decoder for this VARTYPE: %u\n", type);
+        return E_NOTIMPL;
+    }
+}
+
+/****************************************************************************
  *	ctl2_set_custdata
  *
  *  Adds a custom data element to an object in a type library.
@@ -3610,8 +3668,23 @@ static HRESULT WINAPI ITypeInfo2_fnGetCustData(
         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
         VARIANT* pVarVal)  /* [O] The custom data. */
 {
-    FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal);
-    return E_OUTOFMEMORY;
+    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+    MSFT_CDGuid *cdentry;
+    int offset;
+
+    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);
+
+    if (!guid || !pVarVal)
+        return E_INVALIDARG;
+
+    VariantClear(pVarVal);
+
+    offset = ctl2_find_custdata(This->typelib, guid, This->typeinfo->oCustData);
+    if (offset == -1)
+        return S_OK;
+
+    cdentry = (MSFT_CDGuid *)&This->typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset];
+    return ctl2_decode_variant(This->typelib, cdentry->DataOffset, pVarVal);
 }
 
 /******************************************************************************




More information about the wine-cvs mailing list