Module: wine Branch: master Commit: 9d3e2f1b517594c85361c9916ba31a243a0a96cf URL: http://source.winehq.org/git/wine.git/?a=commit;h=9d3e2f1b517594c85361c9916b...
Author: Andrew Eikum aeikum@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); }
/******************************************************************************