static CRITICAL_SECTION cs_bstr_cache = { &cs_bstr_cache_dbg, -1, 0, 0, 0, 0 };
typedef struct {
+#ifdef _WIN64
+ DWORD pad;
+#endif
DWORD size;
union {
char ptr[1];
return CONTAINING_RECORD(str, bstr_t, u.str);
}
-static inline bstr_cache_entry_t *get_cache_entry(size_t size)
+static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx)
{
- unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size-1])/BUCKET_SIZE;
return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache)
? bstr_cache + cache_idx
: NULL;
}
+static inline bstr_cache_entry_t *get_cache_entry(size_t size)
+{
+ unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)-1])/BUCKET_SIZE;
+ return get_cache_entry_from_idx(cache_idx);
+}
+
+static inline bstr_cache_entry_t *get_cache_entry_from_alloc_size(SIZE_T alloc_size)
+{
+ unsigned cache_idx;
+ if (alloc_size < BUCKET_SIZE) return NULL;
+ cache_idx = (alloc_size - BUCKET_SIZE) / BUCKET_SIZE;
+ return get_cache_entry_from_idx(cache_idx);
+}
+
static bstr_t *alloc_bstr(size_t size)
{
- bstr_cache_entry_t *cache_entry = get_cache_entry(size+sizeof(WCHAR));
+ bstr_cache_entry_t *cache_entry = get_cache_entry(size);
bstr_t *ret;
if(cache_entry) {
EnterCriticalSection(&cs_bstr_cache);
if(!cache_entry->cnt) {
- cache_entry = get_cache_entry(size+sizeof(WCHAR)+BUCKET_SIZE);
+ cache_entry = get_cache_entry(size+BUCKET_SIZE);
if(cache_entry && !cache_entry->cnt)
cache_entry = NULL;
}
if(cache_entry) {
if(WARN_ON(heap)) {
- size_t tail;
-
- memset(ret, ARENA_INUSE_FILLER, FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)]));
- tail = bstr_alloc_size(size) - FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)]);
- if(tail)
- memset(ret->u.ptr+size+sizeof(WCHAR), ARENA_TAIL_FILLER, tail);
+ size_t fill_size = (FIELD_OFFSET(bstr_t, u.ptr[size])+2*sizeof(WCHAR)-1) & ~(sizeof(WCHAR)-1);
+ memset(ret, ARENA_INUSE_FILLER, fill_size);
+ memset((char *)ret+fill_size, ARENA_TAIL_FILLER, bstr_alloc_size(size)-fill_size);
}
ret->size = size;
return ret;
}
}
- ret = HeapAlloc(GetProcessHeap(), 0, bstr_alloc_size(size));
+ ret = CoTaskMemAlloc(bstr_alloc_size(size));
if(ret)
ret->size = size;
return ret;
return SysAllocStringLen(str, lstrlenW(str));
}
+static inline IMalloc *get_malloc(void)
+{
+ static IMalloc *malloc;
+
+ if (!malloc)
+ CoGetMalloc(1, &malloc);
+
+ return malloc;
+}
+
/******************************************************************************
* SysFreeString [OLEAUT32.6]
*
{
bstr_cache_entry_t *cache_entry;
bstr_t *bstr;
+ IMalloc *malloc = get_malloc();
+ SIZE_T alloc_size;
if(!str)
return;
bstr = bstr_from_str(str);
- cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR));
+
+ alloc_size = IMalloc_GetSize(malloc, bstr);
+ if (alloc_size == ~0UL)
+ return;
+
+ cache_entry = get_cache_entry_from_alloc_size(alloc_size);
if(cache_entry) {
unsigned i;
cache_entry->cnt++;
if(WARN_ON(heap)) {
- unsigned n = bstr_alloc_size(bstr->size) / sizeof(DWORD) - 1;
- bstr->size = ARENA_FREE_FILLER;
+ unsigned n = (alloc_size-FIELD_OFFSET(bstr_t, u.ptr))/sizeof(DWORD);
for(i=0; i<n; i++)
bstr->u.dwptr[i] = ARENA_FREE_FILLER;
}
LeaveCriticalSection(&cs_bstr_cache);
}
- HeapFree(GetProcessHeap(), 0, bstr);
+ CoTaskMemFree(bstr);
}
/******************************************************************************
{
/* Detect integer overflow. */
if (len >= ((UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))/sizeof(WCHAR)))
- return 0;
+ return FALSE;
if (*old!=NULL) {
- BSTR old_copy = *old;
DWORD newbytelen = len*sizeof(WCHAR);
- bstr_t *bstr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,bstr_alloc_size(newbytelen));
+ bstr_t *old_bstr = bstr_from_str(*old);
+ bstr_t *bstr = CoTaskMemRealloc(old_bstr, bstr_alloc_size(newbytelen));
+
+ if (!bstr) return FALSE;
+
*old = bstr->u.str;
bstr->size = newbytelen;
- /* Subtle hidden feature: The old string data is still there
- * when 'in' is NULL!
- * Some Microsoft program needs it.
- * FIXME: Is it a sideeffect of BSTR caching?
- */
- if (str && old_copy!=str) memmove(*old, str, newbytelen);
- (*old)[len] = 0;
+ /* The old string data is still there when str is NULL */
+ if (str && old_bstr->u.str != str) memmove(bstr->u.str, str, newbytelen);
+ bstr->u.str[len] = 0;
} else {
- /*
- * Allocate the new string
- */
*old = SysAllocStringLen(str, len);
}
- return 1;
+ return TRUE;
}
/******************************************************************************
if(str) {
memcpy(bstr->u.ptr, str, len);
- bstr->u.ptr[len] = bstr->u.ptr[len+1] = 0;
+ bstr->u.ptr[len] = 0;
}else {
- memset(bstr->u.ptr, 0, len+sizeof(WCHAR));
+ memset(bstr->u.ptr, 0, len+1);
}
+ bstr->u.str[(len+sizeof(WCHAR)-1)/sizeof(WCHAR)] = 0;
return bstr->u.str;
}
WCHAR *nameW;
DWORD len;
- if (tlib->major_version != wMaj || tlib->minor_version < wMin)
+ if ((wMaj != 0xffff || wMin != 0xffff) && (tlib->major_version != wMaj || tlib->minor_version < wMin))
return TYPE_E_LIBNOTREGISTERED;
nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
* Success: S_OK
* Failure: Status
*/
-HRESULT WINAPI CreateTypeLib(
- SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib
-) {
- FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
- return E_FAIL;
+HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR file, ICreateTypeLib **ctlib)
+{
+ ICreateTypeLib2 *typelib2;
+ HRESULT hres;
+
+ FIXME("(%d, %s, %p): forwarding to CreateTypeLib2\n", syskind, debugstr_w(file), ctlib);
+
+ hres = CreateTypeLib2(syskind, file, &typelib2);
+ if(SUCCEEDED(hres))
+ {
+ hres = ICreateTypeLib2_QueryInterface(typelib2, &IID_ICreateTypeLib, (void **)&ctlib);
+ ICreateTypeLib2_Release(typelib2);
+ }
+
+ return hres;
}
/******************************************************************************
res= LoadTypeLib(bstr, ppTLib);
SysFreeString(bstr);
- if (*ppTLib)
+ if ((wVerMajor!=0xffff || wVerMinor!=0xffff) && *ppTLib)
{
TLIBATTR *attr;
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;
}
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;
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
}
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;
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;
pArg = (WORD*)(pBlk + pFunc->arg_off);
for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
- char *paramName = pNameTable + *pArg;
+ char *paramName = pNameTable + (*pArg & ~1);
BOOL HaveOffs;
/* If arg type follows then paramName points to the 2nd
letter of the name, else the next WORD is an offset to
meaning that the next WORD is the type, the latter
meaning that the next WORD is an offset to the type. */
- HaveOffs = FALSE;
- if(*pArg == 0xffff)
+ if(*pArg == 0xffff || *pArg == 0xfffe)
paramName = NULL;
- else if(*pArg == 0xfffe) {
- paramName = NULL;
- HaveOffs = TRUE;
- }
- else if(paramName[-1] && !isalnum(paramName[-1]))
- HaveOffs = TRUE;
+ HaveOffs = !(*pArg & 1);
pArg++;
+ TRACE_(typelib)("param %d: paramName %s, *pArg %#x\n",
+ param, debugstr_a(paramName), *pArg);
+
if(HaveOffs) { /* the next word is an offset to type */
pType = (WORD*)(pBlk + *pArg);
SLTG_DoElem(pType, pBlk,
&pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
pArg++;
} else {
- if(paramName)
- paramName--;
pArg = SLTG_DoElem(pArg, pBlk,
&pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
}
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;
}
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);
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,
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)
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);
+ 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);
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,
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)
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);
+ 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);
/* 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;
/****************************************************************************
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;
/* We'll set up a ptr to the main library block, which is the last one. */
- for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0;
+ for(pBlk = pFirstBlk, order = pHeader->first_blk - 1;
pBlkEntry[order].next != 0;
- order = pBlkEntry[order].next - 1, i++) {
+ order = pBlkEntry[order].next - 1) {
pBlk = (char*)pBlk + pBlkEntry[order].len;
}
pLibBlk = pBlk;
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
(*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;
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:
SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
- pTIHeader, pTITail);
+ pTIHeader, pTITail, hlp_strings);
break;
case TKIND_COCLASS:
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:
{
WMSFT_SegContents *cdguids_seg = &file->cdguids_seg;
DWORD ret = cdguids_seg->len, offs;
- MSFT_CDGuid *cdguid = cdguids_seg->data;
+ MSFT_CDGuid *cdguid;
TLBCustData *cd;
if(list_empty(custdata_list))
cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list);
if(!cdguids_seg->data){
cdguid = cdguids_seg->data = heap_alloc(cdguids_seg->len);
- }else
+ }else {
cdguids_seg->data = heap_realloc(cdguids_seg->data, cdguids_seg->len);
+ cdguid = (MSFT_CDGuid*)((char*)cdguids_seg->data + ret);
+ }
offs = ret + sizeof(MSFT_CDGuid);
LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){
else
file.header.NameOffset = -1;
- file.header.CustomDataOffset = -1; /* TODO SetCustData not impl yet */
+ file.header.CustomDataOffset = WMSFT_compile_custdata(&This->custdata_list, &file);
if(This->guid)
file.header.posguid = This->guid->offset;
REFGUID guid, VARIANT *varVal)
{
ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
- FIXME("%p %s %p - stub\n", This, debugstr_guid(guid), varVal);
- return E_NOTIMPL;
+ TLBGuid *tlbguid;
+
+ TRACE("%p %s %p\n", This, debugstr_guid(guid), varVal);
+
+ if (!guid || !varVal)
+ return E_INVALIDARG;
+
+ tlbguid = TLB_append_guid(&This->guid_list, guid, -1);
+
+ return TLB_set_custdata(&This->custdata_list, tlbguid, varVal);
}
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 *iface,
ptr = *(DWORD*)Buffer;
Buffer += sizeof(DWORD);
- /* Clear any existing interface which WdtpInterfacePointer_UserUnmarshal()
- would try to release. This has been done already with a VariantClear(). */
- *ppunk = NULL;
-
if(!ptr)
return Buffer;
{
VariantClear(pvar);
V_BYREF(pvar) = CoTaskMemAlloc(mem_size);
+ memset(V_BYREF(pvar), 0, mem_size);
}
else if (!V_BYREF(pvar))
+ {
V_BYREF(pvar) = CoTaskMemAlloc(mem_size);
- memcpy(V_BYREF(pvar), Pos, type_size);
+ memset(V_BYREF(pvar), 0, mem_size);
+ }
+
+ if(!(header->vt & VT_ARRAY)
+ && (header->vt & VT_TYPEMASK) != VT_BSTR
+ && (header->vt & VT_TYPEMASK) != VT_VARIANT
+ && (header->vt & VT_TYPEMASK) != VT_UNKNOWN
+ && (header->vt & VT_TYPEMASK) != VT_DISPATCH
+ && (header->vt & VT_TYPEMASK) != VT_RECORD)
+ memcpy(V_BYREF(pvar), Pos, type_size);
+
if((header->vt & VT_TYPEMASK) != VT_VARIANT)
Pos += type_size;
else
else
{
VariantClear(pvar);
- if((header->vt & VT_TYPEMASK) == VT_DECIMAL)
+ if(header->vt & VT_ARRAY)
+ V_ARRAY(pvar) = NULL;
+ else if((header->vt & VT_TYPEMASK) == VT_BSTR)
+ V_BSTR(pvar) = NULL;
+ else if((header->vt & VT_TYPEMASK) == VT_UNKNOWN)
+ V_UNKNOWN(pvar) = NULL;
+ else if((header->vt & VT_TYPEMASK) == VT_DISPATCH)
+ V_DISPATCH(pvar) = NULL;
+ else if((header->vt & VT_TYPEMASK) == VT_RECORD)
+ V_RECORD(pvar) = NULL;
+ else if((header->vt & VT_TYPEMASK) == VT_DECIMAL)
memcpy(pvar, Pos, type_size);
else
memcpy(&pvar->n1.n2.n3, Pos, type_size);
switch (header->vt)
{
case VT_BSTR:
- V_BSTR(pvar) = NULL;
Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar));
break;
case VT_BSTR | VT_BYREF:
- *V_BSTRREF(pvar) = NULL;
Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar));
break;
case VT_VARIANT | VT_BYREF:
if (!ptr)
{
+ SafeArrayDestroy(*ppsa);
*ppsa = NULL;
TRACE("NULL safe array unmarshaled\n");
wiresab = (SAFEARRAYBOUND *)Buffer;
Buffer += sizeof(wiresab[0]) * wiresa->cDims;
- if(vt)
+ if(*ppsa && (*ppsa)->cDims==wiresa->cDims)
+ {
+ if(((*ppsa)->fFeatures & ~FADF_AUTOSETFLAGS) != (wiresa->fFeatures & ~FADF_AUTOSETFLAGS))
+ RpcRaiseException(DISP_E_BADCALLEE);
+
+ if(SAFEARRAY_GetCellCount(*ppsa)*(*ppsa)->cbElements != cell_count*elem_mem_size(wiresa, sftype))
+ {
+ if((*ppsa)->fFeatures & (FADF_AUTO|FADF_STATIC|FADF_EMBEDDED|FADF_FIXEDSIZE))
+ RpcRaiseException(DISP_E_BADCALLEE);
+
+ hr = SafeArrayDestroyData(*ppsa);
+ if(FAILED(hr))
+ RpcRaiseException(hr);
+ }
+ memcpy((*ppsa)->rgsabound, wiresab, sizeof(*wiresab)*wiresa->cDims);
+
+ if((*ppsa)->fFeatures & FADF_HAVEVARTYPE)
+ ((DWORD*)(*ppsa))[-1] = vt;
+ }
+ else if(vt)
{
+ SafeArrayDestroy(*ppsa);
*ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL);
if (!*ppsa) RpcRaiseException(E_OUTOFMEMORY);
}
else
{
+ SafeArrayDestroy(*ppsa);
if (FAILED(SafeArrayAllocDescriptor(wiresa->cDims, ppsa)))
RpcRaiseException(E_OUTOFMEMORY);
memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims);
(*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS));
/* FIXME: there should be a limit on how large wiresa->cbElements can be */
(*ppsa)->cbElements = elem_mem_size(wiresa, sftype);
- (*ppsa)->cLocks = 0;
/* SafeArrayCreateEx allocates the data for us, but
* SafeArrayAllocDescriptor doesn't */
- if(!vt)
+ if(!(*ppsa)->pvData)
{
hr = SafeArrayAllocData(*ppsa);
if (FAILED(hr))
TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa);
SafeArrayDestroy(*ppsa);
+ *ppsa = NULL;
}