[OLEAUT32] Sync with Wine Staging 1.9.4. CORE-10912
authorAmine Khaldi <amine.khaldi@reactos.org>
Fri, 4 Mar 2016 09:33:34 +0000 (09:33 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Fri, 4 Mar 2016 09:33:34 +0000 (09:33 +0000)
svn path=/trunk/; revision=70903

reactos/dll/win32/oleaut32/oleaut.c
reactos/dll/win32/oleaut32/olepicture.c
reactos/dll/win32/oleaut32/tmarshal.c
reactos/dll/win32/oleaut32/typelib.c
reactos/dll/win32/oleaut32/typelib.h
reactos/dll/win32/oleaut32/usrmarshal.c
reactos/dll/win32/oleaut32/varformat.c
reactos/media/doc/README.WINE

index 9e4add0..a677b07 100644 (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 };
 
 typedef struct {
+#ifdef _WIN64
+    DWORD pad;
+#endif
     DWORD size;
     union {
         char ptr[1];
@@ -100,24 +103,37 @@ static inline bstr_t *bstr_from_str(BSTR 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)
         ? 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;
         }
@@ -132,19 +148,16 @@ static bstr_t *alloc_bstr(size_t size)
 
         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;
@@ -217,6 +230,16 @@ BSTR WINAPI SysAllocString(LPCOLESTR 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]
  *
@@ -236,12 +259,19 @@ void WINAPI SysFreeString(BSTR str)
 {
     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;
 
@@ -262,8 +292,7 @@ void WINAPI SysFreeString(BSTR str)
             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;
             }
@@ -275,7 +304,7 @@ void WINAPI SysFreeString(BSTR str)
         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. */
     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;
 }
 
 /******************************************************************************
@@ -401,10 +426,11 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
 
     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;
 }
index 2329d4c..ef11dfd 100644 (file)
@@ -452,7 +452,7 @@ static HRESULT WINAPI OLEPictureImpl_QueryInterface(
 
   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;
   }
 
index c0483fd..314fa88 100644 (file)
@@ -58,12 +58,14 @@ xbuf_resize(marshal_state *buf, DWORD newsize)
 
     if(buf->base)
     {
+        newsize = max(newsize, buf->size * 2);
         buf->base = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf->base, newsize);
         if(!buf->base)
             return E_OUTOFMEMORY;
     }
     else
     {
+        newsize = max(newsize, 256);
         buf->base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newsize);
         if(!buf->base)
             return E_OUTOFMEMORY;
@@ -79,7 +81,7 @@ xbuf_add(marshal_state *buf, const BYTE *stuff, DWORD 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;
     }
     memcpy(buf->base+buf->curoff,stuff,size);
index 2a45429..39a153d 100644 (file)
@@ -302,7 +302,7 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin,
             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);
@@ -403,11 +403,21 @@ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID l
  *    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;
 }
 
 /******************************************************************************
@@ -515,7 +525,7 @@ HRESULT WINAPI LoadRegTypeLib(
         res= LoadTypeLib(bstr, ppTLib);
         SysFreeString(bstr);
 
-        if (*ppTLib)
+        if ((wVerMajor!=0xffff || wVerMinor!=0xffff) && *ppTLib)
         {
             TLIBATTR *attr;
 
@@ -3696,6 +3706,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;
@@ -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,
-                       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;
@@ -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)("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
@@ -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,
-                        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;
@@ -4175,6 +4273,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;
@@ -4193,7 +4293,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
        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
@@ -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 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);
            }
@@ -4267,7 +4362,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;
@@ -4284,7 +4379,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);
 
@@ -4294,9 +4389,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,
@@ -4329,7 +4424,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)
@@ -4337,10 +4432,10 @@ 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);
+    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);
@@ -4357,14 +4452,14 @@ 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,
                               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)
@@ -4372,10 +4467,10 @@ 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);
+    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);
@@ -4384,17 +4479,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;
 
 /****************************************************************************
@@ -4413,8 +4508,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;
@@ -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. */
 
-    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;
@@ -4480,53 +4575,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
@@ -4592,6 +4689,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;
@@ -4624,17 +4722,17 @@ 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:
        SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
-                              pTIHeader, pTITail);
+                              pTIHeader, pTITail, hlp_strings);
        break;
 
       case TKIND_COCLASS:
@@ -4649,12 +4747,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:
@@ -9305,7 +9403,7 @@ static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *f
 {
     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))
@@ -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);
     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){
@@ -10007,7 +10107,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 *iface)
     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;
@@ -10157,8 +10257,16 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(ICreateTypeLib2 *iface,
         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,
index 2939115..c4fb124 100644 (file)
@@ -381,18 +381,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
index ef65c07..70adecc 100644 (file)
@@ -333,10 +333,6 @@ static unsigned char *interface_variant_unmarshal(ULONG *pFlags, unsigned char *
   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;
 
@@ -504,10 +500,22 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
         {
             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
@@ -516,7 +524,17 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
     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);
@@ -540,11 +558,9 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
         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:
@@ -947,6 +963,7 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
 
     if (!ptr)
     {
+        SafeArrayDestroy(*ppsa);
         *ppsa = NULL;
 
         TRACE("NULL safe array unmarshaled\n");
@@ -983,13 +1000,34 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
     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);
@@ -1001,11 +1039,10 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
     (*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))
@@ -1075,6 +1112,7 @@ void WINAPI LPSAFEARRAY_UserFree(ULONG *pFlags, LPSAFEARRAY *ppsa)
     TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa);
 
     SafeArrayDestroy(*ppsa);
+    *ppsa = NULL;
 }
 
 
index a2f11c8..f701bfb 100644 (file)
@@ -39,15 +39,6 @@ static const WCHAR szPercent_d[] = { '%','d','\0' };
 static const WCHAR szPercentZeroTwo_d[] = { '%','0','2','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}
  *
@@ -1200,13 +1191,13 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   else
   {
     /* 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))
       return hRes;
 
     np.cDig = sizeof(rgbDig);
     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))
       return hRes;
 
@@ -1609,7 +1600,7 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   {
     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))
       return hRes;
     dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetPositive(header));
@@ -1948,7 +1939,7 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
   }
   else
   {
-    hRes = VariantChangeTypeEx(&vStr, pVarIn, LCID_US, VARIANT_NOUSEROVERRIDE, VT_BSTR);
+    hRes = VariantChangeTypeEx(&vStr, pVarIn, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR);
     if (FAILED(hRes))
       return hRes;
 
index fc3c460..5851207 100644 (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/ole32               # Synced to WineStaging-1.9.4
 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/oledlg              # Synced to WineStaging-1.7.55
 reactos/dll/win32/olepro32            # Synced to WineStaging-1.7.55