Piotr Caban : oleaut32: Added ITypeLib2_GetDocumentation implementation.
Alexandre Julliard
julliard at winehq.org
Thu Feb 25 11:36:22 CST 2010
Module: wine
Branch: master
Commit: 247b11e046d666cf1614348ea227efc262cfff57
URL: http://source.winehq.org/git/wine.git/?a=commit;h=247b11e046d666cf1614348ea227efc262cfff57
Author: Piotr Caban <piotr at codeweavers.com>
Date: Thu Feb 25 15:22:52 2010 +0100
oleaut32: Added ITypeLib2_GetDocumentation implementation.
---
dlls/oleaut32/tests/typelib.c | 26 ++++++++++++
dlls/oleaut32/typelib2.c | 88 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 111 insertions(+), 3 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index 1582bb2..40423f3 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -970,6 +970,7 @@ if(use_midl_tlb) {
static void test_CreateTypeLib(void) {
static const WCHAR stdoleW[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
+ static OLECHAR typelibW[] = {'t','y','p','e','l','i','b',0};
static OLECHAR interface1W[] = {'i','n','t','e','r','f','a','c','e','1',0};
static OLECHAR interface2W[] = {'i','n','t','e','r','f','a','c','e','2',0};
static OLECHAR coclassW[] = {'c','o','c','l','a','s','s',0};
@@ -994,6 +995,8 @@ static void test_CreateTypeLib(void) {
TYPEATTR *typeattr;
TLIBATTR *libattr;
HREFTYPE hreftype;
+ BSTR name, docstring, helpfile;
+ DWORD helpcontext;
int impltypeflags;
HRESULT hres;
@@ -1024,6 +1027,29 @@ static void test_CreateTypeLib(void) {
ITypeLib_ReleaseTLibAttr(tl, libattr);
+ name = (BSTR)0xdeadbeef;
+ hres = ITypeLib_GetDocumentation(tl, -1, &name, &docstring, &helpcontext, &helpfile);
+ ok(hres == S_OK, "got %08x\n", hres);
+ ok(name == NULL, "name != NULL\n");
+ ok(docstring == NULL, "docstring != NULL\n");
+ ok(helpcontext == 0, "helpcontext != 0\n");
+ ok(helpfile == NULL, "helpfile != NULL\n");
+
+ hres = ITypeLib_GetDocumentation(tl, 0, &name, NULL, NULL, NULL);
+ ok(hres == TYPE_E_ELEMENTNOTFOUND, "got %08x\n", hres);
+
+ hres = ICreateTypeLib_SetName(createtl, typelibW);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ hres = ITypeLib_GetDocumentation(tl, -1, NULL, NULL, NULL, NULL);
+ ok(hres == S_OK, "got %08x\n", hres);
+
+ hres = ITypeLib_GetDocumentation(tl, -1, &name, NULL, NULL, NULL);
+ ok(hres == S_OK, "got %08x\n", hres);
+ ok(!memcmp(name, typelibW, sizeof(typelibW)), "name = %s\n", wine_dbgstr_w(name));
+
+ SysFreeString(name);
+
ITypeLib_Release(tl);
hres = ICreateTypeLib_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti);
diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c
index 0f7f18b..ca4bda7 100644
--- a/dlls/oleaut32/typelib2.c
+++ b/dlls/oleaut32/typelib2.c
@@ -396,6 +396,27 @@ static int ctl2_encode_name(
}
/****************************************************************************
+ * ctl2_decode_name
+ *
+ * Converts string stored in typelib data to unicode.
+ */
+static void ctl2_decode_name(
+ char *data, /* [I] String to be decoded */
+ WCHAR **string) /* [O] Decoded string */
+{
+ int i, length;
+ static WCHAR converted_string[0x104];
+
+ length = data[0];
+
+ for(i=0; i<length; i++)
+ converted_string[i] = data[i+4];
+ converted_string[length] = '\0';
+
+ *string = converted_string;
+}
+
+/****************************************************************************
* ctl2_encode_string
*
* Encodes a string to a form suitable for storing into a type library or
@@ -443,7 +464,7 @@ static void ctl2_decode_string(
static WCHAR converted_string[0x104];
length = data[0] + (data[1]<<8);
- if(length & 1)
+ if((length&0x3) == 1)
length >>= 2;
for(i=0; i<length; i++)
@@ -4314,10 +4335,71 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
BSTR* pBstrHelpFile)
{
ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
+ WCHAR *string;
- FIXME("(%p,%d,%p,%p,%p,%p), stub!\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+ TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
- return E_OUTOFMEMORY;
+ if(index != -1) {
+ ICreateTypeInfo2Impl *iter;
+
+ for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
+ index--;
+
+ if(!iter)
+ return TYPE_E_ELEMENTNOTFOUND;
+
+ return ITypeInfo_GetDocumentation((ITypeInfo*)iter->lpVtblTypeInfo2,
+ -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+ }
+
+ if(pBstrName) {
+ if(This->typelib_header.NameOffset == -1)
+ *pBstrName = NULL;
+ else {
+ MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
+ typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];
+
+ ctl2_decode_name((char*)&name->namelen, &string);
+
+ *pBstrName = SysAllocString(string);
+ if(!*pBstrName)
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ if(pBstrDocString) {
+ if(This->typelib_header.helpstring == -1)
+ *pBstrDocString = NULL;
+ else {
+ ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);
+
+ *pBstrDocString = SysAllocString(string);
+ if(!*pBstrDocString) {
+ if(pBstrName) SysFreeString(*pBstrName);
+ return E_OUTOFMEMORY;
+ }
+ }
+ }
+
+ if(pdwHelpContext)
+ *pdwHelpContext = This->typelib_header.helpcontext;
+
+ if(pBstrHelpFile) {
+ if(This->typelib_header.helpfile == -1)
+ *pBstrHelpFile = NULL;
+ else {
+ ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);
+
+ *pBstrHelpFile = SysAllocString(string);
+ if(!*pBstrHelpFile) {
+ if(pBstrName) SysFreeString(*pBstrName);
+ if(pBstrDocString) SysFreeString(*pBstrDocString);
+ return E_OUTOFMEMORY;
+ }
+ }
+ }
+
+ return S_OK;
}
/******************************************************************************
More information about the wine-cvs
mailing list