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