From cf5a12527f08b1028ce24b2509114f34289114c3 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 26 Jan 2016 14:25:05 +0100 Subject: [PATCH] widl-SLTG_Typelib_Support: Implement decoding of SLTG help strings. --- patches/patchinstall.sh | 10 +- ...lement-decoding-of-SLTG-help-strings.patch | 245 ++++++++++++++++++ ...port-for-decoding-SLTG-function-help.patch | 113 ++++++++ ...port-for-decoding-SLTG-variable-help.patch | 95 +++++++ 4 files changed, 461 insertions(+), 2 deletions(-) create mode 100644 patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch create mode 100644 patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch create mode 100644 patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index aea5fb9b..2c5769e6 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -6002,8 +6002,8 @@ fi # Patchset widl-SLTG_Typelib_Support # | # | Modified files: -# | * dlls/oleaut32/typelib.c, tools/widl/Makefile.in, tools/widl/typelib.c, tools/widl/typelib.h, tools/widl/widl.c, -# | tools/widl/widl.h, tools/widl/write_sltg.c +# | * dlls/oleaut32/typelib.c, dlls/oleaut32/typelib.h, tools/widl/Makefile.in, tools/widl/typelib.c, tools/widl/typelib.h, +# | tools/widl/widl.c, tools/widl/widl.h, tools/widl/write_sltg.c # | if test "$enable_widl_SLTG_Typelib_Support" -eq 1; then patch_apply widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch @@ -6028,6 +6028,9 @@ if test "$enable_widl_SLTG_Typelib_Support" -eq 1; then patch_apply widl-SLTG_Typelib_Support/0020-widl-Set-the-lowest-bit-in-the-param-name-to-indicat.patch patch_apply widl-SLTG_Typelib_Support/0021-oleaut32-Fix-logic-for-deciding-whether-type-descrip.patch patch_apply widl-SLTG_Typelib_Support/0022-widl-Add-support-for-function-parameter-flags-to-SLT.patch + patch_apply widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch + patch_apply widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch + patch_apply widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch ( echo '+ { "Dmitry Timoshkov", "widl: Add initial implementation of SLTG typelib generator.", 1 },'; echo '+ { "Dmitry Timoshkov", "widl: Add support for structures.", 1 },'; @@ -6051,6 +6054,9 @@ if test "$enable_widl_SLTG_Typelib_Support" -eq 1; then echo '+ { "Dmitry Timoshkov", "widl: Set the lowest bit in the param name to indicate whether type description follows the name.", 1 },'; echo '+ { "Dmitry Timoshkov", "oleaut32: Fix logic for deciding whether type description follows the name.", 2 },'; echo '+ { "Dmitry Timoshkov", "widl: Add support for function parameter flags to SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Implement decoding of SLTG help strings.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Add support for decoding SLTG function help strings.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Add support for decoding SLTG variable help strings.", 1 },'; ) >> "$patchlist" fi diff --git a/patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch b/patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch new file mode 100644 index 00000000..5ff9dd8b --- /dev/null +++ b/patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch @@ -0,0 +1,245 @@ +From a0bdaee449916e202a5cac26f3e66c28d1566efb Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Jan 2016 15:05:54 +0800 +Subject: oleaut32: Implement decoding of SLTG help strings. + +Based on the patch by Sebastian Lackner . +--- + dlls/oleaut32/typelib.c | 130 +++++++++++++++++++++++++++++++++++++++--------- + dlls/oleaut32/typelib.h | 4 +- + 2 files changed, 109 insertions(+), 25 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index d8d8ec8..4fb5a95 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -3717,6 +3717,87 @@ static BOOL TLB_GUIDFromString(const char *str, GUID *guid) + return TRUE; + } + ++struct bitstream ++{ ++ const BYTE *buffer; ++ DWORD length; ++ WORD current; ++}; ++ ++static const char *lookup_code(const BYTE *table, DWORD table_size, struct bitstream *bits) ++{ ++ const BYTE *p = table; ++ ++ while (p < table + table_size && *p == 0x80) ++ { ++ if (p + 2 >= table + table_size) return NULL; ++ ++ if (!(bits->current & 0xff)) ++ { ++ if (!bits->length) return NULL; ++ bits->current = (*bits->buffer << 8) | 1; ++ bits->buffer++; ++ bits->length--; ++ } ++ ++ if (bits->current & 0x8000) ++ { ++ p += 3; ++ } ++ else ++ { ++ p = table + (*(p + 2) | (*(p + 1) << 8)); ++ } ++ ++ bits->current <<= 1; ++ } ++ ++ if (p + 1 < table + table_size && *(p + 1)) ++ { ++ /* FIXME: Whats the meaning of *p? */ ++ const BYTE *q = p + 1; ++ while (q < table + table_size && *q) q++; ++ return (q < table + table_size) ? (const char *)(p + 1) : NULL; ++ } ++ ++ return NULL; ++} ++ ++static const TLBString *decode_string(const BYTE *table, const char *stream, DWORD stream_length, ITypeLibImpl *lib) ++{ ++ DWORD buf_size, table_size; ++ const char *p; ++ struct bitstream bits; ++ BSTR buf; ++ TLBString *tlbstr; ++ ++ if (!stream_length) return NULL; ++ ++ bits.buffer = (const BYTE *)stream; ++ bits.length = stream_length; ++ bits.current = 0; ++ ++ buf_size = *(const WORD *)table; ++ table += sizeof(WORD); ++ table_size = *(const DWORD *)table; ++ table += sizeof(DWORD); ++ ++ buf = SysAllocStringLen(NULL, buf_size); ++ buf[0] = 0; ++ ++ while ((p = lookup_code(table, table_size, &bits))) ++ { ++ static const WCHAR spaceW[] = { ' ',0 }; ++ if (buf[0]) strcatW(buf, spaceW); ++ MultiByteToWideChar(CP_ACP, 0, p, -1, buf + strlenW(buf), buf_size - strlenW(buf)); ++ } ++ ++ tlbstr = TLB_append_str(&lib->string_list, buf); ++ SysFreeString(buf); ++ ++ return tlbstr; ++} ++ + static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib) + { + WORD bytelen; +@@ -4400,17 +4481,17 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more + manageable copy of it into this */ + typedef struct { +- WORD small_no; + char *index_name; + char *other_name; + WORD res1a; + WORD name_offs; +- WORD more_bytes; ++ WORD hlpstr_len; + char *extra; + WORD res20; + DWORD helpcontext; + WORD res26; + GUID uuid; ++ WORD typekind; + } SLTG_InternalOtherTypeInfo; + + /**************************************************************************** +@@ -4429,8 +4510,8 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + LPVOID pBlk, pFirstBlk; + SLTG_LibBlk *pLibBlk; + SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks; +- char *pAfterOTIBlks = NULL; + char *pNameTable, *ptr; ++ const BYTE *hlp_strings; + int i; + DWORD len, order; + ITypeInfoImpl **ppTypeInfoImpl; +@@ -4496,53 +4577,55 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + len += 0x40; + + /* And now TypeInfoCount of SLTG_OtherTypeInfo */ ++ pTypeLibImpl->TypeInfoCount = *(WORD *)((char *)pLibBlk + len); ++ len += sizeof(WORD); + + pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount); + +- + ptr = (char*)pLibBlk + len; + + for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) { + WORD w, extra; + len = 0; + +- pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr; +- +- w = *(WORD*)(ptr + 2); ++ w = *(WORD*)ptr; + if(w != 0xffff) { + len += w; + pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1); +- memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w); ++ memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 2, w); + pOtherTypeInfoBlks[i].index_name[w] = '\0'; + } +- w = *(WORD*)(ptr + 4 + len); ++ w = *(WORD*)(ptr + 2 + len); + if(w != 0xffff) { +- TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w)); +- len += w; ++ TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 4 + len, w)); + pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1); +- memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w); ++ memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 4 + len, w); + pOtherTypeInfoBlks[i].other_name[w] = '\0'; ++ len += w; + } +- pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6); +- pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); +- extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len); ++ pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + 4 + len); ++ pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + 6 + len); ++ extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len); + if(extra) { + pOtherTypeInfoBlks[i].extra = heap_alloc(extra); +- memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra); ++ memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10 + len, extra); + len += extra; + } +- pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len); +- pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len); +- pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len); +- memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID)); ++ pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 10 + len); ++ pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 12 + len); ++ pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 16 + len); ++ memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 18 + len, sizeof(GUID)); ++ pOtherTypeInfoBlks[i].typekind = *(WORD*)(ptr + 18 + sizeof(GUID) + len); + len += sizeof(SLTG_OtherTypeInfo); + ptr += len; + } + +- pAfterOTIBlks = ptr; ++ /* Get the next DWORD */ ++ len = *(DWORD*)ptr; + +- /* Skip this WORD and get the next DWORD */ +- len = *(DWORD*)(pAfterOTIBlks + 2); ++ hlp_strings = (const BYTE *)ptr + sizeof(DWORD); ++ TRACE("max help string length %#x, help strings length %#x\n", ++ *(WORD *)hlp_strings, *(DWORD *)(hlp_strings + 2)); + + /* Now add this to pLibBLk look at what we're pointing at and + possibly add 0x20, then add 0x216, sprinkle a bit a magic +@@ -4608,6 +4691,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + (*ppTypeInfoImpl)->index = i; + (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl); + (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext; ++ (*ppTypeInfoImpl)->DocString = decode_string(hlp_strings, pOtherTypeInfoBlks[i].extra, pOtherTypeInfoBlks[i].hlpstr_len, pTypeLibImpl); + (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2); + (*ppTypeInfoImpl)->typekind = pTIHeader->typekind; + (*ppTypeInfoImpl)->wMajorVerNum = pTIHeader->major_version; +diff --git a/dlls/oleaut32/typelib.h b/dlls/oleaut32/typelib.h +index 8f274ba..94ec8f2 100644 +--- a/dlls/oleaut32/typelib.h ++++ b/dlls/oleaut32/typelib.h +@@ -387,18 +387,18 @@ typedef struct { + /* we then get 0x40 bytes worth of 0xffff or small numbers followed by + nrOfFileBlks - 2 of these */ + typedef struct { +- WORD small_no; + SLTG_Name index_name; /* This refers to a name in the directory */ + SLTG_Name other_name; /* Another one of these weird names */ + WORD res1a; /* 0xffff */ + WORD name_offs; /* offset to name in name table */ +- WORD more_bytes; /* if this is non-zero we get this many ++ WORD hlpstr_len; /* if this is non-zero we get this many + bytes before the next element, which seem + to reference the docstring of the type ? */ + WORD res20; /* 0xffff */ + DWORD helpcontext; + WORD res26; /* 0xffff */ + GUID uuid; ++ WORD typekind; + } SLTG_OtherTypeInfo; + + /* Next we get WORD 0x0003 followed by a DWORD which if we add to +-- +2.6.4 + diff --git a/patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch b/patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch new file mode 100644 index 00000000..2fb6730c --- /dev/null +++ b/patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch @@ -0,0 +1,113 @@ +From 3d5236979b081ae707d7f047fbf9e24a3cd0e4cf Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Jan 2016 15:41:06 +0800 +Subject: oleaut32: Add support for decoding SLTG function help strings. + +--- + dlls/oleaut32/typelib.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index 4fb5a95..b9d8cbb 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -4240,7 +4240,8 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign + } + + static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, +- unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup) ++ unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup, ++ const BYTE *hlp_strings) + { + SLTG_Function *pFunc; + unsigned short i; +@@ -4277,6 +4278,8 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, + pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3; + pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; + pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1; ++ if (pFunc->helpstring != 0xffff) ++ pFuncDesc->HelpString = decode_string(hlp_strings, pBlk + pFunc->helpstring, pNameTable - pBlk, pTI->pTypeLib); + + if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT) + pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; +@@ -4364,7 +4367,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { + char *pFirstItem; + sltg_ref_lookup_t *ref_lookup = NULL; +@@ -4381,7 +4384,7 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, + } + + if (pTITail->funcs_off != 0xffff) +- SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); ++ SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + + heap_free(ref_lookup); + +@@ -4426,7 +4429,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { + sltg_ref_lookup_t *ref_lookup = NULL; + if (pTIHeader->href_table != 0xffffffff) +@@ -4437,7 +4440,7 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); + + if (pTITail->funcs_off != 0xffff) +- SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); ++ SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + + if (pTITail->impls_off != 0xffff) + SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup); +@@ -4461,7 +4464,7 @@ static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { + sltg_ref_lookup_t *ref_lookup = NULL; + if (pTIHeader->href_table != 0xffffffff) +@@ -4472,7 +4475,7 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); + + if (pTITail->funcs_off != 0xffff) +- SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); ++ SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + heap_free(ref_lookup); + if (TRACE_ON(typelib)) + dump_TypeInfo(pTI); +@@ -4734,7 +4737,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + + case TKIND_INTERFACE: + SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_COCLASS: +@@ -4749,12 +4752,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + + case TKIND_DISPATCH: + SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_MODULE: + SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + default: +-- +2.6.4 + diff --git a/patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch b/patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch new file mode 100644 index 00000000..58a621ac --- /dev/null +++ b/patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch @@ -0,0 +1,95 @@ +From 1d25ef1b6e9ef476686a3103604850ec5005b658 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Jan 2016 16:17:21 +0800 +Subject: oleaut32: Add support for decoding SLTG variable help strings. + +--- + dlls/oleaut32/typelib.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index b9d8cbb..6699e0b 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -4129,7 +4129,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, + } + + static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, +- const char *pNameTable, const sltg_ref_lookup_t *ref_lookup) ++ const char *pNameTable, const sltg_ref_lookup_t *ref_lookup, const BYTE *hlp_strings) + { + TLBVarDesc *pVarDesc; + const TLBString *prevName = NULL; +@@ -4159,6 +4159,12 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign + TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs); + TRACE_(typelib)("memid = 0x%x\n", pItem->memid); + ++ if (pItem->helpstring != 0xffff) ++ { ++ pVarDesc->HelpString = decode_string(hlp_strings, pBlk + pItem->helpstring, pNameTable - pBlk, pTI->pTypeLib); ++ TRACE_(typelib)("helpstring = %s\n", debugstr_w(pVarDesc->HelpString->str)); ++ } ++ + if(pItem->flags & 0x02) + pType = &pItem->type; + else +@@ -4394,9 +4400,9 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, + const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings); + } + + static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, +@@ -4437,7 +4443,7 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + pNameTable); + + if (pTITail->vars_off != 0xffff) +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings); + + if (pTITail->funcs_off != 0xffff) + SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); +@@ -4457,9 +4463,9 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, + const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings); + } + + static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, +@@ -4472,7 +4478,7 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + pNameTable); + + if (pTITail->vars_off != 0xffff) +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings); + + if (pTITail->funcs_off != 0xffff) + SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); +@@ -4727,12 +4733,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + switch(pTIHeader->typekind) { + case TKIND_ENUM: + SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_RECORD: + SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_INTERFACE: +-- +2.6.4 +