[OLEAUT32] Sync with Wine Staging 1.9.4. CORE-10912

svn path=/trunk/; revision=70903
This commit is contained in:
Amine Khaldi 2016-03-04 09:33:34 +00:00
parent 0a2db0a106
commit 5567f3cf36
8 changed files with 292 additions and 127 deletions

View file

@ -67,6 +67,9 @@ static CRITICAL_SECTION_DEBUG cs_bstr_cache_dbg =
static CRITICAL_SECTION cs_bstr_cache = { &cs_bstr_cache_dbg, -1, 0, 0, 0, 0 }; static CRITICAL_SECTION cs_bstr_cache = { &cs_bstr_cache_dbg, -1, 0, 0, 0, 0 };
typedef struct { typedef struct {
#ifdef _WIN64
DWORD pad;
#endif
DWORD size; DWORD size;
union { union {
char ptr[1]; char ptr[1];
@ -100,24 +103,37 @@ static inline bstr_t *bstr_from_str(BSTR str)
return CONTAINING_RECORD(str, bstr_t, u.str); 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) return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache)
? bstr_cache + cache_idx ? bstr_cache + cache_idx
: NULL; : 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) 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; bstr_t *ret;
if(cache_entry) { if(cache_entry) {
EnterCriticalSection(&cs_bstr_cache); EnterCriticalSection(&cs_bstr_cache);
if(!cache_entry->cnt) { 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) if(cache_entry && !cache_entry->cnt)
cache_entry = NULL; cache_entry = NULL;
} }
@ -132,19 +148,16 @@ static bstr_t *alloc_bstr(size_t size)
if(cache_entry) { if(cache_entry) {
if(WARN_ON(heap)) { if(WARN_ON(heap)) {
size_t 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(ret, ARENA_INUSE_FILLER, FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)])); memset((char *)ret+fill_size, ARENA_TAIL_FILLER, bstr_alloc_size(size)-fill_size);
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);
} }
ret->size = size; ret->size = size;
return ret; return ret;
} }
} }
ret = HeapAlloc(GetProcessHeap(), 0, bstr_alloc_size(size)); ret = CoTaskMemAlloc(bstr_alloc_size(size));
if(ret) if(ret)
ret->size = size; ret->size = size;
return ret; return ret;
@ -217,6 +230,16 @@ BSTR WINAPI SysAllocString(LPCOLESTR str)
return SysAllocStringLen(str, lstrlenW(str)); return SysAllocStringLen(str, lstrlenW(str));
} }
static inline IMalloc *get_malloc(void)
{
static IMalloc *malloc;
if (!malloc)
CoGetMalloc(1, &malloc);
return malloc;
}
/****************************************************************************** /******************************************************************************
* SysFreeString [OLEAUT32.6] * SysFreeString [OLEAUT32.6]
* *
@ -236,12 +259,19 @@ void WINAPI SysFreeString(BSTR str)
{ {
bstr_cache_entry_t *cache_entry; bstr_cache_entry_t *cache_entry;
bstr_t *bstr; bstr_t *bstr;
IMalloc *malloc = get_malloc();
SIZE_T alloc_size;
if(!str) if(!str)
return; return;
bstr = bstr_from_str(str); 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) { if(cache_entry) {
unsigned i; unsigned i;
@ -262,8 +292,7 @@ void WINAPI SysFreeString(BSTR str)
cache_entry->cnt++; cache_entry->cnt++;
if(WARN_ON(heap)) { if(WARN_ON(heap)) {
unsigned n = bstr_alloc_size(bstr->size) / sizeof(DWORD) - 1; unsigned n = (alloc_size-FIELD_OFFSET(bstr_t, u.ptr))/sizeof(DWORD);
bstr->size = ARENA_FREE_FILLER;
for(i=0; i<n; i++) for(i=0; i<n; i++)
bstr->u.dwptr[i] = ARENA_FREE_FILLER; bstr->u.dwptr[i] = ARENA_FREE_FILLER;
} }
@ -275,7 +304,7 @@ void WINAPI SysFreeString(BSTR str)
LeaveCriticalSection(&cs_bstr_cache); LeaveCriticalSection(&cs_bstr_cache);
} }
HeapFree(GetProcessHeap(), 0, bstr); CoTaskMemFree(bstr);
} }
/****************************************************************************** /******************************************************************************
@ -342,29 +371,25 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
{ {
/* Detect integer overflow. */ /* Detect integer overflow. */
if (len >= ((UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))/sizeof(WCHAR))) if (len >= ((UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))/sizeof(WCHAR)))
return 0; return FALSE;
if (*old!=NULL) { if (*old!=NULL) {
BSTR old_copy = *old;
DWORD newbytelen = len*sizeof(WCHAR); 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; *old = bstr->u.str;
bstr->size = newbytelen; bstr->size = newbytelen;
/* Subtle hidden feature: The old string data is still there /* The old string data is still there when str is NULL */
* when 'in' is NULL! if (str && old_bstr->u.str != str) memmove(bstr->u.str, str, newbytelen);
* Some Microsoft program needs it. bstr->u.str[len] = 0;
* FIXME: Is it a sideeffect of BSTR caching?
*/
if (str && old_copy!=str) memmove(*old, str, newbytelen);
(*old)[len] = 0;
} else { } else {
/*
* Allocate the new string
*/
*old = SysAllocStringLen(str, len); *old = SysAllocStringLen(str, len);
} }
return 1; return TRUE;
} }
/****************************************************************************** /******************************************************************************
@ -401,10 +426,11 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
if(str) { if(str) {
memcpy(bstr->u.ptr, str, len); memcpy(bstr->u.ptr, str, len);
bstr->u.ptr[len] = bstr->u.ptr[len+1] = 0; bstr->u.ptr[len] = 0;
}else { }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; return bstr->u.str;
} }

View file

@ -452,7 +452,7 @@ static HRESULT WINAPI OLEPictureImpl_QueryInterface(
if (!*ppvObject) if (!*ppvObject)
{ {
FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid)); FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
return E_NOINTERFACE; return E_NOINTERFACE;
} }

View file

@ -58,12 +58,14 @@ xbuf_resize(marshal_state *buf, DWORD newsize)
if(buf->base) if(buf->base)
{ {
newsize = max(newsize, buf->size * 2);
buf->base = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf->base, newsize); buf->base = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf->base, newsize);
if(!buf->base) if(!buf->base)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
else else
{ {
newsize = max(newsize, 256);
buf->base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newsize); buf->base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newsize);
if(!buf->base) if(!buf->base)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -79,7 +81,7 @@ xbuf_add(marshal_state *buf, const BYTE *stuff, DWORD size)
if(buf->size - buf->curoff < size) if(buf->size - buf->curoff < size)
{ {
hr = xbuf_resize(buf, buf->size + size + 100); hr = xbuf_resize(buf, buf->size + size);
if(FAILED(hr)) return hr; if(FAILED(hr)) return hr;
} }
memcpy(buf->base+buf->curoff,stuff,size); memcpy(buf->base+buf->curoff,stuff,size);

View file

@ -302,7 +302,7 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin,
WCHAR *nameW; WCHAR *nameW;
DWORD len; 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; return TYPE_E_LIBNOTREGISTERED;
nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset); nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
@ -403,11 +403,21 @@ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID l
* Success: S_OK * Success: S_OK
* Failure: Status * Failure: Status
*/ */
HRESULT WINAPI CreateTypeLib( HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR file, ICreateTypeLib **ctlib)
SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib {
) { ICreateTypeLib2 *typelib2;
FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib); HRESULT hres;
return E_FAIL;
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;
} }
/****************************************************************************** /******************************************************************************
@ -515,7 +525,7 @@ HRESULT WINAPI LoadRegTypeLib(
res= LoadTypeLib(bstr, ppTLib); res= LoadTypeLib(bstr, ppTLib);
SysFreeString(bstr); SysFreeString(bstr);
if (*ppTLib) if ((wVerMajor!=0xffff || wVerMinor!=0xffff) && *ppTLib)
{ {
TLIBATTR *attr; TLIBATTR *attr;
@ -3696,6 +3706,87 @@ static BOOL TLB_GUIDFromString(const char *str, GUID *guid)
return TRUE; 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) static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib)
{ {
WORD bytelen; WORD bytelen;
@ -4027,7 +4118,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
} }
static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, 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; TLBVarDesc *pVarDesc;
const TLBString *prevName = NULL; const TLBString *prevName = NULL;
@ -4057,6 +4148,12 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs); TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs);
TRACE_(typelib)("memid = 0x%x\n", pItem->memid); 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) if(pItem->flags & 0x02)
pType = &pItem->type; pType = &pItem->type;
else else
@ -4138,7 +4235,8 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
} }
static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, 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; SLTG_Function *pFunc;
unsigned short i; unsigned short i;
@ -4175,6 +4273,8 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3; pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~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) if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT)
pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
@ -4193,7 +4293,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
pArg = (WORD*)(pBlk + pFunc->arg_off); pArg = (WORD*)(pBlk + pFunc->arg_off);
for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) { for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
char *paramName = pNameTable + *pArg; char *paramName = pNameTable + (*pArg & ~1);
BOOL HaveOffs; BOOL HaveOffs;
/* If arg type follows then paramName points to the 2nd /* If arg type follows then paramName points to the 2nd
letter of the name, else the next WORD is an offset to letter of the name, else the next WORD is an offset to
@ -4204,26 +4304,21 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
meaning that the next WORD is the type, the latter meaning that the next WORD is the type, the latter
meaning that the next WORD is an offset to the type. */ meaning that the next WORD is an offset to the type. */
HaveOffs = FALSE; if(*pArg == 0xffff || *pArg == 0xfffe)
if(*pArg == 0xffff)
paramName = NULL; paramName = NULL;
else if(*pArg == 0xfffe) {
paramName = NULL;
HaveOffs = TRUE;
}
else if(paramName[-1] && !isalnum(paramName[-1]))
HaveOffs = TRUE;
HaveOffs = !(*pArg & 1);
pArg++; 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 */ if(HaveOffs) { /* the next word is an offset to type */
pType = (WORD*)(pBlk + *pArg); pType = (WORD*)(pBlk + *pArg);
SLTG_DoElem(pType, pBlk, SLTG_DoElem(pType, pBlk,
&pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
pArg++; pArg++;
} else { } else {
if(paramName)
paramName--;
pArg = SLTG_DoElem(pArg, pBlk, pArg = SLTG_DoElem(pArg, pBlk,
&pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
} }
@ -4267,7 +4362,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
char *pFirstItem; char *pFirstItem;
sltg_ref_lookup_t *ref_lookup = NULL; sltg_ref_lookup_t *ref_lookup = NULL;
@ -4284,7 +4379,7 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
} }
if (pTITail->funcs_off != 0xffff) 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); heap_free(ref_lookup);
@ -4294,9 +4389,9 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, 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_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
@ -4329,7 +4424,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
sltg_ref_lookup_t *ref_lookup = NULL; sltg_ref_lookup_t *ref_lookup = NULL;
if (pTIHeader->href_table != 0xffffffff) if (pTIHeader->href_table != 0xffffffff)
@ -4337,10 +4432,10 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
pNameTable); pNameTable);
if (pTITail->vars_off != 0xffff) 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) 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) if (pTITail->impls_off != 0xffff)
SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup); SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
@ -4357,14 +4452,14 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, 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, static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
const SLTG_TypeInfoTail *pTITail) const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
{ {
sltg_ref_lookup_t *ref_lookup = NULL; sltg_ref_lookup_t *ref_lookup = NULL;
if (pTIHeader->href_table != 0xffffffff) if (pTIHeader->href_table != 0xffffffff)
@ -4372,10 +4467,10 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
pNameTable); pNameTable);
if (pTITail->vars_off != 0xffff) 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) 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); heap_free(ref_lookup);
if (TRACE_ON(typelib)) if (TRACE_ON(typelib))
dump_TypeInfo(pTI); dump_TypeInfo(pTI);
@ -4384,17 +4479,17 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
manageable copy of it into this */ manageable copy of it into this */
typedef struct { typedef struct {
WORD small_no;
char *index_name; char *index_name;
char *other_name; char *other_name;
WORD res1a; WORD res1a;
WORD name_offs; WORD name_offs;
WORD more_bytes; WORD hlpstr_len;
char *extra; char *extra;
WORD res20; WORD res20;
DWORD helpcontext; DWORD helpcontext;
WORD res26; WORD res26;
GUID uuid; GUID uuid;
WORD typekind;
} SLTG_InternalOtherTypeInfo; } SLTG_InternalOtherTypeInfo;
/**************************************************************************** /****************************************************************************
@ -4413,8 +4508,8 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
LPVOID pBlk, pFirstBlk; LPVOID pBlk, pFirstBlk;
SLTG_LibBlk *pLibBlk; SLTG_LibBlk *pLibBlk;
SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks; SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks;
char *pAfterOTIBlks = NULL;
char *pNameTable, *ptr; char *pNameTable, *ptr;
const BYTE *hlp_strings;
int i; int i;
DWORD len, order; DWORD len, order;
ITypeInfoImpl **ppTypeInfoImpl; ITypeInfoImpl **ppTypeInfoImpl;
@ -4465,9 +4560,9 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
/* We'll set up a ptr to the main library block, which is the last one. */ /* 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; pBlkEntry[order].next != 0;
order = pBlkEntry[order].next - 1, i++) { order = pBlkEntry[order].next - 1) {
pBlk = (char*)pBlk + pBlkEntry[order].len; pBlk = (char*)pBlk + pBlkEntry[order].len;
} }
pLibBlk = pBlk; pLibBlk = pBlk;
@ -4480,53 +4575,55 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
len += 0x40; len += 0x40;
/* And now TypeInfoCount of SLTG_OtherTypeInfo */ /* And now TypeInfoCount of SLTG_OtherTypeInfo */
pTypeLibImpl->TypeInfoCount = *(WORD *)((char *)pLibBlk + len);
len += sizeof(WORD);
pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount); pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount);
ptr = (char*)pLibBlk + len; ptr = (char*)pLibBlk + len;
for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) { for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
WORD w, extra; WORD w, extra;
len = 0; len = 0;
pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr; w = *(WORD*)ptr;
w = *(WORD*)(ptr + 2);
if(w != 0xffff) { if(w != 0xffff) {
len += w; len += w;
pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1); 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'; pOtherTypeInfoBlks[i].index_name[w] = '\0';
} }
w = *(WORD*)(ptr + 4 + len); w = *(WORD*)(ptr + 2 + len);
if(w != 0xffff) { if(w != 0xffff) {
TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w)); TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 4 + len, w));
len += w;
pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1); 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'; pOtherTypeInfoBlks[i].other_name[w] = '\0';
len += w;
} }
pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6); pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + 4 + len);
pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + 6 + len);
extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len); extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len);
if(extra) { if(extra) {
pOtherTypeInfoBlks[i].extra = heap_alloc(extra); pOtherTypeInfoBlks[i].extra = heap_alloc(extra);
memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra); memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10 + len, extra);
len += extra; len += extra;
} }
pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len); pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 10 + len);
pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len); pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 12 + len);
pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len); pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 16 + len);
memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID)); memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 18 + len, sizeof(GUID));
pOtherTypeInfoBlks[i].typekind = *(WORD*)(ptr + 18 + sizeof(GUID) + len);
len += sizeof(SLTG_OtherTypeInfo); len += sizeof(SLTG_OtherTypeInfo);
ptr += len; ptr += len;
} }
pAfterOTIBlks = ptr; /* Get the next DWORD */
len = *(DWORD*)ptr;
/* Skip this WORD and get the next DWORD */ hlp_strings = (const BYTE *)ptr + sizeof(DWORD);
len = *(DWORD*)(pAfterOTIBlks + 2); 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 /* Now add this to pLibBLk look at what we're pointing at and
possibly add 0x20, then add 0x216, sprinkle a bit a magic possibly add 0x20, then add 0x216, sprinkle a bit a magic
@ -4592,6 +4689,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
(*ppTypeInfoImpl)->index = i; (*ppTypeInfoImpl)->index = i;
(*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl); (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl);
(*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext; (*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)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2);
(*ppTypeInfoImpl)->typekind = pTIHeader->typekind; (*ppTypeInfoImpl)->typekind = pTIHeader->typekind;
(*ppTypeInfoImpl)->wMajorVerNum = pTIHeader->major_version; (*ppTypeInfoImpl)->wMajorVerNum = pTIHeader->major_version;
@ -4624,17 +4722,17 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
switch(pTIHeader->typekind) { switch(pTIHeader->typekind) {
case TKIND_ENUM: case TKIND_ENUM:
SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_RECORD: case TKIND_RECORD:
SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_INTERFACE: case TKIND_INTERFACE:
SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_COCLASS: case TKIND_COCLASS:
@ -4649,12 +4747,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
case TKIND_DISPATCH: case TKIND_DISPATCH:
SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
case TKIND_MODULE: case TKIND_MODULE:
SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
pTIHeader, pTITail); pTIHeader, pTITail, hlp_strings);
break; break;
default: default:
@ -9305,7 +9403,7 @@ static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *f
{ {
WMSFT_SegContents *cdguids_seg = &file->cdguids_seg; WMSFT_SegContents *cdguids_seg = &file->cdguids_seg;
DWORD ret = cdguids_seg->len, offs; DWORD ret = cdguids_seg->len, offs;
MSFT_CDGuid *cdguid = cdguids_seg->data; MSFT_CDGuid *cdguid;
TLBCustData *cd; TLBCustData *cd;
if(list_empty(custdata_list)) if(list_empty(custdata_list))
@ -9314,8 +9412,10 @@ static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *f
cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list); cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list);
if(!cdguids_seg->data){ if(!cdguids_seg->data){
cdguid = cdguids_seg->data = heap_alloc(cdguids_seg->len); cdguid = cdguids_seg->data = heap_alloc(cdguids_seg->len);
}else }else {
cdguids_seg->data = heap_realloc(cdguids_seg->data, cdguids_seg->len); cdguids_seg->data = heap_realloc(cdguids_seg->data, cdguids_seg->len);
cdguid = (MSFT_CDGuid*)((char*)cdguids_seg->data + ret);
}
offs = ret + sizeof(MSFT_CDGuid); offs = ret + sizeof(MSFT_CDGuid);
LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){ LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){
@ -10007,7 +10107,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 *iface)
else else
file.header.NameOffset = -1; 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) if(This->guid)
file.header.posguid = This->guid->offset; file.header.posguid = This->guid->offset;
@ -10157,8 +10257,16 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(ICreateTypeLib2 *iface,
REFGUID guid, VARIANT *varVal) REFGUID guid, VARIANT *varVal)
{ {
ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface);
FIXME("%p %s %p - stub\n", This, debugstr_guid(guid), varVal); TLBGuid *tlbguid;
return E_NOTIMPL;
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, static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 *iface,

View file

@ -381,18 +381,18 @@ typedef struct {
/* we then get 0x40 bytes worth of 0xffff or small numbers followed by /* we then get 0x40 bytes worth of 0xffff or small numbers followed by
nrOfFileBlks - 2 of these */ nrOfFileBlks - 2 of these */
typedef struct { typedef struct {
WORD small_no;
SLTG_Name index_name; /* This refers to a name in the directory */ SLTG_Name index_name; /* This refers to a name in the directory */
SLTG_Name other_name; /* Another one of these weird names */ SLTG_Name other_name; /* Another one of these weird names */
WORD res1a; /* 0xffff */ WORD res1a; /* 0xffff */
WORD name_offs; /* offset to name in name table */ 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 bytes before the next element, which seem
to reference the docstring of the type ? */ to reference the docstring of the type ? */
WORD res20; /* 0xffff */ WORD res20; /* 0xffff */
DWORD helpcontext; DWORD helpcontext;
WORD res26; /* 0xffff */ WORD res26; /* 0xffff */
GUID uuid; GUID uuid;
WORD typekind;
} SLTG_OtherTypeInfo; } SLTG_OtherTypeInfo;
/* Next we get WORD 0x0003 followed by a DWORD which if we add to /* Next we get WORD 0x0003 followed by a DWORD which if we add to

View file

@ -333,10 +333,6 @@ static unsigned char *interface_variant_unmarshal(ULONG *pFlags, unsigned char *
ptr = *(DWORD*)Buffer; ptr = *(DWORD*)Buffer;
Buffer += sizeof(DWORD); 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) if(!ptr)
return Buffer; return Buffer;
@ -504,10 +500,22 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
{ {
VariantClear(pvar); VariantClear(pvar);
V_BYREF(pvar) = CoTaskMemAlloc(mem_size); V_BYREF(pvar) = CoTaskMemAlloc(mem_size);
memset(V_BYREF(pvar), 0, mem_size);
} }
else if (!V_BYREF(pvar)) else if (!V_BYREF(pvar))
{
V_BYREF(pvar) = CoTaskMemAlloc(mem_size); 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) if((header->vt & VT_TYPEMASK) != VT_VARIANT)
Pos += type_size; Pos += type_size;
else else
@ -516,7 +524,17 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
else else
{ {
VariantClear(pvar); 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); memcpy(pvar, Pos, type_size);
else else
memcpy(&pvar->n1.n2.n3, Pos, type_size); memcpy(&pvar->n1.n2.n3, Pos, type_size);
@ -540,11 +558,9 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
switch (header->vt) switch (header->vt)
{ {
case VT_BSTR: case VT_BSTR:
V_BSTR(pvar) = NULL;
Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar)); Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar));
break; break;
case VT_BSTR | VT_BYREF: case VT_BSTR | VT_BYREF:
*V_BSTRREF(pvar) = NULL;
Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar)); Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar));
break; break;
case VT_VARIANT | VT_BYREF: case VT_VARIANT | VT_BYREF:
@ -947,6 +963,7 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
if (!ptr) if (!ptr)
{ {
SafeArrayDestroy(*ppsa);
*ppsa = NULL; *ppsa = NULL;
TRACE("NULL safe array unmarshaled\n"); TRACE("NULL safe array unmarshaled\n");
@ -983,13 +1000,34 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
wiresab = (SAFEARRAYBOUND *)Buffer; wiresab = (SAFEARRAYBOUND *)Buffer;
Buffer += sizeof(wiresab[0]) * wiresa->cDims; 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); *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL);
if (!*ppsa) RpcRaiseException(E_OUTOFMEMORY); if (!*ppsa) RpcRaiseException(E_OUTOFMEMORY);
} }
else else
{ {
SafeArrayDestroy(*ppsa);
if (FAILED(SafeArrayAllocDescriptor(wiresa->cDims, ppsa))) if (FAILED(SafeArrayAllocDescriptor(wiresa->cDims, ppsa)))
RpcRaiseException(E_OUTOFMEMORY); RpcRaiseException(E_OUTOFMEMORY);
memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims); memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims);
@ -1001,11 +1039,10 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
(*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS)); (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS));
/* FIXME: there should be a limit on how large wiresa->cbElements can be */ /* FIXME: there should be a limit on how large wiresa->cbElements can be */
(*ppsa)->cbElements = elem_mem_size(wiresa, sftype); (*ppsa)->cbElements = elem_mem_size(wiresa, sftype);
(*ppsa)->cLocks = 0;
/* SafeArrayCreateEx allocates the data for us, but /* SafeArrayCreateEx allocates the data for us, but
* SafeArrayAllocDescriptor doesn't */ * SafeArrayAllocDescriptor doesn't */
if(!vt) if(!(*ppsa)->pvData)
{ {
hr = SafeArrayAllocData(*ppsa); hr = SafeArrayAllocData(*ppsa);
if (FAILED(hr)) if (FAILED(hr))
@ -1075,6 +1112,7 @@ void WINAPI LPSAFEARRAY_UserFree(ULONG *pFlags, LPSAFEARRAY *ppsa)
TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa); TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa);
SafeArrayDestroy(*ppsa); SafeArrayDestroy(*ppsa);
*ppsa = NULL;
} }

