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