From: Dmitry Timoshkov dmitry@baikal.ru
Based on a patch by Sebastian Lackner sebastian@fds-team.de.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/oleaut32/typelib.c | 91 ++++++++++++++++++++++++++++++++++++++++- dlls/oleaut32/typelib.h | 2 +- 2 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index bdf8232408f..323d2ed848c 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -3667,6 +3667,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]) lstrcatW(buf, spaceW); + MultiByteToWideChar(CP_ACP, 0, p, -1, buf + lstrlenW(buf), buf_size - lstrlenW(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; @@ -4357,7 +4438,7 @@ typedef struct { char *other_name; WORD res1a; WORD name_offs; - WORD more_bytes; + WORD hlpstr_len; char *extra; WORD res20; DWORD helpcontext; @@ -4383,6 +4464,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) SLTG_LibBlk *pLibBlk; SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks; char *pNameTable, *ptr; + const BYTE *hlp_strings; int i; DWORD len, order; ITypeInfoImpl **ppTypeInfoImpl; @@ -4476,7 +4558,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) } pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 4); pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); - extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 8 + len); + extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len); if(extra) { pOtherTypeInfoBlks[i].extra = malloc(extra); memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10, extra); @@ -4494,6 +4576,10 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) /* Get the next DWORD */ len = *(DWORD*)ptr;
+ hlp_strings = (const BYTE *)ptr + sizeof(DWORD); + TRACE("max help string length %#x, help strings length %#lx\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 dust and we should be pointing at the beginning of the name @@ -4558,6 +4644,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)->typeattr.typekind = pTIHeader->typekind; (*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version; diff --git a/dlls/oleaut32/typelib.h b/dlls/oleaut32/typelib.h index 2762cae70ad..bfe908c035f 100644 --- a/dlls/oleaut32/typelib.h +++ b/dlls/oleaut32/typelib.h @@ -386,7 +386,7 @@ typedef struct { 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 */