View file

@ -39,15 +39,6 @@ static const WCHAR szPercent_d[] = { '%','d','\0' };
static const WCHAR szPercentZeroTwo_d[] = { '%','0','2','d','\0' }; static const WCHAR szPercentZeroTwo_d[] = { '%','0','2','d','\0' };
static const WCHAR szPercentZeroStar_d[] = { '%','0','*','d','\0' }; static const WCHAR szPercentZeroStar_d[] = { '%','0','*','d','\0' };
#if 0
#define dump_tokens(rgb) do { \
int i_; TRACE("Tokens->{\n"); \
for (i_ = 0; i_ < rgb[0]; i_++) \
TRACE("%s0x%02x", i_?",":"",rgb[i_]); \
TRACE(" }\n"); \
} while(0)
#endif
/****************************************************************************** /******************************************************************************
* Variant-Formats {OLEAUT32} * Variant-Formats {OLEAUT32}
* *
@ -1200,13 +1191,13 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
else else
{ {
/* Get a number string from pVarIn, and parse it */ /* Get a number string from pVarIn, and parse it */
hRes = VariantChangeTypeEx(&vString, pVarIn, LCID_US, VARIANT_NOUSEROVERRIDE, VT_BSTR); hRes = VariantChangeTypeEx(&vString, pVarIn, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR);
if (FAILED(hRes)) if (FAILED(hRes))
return hRes; return hRes;
np.cDig = sizeof(rgbDig); np.cDig = sizeof(rgbDig);
np.dwInFlags = NUMPRS_STD; np.dwInFlags = NUMPRS_STD;
hRes = VarParseNumFromStr(V_BSTR(&vString), LCID_US, 0, &np, rgbDig); hRes = VarParseNumFromStr(V_BSTR(&vString), lcid, 0, &np, rgbDig);
if (FAILED(hRes)) if (FAILED(hRes))
return hRes; return hRes;
@ -1609,7 +1600,7 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat,
{ {
USHORT usFlags = dwFlags & VARIANT_CALENDAR_HIJRI ? VAR_CALENDAR_HIJRI : 0; USHORT usFlags = dwFlags & VARIANT_CALENDAR_HIJRI ? VAR_CALENDAR_HIJRI : 0;
hRes = VariantChangeTypeEx(&vDate, pVarIn, LCID_US, usFlags, VT_DATE); hRes = VariantChangeTypeEx(&vDate, pVarIn, lcid, usFlags, VT_DATE);
if (FAILED(hRes)) if (FAILED(hRes))
return hRes; return hRes;
dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetPositive(header)); dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetPositive(header));
@ -1948,7 +1939,7 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
} }
else else
{ {
hRes = VariantChangeTypeEx(&vStr, pVarIn, LCID_US, VARIANT_NOUSEROVERRIDE, VT_BSTR); hRes = VariantChangeTypeEx(&vStr, pVarIn, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR);
if (FAILED(hRes)) if (FAILED(hRes))
return hRes; return hRes;

View file

@ -144,7 +144,7 @@ reactos/dll/win32/odbc32 # Synced to WineStaging-1.9.4. Depends on
reactos/dll/win32/odbccp32 # Synced to WineStaging-1.7.55 reactos/dll/win32/odbccp32 # Synced to WineStaging-1.7.55
reactos/dll/win32/ole32 # Synced to WineStaging-1.9.4 reactos/dll/win32/ole32 # Synced to WineStaging-1.9.4
reactos/dll/win32/oleacc # Synced to WineStaging-1.7.55 reactos/dll/win32/oleacc # Synced to WineStaging-1.7.55
reactos/dll/win32/oleaut32 # Synced to WineStaging-1.7.55 reactos/dll/win32/oleaut32 # Synced to WineStaging-1.9.4
reactos/dll/win32/olecli32 # Synced to WineStaging-1.7.55 reactos/dll/win32/olecli32 # Synced to WineStaging-1.7.55
reactos/dll/win32/oledlg # Synced to WineStaging-1.7.55 reactos/dll/win32/oledlg # Synced to WineStaging-1.7.55
reactos/dll/win32/olepro32 # Synced to WineStaging-1.7.55 reactos/dll/win32/olepro32 # Synced to WineStaging-1.7.55