[OLEAUT32]
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 12 Dec 2012 13:52:25 +0000 (13:52 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 12 Dec 2012 13:52:25 +0000 (13:52 +0000)
* Sync to Wine 1.5.19.

svn path=/trunk/; revision=57889

29 files changed:
reactos/dll/win32/oleaut32/CMakeLists.txt
reactos/dll/win32/oleaut32/connpt.c
reactos/dll/win32/oleaut32/dispatch.c
reactos/dll/win32/oleaut32/oleaut.c
reactos/dll/win32/oleaut32/oleaut32.rc
reactos/dll/win32/oleaut32/oleaut32.rgs [new file with mode: 0644]
reactos/dll/win32/oleaut32/oleaut32_oaidl.idl
reactos/dll/win32/oleaut32/oleaut32_oaidl.rgs [new file with mode: 0644]
reactos/dll/win32/oleaut32/oleaut32_ocidl.idl
reactos/dll/win32/oleaut32/oleaut32_ocidl.rgs [new file with mode: 0644]
reactos/dll/win32/oleaut32/olefont.c
reactos/dll/win32/oleaut32/olepicture.c
reactos/dll/win32/oleaut32/olepropframe.c [new file with mode: 0644]
reactos/dll/win32/oleaut32/recinfo.c
reactos/dll/win32/oleaut32/regsvr.c [deleted file]
reactos/dll/win32/oleaut32/safearray.c
reactos/dll/win32/oleaut32/stubs.c [deleted file]
reactos/dll/win32/oleaut32/tmarshal.c
reactos/dll/win32/oleaut32/typelib.c
reactos/dll/win32/oleaut32/typelib.h
reactos/dll/win32/oleaut32/typelib2.c
reactos/dll/win32/oleaut32/ungif.c [deleted file]
reactos/dll/win32/oleaut32/ungif.h [deleted file]
reactos/dll/win32/oleaut32/usrmarshal.c
reactos/dll/win32/oleaut32/varformat.c
reactos/dll/win32/oleaut32/variant.c
reactos/dll/win32/oleaut32/vartype.c
reactos/dll/win32/oleaut32/version.rc [deleted file]
reactos/media/doc/README.WINE

index 138fbe0..5c3621c 100644 (file)
@@ -2,19 +2,16 @@
 remove_definitions(-D_WIN32_WINNT=0x502)
 add_definitions(-D_WIN32_WINNT=0x600)
 
-add_definitions(-DPROXY_CLSID_IS="{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}")
-
 add_definitions(
     -D__WINESRC__
     -DCOM_NO_WINDOWS_H
     -D_OLEAUT32_
     -DPROXY_DELEGATION
-    -DREGISTER_PROXY_DLL
-    -DENTRY_PREFIX=OLEAUTPS_)
+    -DWINE_REGISTER_DLL
+    -DENTRY_PREFIX=OLEAUTPS_
+    -DPROXY_CLSID=CLSID_PSFactoryBuffer)
 
-include_directories(
-    ${REACTOS_SOURCE_DIR}/include/reactos/libs/libjpeg
-    ${REACTOS_SOURCE_DIR}/include/reactos/wine)
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
 
 spec2def(oleaut32.dll oleaut32.spec ADD_IMPORTLIB)
 
@@ -27,14 +24,12 @@ list(APPEND SOURCE
     oleaut.c
     olefont.c
     olepicture.c
+    olepropframe.c
     recinfo.c
-    regsvr.c
     safearray.c
-    stubs.c
     tmarshal.c
     typelib.c
     typelib2.c
-    ungif.c
     usrmarshal.c
     varformat.c
     variant.c
@@ -51,15 +46,10 @@ if(MSVC)
 endif()
 
 add_library(oleaut32 SHARED ${SOURCE})
+add_idl_headers(oleaut32_idlheader oleaut32_oaidl.idl)
+add_dependencies(oleaut32 oleaut32_idlheader)
 set_module_type(oleaut32 win32dll)
-
-target_link_libraries(oleaut32
-    wine
-    wineldr
-    uuid
-    ${PSEH_LIB})
-
+target_link_libraries(oleaut32 wine wineldr uuid ${PSEH_LIB})
 add_delay_importlibs(oleaut32 comctl32 urlmon windowscodecs)
 add_importlibs(oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET oleaut32 DESTINATION reactos/system32 FOR all)
-
index 94e8e7c..59768a0 100644 (file)
@@ -48,7 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
  */
 typedef struct ConnectionPointImpl {
 
-  const IConnectionPointVtbl *lpvtbl;
+  IConnectionPoint IConnectionPoint_iface;
 
   /* IUnknown of our main object*/
   IUnknown *Obj;
@@ -74,7 +74,7 @@ static const IConnectionPointVtbl ConnectionPointImpl_VTable;
  */
 typedef struct EnumConnectionsImpl {
 
-  const IEnumConnectionsVtbl *lpvtbl;
+  IEnumConnections IEnumConnections_iface;
 
   LONG ref;
 
@@ -94,6 +94,15 @@ static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk,
                                                          DWORD nSinks,
                                                          CONNECTDATA *pCD);
 
+static inline ConnectionPointImpl *impl_from_IConnectionPoint(IConnectionPoint *iface)
+{
+  return CONTAINING_RECORD(iface, ConnectionPointImpl, IConnectionPoint_iface);
+}
+
+static inline EnumConnectionsImpl *impl_from_IEnumConnections(IEnumConnections *iface)
+{
+  return CONTAINING_RECORD(iface, EnumConnectionsImpl, IEnumConnections_iface);
+}
 
 /************************************************************************
  * ConnectionPointImpl_Construct
@@ -104,7 +113,7 @@ static ConnectionPointImpl *ConnectionPointImpl_Construct(IUnknown *pUnk,
   ConnectionPointImpl *Obj;
 
   Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj));
-  Obj->lpvtbl = &ConnectionPointImpl_VTable;
+  Obj->IConnectionPoint_iface.lpVtbl = &ConnectionPointImpl_VTable;
   Obj->Obj = pUnk;
   Obj->ref = 1;
   Obj->iid =  *riid;
@@ -143,7 +152,7 @@ static HRESULT WINAPI ConnectionPointImpl_QueryInterface(
   REFIID  riid,
   void**  ppvObject)
 {
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
 
   /*
@@ -178,7 +187,7 @@ static HRESULT WINAPI ConnectionPointImpl_QueryInterface(
    * Query Interface always increases the reference count by one when it is
    * successful
    */
-  ConnectionPointImpl_AddRef((IConnectionPoint*)This);
+  ConnectionPointImpl_AddRef(&This->IConnectionPoint_iface);
 
   return S_OK;
 }
@@ -191,7 +200,7 @@ static HRESULT WINAPI ConnectionPointImpl_QueryInterface(
  */
 static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface)
 {
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   ULONG refCount = InterlockedIncrement(&This->ref);
 
   TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
@@ -207,7 +216,7 @@ static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface)
 static ULONG WINAPI ConnectionPointImpl_Release(
       IConnectionPoint* iface)
 {
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   ULONG refCount = InterlockedDecrement(&This->ref);
 
   TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
@@ -228,7 +237,7 @@ static HRESULT WINAPI ConnectionPointImpl_GetConnectionInterface(
                                               IConnectionPoint *iface,
                                               IID              *piid)
 {
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   TRACE("(%p)->(%p) returning %s\n", This, piid, debugstr_guid(&(This->iid)));
   *piid = This->iid;
   return S_OK;
@@ -242,7 +251,7 @@ static HRESULT WINAPI ConnectionPointImpl_GetConnectionPointContainer(
                                      IConnectionPoint           *iface,
                                      IConnectionPointContainer  **ppCPC)
 {
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   TRACE("(%p)->(%p)\n", This, ppCPC);
 
   return IUnknown_QueryInterface(This->Obj,
@@ -259,7 +268,7 @@ static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface,
                                                 DWORD *pdwCookie)
 {
   DWORD i;
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   IUnknown *lpSink;
   TRACE("(%p)->(%p, %p)\n", This, lpUnk, pdwCookie);
 
@@ -290,7 +299,7 @@ static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface,
 static HRESULT WINAPI ConnectionPointImpl_Unadvise(IConnectionPoint *iface,
                                                   DWORD dwCookie)
 {
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   TRACE("(%p)->(%d)\n", This, dwCookie);
 
   if(dwCookie == 0 || dwCookie > This->maxSinks) return E_INVALIDARG;
@@ -311,7 +320,7 @@ static HRESULT WINAPI ConnectionPointImpl_EnumConnections(
                                                    IConnectionPoint *iface,
                                                    LPENUMCONNECTIONS *ppEnum)
 {
-  ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ConnectionPointImpl *This = impl_from_IConnectionPoint(iface);
   CONNECTDATA *pCD;
   DWORD i, nextslot;
   EnumConnectionsImpl *EnumObj;
@@ -339,9 +348,9 @@ static HRESULT WINAPI ConnectionPointImpl_EnumConnections(
   IUnknown_AddRef((IUnknown*)This);
 
   EnumObj = EnumConnectionsImpl_Construct((IUnknown*)This, This->nSinks, pCD);
-  hr = IEnumConnections_QueryInterface((IEnumConnections*)EnumObj,
+  hr = IEnumConnections_QueryInterface(&EnumObj->IEnumConnections_iface,
                                  &IID_IEnumConnections, (LPVOID)ppEnum);
-  IEnumConnections_Release((IEnumConnections*)EnumObj);
+  IEnumConnections_Release(&EnumObj->IEnumConnections_iface);
 
   HeapFree(GetProcessHeap(), 0, pCD);
   return hr;
@@ -373,7 +382,7 @@ static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk,
   EnumConnectionsImpl *Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj));
   DWORD i;
 
-  Obj->lpvtbl = &EnumConnectionsImpl_VTable;
+  Obj->IEnumConnections_iface.lpVtbl = &EnumConnectionsImpl_VTable;
   Obj->ref = 1;
   Obj->pUnk = pUnk;
   Obj->pCD = HeapAlloc(GetProcessHeap(), 0, nSinks * sizeof(CONNECTDATA));
@@ -460,7 +469,7 @@ static HRESULT WINAPI EnumConnectionsImpl_QueryInterface(
  */
 static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface)
 {
-  EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  EnumConnectionsImpl *This = impl_from_IEnumConnections(iface);
   ULONG refCount = InterlockedIncrement(&This->ref);
 
   TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
@@ -476,7 +485,7 @@ static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface)
  */
 static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections* iface)
 {
-  EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  EnumConnectionsImpl *This = impl_from_IEnumConnections(iface);
   ULONG refCount = InterlockedDecrement(&This->ref);
 
   TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
@@ -499,7 +508,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface,
                                               ULONG cConn, LPCONNECTDATA pCD,
                                               ULONG *pEnum)
 {
-  EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  EnumConnectionsImpl *This = impl_from_IEnumConnections(iface);
   DWORD nRet = 0;
   TRACE("(%p)->(%d, %p, %p)\n", This, cConn, pCD, pEnum);
 
@@ -534,7 +543,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface,
 static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections* iface,
                                               ULONG cSkip)
 {
-  EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  EnumConnectionsImpl *This = impl_from_IEnumConnections(iface);
   TRACE("(%p)->(%d)\n", This, cSkip);
 
   if(This->nCur + cSkip >= This->nConns)
@@ -552,7 +561,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections* iface,
  */
 static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections* iface)
 {
-  EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  EnumConnectionsImpl *This = impl_from_IEnumConnections(iface);
   TRACE("(%p)\n", This);
 
   This->nCur = 0;
@@ -568,7 +577,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections* iface)
 static HRESULT WINAPI EnumConnectionsImpl_Clone(IEnumConnections* iface,
                                                LPENUMCONNECTIONS *ppEnum)
 {
-  EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  EnumConnectionsImpl *This = impl_from_IEnumConnections(iface);
   EnumConnectionsImpl *newObj;
   TRACE("(%p)->(%p)\n", This, ppEnum);
 
@@ -613,8 +622,8 @@ HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid,
   Obj = ConnectionPointImpl_Construct(pUnk, riid);
   if(!Obj) return E_OUTOFMEMORY;
 
-  hr = IConnectionPoint_QueryInterface((IConnectionPoint *)Obj,
+  hr = IConnectionPoint_QueryInterface(&Obj->IConnectionPoint_iface,
                                       &IID_IConnectionPoint, (LPVOID)pCP);
-  IConnectionPoint_Release((IConnectionPoint *)Obj);
+  IConnectionPoint_Release(&Obj->IConnectionPoint_iface);
   return hr;
 }
index ed3fad4..760f8aa 100644 (file)
@@ -232,12 +232,17 @@ HRESULT WINAPI CreateStdDispatch(
 
 typedef struct
 {
-    const IDispatchVtbl *lpVtbl;
+    IDispatch IDispatch_iface;
     void * pvThis;
     ITypeInfo * pTypeInfo;
     LONG ref;
 } StdDispatch;
 
+static inline StdDispatch *impl_from_IDispatch(IDispatch *iface)
+{
+    return CONTAINING_RECORD(iface, StdDispatch, IDispatch_iface);
+}
+
 /******************************************************************************
  * IDispatch_QueryInterface {OLEAUT32}
  *
@@ -248,7 +253,7 @@ static HRESULT WINAPI StdDispatch_QueryInterface(
   REFIID riid,
   void** ppvObject)
 {
-    StdDispatch *This = (StdDispatch *)iface;
+    StdDispatch *This = impl_from_IDispatch(iface);
     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject);
 
     if (IsEqualIID(riid, &IID_IDispatch) ||
@@ -268,7 +273,7 @@ static HRESULT WINAPI StdDispatch_QueryInterface(
  */
 static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface)
 {
-    StdDispatch *This = (StdDispatch *)iface;
+    StdDispatch *This = impl_from_IDispatch(iface);
     ULONG refCount = InterlockedIncrement(&This->ref);
 
     TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
@@ -283,7 +288,7 @@ static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface)
  */
 static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface)
 {
-    StdDispatch *This = (StdDispatch *)iface;
+    StdDispatch *This = impl_from_IDispatch(iface);
     ULONG refCount = InterlockedDecrement(&This->ref);
 
     TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
@@ -316,7 +321,7 @@ static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface)
  */
 static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo)
 {
-    StdDispatch *This = (StdDispatch *)iface;
+    StdDispatch *This = impl_from_IDispatch(iface);
     TRACE("(%p)\n", pctinfo);
 
     *pctinfo = This->pTypeInfo ? 1 : 0;
@@ -343,7 +348,7 @@ static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pcti
  */
 static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
 {
-    StdDispatch *This = (StdDispatch *)iface;
+    StdDispatch *This = impl_from_IDispatch(iface);
     TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo);
 
     *ppTInfo = NULL;
@@ -386,7 +391,7 @@ static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCI
  */
 static HRESULT WINAPI StdDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
 {
-    StdDispatch *This = (StdDispatch *)iface;
+    StdDispatch *This = impl_from_IDispatch(iface);
     TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
 
     if (!IsEqualGUID(riid, &IID_NULL))
@@ -424,7 +429,7 @@ static HRESULT WINAPI StdDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember,
                                          WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult,
                                          EXCEPINFO * pExcepInfo, UINT * puArgErr)
 {
-    StdDispatch *This = (StdDispatch *)iface;
+    StdDispatch *This = impl_from_IDispatch(iface);
     TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
 
     if (!IsEqualGUID(riid, &IID_NULL))
@@ -455,9 +460,9 @@ static IDispatch * StdDispatch_Construct(
 
     pStdDispatch = CoTaskMemAlloc(sizeof(StdDispatch));
     if (!pStdDispatch)
-        return (IDispatch *)pStdDispatch;
+        return &pStdDispatch->IDispatch_iface;
 
-    pStdDispatch->lpVtbl = &StdDispatch_VTable;
+    pStdDispatch->IDispatch_iface.lpVtbl = &StdDispatch_VTable;
     pStdDispatch->pvThis = pvThis;
     pStdDispatch->pTypeInfo = pTypeInfo;
     pStdDispatch->ref = 1;
@@ -466,5 +471,5 @@ static IDispatch * StdDispatch_Construct(
      * being destroyed until we are done with it */
     ITypeInfo_AddRef(pTypeInfo);
 
-    return (IDispatch *)pStdDispatch;
+    return &pStdDispatch->IDispatch_iface;
 }
index 89e1ab9..250a812 100644 (file)
 #include "ole2.h"
 #include "olectl.h"
 #include "oleauto.h"
+#include "initguid.h"
 #include "typelib.h"
+#include "oleaut32_oaidl.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
-static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
+WINE_DECLARE_DEBUG_CHANNEL(heap);
 
 /******************************************************************************
  * BSTR  {OLEAUT32}
@@ -49,8 +51,8 @@ static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
  *  string type in ole automation. When encapsulated in a Variant type they are
  *  automatically copied and destroyed as the variant is processed.
  *
- *  The low level BSTR Api allows manipulation of these strings and is used by
- *  higher level Api calls to manage the strings transparently to the caller.
+ *  The low level BSTR API allows manipulation of these strings and is used by
+ *  higher level API calls to manage the strings transparently to the caller.
  *
  *  Internally the BSTR type is allocated with space for a DWORD byte count before
  *  the string data begins. This is undocumented and non-system code should not
@@ -68,6 +70,100 @@ static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
  *  'Inside OLE, second edition' by Kraig Brockshmidt.
  */
 
+static BOOL bstr_cache_enabled;
+
+static CRITICAL_SECTION cs_bstr_cache;
+static CRITICAL_SECTION_DEBUG cs_bstr_cache_dbg =
+{
+    0, 0, &cs_bstr_cache,
+    { &cs_bstr_cache_dbg.ProcessLocksList, &cs_bstr_cache_dbg.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": bstr_cache") }
+};
+static CRITICAL_SECTION cs_bstr_cache = { &cs_bstr_cache_dbg, -1, 0, 0, 0, 0 };
+
+typedef struct {
+    DWORD size;
+    union {
+        char ptr[1];
+        WCHAR str[1];
+        DWORD dwptr[1];
+    } u;
+} bstr_t;
+
+typedef struct {
+    unsigned short head;
+    unsigned short cnt;
+    bstr_t *buf[6];
+} bstr_cache_entry_t;
+
+#define BUCKET_SIZE 16
+
+#define ARENA_INUSE_FILLER     0x55
+#define ARENA_TAIL_FILLER      0xab
+#define ARENA_FREE_FILLER      0xfeeefeee
+
+static bstr_cache_entry_t bstr_cache[0x10000/BUCKET_SIZE];
+
+static inline size_t bstr_alloc_size(size_t size)
+{
+    return (FIELD_OFFSET(bstr_t, u.ptr[size]) + sizeof(WCHAR) + BUCKET_SIZE-1) & ~(BUCKET_SIZE-1);
+}
+
+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)
+{
+    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 bstr_t *alloc_bstr(size_t size)
+{
+    bstr_cache_entry_t *cache_entry = get_cache_entry(size+sizeof(WCHAR));
+    bstr_t *ret;
+
+    if(cache_entry) {
+        EnterCriticalSection(&cs_bstr_cache);
+
+        if(!cache_entry->cnt) {
+            cache_entry = get_cache_entry(size+sizeof(WCHAR)+BUCKET_SIZE);
+            if(cache_entry && !cache_entry->cnt)
+                cache_entry = NULL;
+        }
+
+        if(cache_entry) {
+            ret = cache_entry->buf[cache_entry->head++];
+            cache_entry->head %= sizeof(cache_entry->buf)/sizeof(*cache_entry->buf);
+            cache_entry->cnt--;
+        }
+
+        LeaveCriticalSection(&cs_bstr_cache);
+
+        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);
+            }
+            ret->size = size;
+            return ret;
+        }
+    }
+
+    ret = HeapAlloc(GetProcessHeap(), 0, bstr_alloc_size(size));
+    if(ret)
+        ret->size = size;
+    return ret;
+}
+
 /******************************************************************************
  *             SysStringLen  [OLEAUT32.7]
  *
@@ -87,18 +183,7 @@ static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
  */
 UINT WINAPI SysStringLen(BSTR str)
 {
-    DWORD* bufferPointer;
-
-     if (!str) return 0;
-    /*
-     * The length of the string (in bytes) is contained in a DWORD placed
-     * just before the BSTR pointer
-     */
-    bufferPointer = (DWORD*)str;
-
-    bufferPointer--;
-
-    return (int)(*bufferPointer/sizeof(WCHAR));
+    return str ? bstr_from_str(str)->size/sizeof(WCHAR) : 0;
 }
 
 /******************************************************************************
@@ -117,18 +202,7 @@ UINT WINAPI SysStringLen(BSTR str)
  */
 UINT WINAPI SysStringByteLen(BSTR str)
 {
-    DWORD* bufferPointer;
-
-     if (!str) return 0;
-    /*
-     * The length of the string (in bytes) is contained in a DWORD placed
-     * just before the BSTR pointer
-     */
-    bufferPointer = (DWORD*)str;
-
-    bufferPointer--;
-
-    return (int)(*bufferPointer);
+    return str ? bstr_from_str(str)->size : 0;
 }
 
 /******************************************************************************
@@ -174,24 +248,36 @@ BSTR WINAPI SysAllocString(LPCOLESTR str)
  */
 void WINAPI SysFreeString(BSTR str)
 {
-    DWORD* bufferPointer;
+    bstr_cache_entry_t *cache_entry;
+    bstr_t *bstr;
 
-    /* NULL is a valid parameter */
-    if(!str) return;
+    if(!str)
+        return;
 
-    /*
-     * We have to be careful when we free a BSTR pointer, it points to
-     * the beginning of the string but it skips the byte count contained
-     * before the string.
-     */
-    bufferPointer = (DWORD*)str;
+    bstr = bstr_from_str(str);
+    cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR));
+    if(cache_entry) {
+        EnterCriticalSection(&cs_bstr_cache);
 
-    bufferPointer--;
+        if(cache_entry->cnt < sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)) {
+            cache_entry->buf[(cache_entry->head+cache_entry->cnt)%((sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)))] = bstr;
+            cache_entry->cnt++;
 
-    /*
-     * Free the memory from its "real" origin.
-     */
-    HeapFree(GetProcessHeap(), 0, bufferPointer);
+            if(WARN_ON(heap)) {
+                unsigned i, n = bstr_alloc_size(bstr->size) / sizeof(DWORD) - 1;
+                bstr->size = ARENA_FREE_FILLER;
+                for(i=0; i<n; i++)
+                    bstr->u.dwptr[i] = ARENA_FREE_FILLER;
+            }
+
+            LeaveCriticalSection(&cs_bstr_cache);
+            return;
+        }
+
+        LeaveCriticalSection(&cs_bstr_cache);
+    }
+
+    HeapFree(GetProcessHeap(), 0, bstr);
 }
 
 /******************************************************************************
@@ -212,61 +298,28 @@ void WINAPI SysFreeString(BSTR str)
  */
 BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
 {
-    DWORD  bufferSize;
-    DWORD* newBuffer;
-    WCHAR* stringBuffer;
+    bstr_t *bstr;
+    DWORD size;
 
     /* Detect integer overflow. */
     if (len >= ((UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))/sizeof(WCHAR)))
        return NULL;
-    /*
-     * Find the length of the buffer passed-in, in bytes.
-     */
-    bufferSize = len * sizeof (WCHAR);
-
-    /*
-     * Allocate a new buffer to hold the string.
-     * don't forget to keep an empty spot at the beginning of the
-     * buffer for the character count and an extra character at the
-     * end for the NULL.
-     */
-    newBuffer = HeapAlloc(GetProcessHeap(), 0,
-                          bufferSize + sizeof(WCHAR) + sizeof(DWORD));
 
-    /*
-     * If the memory allocation failed, return a null pointer.
-     */
-    if (!newBuffer)
-      return NULL;
-
-    /*
-     * Copy the length of the string in the placeholder.
-     */
-    *newBuffer = bufferSize;
-
-    /*
-     * Skip the byte count.
-     */
-    newBuffer++;
+    TRACE("%s\n", debugstr_wn(str, len));
 
-    /*
-     * Copy the information in the buffer.
-     * Since it is valid to pass a NULL pointer here, we'll initialize the
-     * buffer to nul if it is the case.
-     */
-    if (str != 0)
-      memcpy(newBuffer, str, bufferSize);
-    else
-      memset(newBuffer, 0, bufferSize);
+    size = len*sizeof(WCHAR);
+    bstr = alloc_bstr(size);
+    if(!bstr)
+        return NULL;
 
-    /*
-     * Make sure that there is a nul character at the end of the
-     * string.
-     */
-    stringBuffer = (WCHAR*)newBuffer;
-    stringBuffer[len] = '\0';
+    if(str) {
+        memcpy(bstr->u.str, str, size);
+        bstr->u.str[len] = 0;
+    }else {
+        memset(bstr->u.str, 0, size+sizeof(WCHAR));
+    }
 
-    return stringBuffer;
+    return bstr->u.str;
 }
 
 /******************************************************************************
@@ -296,12 +349,13 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
     if (*old!=NULL) {
       BSTR old_copy = *old;
       DWORD newbytelen = len*sizeof(WCHAR);
-      DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD));
-      *old = (BSTR)(ptr+1);
-      *ptr = newbytelen;
+      bstr_t *bstr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,bstr_alloc_size(newbytelen));
+      *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;
@@ -337,55 +391,24 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
  */
 BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
 {
-    DWORD* newBuffer;
-    char* stringBuffer;
+    bstr_t *bstr;
 
     /* Detect integer overflow. */
     if (len >= (UINT_MAX-sizeof(WCHAR)-sizeof(DWORD)))
        return NULL;
 
-    /*
-     * Allocate a new buffer to hold the string.
-     * don't forget to keep an empty spot at the beginning of the
-     * buffer for the character count and an extra character at the
-     * end for the NULL.
-     */
-    newBuffer = HeapAlloc(GetProcessHeap(), 0,
-                          len + sizeof(WCHAR) + sizeof(DWORD));
-
-    /*
-     * If the memory allocation failed, return a null pointer.
-     */
-    if (newBuffer==0)
-      return 0;
-
-    /*
-     * Copy the length of the string in the placeholder.
-     */
-    *newBuffer = len;
+    bstr = alloc_bstr(len);
+    if(!bstr)
+        return NULL;
 
-    /*
-     * Skip the byte count.
-     */
-    newBuffer++;
-
-    /*
-     * Copy the information in the buffer.
-     * Since it is valid to pass a NULL pointer here, we'll initialize the
-     * buffer to nul if it is the case.
-     */
-    if (str != 0)
-      memcpy(newBuffer, str, len);
-
-    /*
-     * Make sure that there is a nul character at the end of the
-     * string.
-     */
-    stringBuffer = (char *)newBuffer;
-    stringBuffer[len] = 0;
-    stringBuffer[len+1] = 0;
+    if(str) {
+        memcpy(bstr->u.ptr, str, len);
+        bstr->u.ptr[len] = bstr->u.ptr[len+1] = 0;
+    }else {
+        memset(bstr->u.ptr, 0, len+sizeof(WCHAR));
+    }
 
-    return (LPWSTR)stringBuffer;
+    return bstr->u.str;
 }
 
 /******************************************************************************
@@ -437,14 +460,15 @@ INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR str)
  *  Nothing.
  *
  * NOTES
- *  See BSTR.
+ *  SetOaNoCache does not release cached strings, so it leaks by design.
  */
 void WINAPI SetOaNoCache(void)
 {
-  BSTR_bCache = FALSE;
+    TRACE("\n");
+    bstr_cache_enabled = FALSE;
 }
 
-static const WCHAR     _delimiter[2] = {'!',0}; /* default delimiter apparently */
+static const WCHAR     _delimiter[] = {'!',0}; /* default delimiter apparently */
 static const WCHAR     *pdelimiter = &_delimiter[0];
 
 /***********************************************************************
@@ -469,6 +493,7 @@ HRESULT WINAPI RegisterActiveObject(
        HRESULT                 ret;
        LPRUNNINGOBJECTTABLE    runobtable;
        LPMONIKER               moniker;
+        DWORD                   rot_flags = ROTFLAGS_REGISTRATIONKEEPSALIVE; /* default registration is strong */
 
        StringFromGUID2(rcid,guidbuf,39);
        ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
@@ -479,7 +504,9 @@ HRESULT WINAPI RegisterActiveObject(
                IMoniker_Release(moniker);
                return ret;
        }
-       ret = IRunningObjectTable_Register(runobtable,dwFlags,punk,moniker,pdwRegister);
+        if(dwFlags == ACTIVEOBJECT_WEAK)
+          rot_flags = 0;
+       ret = IRunningObjectTable_Register(runobtable,rot_flags,punk,moniker,pdwRegister);
        IRunningObjectTable_Release(runobtable);
        IMoniker_Release(moniker);
        return ret;
@@ -594,8 +621,11 @@ ULONG WINAPI OaBuildVersion(void)
     case 0x80000a04:  /* WIN98 */
     case 0x00000004:  /* NT40 */
     case 0x00000005:  /* W2K */
-    case 0x00000105:  /* WinXP */
                return MAKELONG(0xffff, 40);
+    case 0x00000105:  /* WinXP */
+    case 0x00000006:  /* Vista */
+    case 0x00000106:  /* Win7 */
+               return MAKELONG(0xffff, 50);
     default:
                FIXME("Version value not known yet. Please investigate it !\n");
                return MAKELONG(0xffff, 40);  /* for now return the same value as for w2k */
@@ -694,6 +724,8 @@ HRESULT WINAPI OleTranslateColor(
 
 extern HRESULT WINAPI OLEAUTPS_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
 extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
+extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN;
+extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN;
 extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN;
 
 extern void _get_STDFONT_CF(LPVOID *);
@@ -704,7 +736,7 @@ static HRESULT WINAPI PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer *iface, R
     if (IsEqualIID(riid, &IID_IUnknown) ||
         IsEqualIID(riid, &IID_IPSFactoryBuffer))
     {
-        IUnknown_AddRef(iface);
+        IPSFactoryBuffer_AddRef(iface);
         *ppv = iface;
         return S_OK;
     }
@@ -829,9 +861,29 @@ HRESULT WINAPI DllCanUnloadNow(void)
  */
 BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
 {
+    static const WCHAR oanocacheW[] = {'o','a','n','o','c','a','c','h','e',0};
+
+    bstr_cache_enabled = !GetEnvironmentVariableW(oanocacheW, NULL, 0);
+
     return OLEAUTPS_DllMain( hInstDll, fdwReason, lpvReserved );
 }
 
+/***********************************************************************
+ *             DllRegisterServer (OLEAUT32.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+    return OLEAUTPS_DllRegisterServer();
+}
+
+/***********************************************************************
+ *             DllUnregisterServer (OLEAUT32.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    return OLEAUTPS_DllUnregisterServer();
+}
+
 /***********************************************************************
  *              OleIconToCursor (OLEAUT32.415)
  */
index 3b52375..b15b856 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Top level resource file for oleaut32
+ * Resources for oleaut32
  *
  * Copyright 2003 Jon Griffiths
  *
@@ -22,8 +22,6 @@
 #include "winbase.h"
 #include "resource.h"
 
-#include "version.rc"
-
 #ifdef LANGUAGE_BG_BG
     #include "oleaut32_Bg.rc"
 #endif
  *  Turkish (at least) are localised in XP Home.
  *  I expect Chinese etc are localised in Asian Editions also.
  */
+
+/* @makedep: oleaut32.rgs */
+1 WINE_REGISTRY oleaut32.rgs
+
+2 WINE_REGISTRY oleaut32_oaidl.rgs
+3 WINE_REGISTRY oleaut32_ocidl.rgs
+
+#define WINE_FILEDESCRIPTION_STR "Wine OLE dll"
+#define WINE_FILENAME_STR "oleaut32.dll"
+#define WINE_FILEVERSION 6, 0, 6001, 18000 /* version from Vista SP1 */
+#define WINE_FILEVERSION_STR "6.0.6001.18000"
+#define WINE_EXTRAVALUES VALUE "OLESelfRegister",""
+
+#include "wine/wine_common_ver.rc"
diff --git a/reactos/dll/win32/oleaut32/oleaut32.rgs b/reactos/dll/win32/oleaut32/oleaut32.rgs
new file mode 100644 (file)
index 0000000..87a848c
--- /dev/null
@@ -0,0 +1,57 @@
+HKCR
+{
+    NoRemove CLSID
+    {
+        '{00020420-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' }
+        '{00020421-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' }
+        '{00020422-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' }
+        '{00020423-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' }
+        '{00020424-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' }
+        '{00020425-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' }
+        '{DF0B3D60-548F-101B-8E65-08002B2BD119}' { InprocServer = s 'ole2disp.dll' }
+    }
+    NoRemove Interface
+    {
+        '{0000002E-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}'
+        }
+        '{00020400-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid   = s '{00020420-0000-0000-C000-000000000046}'
+            ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}'
+        }
+        '{00020401-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid   = s '{00020422-0000-0000-C000-000000000046}'
+            ProxyStubClsid32 = s '{00020422-0000-0000-C000-000000000046}'
+        }
+        '{00020402-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid   = s '{00020423-0000-0000-C000-000000000046}'
+            ProxyStubClsid32 = s '{00020423-0000-0000-C000-000000000046}'
+        }
+        '{00020403-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid   = s '{00020425-0000-0000-C000-000000000046}'
+            ProxyStubClsid32 = s '{00020425-0000-0000-C000-000000000046}'
+        }
+        '{00020404-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid   = s '{00020421-0000-0000-C000-000000000046}'
+            ProxyStubClsid32 = s '{00020421-0000-0000-C000-000000000046}'
+        }
+        '{00020411-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}'
+        }
+        '{00020412-0000-0000-C000-000000000046}'
+        {
+            ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}'
+        }
+        '{DF0B3D60-548F-101B-8E65-08002B2BD119}'
+        {
+            ProxyStubClsid32 = s '{DF0B3D60-548F-101B-8E65-08002B2BD119}'
+        }
+    }
+}
index 320e7ec..3574d08 100644 (file)
@@ -23,3 +23,9 @@
 cpp_quote("#if 0    /* oleaut32_oaidl.idl hack */")
 #include "oaidl.idl"
 cpp_quote("#endif   /* oleaut32_oaidl.idl hack */")
+
+[
+    threading(both),
+    uuid(b196b286-bab4-101a-b69c-00aa00341d07)
+]
+coclass PSFactoryBuffer { interface IFactoryBuffer; }
diff --git a/reactos/dll/win32/oleaut32/oleaut32_oaidl.rgs b/reactos/dll/win32/oleaut32/oleaut32_oaidl.rgs
new file mode 100644 (file)
index 0000000..ebd7b5a
--- /dev/null
@@ -0,0 +1,78 @@
+HKCR
+{
+    NoRemove Interface
+    {
+        '{00020400-0000-0000-C000-000000000046}' = s 'IDispatch'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{00020404-0000-0000-C000-000000000046}' = s 'IEnumVARIANT'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{00020403-0000-0000-C000-000000000046}' = s 'ITypeComp'
+        {
+            NumMethods = s 5
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{00020401-0000-0000-C000-000000000046}' = s 'ITypeInfo'
+        {
+            NumMethods = s 22
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{00020412-0000-0000-C000-000000000046}' = s 'ITypeInfo2'
+        {
+            NumMethods = s 37
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{00020402-0000-0000-C000-000000000046}' = s 'ITypeLib'
+        {
+            NumMethods = s 13
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{00020411-0000-0000-C000-000000000046}' = s 'ITypeLib2'
+        {
+            NumMethods = s 17
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{1CF2B120-547D-101B-8E65-08002B2BD119}' = s 'IErrorInfo'
+        {
+            NumMethods = s 8
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{22F03340-547D-101B-8E65-08002B2BD119}' = s 'ICreateErrorInfo'
+        {
+            NumMethods = s 8
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{DF0B3D60-548F-101B-8E65-08002B2BD119}' = s 'ISupportErrorInfo'
+        {
+            NumMethods = s 4
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{0000002E-0000-0000-C000-000000000046}' = s 'ITypeFactory'
+        {
+            NumMethods = s 4
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{3127CA40-446E-11CE-8135-00AA004BB851}' = s 'IErrorLog'
+        {
+            NumMethods = s 4
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{55272A00-42CB-11CE-8135-00AA004BB851}' = s 'IPropertyBag'
+        {
+            NumMethods = s 5
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+    }
+    NoRemove CLSID
+    {
+        '{B196B286-BAB4-101A-B69C-00AA00341D07}' = s 'PSFactoryBuffer'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+    }
+}
\ No newline at end of file
index dcd3ea4..fad3741 100644 (file)
  */
 
 #include "ocidl.idl"
+
+[
+    threading(both),
+    uuid(b196b286-bab4-101a-b69c-00aa00341d07)
+]
+coclass PSFactoryBuffer { interface IFactoryBuffer; }
+
+[
+    helpstring("Standard Font"),
+    progid("StdFont"),
+    threading(both),
+    uuid(0be35203-8f91-11ce-9de3-00aa004bb851)
+]
+coclass StdFont { interface IFont; }
+
+[
+    helpstring("Obsolete Font"),
+    progid("OldFont"),
+    threading(both),
+    uuid(46763ee0-cab2-11ce-8c20-00aa0051e5d4)
+]
+coclass OldFont { interface IFont; }
+
+[
+    helpstring("Standard Picture"),
+    progid("StdPicture"),
+    threading(apartment),
+    uuid(0be35204-8f91-11ce-9de3-00aa004bb851)
+]
+coclass StdPicture { interface IPicture; }
+
+[
+    threading(both),
+    uuid(00020420-0000-0000-c000-000000000046)
+]
+coclass PSDispatch { }
+
+[
+    threading(both),
+    uuid(00020421-0000-0000-c000-000000000046)
+]
+coclass PSEnumVariant { }
+
+[
+    threading(both),
+    uuid(00020422-0000-0000-c000-000000000046)
+]
+coclass PSTypeInfo { }
+
+[
+    threading(both),
+    uuid(00020423-0000-0000-c000-000000000046)
+]
+coclass PSTypeLib { }
+
+[
+    threading(both),
+    uuid(00020424-0000-0000-c000-000000000046)
+]
+coclass PSOAInterface { }
+
+[
+    threading(both),
+    uuid(00020425-0000-0000-c000-000000000046)
+]
+coclass PSTypeComp { }
+
+[
+    threading(both),
+    uuid(df0b3d60-548f-101b-8e65-08002b2bd119)
+]
+coclass PSSupportErrorInfo { }
+
+[
+    threading(both),
+    uuid(0000002f-0000-0000-c000-000000000046)
+]
+coclass CLSID_RecordInfo { }
diff --git a/reactos/dll/win32/oleaut32/oleaut32_ocidl.rgs b/reactos/dll/win32/oleaut32/oleaut32_ocidl.rgs
new file mode 100644 (file)
index 0000000..e8b25ae
--- /dev/null
@@ -0,0 +1,252 @@
+HKCR
+{
+    NoRemove Interface
+    {
+        '{BEF6E002-A874-101A-8BBA-00AA00300CAB}' = s 'IFont'
+        {
+            NumMethods = s 27
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{BEF6E003-A874-101A-8BBA-00AA00300CAB}' = s 'IFontDisp'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{4EF6100A-AF88-11D0-9846-00C04FC29993}' = s 'IFontEventsDisp'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{7BF80980-BF32-101A-8BBB-00AA00300CAB}' = s 'IPicture'
+        {
+            NumMethods = s 17
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{7BF80981-BF32-101A-8BBB-00AA00300CAB}' = s 'IPictureDisp'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B288-BAB4-101A-B69C-00AA00341D07}' = s 'IOleControl'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B289-BAB4-101A-B69C-00AA00341D07}' = s 'IOleControlSite'
+        {
+            NumMethods = s 10
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{9C2CAD80-3424-11CF-B670-00AA004CD6D8}' = s 'IOleInPlaceSiteEx'
+        {
+            NumMethods = s 18
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B28F-BAB4-101A-B69C-00AA00341D07}' = s 'IClassFactory2'
+        {
+            NumMethods = s 8
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B283-BAB4-101A-B69C-00AA00341D07}' = s 'IProvideClassInfo'
+        {
+            NumMethods = s 4
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{A6BC3AC0-DBAA-11CE-9DE3-00AA004BB851}' = s 'IProvideClassInfo2'
+        {
+            NumMethods = s 5
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{A7ABA9C1-8983-11CF-8F20-00805F2CD064}' = s 'IProvideMultipleClassInfo'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B286-BAB4-101A-B69C-00AA00341D07}' = s 'IConnectionPoint'
+        {
+            NumMethods = s 8
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B284-BAB4-101A-B69C-00AA00341D07}' = s 'IConnectionPointContainer'
+        {
+            NumMethods = s 5
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B287-BAB4-101A-B69C-00AA00341D07}' = s 'IEnumConnections'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B285-BAB4-101A-B69C-00AA00341D07}' = s 'IEnumConnectionPoints'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B28D-BAB4-101A-B69C-00AA00341D07}' = s 'IPropertyPage'
+        {
+            NumMethods = s 14
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{01E44665-24AC-101B-84ED-08002B2EC713}' = s 'IPropertyPage2'
+        {
+            NumMethods = s 15
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B28C-BAB4-101A-B69C-00AA00341D07}' = s 'IPropertyPageSite'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{9BFBBC02-EFF1-101A-84ED-00AA00341D07}' = s 'IPropertyNotifySink'
+        {
+            NumMethods = s 5
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{742B0E01-14E6-101B-914E-00AA00300CAB}' = s 'ISimpleFrameSite'
+        {
+            NumMethods = s 5
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{7FD52380-4E07-101B-AE2D-08002B2EC713}' = s 'IPersistStreamInit'
+        {
+            NumMethods = s 9
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{BD1AE5E0-A6AE-11CE-BD37-504200C10000}' = s 'IPersistMemory'
+        {
+            NumMethods = s 9
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{37D84F60-42CB-11CE-8135-00AA004BB851}' = s 'IPersistPropertyBag'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{22F55882-280B-11D0-A8A9-00A0C90C2004}' = s 'IPropertyBag2'
+        {
+            NumMethods = s 8
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{22F55881-280B-11D0-A8A9-00A0C90C2004}' = s 'IPersistPropertyBag2'
+        {
+            NumMethods = s 8
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B196B28B-BAB4-101A-B69C-00AA00341D07}' = s 'ISpecifyPropertyPages'
+        {
+            NumMethods = s 4
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{376BD3AA-3845-101B-84ED-08002B2EC713}' = s 'IPerPropertyBrowsing'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{3AF24290-0C96-11CE-A0CF-00AA00600AB8}' = s 'IAdviseSinkEx'
+        {
+            NumMethods = s 9
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{55980BA0-35AA-11CF-B671-00AA004CD6D8}' = s 'IPointerInactive'
+        {
+            NumMethods = s 6
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{FC4801A3-2BA9-11CF-A229-00AA003D7352}' = s 'IObjectWithSite'
+        {
+            NumMethods = s 5
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{894AD3B0-EF97-11CE-9BC9-00AA00608E01}' = s 'IOleUndoUnit'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{A1FAF330-EF97-11CE-9BC9-00AA00608E01}' = s 'IOleParentUndoUnit'
+        {
+            NumMethods = s 12
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{B3E7C340-EF97-11CE-9BC9-00AA00608E01}' = s 'IEnumOleUndoUnits'
+        {
+            NumMethods = s 7
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{D001F200-EF97-11CE-9BC9-00AA00608E01}' = s 'IOleUndoManager'
+        {
+            NumMethods = s 15
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+        '{CF51ED10-62FE-11CF-BF86-00A0C9034836}' = s 'IQuickActivate'
+        {
+            NumMethods = s 6
+            ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}'
+        }
+    }
+    NoRemove CLSID
+    {
+        '{B196B286-BAB4-101A-B69C-00AA00341D07}' = s 'PSFactoryBuffer'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{0BE35203-8F91-11CE-9DE3-00AA004BB851}' = s 'Standard Font'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+            ProgId = s 'StdFont'
+        }
+        '{46763EE0-CAB2-11CE-8C20-00AA0051E5D4}' = s 'Obsolete Font'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+            ProgId = s 'OldFont'
+        }
+        '{0BE35204-8F91-11CE-9DE3-00AA004BB851}' = s 'Standard Picture'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
+            ProgId = s 'StdPicture'
+        }
+        '{00020420-0000-0000-C000-000000000046}' = s 'PSDispatch'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{00020421-0000-0000-C000-000000000046}' = s 'PSEnumVariant'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{00020422-0000-0000-C000-000000000046}' = s 'PSTypeInfo'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{00020423-0000-0000-C000-000000000046}' = s 'PSTypeLib'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{00020424-0000-0000-C000-000000000046}' = s 'PSOAInterface'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{00020425-0000-0000-C000-000000000046}' = s 'PSTypeComp'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{DF0B3D60-548F-101B-8E65-08002B2BD119}' = s 'PSSupportErrorInfo'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+        '{0000002F-0000-0000-C000-000000000046}' = s 'CLSID_RecordInfo'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+        }
+    }
+    'StdFont' = s 'Standard Font'
+    {
+        CLSID = s '{0BE35203-8F91-11CE-9DE3-00AA004BB851}'
+    }
+    'OldFont' = s 'Obsolete Font'
+    {
+        CLSID = s '{46763EE0-CAB2-11CE-8C20-00AA0051E5D4}'
+    }
+    'StdPicture' = s 'Standard Picture'
+    {
+        CLSID = s '{0BE35204-8F91-11CE-9DE3-00AA004BB851}'
+    }
+}
\ No newline at end of file
index 3c8c91f..b5c0cb4 100644 (file)
@@ -251,12 +251,12 @@ struct OLEFontImpl
    * The first two are supported by the first vtable, the next two are
    * supported by the second table and the last two have their own.
    */
-  const IFontVtbl*                     lpVtbl;
-  const IDispatchVtbl*                 lpvtblIDispatch;
-  const IPersistStreamVtbl*            lpvtblIPersistStream;
-  const IConnectionPointContainerVtbl* lpvtblIConnectionPointContainer;
-  const IPersistPropertyBagVtbl*       lpvtblIPersistPropertyBag;
-  const IPersistStreamInitVtbl*        lpvtblIPersistStreamInit;
+  IFont                       IFont_iface;
+  IDispatch                   IDispatch_iface;
+  IPersistStream              IPersistStream_iface;
+  IConnectionPointContainer   IConnectionPointContainer_iface;
+  IPersistPropertyBag         IPersistPropertyBag_iface;
+  IPersistStreamInit          IPersistStreamInit_iface;
   /*
    * Reference count for that instance of the class.
    */
@@ -278,40 +278,43 @@ struct OLEFontImpl
   LONG cyLogical;
   LONG cyHimetric;
 
+  /*
+   * Stash realized height (pixels) from TEXTMETRIC - used in get_Size()
+   */
+  LONG nRealHeight;
+
   IConnectionPoint *pPropertyNotifyCP;
   IConnectionPoint *pFontEventsCP;
 };
 
-/*
- * Here, I define utility macros to help with the casting of the
- * "this" parameter.
- * There is a version to accommodate all of the VTables implemented
- * by this object.
- */
+static inline OLEFontImpl *impl_from_IFont(IFont *iface)
+{
+    return CONTAINING_RECORD(iface, OLEFontImpl, IFont_iface);
+}
 
 static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface )
 {
-    return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIDispatch));
+    return CONTAINING_RECORD(iface, OLEFontImpl, IDispatch_iface);
 }
 
 static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface )
 {
-    return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStream));
+    return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStream_iface);
 }
 
 static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
 {
-    return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIConnectionPointContainer));
+    return CONTAINING_RECORD(iface, OLEFontImpl, IConnectionPointContainer_iface);
 }
 
 static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface )
 {
-    return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistPropertyBag));
+    return CONTAINING_RECORD(iface, OLEFontImpl, IPersistPropertyBag_iface);
 }
 
 static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface )
 {
-    return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStreamInit));
+    return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStreamInit_iface);
 }
 
 
@@ -331,21 +334,17 @@ HRESULT WINAPI OleCreateFontIndirect(
   REFIID     riid,
   LPVOID*     ppvObj)
 {
-  OLEFontImpl* newFont = 0;
-  HRESULT      hr      = S_OK;
+  OLEFontImpl* newFont;
+  HRESULT      hr;
+  FONTDESC     fd;
 
   TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
-  /*
-   * Sanity check
-   */
-  if (ppvObj==0)
-    return E_POINTER;
+
+  if (!ppvObj) return E_POINTER;
 
   *ppvObj = 0;
 
   if (!lpFontDesc) {
-    FONTDESC fd;
-
     static WCHAR fname[] = { 'S','y','s','t','e','m',0 };
 
     fd.cbSizeofstruct = sizeof(fd);
@@ -360,24 +359,11 @@ HRESULT WINAPI OleCreateFontIndirect(
     lpFontDesc = &fd;
   }
 
-  /*
-   * Try to construct a new instance of the class.
-   */
   newFont = OLEFontImpl_Construct(lpFontDesc);
+  if (!newFont) return E_OUTOFMEMORY;
 
-  if (newFont == 0)
-    return E_OUTOFMEMORY;
-
-  /*
-   * Make sure it supports the interface required by the caller.
-   */
-  hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
-
-  /*
-   * Release the reference obtained in the constructor. If
-   * the QueryInterface was unsuccessful, it will free the class.
-   */
-  IFont_Release((IFont*)newFont);
+  hr = IFont_QueryInterface(&newFont->IFont_iface, riid, ppvObj);
+  IFont_Release(&newFont->IFont_iface);
 
   return hr;
 }
@@ -455,11 +441,11 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
         IFontEventsDisp *disp;
 
         IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp);
-        IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL,
-                         LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL,
-                         NULL, NULL);
+        IFontEventsDisp_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL,
+                               LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL,
+                               NULL, NULL);
 
-        IDispatch_Release(disp);
+        IFontEventsDisp_Release(disp);
         IUnknown_Release(CD.pUnk);
     }
     VariantClear(&vararg);
@@ -477,82 +463,75 @@ static HRESULT WINAPI OLEFontImpl_QueryInterface(
   REFIID  riid,
   void**  ppvObject)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
-  TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
+  OLEFontImpl *this = impl_from_IFont(iface);
 
-  /*
-   * Perform a sanity check on the parameters.
-   */
-  if ( (this==0) || (ppvObject==0) )
-    return E_INVALIDARG;
+  TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
 
-  /*
-   * Initialize the return parameter.
-   */
   *ppvObject = 0;
 
-  /*
-   * Compare the riid with the interface IDs implemented by this object.
-   */
-  if (IsEqualGUID(&IID_IUnknown, riid))
-    *ppvObject = this;
-  if (IsEqualGUID(&IID_IFont, riid))
+  if (IsEqualGUID(&IID_IUnknown, riid) ||
+      IsEqualGUID(&IID_IFont, riid))
+  {
     *ppvObject = this;
-  if (IsEqualGUID(&IID_IDispatch, riid))
-    *ppvObject = &this->lpvtblIDispatch;
-  if (IsEqualGUID(&IID_IFontDisp, riid))
-    *ppvObject = &this->lpvtblIDispatch;
-  if (IsEqualIID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistStream, riid))
-    *ppvObject = &this->lpvtblIPersistStream;
-  if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
-    *ppvObject = &this->lpvtblIConnectionPointContainer;
-  if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
-    *ppvObject = &this->lpvtblIPersistPropertyBag;
-  if (IsEqualGUID(&IID_IPersistStreamInit, riid))
-    *ppvObject = &this->lpvtblIPersistStreamInit;
+  }
+  else if (IsEqualGUID(&IID_IDispatch, riid) ||
+           IsEqualGUID(&IID_IFontDisp, riid))
+  {
+    *ppvObject = &this->IDispatch_iface;
+  }
+  else if (IsEqualGUID(&IID_IPersist, riid) ||
+           IsEqualGUID(&IID_IPersistStream, riid))
+  {
+    *ppvObject = &this->IPersistStream_iface;
+  }
+  else if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
+  {
+    *ppvObject = &this->IConnectionPointContainer_iface;
+  }
+  else if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
+  {
+    *ppvObject = &this->IPersistPropertyBag_iface;
+  }
+  else if (IsEqualGUID(&IID_IPersistStreamInit, riid))
+  {
+    *ppvObject = &this->IPersistStreamInit_iface;
+  }
 
-  /*
-   * Check that we obtained an interface.
-   */
-  if ((*ppvObject)==0)
+  if (!*ppvObject)
   {
-    FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
+    FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid));
     return E_NOINTERFACE;
   }
-  OLEFontImpl_AddRef((IFont*)this);
+
+  IFont_AddRef(iface);
+
   return S_OK;
 }
 
 /************************************************************************
  * OLEFontImpl_AddRef (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static ULONG WINAPI OLEFontImpl_AddRef(
   IFont* iface)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(ref=%d)\n", this, this->ref);
   return InterlockedIncrement(&this->ref);
 }
 
 /************************************************************************
  * OLEFontImpl_Release (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
-static ULONG WINAPI OLEFontImpl_Release(
-      IFont* iface)
+static ULONG WINAPI OLEFontImpl_Release(IFont* iface)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
-  ULONG ret;
+  OLEFontImpl *this = impl_from_IFont(iface);
+  ULONG ref;
+
   TRACE("(%p)->(ref=%d)\n", this, this->ref);
 
-  /* Decrease the reference count for current interface */
-  ret = InterlockedDecrement(&this->ref);
+  ref = InterlockedDecrement(&this->ref);
 
-  /* If the reference count goes down to 0, destroy. */
-  if (ret == 0)
+  if (ref == 0)
   {
     ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
 
@@ -574,7 +553,7 @@ static ULONG WINAPI OLEFontImpl_Release(
     OLEFontImpl_Destroy(this);
   }
 
-  return ret;
+  return ref;
 }
 
 typedef struct
@@ -598,86 +577,85 @@ static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm,
 
 static void realize_font(OLEFontImpl *This)
 {
-    if (This->dirty)
-    {
-        LOGFONTW logFont;
-        INT fontHeight;
-        WCHAR text_face[LF_FACESIZE];
-        HDC hdc = get_dc();
-        HFONT old_font;
-        TEXTMETRICW tm;
+    LOGFONTW logFont;
+    INT fontHeight;
+    WCHAR text_face[LF_FACESIZE];
+    HDC hdc = get_dc();
+    HFONT old_font;
+    TEXTMETRICW tm;
 
-        text_face[0] = 0;
+    if (!This->dirty) return;
 
-        if(This->gdiFont)
-        {
-            old_font = SelectObject(hdc, This->gdiFont);
-            GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
-            SelectObject(hdc, old_font);
-            dec_int_ref(This->gdiFont);
-            This->gdiFont = 0;
-        }
-
-        memset(&logFont, 0, sizeof(LOGFONTW));
+    text_face[0] = 0;
 
-        lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
-        logFont.lfCharSet         = This->description.sCharset;
+    if(This->gdiFont)
+    {
+        old_font = SelectObject(hdc, This->gdiFont);
+        GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+        SelectObject(hdc, old_font);
+        dec_int_ref(This->gdiFont);
+        This->gdiFont = 0;
+    }
 
-        /* If the font name has been changed then enumerate all charsets
-           and pick one that'll result in the font specified being selected */
-        if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName))
-        {
-            enum_data data;
-            data.orig_cs = This->description.sCharset;
-            data.avail_cs = -1;
-            logFont.lfCharSet = DEFAULT_CHARSET;
-            EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0);
-            if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs;
-        }
+    memset(&logFont, 0, sizeof(LOGFONTW));
 
+    lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
+    logFont.lfCharSet = This->description.sCharset;
 
-        /*
-         * The height of the font returned by the get_Size property is the
-         * height of the font in points multiplied by 10000... Using some
-         * simple conversions and the ratio given by the application, it can
-         * be converted to a height in pixels.
-         *
-         * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
-         * Ratio is applied here relative to the standard.
-         */
+    /* If the font name has been changed then enumerate all charsets
+       and pick one that'll result in the font specified being selected */
+    if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName))
+    {
+        enum_data data;
+        data.orig_cs = This->description.sCharset;
+        data.avail_cs = -1;
+        logFont.lfCharSet = DEFAULT_CHARSET;
+        EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0);
+        if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs;
+    }
 
-        fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
+    /*
+     * The height of the font returned by the get_Size property is the
+     * height of the font in points multiplied by 10000... Using some
+     * simple conversions and the ratio given by the application, it can
+     * be converted to a height in pixels.
+     *
+     * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
+     * Ratio is applied here relative to the standard.
+     */
 
+    fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
 
-        logFont.lfHeight          = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
+    logFont.lfHeight          = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
                                                                   (-fontHeight/10000L);
-        logFont.lfItalic          = This->description.fItalic;
-        logFont.lfUnderline       = This->description.fUnderline;
-        logFont.lfStrikeOut       = This->description.fStrikethrough;
-        logFont.lfWeight          = This->description.sWeight;
-        logFont.lfOutPrecision    = OUT_CHARACTER_PRECIS;
-        logFont.lfClipPrecision   = CLIP_DEFAULT_PRECIS;
-        logFont.lfQuality         = DEFAULT_QUALITY;
-        logFont.lfPitchAndFamily  = DEFAULT_PITCH;
-
-        This->gdiFont = CreateFontIndirectW(&logFont);
-        This->dirty = FALSE;
-
-        add_hfontitem(This->gdiFont);
-
-        /* Fixup the name and charset properties so that they match the
-           selected font */
-        old_font = SelectObject(get_dc(), This->gdiFont);
-        GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
-        if(lstrcmpiW(text_face, This->description.lpstrName))
-        {
-            HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
-            This->description.lpstrName = strdupW(text_face);
-        }
-        GetTextMetricsW(hdc, &tm);
-        This->description.sCharset = tm.tmCharSet;
-        SelectObject(hdc, old_font);
+    logFont.lfItalic          = This->description.fItalic;
+    logFont.lfUnderline       = This->description.fUnderline;
+    logFont.lfStrikeOut       = This->description.fStrikethrough;
+    logFont.lfWeight          = This->description.sWeight;
+    logFont.lfOutPrecision    = OUT_CHARACTER_PRECIS;
+    logFont.lfClipPrecision   = CLIP_DEFAULT_PRECIS;
+    logFont.lfQuality         = DEFAULT_QUALITY;
+    logFont.lfPitchAndFamily  = DEFAULT_PITCH;
+
+    This->gdiFont = CreateFontIndirectW(&logFont);
+    This->dirty = FALSE;
+
+    add_hfontitem(This->gdiFont);
+
+    /* Fixup the name and charset properties so that they match the
+       selected font */
+    old_font = SelectObject(get_dc(), This->gdiFont);
+    GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+    if(lstrcmpiW(text_face, This->description.lpstrName))
+    {
+        HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
+        This->description.lpstrName = strdupW(text_face);
     }
+    GetTextMetricsW(hdc, &tm);
+    This->description.sCharset = tm.tmCharSet;
+    /* While we have it handy, stash the realized font height for use by get_Size() */
+    This->nRealHeight = tm.tmHeight - tm.tmInternalLeading; /* corresponds to LOGFONT lfHeight */
+    SelectObject(hdc, old_font);
 }
 
 /************************************************************************
@@ -689,15 +667,13 @@ static HRESULT WINAPI OLEFontImpl_get_Name(
   IFont*  iface,
   BSTR* pname)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, pname);
-  /*
-   * Sanity check.
-   */
+
   if (pname==0)
     return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
   if (this->description.lpstrName!=0)
     *pname = SysAllocString(this->description.lpstrName);
@@ -709,78 +685,60 @@ static HRESULT WINAPI OLEFontImpl_get_Name(
 
 /************************************************************************
  * OLEFontImpl_put_Name (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Name(
   IFont* iface,
   BSTR name)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
-  TRACE("(%p)->(%p)\n", this, name);
+  OLEFontImpl *This = impl_from_IFont(iface);
+  TRACE("(%p)->(%p)\n", This, name);
 
   if (!name)
     return CTL_E_INVALIDPROPERTYVALUE;
 
-  if (this->description.lpstrName==0)
-  {
-    this->description.lpstrName = HeapAlloc(GetProcessHeap(),
-                                           0,
-                                           (lstrlenW(name)+1) * sizeof(WCHAR));
-  }
-  else
-  {
-    this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
-                                             0,
-                                             this->description.lpstrName,
-                                             (lstrlenW(name)+1) * sizeof(WCHAR));
-  }
-
-  if (this->description.lpstrName==0)
-    return E_OUTOFMEMORY;
+  HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
+  This->description.lpstrName = strdupW(name);
+  if (!This->description.lpstrName) return E_OUTOFMEMORY;
 
-  strcpyW(this->description.lpstrName, name);
-  TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
-  OLEFont_SendNotify(this, DISPID_FONT_NAME);
+  TRACE("new name %s\n", debugstr_w(This->description.lpstrName));
+  OLEFont_SendNotify(This, DISPID_FONT_NAME);
   return S_OK;
 }
 
 /************************************************************************
  * OLEFontImpl_get_Size (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_get_Size(
   IFont* iface,
   CY*    psize)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, psize);
 
-  /*
-   * Sanity check
-   */
-  if (psize==0)
-    return E_POINTER;
+  if (!psize) return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
+  /*
+   * Convert realized font height in pixels to points descaled by current
+   * scaling ratio then scaled up by 10000.
+   */
+  psize->s.Lo = MulDiv(this->nRealHeight,
+                       this->cyHimetric * 72 * 10000,
+                       this->cyLogical * 2540);
   psize->s.Hi = 0;
-  psize->s.Lo = this->description.cySize.s.Lo;
 
   return S_OK;
 }
 
 /************************************************************************
  * OLEFontImpl_put_Size (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Size(
   IFont* iface,
   CY     size)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d)\n", this, size.s.Lo);
   this->description.cySize.s.Hi = 0;
   this->description.cySize.s.Lo = size.s.Lo;
@@ -798,15 +756,12 @@ static HRESULT WINAPI OLEFontImpl_get_Bold(
   IFont*  iface,
   BOOL* pbold)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, pbold);
-  /*
-   * Sanity check
-   */
-  if (pbold==0)
-    return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  if (!pbold) return E_POINTER;
+
+  realize_font(this);
 
   *pbold = this->description.sWeight > 550;
 
@@ -815,14 +770,12 @@ static HRESULT WINAPI OLEFontImpl_get_Bold(
 
 /************************************************************************
  * OLEFontImpl_put_Bold (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Bold(
   IFont* iface,
   BOOL bold)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d)\n", this, bold);
   this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
   OLEFont_SendNotify(this, DISPID_FONT_BOLD);
@@ -832,22 +785,18 @@ static HRESULT WINAPI OLEFontImpl_put_Bold(
 
 /************************************************************************
  * OLEFontImpl_get_Italic (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_get_Italic(
   IFont*  iface,
   BOOL* pitalic)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, pitalic);
-  /*
-   * Sanity check
-   */
+
   if (pitalic==0)
     return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
   *pitalic = this->description.fItalic;
 
@@ -856,14 +805,12 @@ static HRESULT WINAPI OLEFontImpl_get_Italic(
 
 /************************************************************************
  * OLEFontImpl_put_Italic (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Italic(
   IFont* iface,
   BOOL italic)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d)\n", this, italic);
 
   this->description.fItalic = italic;
@@ -874,23 +821,18 @@ static HRESULT WINAPI OLEFontImpl_put_Italic(
 
 /************************************************************************
  * OLEFontImpl_get_Underline (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_get_Underline(
   IFont*  iface,
   BOOL* punderline)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, punderline);
 
-  /*
-   * Sanity check
-   */
   if (punderline==0)
     return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
   *punderline = this->description.fUnderline;
 
@@ -899,14 +841,12 @@ static HRESULT WINAPI OLEFontImpl_get_Underline(
 
 /************************************************************************
  * OLEFontImpl_put_Underline (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Underline(
   IFont* iface,
   BOOL underline)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d)\n", this, underline);
 
   this->description.fUnderline = underline;
@@ -917,23 +857,18 @@ static HRESULT WINAPI OLEFontImpl_put_Underline(
 
 /************************************************************************
  * OLEFontImpl_get_Strikethrough (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
   IFont*  iface,
   BOOL* pstrikethrough)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, pstrikethrough);
 
-  /*
-   * Sanity check
-   */
   if (pstrikethrough==0)
     return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
   *pstrikethrough = this->description.fStrikethrough;
 
@@ -942,14 +877,12 @@ static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
 
 /************************************************************************
  * OLEFontImpl_put_Strikethrough (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
  IFont* iface,
  BOOL strikethrough)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d)\n", this, strikethrough);
 
   this->description.fStrikethrough = strikethrough;
@@ -960,23 +893,18 @@ static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
 
 /************************************************************************
  * OLEFontImpl_get_Weight (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_get_Weight(
   IFont* iface,
   short* pweight)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, pweight);
 
-  /*
-   * Sanity check
-   */
   if (pweight==0)
     return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
   *pweight = this->description.sWeight;
 
@@ -985,14 +913,12 @@ static HRESULT WINAPI OLEFontImpl_get_Weight(
 
 /************************************************************************
  * OLEFontImpl_put_Weight (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Weight(
   IFont* iface,
   short  weight)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d)\n", this, weight);
 
   this->description.sWeight = weight;
@@ -1003,23 +929,18 @@ static HRESULT WINAPI OLEFontImpl_put_Weight(
 
 /************************************************************************
  * OLEFontImpl_get_Charset (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_get_Charset(
   IFont* iface,
   short* pcharset)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, pcharset);
 
-  /*
-   * Sanity check
-   */
   if (pcharset==0)
     return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
   *pcharset = this->description.sCharset;
 
@@ -1028,14 +949,12 @@ static HRESULT WINAPI OLEFontImpl_get_Charset(
 
 /************************************************************************
  * OLEFontImpl_put_Charset (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_put_Charset(
   IFont* iface,
   short charset)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d)\n", this, charset);
 
   this->description.sCharset = charset;
@@ -1046,19 +965,17 @@ static HRESULT WINAPI OLEFontImpl_put_Charset(
 
 /************************************************************************
  * OLEFontImpl_get_hFont (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_get_hFont(
   IFont*   iface,
   HFONT* phfont)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%p)\n", this, phfont);
   if (phfont==NULL)
     return E_POINTER;
 
-  if(this->dirty) realize_font(this);
+  realize_font(this);
 
   *phfont = this->gdiFont;
   TRACE("Returning %p\n", *phfont);
@@ -1067,15 +984,13 @@ static HRESULT WINAPI OLEFontImpl_get_hFont(
 
 /************************************************************************
  * OLEFontImpl_Clone (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_Clone(
   IFont*  iface,
   IFont** ppfont)
 {
-  OLEFontImpl* newObject = 0;
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
+  OLEFontImpl* newObject;
 
   TRACE("(%p)->(%p)\n", this, ppfont);
 
@@ -1084,32 +999,19 @@ static HRESULT WINAPI OLEFontImpl_Clone(
 
   *ppfont = NULL;
 
-  /*
-   * Allocate space for the object.
-   */
   newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
-
   if (newObject==NULL)
     return E_OUTOFMEMORY;
 
   *newObject = *this;
-
-  /* We need to alloc new memory for the string, otherwise
-   * we free memory twice.
-   */
-  newObject->description.lpstrName = HeapAlloc(
-       GetProcessHeap(),0,
-       (1+strlenW(this->description.lpstrName))*2
-  );
-  strcpyW(newObject->description.lpstrName, this->description.lpstrName);
-
+  /* allocate separate buffer */
+  newObject->description.lpstrName = strdupW(this->description.lpstrName);
 
   /* Increment internal ref in hfont item list */
   if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
 
   InterlockedIncrement(&ifont_cnt);
 
-  /* create new connection points */
   newObject->pPropertyNotifyCP = NULL;
   newObject->pFontEventsCP = NULL;
   CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
@@ -1122,28 +1024,26 @@ static HRESULT WINAPI OLEFontImpl_Clone(
   }
 
   /* The cloned object starts with a reference count of 1 */
-  newObject->ref          = 1;
+  newObject->ref = 1;
 
-  *ppfont = (IFont*)newObject;
+  *ppfont = &newObject->IFont_iface;
 
   return S_OK;
 }
 
 /************************************************************************
  * OLEFontImpl_IsEqual (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_IsEqual(
   IFont* iface,
   IFont* pFontOther)
 {
-  OLEFontImpl *left = (OLEFontImpl *)iface;
-  OLEFontImpl *right = (OLEFontImpl *)pFontOther;
+  OLEFontImpl *left = impl_from_IFont(iface);
+  OLEFontImpl *right = impl_from_IFont(pFontOther);
   INT ret;
   INT left_len,right_len;
 
-  if((iface == NULL) || (pFontOther == NULL))
+  if(pFontOther == NULL)
     return E_POINTER;
   else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo)
     return S_FALSE;
@@ -1173,27 +1073,27 @@ static HRESULT WINAPI OLEFontImpl_IsEqual(
 
 /************************************************************************
  * OLEFontImpl_SetRatio (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_SetRatio(
   IFont* iface,
   LONG   cyLogical,
   LONG   cyHimetric)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric);
 
+  if(cyLogical == 0 || cyHimetric == 0)
+    return E_INVALIDARG;
+
   this->cyLogical  = cyLogical;
   this->cyHimetric = cyHimetric;
+  this->dirty = TRUE;
 
   return S_OK;
 }
 
 /************************************************************************
  * OLEFontImpl_QueryTextMetrics (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT      WINAPI OLEFontImpl_QueryTextMetrics(
   IFont*         iface,
@@ -1203,7 +1103,7 @@ static HRESULT      WINAPI OLEFontImpl_QueryTextMetrics(
   HFONT hOldFont, hNewFont;
 
   hdcRef = GetDC(0);
-  OLEFontImpl_get_hFont(iface, &hNewFont);
+  IFont_get_hFont(iface, &hNewFont);
   hOldFont = SelectObject(hdcRef, hNewFont);
   GetTextMetricsW(hdcRef, ptm);
   SelectObject(hdcRef, hOldFont);
@@ -1213,14 +1113,12 @@ static HRESULT      WINAPI OLEFontImpl_QueryTextMetrics(
 
 /************************************************************************
  * OLEFontImpl_AddRefHfont (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
   IFont*  iface,
   HFONT hfont)
 {
-    OLEFontImpl *this = (OLEFontImpl *)iface;
+    OLEFontImpl *this = impl_from_IFont(iface);
 
     TRACE("(%p)->(%p)\n", this, hfont);
 
@@ -1231,14 +1129,12 @@ static HRESULT WINAPI OLEFontImpl_AddRefHfont(
 
 /************************************************************************
  * OLEFontImpl_ReleaseHfont (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
   IFont*  iface,
   HFONT hfont)
 {
-    OLEFontImpl *this = (OLEFontImpl *)iface;
+    OLEFontImpl *this = impl_from_IFont(iface);
 
     TRACE("(%p)->(%p)\n", this, hfont);
 
@@ -1249,21 +1145,16 @@ static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
 
 /************************************************************************
  * OLEFontImpl_SetHdc (IFont)
- *
- * See Windows documentation for more details on IFont methods.
  */
 static HRESULT WINAPI OLEFontImpl_SetHdc(
   IFont* iface,
   HDC  hdc)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
+  OLEFontImpl *this = impl_from_IFont(iface);
   FIXME("(%p)->(%p): Stub\n", this, hdc);
   return E_NOTIMPL;
 }
 
-/*
- * Virtual function tables for the OLEFontImpl class.
- */
 static const IFontVtbl OLEFontImpl_VTable =
 {
   OLEFontImpl_QueryInterface,
@@ -1297,8 +1188,6 @@ static const IFontVtbl OLEFontImpl_VTable =
 
 /************************************************************************
  * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
   IDispatch* iface,
@@ -1306,40 +1195,31 @@ static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
   VOID**     ppvoid)
 {
   OLEFontImpl *this = impl_from_IDispatch(iface);
-
-  return IFont_QueryInterface((IFont *)this, riid, ppvoid);
+  return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
 }
 
 /************************************************************************
  * OLEFontImpl_IDispatch_Release (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
   IDispatch* iface)
 {
   OLEFontImpl *this = impl_from_IDispatch(iface);
-
-  return IFont_Release((IFont *)this);
+  return IFont_Release(&this->IFont_iface);
 }
 
 /************************************************************************
  * OLEFontImpl_IDispatch_AddRef (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
   IDispatch* iface)
 {
   OLEFontImpl *this = impl_from_IDispatch(iface);
-
-  return IFont_AddRef((IFont *)this);
+  return IFont_AddRef(&this->IFont_iface);
 }
 
 /************************************************************************
  * OLEFontImpl_GetTypeInfoCount (IDispatch)
- *
- * See Windows documentation for more details on IDispatch methods.
  */
 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
   IDispatch*    iface,
@@ -1354,8 +1234,6 @@ static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
 
 /************************************************************************
  * OLEFontImpl_GetTypeInfo (IDispatch)
- *
- * See Windows documentation for more details on IDispatch methods.
  */
 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
   IDispatch*  iface,
@@ -1386,8 +1264,6 @@ static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
 
 /************************************************************************
  * OLEFontImpl_GetIDsOfNames (IDispatch)
- *
- * See Windows documentation for more details on IDispatch methods.
  */
 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
   IDispatch*  iface,
@@ -1405,33 +1281,24 @@ static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
   TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid),
         rgszNames, cNames, (int)lcid, rgDispId);
 
-  if (cNames == 0)
+  if (cNames == 0) return E_INVALIDARG;
+
+  hres = IDispatch_GetTypeInfo(iface, 0, lcid, &pTInfo);
+  if (FAILED(hres))
   {
-    return E_INVALIDARG;
+    ERR("GetTypeInfo failed.\n");
+    return hres;
   }
-  else
-  {
-    /* retrieve type information */
-    hres = OLEFontImpl_GetTypeInfo(iface, 0, lcid, &pTInfo);
 
-    if (FAILED(hres))
-    {
-      ERR("GetTypeInfo failed.\n");
-      return hres;
-    }
+  /* convert names to DISPIDs */
+  hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId);
+  ITypeInfo_Release(pTInfo);
 
-    /* convert names to DISPIDs */
-    hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId);
-    ITypeInfo_Release(pTInfo);
-
-    return hres;
-  }
+  return hres;
 }
 
 /************************************************************************
  * OLEFontImpl_Invoke (IDispatch)
- *
- * See Windows documentation for more details on IDispatch methods.
  * 
  * Note: Do not call _put_Xxx methods, since setting things here
  * should not call notify functions as I found out debugging the generic
@@ -1494,7 +1361,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_NAME:
     if (wFlags & DISPATCH_PROPERTYGET) {
       V_VT(pVarResult) = VT_BSTR;
-      return IFont_get_Name((IFont *)this, &V_BSTR(pVarResult));
+      return IFont_get_Name(&this->IFont_iface, &V_BSTR(pVarResult));
     } else {
       VARIANTARG vararg;
 
@@ -1503,7 +1370,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Name((IFont *)this, V_BSTR(&vararg));
+      hr = IFont_put_Name(&this->IFont_iface, V_BSTR(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1512,7 +1379,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_BOLD:
     if (wFlags & DISPATCH_PROPERTYGET) {
       BOOL value;
-      hr = IFont_get_Bold((IFont *)this, &value);
+      hr = IFont_get_Bold(&this->IFont_iface, &value);
       V_VT(pVarResult) = VT_BOOL;
       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
       return hr;
@@ -1524,7 +1391,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Bold((IFont *)this, V_BOOL(&vararg));
+      hr = IFont_put_Bold(&this->IFont_iface, V_BOOL(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1533,7 +1400,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_ITALIC:
     if (wFlags & DISPATCH_PROPERTYGET) {
       BOOL value;
-      hr = IFont_get_Italic((IFont *)this, &value);
+      hr = IFont_get_Italic(&this->IFont_iface, &value);
       V_VT(pVarResult) = VT_BOOL;
       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
       return hr;
@@ -1545,7 +1412,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Italic((IFont *)this, V_BOOL(&vararg));
+      hr = IFont_put_Italic(&this->IFont_iface, V_BOOL(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1554,7 +1421,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_UNDER:
     if (wFlags & DISPATCH_PROPERTYGET) {
       BOOL value;
-      hr = IFont_get_Underline((IFont *)this, &value);
+      hr = IFont_get_Underline(&this->IFont_iface, &value);
       V_VT(pVarResult) = VT_BOOL;
       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
       return hr;
@@ -1566,7 +1433,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Underline((IFont *)this, V_BOOL(&vararg));
+      hr = IFont_put_Underline(&this->IFont_iface, V_BOOL(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1575,7 +1442,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_STRIKE:
     if (wFlags & DISPATCH_PROPERTYGET) {
       BOOL value;
-      hr = IFont_get_Strikethrough((IFont *)this, &value);
+      hr = IFont_get_Strikethrough(&this->IFont_iface, &value);
       V_VT(pVarResult) = VT_BOOL;
       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
       return hr;
@@ -1587,7 +1454,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Strikethrough((IFont *)this, V_BOOL(&vararg));
+      hr = IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1596,7 +1463,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_SIZE:
     if (wFlags & DISPATCH_PROPERTYGET) {
       V_VT(pVarResult) = VT_CY;
-      return OLEFontImpl_get_Size((IFont *)this, &V_CY(pVarResult));
+      return IFont_get_Size(&this->IFont_iface, &V_CY(pVarResult));
     } else {
       VARIANTARG vararg;
 
@@ -1605,7 +1472,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Size((IFont *)this, V_CY(&vararg));
+      hr = IFont_put_Size(&this->IFont_iface, V_CY(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1614,7 +1481,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_WEIGHT:
     if (wFlags & DISPATCH_PROPERTYGET) {
       V_VT(pVarResult) = VT_I2;
-      return OLEFontImpl_get_Weight((IFont *)this, &V_I2(pVarResult));
+      return IFont_get_Weight(&this->IFont_iface, &V_I2(pVarResult));
     } else {
       VARIANTARG vararg;
 
@@ -1623,7 +1490,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Weight((IFont *)this, V_I2(&vararg));
+      hr = IFont_put_Weight(&this->IFont_iface, V_I2(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1632,7 +1499,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
   case DISPID_FONT_CHARSET:
     if (wFlags & DISPATCH_PROPERTYGET) {
       V_VT(pVarResult) = VT_I2;
-      return OLEFontImpl_get_Charset((IFont *)this, &V_I2(pVarResult));
+      return OLEFontImpl_get_Charset(&this->IFont_iface, &V_I2(pVarResult));
     } else {
       VARIANTARG vararg;
 
@@ -1641,7 +1508,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IFont_put_Charset((IFont *)this, V_I2(&vararg));
+      hr = IFont_put_Charset(&this->IFont_iface, V_I2(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -1666,8 +1533,6 @@ static const IDispatchVtbl OLEFontImpl_IDispatch_VTable =
 
 /************************************************************************
  * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
   IPersistStream* iface,
@@ -1676,39 +1541,33 @@ static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
 {
   OLEFontImpl *this = impl_from_IPersistStream(iface);
 
-  return IFont_QueryInterface((IFont *)this, riid, ppvoid);
+  return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
 }
 
 /************************************************************************
  * OLEFontImpl_IPersistStream_Release (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
   IPersistStream* iface)
 {
   OLEFontImpl *this = impl_from_IPersistStream(iface);
 
-  return IFont_Release((IFont *)this);
+  return IFont_Release(&this->IFont_iface);
 }
 
 /************************************************************************
  * OLEFontImpl_IPersistStream_AddRef (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
   IPersistStream* iface)
 {
   OLEFontImpl *this = impl_from_IPersistStream(iface);
 
-  return IFont_AddRef((IFont *)this);
+  return IFont_AddRef(&this->IFont_iface);
 }
 
 /************************************************************************
  * OLEFontImpl_GetClassID (IPersistStream)
- *
- * See Windows documentation for more details on IPersistStream methods.
  */
 static HRESULT WINAPI OLEFontImpl_GetClassID(
   IPersistStream* iface,
@@ -1760,80 +1619,50 @@ static HRESULT WINAPI OLEFontImpl_Load(
   IPersistStream*  iface,
   IStream*         pLoadStream)
 {
-  char  readBuffer[0x100];
+  OLEFontImpl *this = impl_from_IPersistStream(iface);
+  BYTE  version, attributes, string_size;
+  char readBuffer[0x100];
   ULONG cbRead;
-  BYTE  bVersion;
-  BYTE  bAttributes;
-  BYTE  bStringSize;
   INT len;
 
-  OLEFontImpl *this = impl_from_IPersistStream(iface);
+  /* Version */
+  IStream_Read(pLoadStream, &version, sizeof(BYTE), &cbRead);
+  if ((cbRead != sizeof(BYTE)) || (version != 0x01)) return E_FAIL;
 
-  /*
-   * Read the version byte
-   */
-  IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
+  /* Charset */
+  IStream_Read(pLoadStream, &this->description.sCharset, sizeof(WORD), &cbRead);
+  if (cbRead != sizeof(WORD)) return E_FAIL;
 
-  if ( (cbRead!=1) ||
-       (bVersion!=0x01) )
-    return E_FAIL;
+  /* Attributes */
+  IStream_Read(pLoadStream, &attributes, sizeof(BYTE), &cbRead);
+  if (cbRead != sizeof(BYTE)) return E_FAIL;
 
-  /*
-   * Charset
-   */
-  IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
+  this->description.fItalic        = (attributes & FONTPERSIST_ITALIC) != 0;
+  this->description.fStrikethrough = (attributes & FONTPERSIST_STRIKETHROUGH) != 0;
+  this->description.fUnderline     = (attributes & FONTPERSIST_UNDERLINE) != 0;
 
-  if (cbRead!=2)
-    return E_FAIL;
+  /* Weight */
+  IStream_Read(pLoadStream, &this->description.sWeight, sizeof(WORD), &cbRead);
+  if (cbRead != sizeof(WORD)) return E_FAIL;
 
-  /*
-   * Attributes
-   */
-  IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
-
-  if (cbRead!=1)
-    return E_FAIL;
-
-  this->description.fItalic        = (bAttributes & FONTPERSIST_ITALIC) != 0;
-  this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
-  this->description.fUnderline     = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
-
-  /*
-   * Weight
-   */
-  IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
-
-  if (cbRead!=2)
-    return E_FAIL;
-
-  /*
-   * Size
-   */
-  IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
-
-  if (cbRead!=4)
-    return E_FAIL;
+  /* Size */
+  IStream_Read(pLoadStream, &this->description.cySize.s.Lo, sizeof(DWORD), &cbRead);
+  if (cbRead != sizeof(DWORD)) return E_FAIL;
 
   this->description.cySize.s.Hi = 0;
 
-  /*
-   * FontName
-   */
-  IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
-
-  if (cbRead!=1)
-    return E_FAIL;
-
-  IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
+  /* Name */
+  IStream_Read(pLoadStream, &string_size, sizeof(BYTE), &cbRead);
+  if (cbRead != sizeof(BYTE)) return E_FAIL;
 
-  if (cbRead!=bStringSize)
-    return E_FAIL;
+  IStream_Read(pLoadStream, readBuffer, string_size, &cbRead);
+  if (cbRead != string_size) return E_FAIL;
 
   HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
 
-  len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
+  len = MultiByteToWideChar( CP_ACP, 0, readBuffer, string_size, NULL, 0 );
   this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
-  MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
+  MultiByteToWideChar( CP_ACP, 0, readBuffer, string_size, this->description.lpstrName, len );
   this->description.lpstrName[len] = 0;
 
   /* Ensure use of this font causes a new one to be created */
@@ -1846,99 +1675,72 @@ static HRESULT WINAPI OLEFontImpl_Load(
 
 /************************************************************************
  * OLEFontImpl_Save (IPersistStream)
- *
- * See Windows documentation for more details on IPersistStream methods.
  */
 static HRESULT WINAPI OLEFontImpl_Save(
   IPersistStream*  iface,
   IStream*         pOutStream,
   BOOL             fClearDirty)
 {
-  char* writeBuffer = NULL;
-  ULONG cbWritten;
-  BYTE  bVersion = 0x01;
-  BYTE  bAttributes;
-  BYTE  bStringSize;
-
   OLEFontImpl *this = impl_from_IPersistStream(iface);
+  BYTE  attributes, string_size;
+  const BYTE version = 0x01;
+  char* writeBuffer = NULL;
+  ULONG written;
 
-  /*
-   * Read the version byte
-   */
-  IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
-
-  if (cbWritten!=1)
-    return E_FAIL;
+  TRACE("(%p)->(%p %d)\n", this, pOutStream, fClearDirty);
 
-  /*
-   * Charset
-   */
-  IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
+  /* Version */
+  IStream_Write(pOutStream, &version, sizeof(BYTE), &written);
+  if (written != sizeof(BYTE)) return E_FAIL;
 
-  if (cbWritten!=2)
-    return E_FAIL;
+  /* Charset */
+  IStream_Write(pOutStream, &this->description.sCharset, sizeof(WORD), &written);
+  if (written != sizeof(WORD)) return E_FAIL;
 
-  /*
-   * Attributes
-   */
-  bAttributes = 0;
+  /* Attributes */
+  attributes = 0;
 
   if (this->description.fItalic)
-    bAttributes |= FONTPERSIST_ITALIC;
+    attributes |= FONTPERSIST_ITALIC;
 
   if (this->description.fStrikethrough)
-    bAttributes |= FONTPERSIST_STRIKETHROUGH;
+    attributes |= FONTPERSIST_STRIKETHROUGH;
 
   if (this->description.fUnderline)
-    bAttributes |= FONTPERSIST_UNDERLINE;
-
-  IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
+    attributes |= FONTPERSIST_UNDERLINE;
 
-  if (cbWritten!=1)
-    return E_FAIL;
+  IStream_Write(pOutStream, &attributes, sizeof(BYTE), &written);
+  if (written != sizeof(BYTE)) return E_FAIL;
 
-  /*
-   * Weight
-   */
-  IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
-
-  if (cbWritten!=2)
-    return E_FAIL;
+  /* Weight */
+  IStream_Write(pOutStream, &this->description.sWeight, sizeof(WORD), &written);
+  if (written != sizeof(WORD)) return E_FAIL;
 
-  /*
-   * Size
-   */
-  IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
-
-  if (cbWritten!=4)
-    return E_FAIL;
+  /* Size */
+  IStream_Write(pOutStream, &this->description.cySize.s.Lo, sizeof(DWORD), &written);
+  if (written != sizeof(DWORD)) return E_FAIL;
 
-  /*
-   * FontName
-   */
-  if (this->description.lpstrName!=0)
-    bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
+  /* FontName */
+  if (this->description.lpstrName)
+    string_size = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
                                        strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
   else
-    bStringSize = 0;
+    string_size = 0;
 
-  IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
-
-  if (cbWritten!=1)
-    return E_FAIL;
+  IStream_Write(pOutStream, &string_size, sizeof(BYTE), &written);
+  if (written != sizeof(BYTE)) return E_FAIL;
 
-  if (bStringSize!=0)
+  if (string_size)
   {
-      if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
+      if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, string_size ))) return E_OUTOFMEMORY;
       WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
                            strlenW(this->description.lpstrName),
-                           writeBuffer, bStringSize, NULL, NULL );
+                           writeBuffer, string_size, NULL, NULL );
 
-    IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
-    HeapFree(GetProcessHeap(), 0, writeBuffer);
+      IStream_Write(pOutStream, writeBuffer, string_size, &written);
+      HeapFree(GetProcessHeap(), 0, writeBuffer);
 
-    if (cbWritten!=bStringSize)
-      return E_FAIL;
+      if (written != string_size) return E_FAIL;
   }
 
   return S_OK;
@@ -1946,8 +1748,6 @@ static HRESULT WINAPI OLEFontImpl_Save(
 
 /************************************************************************
  * OLEFontImpl_GetSizeMax (IPersistStream)
- *
- * See Windows documentation for more details on IPersistStream methods.
  */
 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
   IPersistStream*  iface,
@@ -1990,8 +1790,6 @@ static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable =
 
 /************************************************************************
  * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
   IConnectionPointContainer* iface,
@@ -2000,40 +1798,33 @@ static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
 {
   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
 
-  return IFont_QueryInterface((IFont*)this, riid, ppvoid);
+  return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
 }
 
 /************************************************************************
  * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
   IConnectionPointContainer* iface)
 {
   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
 
-  return IFont_Release((IFont*)this);
+  return IFont_Release(&this->IFont_iface);
 }
 
 /************************************************************************
  * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
- *
- * See Windows documentation for more details on IUnknown methods.
  */
 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
   IConnectionPointContainer* iface)
 {
   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
 
-  return IFont_AddRef((IFont*)this);
+  return IFont_AddRef(&this->IFont_iface);
 }
 
 /************************************************************************
  * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
- *
- * See Windows documentation for more details on IConnectionPointContainer
- * methods.
  */
 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
   IConnectionPointContainer* iface,
@@ -2047,9 +1838,6 @@ static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
 
 /************************************************************************
  * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
- *
- * See Windows documentation for more details on IConnectionPointContainer
- * methods.
  */
 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
    IConnectionPointContainer* iface,
@@ -2090,21 +1878,21 @@ static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
    IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
 ) {
   OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
-  return IFont_QueryInterface((IFont *)this,riid,ppvObj);
+  return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj);
 }
 
 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
    IPersistPropertyBag *iface
 ) {
   OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
-  return IFont_AddRef((IFont *)this);
+  return IFont_AddRef(&this->IFont_iface);
 }
 
 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
    IPersistPropertyBag *iface
 ) {
   OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
-  return IFont_Release((IFont *)this);
+  return IFont_Release(&this->IFont_iface);
 }
 
 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
@@ -2140,111 +1928,106 @@ static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
     static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0};
     static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0};
     static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
-    VARIANT rawAttr;
-    VARIANT valueAttr;
-    HRESULT iRes = S_OK;
     OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
+    VARIANT value;
+    HRESULT iRes;
 
-    VariantInit(&rawAttr);
-    VariantInit(&valueAttr);
+    VariantInit(&value);
 
-    if (iRes == S_OK) {
-        iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog);
+    iRes = IPropertyBag_Read(pPropBag, sAttrName, &value, pErrorLog);
+    if (iRes == S_OK)
+    {
+        iRes = VariantChangeType(&value, &value, 0, VT_BSTR);
         if (iRes == S_OK)
-        {
-            iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR);
-            if (iRes == S_OK)
-                iRes = IFont_put_Name((IFont *)this, V_BSTR(&valueAttr));
-        }
-        else if (iRes == E_INVALIDARG)
-            iRes = S_OK;
-        VariantClear(&rawAttr);
-        VariantClear(&valueAttr);
+            iRes = IFont_put_Name(&this->IFont_iface, V_BSTR(&value));
     }
+    else if (iRes == E_INVALIDARG)
+        iRes = S_OK;
+
+    VariantClear(&value);
 
     if (iRes == S_OK) {
-        iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog);
+        iRes = IPropertyBag_Read(pPropBag, sAttrSize, &value, pErrorLog);
         if (iRes == S_OK)
         {
-            iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY);
+            iRes = VariantChangeType(&value, &value, 0, VT_CY);
             if (iRes == S_OK)
-                iRes = IFont_put_Size((IFont *)this, V_CY(&valueAttr));
+                iRes = IFont_put_Size(&this->IFont_iface, V_CY(&value));
         }
         else if (iRes == E_INVALIDARG)
             iRes = S_OK;
-        VariantClear(&rawAttr);
-        VariantClear(&valueAttr);
+
+        VariantClear(&value);
     }
 
     if (iRes == S_OK) {
-        iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog);
+        iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &value, pErrorLog);
         if (iRes == S_OK)
         {
-            iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
+            iRes = VariantChangeType(&value, &value, 0, VT_I2);
             if (iRes == S_OK)
-                iRes = IFont_put_Charset((IFont *)this, V_I2(&valueAttr));
+                iRes = IFont_put_Charset(&this->IFont_iface, V_I2(&value));
         }
         else if (iRes == E_INVALIDARG)
             iRes = S_OK;
-        VariantClear(&rawAttr);
-        VariantClear(&valueAttr);
+
+        VariantClear(&value);
     }
 
     if (iRes == S_OK) {
-        iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog);
+        iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &value, pErrorLog);
         if (iRes == S_OK)
         {
-            iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
+            iRes = VariantChangeType(&value, &value, 0, VT_I2);
             if (iRes == S_OK)
-                iRes = IFont_put_Weight((IFont *)this, V_I2(&valueAttr));
+                iRes = IFont_put_Weight(&this->IFont_iface, V_I2(&value));
         }
         else if (iRes == E_INVALIDARG)
             iRes = S_OK;
-        VariantClear(&rawAttr);
-        VariantClear(&valueAttr);
 
+        VariantClear(&value);
     }
 
     if (iRes == S_OK) {
-        iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog);
+        iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &value, pErrorLog);
         if (iRes == S_OK)
         {
-            iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
+            iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
             if (iRes == S_OK)
-                iRes = IFont_put_Underline((IFont *)this, V_BOOL(&valueAttr));
+                iRes = IFont_put_Underline(&this->IFont_iface, V_BOOL(&value));
         }
         else if (iRes == E_INVALIDARG)
             iRes = S_OK;
-        VariantClear(&rawAttr);
-        VariantClear(&valueAttr);
+
+        VariantClear(&value);
     }
 
     if (iRes == S_OK) {
-        iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog);
+        iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &value, pErrorLog);
         if (iRes == S_OK)
         {
-            iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
+            iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
             if (iRes == S_OK)
-                iRes = IFont_put_Italic((IFont *)this, V_BOOL(&valueAttr));
+                iRes = IFont_put_Italic(&this->IFont_iface, V_BOOL(&value));
         }
         else if (iRes == E_INVALIDARG)
             iRes = S_OK;
-        VariantClear(&rawAttr);
-        VariantClear(&valueAttr);
+
+        VariantClear(&value);
     }
 
     if (iRes == S_OK) {
-        iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog);
+        iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &value, pErrorLog);
         if (iRes == S_OK)
         {
-            iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
+            iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
             if (iRes == S_OK)
-                IFont_put_Strikethrough((IFont *)this, V_BOOL(&valueAttr));
+                IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&value));
         }
         else if (iRes == E_INVALIDARG)
             iRes = S_OK;
-        VariantClear(&rawAttr);
-        VariantClear(&valueAttr);
+
+        VariantClear(&value);
     }
 
     if (FAILED(iRes))
@@ -2279,21 +2062,21 @@ static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
    IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
 ) {
   OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
-  return IFont_QueryInterface((IFont *)this,riid,ppvObj);
+  return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj);
 }
 
 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
    IPersistStreamInit *iface
 ) {
   OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
-  return IFont_AddRef((IFont *)this);
+  return IFont_AddRef(&this->IFont_iface);
 }
 
 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
    IPersistStreamInit *iface
 ) {
   OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
-  return IFont_Release((IFont *)this);
+  return IFont_Release(&this->IFont_iface);
 }
 
 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
@@ -2363,42 +2146,24 @@ static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable =
  */
 static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
 {
-  OLEFontImpl* newObject = 0;
+  OLEFontImpl* newObject;
 
-  /*
-   * Allocate space for the object.
-   */
   newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
 
   if (newObject==0)
     return newObject;
 
-  /*
-   * Initialize the virtual function table.
-   */
-  newObject->lpVtbl = &OLEFontImpl_VTable;
-  newObject->lpvtblIDispatch = &OLEFontImpl_IDispatch_VTable;
-  newObject->lpvtblIPersistStream = &OLEFontImpl_IPersistStream_VTable;
-  newObject->lpvtblIConnectionPointContainer = &OLEFontImpl_IConnectionPointContainer_VTable;
-  newObject->lpvtblIPersistPropertyBag = &OLEFontImpl_IPersistPropertyBag_VTable;
-  newObject->lpvtblIPersistStreamInit = &OLEFontImpl_IPersistStreamInit_VTable;
+  newObject->IFont_iface.lpVtbl = &OLEFontImpl_VTable;
+  newObject->IDispatch_iface.lpVtbl = &OLEFontImpl_IDispatch_VTable;
+  newObject->IPersistStream_iface.lpVtbl = &OLEFontImpl_IPersistStream_VTable;
+  newObject->IConnectionPointContainer_iface.lpVtbl = &OLEFontImpl_IConnectionPointContainer_VTable;
+  newObject->IPersistPropertyBag_iface.lpVtbl = &OLEFontImpl_IPersistPropertyBag_VTable;
+  newObject->IPersistStreamInit_iface.lpVtbl = &OLEFontImpl_IPersistStreamInit_VTable;
 
-  /*
-   * Start with one reference count. The caller of this function
-   * must release the interface pointer when it is done.
-   */
   newObject->ref = 1;
 
-  /*
-   * Copy the description of the font in the object.
-   */
-  assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
-
   newObject->description.cbSizeofstruct = sizeof(FONTDESC);
-  newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
-                                              0,
-                                              (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
-  strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
+  newObject->description.lpstrName      = strdupW(fontDesc->lpstrName);
   newObject->description.cySize         = fontDesc->cySize;
   newObject->description.sWeight        = fontDesc->sWeight;
   newObject->description.sCharset       = fontDesc->sCharset;
@@ -2406,18 +2171,15 @@ static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
   newObject->description.fUnderline     = fontDesc->fUnderline;
   newObject->description.fStrikethrough = fontDesc->fStrikethrough;
 
-  /*
-   * Initializing all the other members.
-   */
   newObject->gdiFont  = 0;
   newObject->dirty = TRUE;
-  newObject->cyLogical  = 72L;
+  newObject->cyLogical  = GetDeviceCaps(get_dc(), LOGPIXELSY);
   newObject->cyHimetric = 2540L;
   newObject->pPropertyNotifyCP = NULL;
   newObject->pFontEventsCP = NULL;
 
-  CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
-  CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
+  CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
+  CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
 
   if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
   {
@@ -2458,13 +2220,18 @@ static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
 typedef struct
 {
     /* IUnknown fields */
-    const IClassFactoryVtbl    *lpVtbl;
-    LONG                        ref;
+    IClassFactory IClassFactory_iface;
+    LONG          ref;
 } IClassFactoryImpl;
 
+static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
+{
+        return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
+}
+
 static HRESULT WINAPI
 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
 
        FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
        return E_NOINTERFACE;
@@ -2472,12 +2239,12 @@ SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
 
 static ULONG WINAPI
 SFCF_AddRef(LPCLASSFACTORY iface) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
        return InterlockedIncrement(&This->ref);
 }
 
 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
        /* static class, won't be  freed */
        return InterlockedDecrement(&This->ref);
 }
@@ -2490,7 +2257,7 @@ static HRESULT WINAPI SFCF_CreateInstance(
 }
 
 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
        FIXME("(%p)->(%d),stub!\n",This,dolock);
        return S_OK;
 }
@@ -2502,6 +2269,6 @@ static const IClassFactoryVtbl SFCF_Vtbl = {
        SFCF_CreateInstance,
        SFCF_LockServer
 };
-static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
+static IClassFactoryImpl STDFONT_CF = {{&SFCF_Vtbl}, 1 };
 
 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = &STDFONT_CF; }
index b8e949d..3fdb1c7 100644 (file)
 #include "oleauto.h"
 #include "connpt.h"
 #include "urlmon.h"
+#include "initguid.h"
 #include "wincodec.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
 #include "wine/library.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
+WINE_DEFAULT_DEBUG_CHANNEL(olepicture);
+
+#define BITMAP_FORMAT_BMP   0x4d42 /* "BM" */
+#define BITMAP_FORMAT_JPEG  0xd8ff
+#define BITMAP_FORMAT_GIF   0x4947
+#define BITMAP_FORMAT_PNG   0x5089
+#define BITMAP_FORMAT_APM   0xcdd7
 
 #include "pshpack1.h"
 
@@ -114,10 +121,10 @@ typedef struct OLEPictureImpl {
    * IPicture handles IUnknown
    */
 
-    const IPictureVtbl       *lpVtbl;
-    const IDispatchVtbl      *lpvtblIDispatch;
-    const IPersistStreamVtbl *lpvtblIPersistStream;
-    const IConnectionPointContainerVtbl *lpvtblIConnectionPointContainer;
+    IPicture                  IPicture_iface;
+    IDispatch                 IDispatch_iface;
+    IPersistStream            IPersistStream_iface;
+    IConnectionPointContainer IConnectionPointContainer_iface;
 
   /* Object reference count */
     LONG ref;
@@ -140,6 +147,7 @@ typedef struct OLEPictureImpl {
 
     BOOL keepOrigFormat;
     HDC        hDCCur;
+    HBITMAP stock_bitmap;
 
   /* Bitmap transparency mask */
     HBITMAP hbmMask;
@@ -154,23 +162,24 @@ typedef struct OLEPictureImpl {
     unsigned int loadtime_format;   /* for PICTYPE_BITMAP only, keeps track of image format (GIF/BMP/JPEG) */
 } OLEPictureImpl;
 
-/*
- * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
- */
+static inline OLEPictureImpl *impl_from_IPicture(IPicture *iface)
+{
+    return CONTAINING_RECORD(iface, OLEPictureImpl, IPicture_iface);
+}
 
 static inline OLEPictureImpl *impl_from_IDispatch( IDispatch *iface )
 {
-    return (OLEPictureImpl *)((char*)iface - FIELD_OFFSET(OLEPictureImpl, lpvtblIDispatch));
+    return CONTAINING_RECORD(iface, OLEPictureImpl, IDispatch_iface);
 }
 
 static inline OLEPictureImpl *impl_from_IPersistStream( IPersistStream *iface )
 {
-    return (OLEPictureImpl *)((char*)iface - FIELD_OFFSET(OLEPictureImpl, lpvtblIPersistStream));
+    return CONTAINING_RECORD(iface, OLEPictureImpl, IPersistStream_iface);
 }
 
 static inline OLEPictureImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
 {
-    return (OLEPictureImpl *)((char*)iface - FIELD_OFFSET(OLEPictureImpl, lpvtblIConnectionPointContainer));
+    return CONTAINING_RECORD(iface, OLEPictureImpl, IConnectionPointContainer_iface);
 }
 
 /*
@@ -181,28 +190,48 @@ static const IDispatchVtbl OLEPictureImpl_IDispatch_VTable;
 static const IPersistStreamVtbl OLEPictureImpl_IPersistStream_VTable;
 static const IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContainer_VTable;
 
+/* pixels to HIMETRIC units conversion */
+static inline OLE_XSIZE_HIMETRIC xpixels_to_himetric(INT pixels, HDC hdc)
+{
+    return MulDiv(pixels, 2540, GetDeviceCaps(hdc, LOGPIXELSX));
+}
+
+static inline OLE_YSIZE_HIMETRIC ypixels_to_himetric(INT pixels, HDC hdc)
+{
+    return MulDiv(pixels, 2540, GetDeviceCaps(hdc, LOGPIXELSY));
+}
+
 /***********************************************************************
  * Implementation of the OLEPictureImpl class.
  */
 
-static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) {
+static void OLEPictureImpl_SetBitmap(OLEPictureImpl *This)
+{
   BITMAP bm;
   HDC hdcRef;
 
   TRACE("bitmap handle %p\n", This->desc.u.bmp.hbitmap);
-  if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
+  if(GetObjectW(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
     ERR("GetObject fails\n");
     return;
   }
   This->origWidth = bm.bmWidth;
   This->origHeight = bm.bmHeight;
+
+  TRACE("width %d, height %d, bpp %d\n", bm.bmWidth, bm.bmHeight, bm.bmBitsPixel);
+
   /* The width and height are stored in HIMETRIC units (0.01 mm),
      so we take our pixel width divide by pixels per inch and
      multiply by 25.4 * 100 */
   /* Should we use GetBitmapDimension if available? */
   hdcRef = CreateCompatibleDC(0);
-  This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
-  This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
+
+  This->himetricWidth  = xpixels_to_himetric(bm.bmWidth, hdcRef);
+  This->himetricHeight = ypixels_to_himetric(bm.bmHeight, hdcRef);
+  This->stock_bitmap = GetCurrentObject( hdcRef, OBJ_BITMAP );
+
+  This->loadtime_format = BITMAP_FORMAT_BMP;
+
   DeleteDC(hdcRef);
 }
 
@@ -216,7 +245,7 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This)
         BITMAP bm;
 
         TRACE("bitmap handle for icon is %p\n", infoIcon.hbmColor);
-        if(GetObjectA(infoIcon.hbmColor ? infoIcon.hbmColor : infoIcon.hbmMask, sizeof(bm), &bm) != sizeof(bm)) {
+        if(GetObjectW(infoIcon.hbmColor ? infoIcon.hbmColor : infoIcon.hbmMask, sizeof(bm), &bm) != sizeof(bm)) {
             ERR("GetObject fails on icon bitmap\n");
             return;
         }
@@ -225,8 +254,10 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This)
         This->origHeight = infoIcon.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
         /* see comment on HIMETRIC on OLEPictureImpl_SetBitmap() */
         hdcRef = GetDC(0);
-        This->himetricWidth = (This->origWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
-        This->himetricHeight= (This->origHeight *2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
+
+        This->himetricWidth  = xpixels_to_himetric(This->origWidth, hdcRef);
+        This->himetricHeight = ypixels_to_himetric(This->origHeight, hdcRef);
+
         ReleaseDC(0, hdcRef);
 
         DeleteObject(infoIcon.hbmMask);
@@ -263,10 +294,10 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
   /*
    * Initialize the virtual function table.
    */
-  newObject->lpVtbl = &OLEPictureImpl_VTable;
-  newObject->lpvtblIDispatch = &OLEPictureImpl_IDispatch_VTable;
-  newObject->lpvtblIPersistStream = &OLEPictureImpl_IPersistStream_VTable;
-  newObject->lpvtblIConnectionPointContainer = &OLEPictureImpl_IConnectionPointContainer_VTable;
+  newObject->IPicture_iface.lpVtbl = &OLEPictureImpl_VTable;
+  newObject->IDispatch_iface.lpVtbl = &OLEPictureImpl_IDispatch_VTable;
+  newObject->IPersistStream_iface.lpVtbl = &OLEPictureImpl_IPersistStream_VTable;
+  newObject->IConnectionPointContainer_iface.lpVtbl = &OLEPictureImpl_IConnectionPointContainer_VTable;
 
   newObject->pCP = NULL;
   CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP);
@@ -381,7 +412,7 @@ static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
 static ULONG WINAPI OLEPictureImpl_AddRef(
   IPicture* iface)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   ULONG refCount = InterlockedIncrement(&This->ref);
 
   TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
@@ -397,7 +428,7 @@ static ULONG WINAPI OLEPictureImpl_AddRef(
 static ULONG WINAPI OLEPictureImpl_Release(
       IPicture* iface)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   ULONG refCount = InterlockedDecrement(&This->ref);
 
   TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
@@ -420,48 +451,33 @@ static HRESULT WINAPI OLEPictureImpl_QueryInterface(
   REFIID  riid,
   void**  ppvObject)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
+
   TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
 
-  /*
-   * Perform a sanity check on the parameters.
-   */
-  if ( (This==0) || (ppvObject==0) )
+  if (!ppvObject)
     return E_INVALIDARG;
 
-  /*
-   * Initialize the return parameter.
-   */
   *ppvObject = 0;
 
-  /*
-   * Compare the riid with the interface IDs implemented by this object.
-   */
   if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IPicture, riid))
     *ppvObject = This;
   else if (IsEqualIID(&IID_IDispatch, riid))
-    *ppvObject = &This->lpvtblIDispatch;
+    *ppvObject = &This->IDispatch_iface;
   else if (IsEqualIID(&IID_IPictureDisp, riid))
-    *ppvObject = &This->lpvtblIDispatch;
+    *ppvObject = &This->IDispatch_iface;
   else if (IsEqualIID(&IID_IPersist, riid) || IsEqualIID(&IID_IPersistStream, riid))
-    *ppvObject = &This->lpvtblIPersistStream;
+    *ppvObject = &This->IPersistStream_iface;
   else if (IsEqualIID(&IID_IConnectionPointContainer, riid))
-    *ppvObject = &This->lpvtblIConnectionPointContainer;
+    *ppvObject = &This->IConnectionPointContainer_iface;
 
-  /*
-   * Check that we obtained an interface.
-   */
-  if ((*ppvObject)==0)
+  if (!*ppvObject)
   {
     FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
     return E_NOINTERFACE;
   }
 
-  /*
-   * Query Interface always increases the reference count by one when it is
-   * successful
-   */
-  OLEPictureImpl_AddRef((IPicture*)This);
+  IPicture_AddRef(iface);
 
   return S_OK;
 }
@@ -477,7 +493,7 @@ static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID)
   IEnumConnections *pEnum;
   CONNECTDATA CD;
 
-  if (IConnectionPoint_EnumConnections(this->pCP, &pEnum))
+  if (IConnectionPoint_EnumConnections(this->pCP, &pEnum) != S_OK)
       return;
   while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
     IPropertyNotifySink *sink;
@@ -496,7 +512,7 @@ static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID)
 static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
                                                OLE_HANDLE *phandle)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p)\n", This, phandle);
 
   if(!phandle)
@@ -533,7 +549,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
                                              OLE_HANDLE *phandle)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   HRESULT hres;
   TRACE("(%p)->(%p)\n", This, phandle);
 
@@ -572,7 +588,7 @@ static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface,
                                              short *ptype)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p): type is %d\n", This, ptype, This->desc.picType);
 
   if(!ptype)
@@ -588,7 +604,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
                                               OLE_XSIZE_HIMETRIC *pwidth)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p): width is %d\n", This, pwidth, This->himetricWidth);
   *pwidth = This->himetricWidth;
   return S_OK;
@@ -600,7 +616,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
                                                OLE_YSIZE_HIMETRIC *pheight)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p): height is %d\n", This, pheight, This->himetricHeight);
   *pheight = This->himetricHeight;
   return S_OK;
@@ -617,7 +633,7 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
                                            OLE_YSIZE_HIMETRIC cySrc,
                                            LPCRECT prcWBounds)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p, (%d,%d), (%d,%d) <- (%d,%d), (%d,%d), %p)\n",
        This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds);
   if(prcWBounds)
@@ -736,7 +752,7 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
                                              OLE_HANDLE hpal)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   FIXME("(%p)->(%08x): stub\n", This, hpal);
   OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
   return E_NOTIMPL;
@@ -748,7 +764,7 @@ static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface,
                                               HDC *phdc)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p), returning %p\n", This, This->hDCCur);
   if (phdc) *phdc = This->hDCCur;
   return S_OK;
@@ -762,13 +778,13 @@ static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
                                                   HDC *phdcOut,
                                                   OLE_HANDLE *phbmpOut)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut);
   if (This->desc.picType == PICTYPE_BITMAP) {
-      SelectObject(hdcIn,This->desc.u.bmp.hbitmap);
-
       if (phdcOut)
          *phdcOut = This->hDCCur;
+      if (This->hDCCur) SelectObject(This->hDCCur,This->stock_bitmap);
+      if (hdcIn) SelectObject(hdcIn,This->desc.u.bmp.hbitmap);
       This->hDCCur = hdcIn;
       if (phbmpOut)
          *phbmpOut = HandleToUlong(This->desc.u.bmp.hbitmap);
@@ -785,7 +801,7 @@ static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
                                                            BOOL *pfKeep)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p)\n", This, pfKeep);
   if (!pfKeep)
       return E_POINTER;
@@ -799,7 +815,7 @@ static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
                                                            BOOL keep)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%d)\n", This, keep);
   This->keepOrigFormat = keep;
   /* FIXME: what DISPID notification here? */
@@ -811,7 +827,7 @@ static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
  */
 static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->()\n", This);
   OLEPicture_SendNotify(This,DISPID_PICT_HANDLE);
   This->bIsDirty = TRUE;
@@ -826,7 +842,7 @@ static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
                                                BOOL SaveMemCopy,
                                                LONG *pcbSize)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize);
   return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize);
 }
@@ -837,7 +853,7 @@ static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
 static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
                                                    DWORD *pdwAttr)
 {
-  OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  OLEPictureImpl *This = impl_from_IPicture(iface);
   TRACE("(%p)->(%p).\n", This, pdwAttr);
 
   if(!pdwAttr)
@@ -867,7 +883,7 @@ static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface(
 {
   OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);
 
-  return IPicture_QueryInterface((IPicture *)This,riid,ppvoid);
+  return IPicture_QueryInterface(&This->IPicture_iface,riid,ppvoid);
 }
 
 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef(
@@ -875,7 +891,7 @@ static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef(
 {
   OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);
 
-  return IPicture_AddRef((IPicture *)This);
+  return IPicture_AddRef(&This->IPicture_iface);
 }
 
 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release(
@@ -883,7 +899,7 @@ static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release(
 {
   OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);
 
-  return IPicture_Release((IPicture *)This);
+  return IPicture_Release(&This->IPicture_iface);
 }
 
 static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints(
@@ -929,7 +945,7 @@ static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface(
 {
   OLEPictureImpl *This = impl_from_IPersistStream(iface);
 
-  return IPicture_QueryInterface((IPicture *)This, riid, ppvoid);
+  return IPicture_QueryInterface(&This->IPicture_iface, riid, ppvoid);
 }
 
 /************************************************************************
@@ -942,7 +958,7 @@ static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef(
 {
   OLEPictureImpl *This = impl_from_IPersistStream(iface);
 
-  return IPicture_AddRef((IPicture *)This);
+  return IPicture_AddRef(&This->IPicture_iface);
 }
 
 /************************************************************************
@@ -955,7 +971,7 @@ static ULONG WINAPI OLEPictureImpl_IPersistStream_Release(
 {
   OLEPictureImpl *This = impl_from_IPersistStream(iface);
 
-  return IPicture_Release((IPicture *)This);
+  return IPicture_Release(&This->IPicture_iface);
 }
 
 /************************************************************************
@@ -1222,16 +1238,34 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x
        }
        if (i==cifd->idCount) i=0;
     }
-
-    hicon = CreateIconFromResourceEx(
-               xbuf+cifd->idEntries[i].dwDIBOffset,
-               cifd->idEntries[i].dwDIBSize,
-               TRUE, /* is icon */
-               0x00030000,
-               cifd->idEntries[i].bWidth,
-               cifd->idEntries[i].bHeight,
-               0
-    );
+    if (cifd->idType == 2)
+    {
+        LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, cifd->idEntries[i].dwDIBSize + 4);
+        memcpy(buf, &cifd->idEntries[i].xHotspot, 4);
+        memcpy(buf + 4, xbuf+cifd->idEntries[i].dwDIBOffset, cifd->idEntries[i].dwDIBSize);
+        hicon = CreateIconFromResourceEx(
+                   buf,
+                   cifd->idEntries[i].dwDIBSize + 4,
+                   FALSE, /* is cursor */
+                   0x00030000,
+                   cifd->idEntries[i].bWidth,
+                   cifd->idEntries[i].bHeight,
+                   0
+       );
+       HeapFree(GetProcessHeap(), 0, buf);
+    }
+    else
+    {
+        hicon = CreateIconFromResourceEx(
+                   xbuf+cifd->idEntries[i].dwDIBOffset,
+                   cifd->idEntries[i].dwDIBSize,
+                   TRUE, /* is icon */
+                   0x00030000,
+                   cifd->idEntries[i].bWidth,
+                   cifd->idEntries[i].bHeight,
+                   0
+       );
+    }
     if (!hicon) {
        ERR("CreateIcon failed.\n");
        return E_FAIL;
@@ -1241,8 +1275,8 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x
        This->origWidth = cifd->idEntries[i].bWidth;
        This->origHeight = cifd->idEntries[i].bHeight;
        hdcRef = CreateCompatibleDC(0);
-       This->himetricWidth =(cifd->idEntries[i].bWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
-       This->himetricHeight=(cifd->idEntries[i].bHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
+       This->himetricWidth = xpixels_to_himetric(cifd->idEntries[i].bWidth, hdcRef);
+       This->himetricHeight= ypixels_to_himetric(cifd->idEntries[i].bHeight, hdcRef);
        DeleteDC(hdcRef);
        return S_OK;
     }
@@ -1297,17 +1331,6 @@ static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This,
     return S_OK;
 }
 
-/************************************************************************
- * BITMAP FORMAT FLAGS -
- *   Flags that differentiate between different types of bitmaps.
- */
-
-#define BITMAP_FORMAT_BMP   0x4d42 /* "BM" */
-#define BITMAP_FORMAT_JPEG  0xd8ff
-#define BITMAP_FORMAT_GIF   0x4947
-#define BITMAP_FORMAT_PNG   0x5089
-#define BITMAP_FORMAT_APM   0xcdd7
-
 /************************************************************************
  * OLEPictureImpl_IPersistStream_Load (IUnknown)
  *
@@ -1316,11 +1339,11 @@ static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This,
  *     DWORD magic;
  *     DWORD len;
  *
- * Currently implemented: BITMAP, ICON, JPEG, GIF, WMF, EMF
+ * Currently implemented: BITMAP, ICON, CURSOR, JPEG, GIF, WMF, EMF
  */
-static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
-  HRESULT      hr = E_FAIL;
-  BOOL         headerisdata = FALSE;
+static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) {
+  HRESULT      hr;
+  BOOL         headerisdata;
   BOOL         statfailed = FALSE;
   ULONG                xread, toread;
   ULONG        headerread;
@@ -1348,8 +1371,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
    * Also handle streams where we do not have a working "Stat" method by
    * reading all data until the end of the stream.
    */
-  hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
-  if (hr) {
+  hr = IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
+  if (hr != S_OK) {
       TRACE("stat failed with hres %x, proceeding to read all data.\n",hr);
       statfailed = TRUE;
       /* we will read at least 8 byte ... just right below */
@@ -1360,8 +1383,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
   headerread = 0;
   headerisdata = FALSE;
   do {
-      hr=IStream_Read(pStm,header,8,&xread);
-      if (hr || xread!=8) {
+      hr = IStream_Read(pStm, header, 8, &xread);
+      if (hr != S_OK || xread!=8) {
           ERR("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread);
           return (hr?hr:E_FAIL);
       }
@@ -1379,6 +1402,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
               !memcmp(&(header[0]), "BM",       2) ||   /* BMP header */
               !memcmp(&(header[0]), "\xff\xd8", 2) ||   /* JPEG header */
               (header[0] == EMR_HEADER)            ||   /* EMF header */
+              (header[0] == 0x10000)               ||   /* icon: idReserved 0, idType 1 */
+              (header[0] == 0x20000)               ||   /* cursor: idReserved 0, idType 2 */
               (header[1] > statstg.cbSize.QuadPart)||   /* invalid size */
               (header[1]==0)
           ) {/* Found start of bitmap data */
@@ -1406,11 +1431,11 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
       while (1) {
           while (xread < origsize) {
               hr = IStream_Read(pStm,xbuf+xread,origsize-xread,&nread);
-              xread+=nread;
-              if (hr || !nread)
+              xread += nread;
+              if (hr != S_OK || !nread)
                   break;
           }
-          if (!nread || hr) /* done, or error */
+          if (!nread || hr != S_OK) /* done, or error */
               break;
           if (xread == origsize) {
               origsize += sizeinc;
@@ -1418,7 +1443,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
               xbuf = HeapReAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, xbuf, origsize);
           }
       }
-      if (hr)
+      if (hr != S_OK)
           TRACE("hr in no-stat loader case is %08x\n", hr);
       TRACE("loaded %d bytes.\n", xread);
       This->datalen = xread;
@@ -1435,8 +1460,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
       while (xread < This->datalen) {
           ULONG nread;
           hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread);
-          xread+=nread;
-          if (hr || !nread)
+          xread += nread;
+          if (hr != S_OK || !nread)
               break;
       }
       if (xread != This->datalen)
@@ -1471,7 +1496,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
   case BITMAP_FORMAT_APM: /* APM */
     hr = OLEPictureImpl_LoadAPM(This, xbuf, xread);
     break;
-  case 0x0000: { /* ICON , first word is dwReserved */
+  case 0x0000: { /* ICON or CURSOR, first word is dwReserved */
     hr = OLEPictureImpl_LoadIcon(This, xbuf, xread);
     break;
   }
@@ -1617,6 +1642,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
                        pIconDir = (CURSORICONFILEDIR *)pIconData;
                        pIconDir->idType = 1;
                        pIconDir->idCount = 1;
+                       pIconDir->idReserved = 0;
 
                        /* Fill out the CURSORICONFILEDIRENTRY */
                        pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
@@ -1723,6 +1749,7 @@ static HRESULT WINAPI OLEPictureImpl_Save(
     HRESULT hResult = E_NOTIMPL;
     void * pIconData;
     unsigned int iDataSize;
+    DWORD header[2];
     ULONG dummy;
     int iSerializeResult = 0;
     OLEPictureImpl *This = impl_from_IPersistStream(iface);
@@ -1730,6 +1757,12 @@ static HRESULT WINAPI OLEPictureImpl_Save(
     TRACE("%p %p %d\n", This, pStm, fClearDirty);
 
     switch (This->desc.picType) {
+    case PICTYPE_NONE:
+        header[0] = 0x0000746c;
+        header[1] = 0;
+        hResult = IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+        break;
+
     case PICTYPE_ICON:
         if (This->bIsDirty || !This->data) {
             if (!serializeIcon(This->desc.u.icon.hicon, &pIconData, &iDataSize)) {
@@ -1741,19 +1774,15 @@ static HRESULT WINAPI OLEPictureImpl_Save(
             This->data = pIconData;
             This->datalen = iDataSize;
         }
-        if (This->loadtime_magic != 0xdeadbeef) {
-            DWORD header[2];
 
-            header[0] = This->loadtime_magic;
-            header[1] = This->datalen;
-            IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
-        }
+        header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
+        header[1] = This->datalen;
+        IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
         IStream_Write(pStm, This->data, This->datalen, &dummy);
-
         hResult = S_OK;
         break;
     case PICTYPE_BITMAP:
-        if (This->bIsDirty) {
+        if (This->bIsDirty || !This->data) {
             switch (This->keepOrigFormat ? This->loadtime_format : BITMAP_FORMAT_BMP) {
             case BITMAP_FORMAT_BMP:
                 iSerializeResult = serializeBMP(This->desc.u.bmp.hbitmap, &pIconData, &iDataSize);
@@ -1771,38 +1800,23 @@ static HRESULT WINAPI OLEPictureImpl_Save(
                 FIXME("(%p,%p,%d), PICTYPE_BITMAP (format UNKNOWN, using BMP?) not implemented!\n",This,pStm,fClearDirty);
                 break;
             }
-            if (iSerializeResult) {
-                /*
-                if (This->loadtime_magic != 0xdeadbeef) {
-                */
-                if (1) {
-                    DWORD header[2];
-
-                    header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
-                    header[1] = iDataSize;
-                    IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
-                }
-                IStream_Write(pStm, pIconData, iDataSize, &dummy);
-
-                HeapFree(GetProcessHeap(), 0, This->data);
-                This->data = pIconData;
-                This->datalen = iDataSize;
-                hResult = S_OK;
-            }
-        } else {
-            /*
-            if (This->loadtime_magic != 0xdeadbeef) {
-            */
-            if (1) {
-                DWORD header[2];
-
-                header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
-                header[1] = This->datalen;
-                IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+
+            if (!iSerializeResult)
+            {
+                hResult = E_FAIL;
+                break;
             }
-            IStream_Write(pStm, This->data, This->datalen, &dummy);
-            hResult = S_OK;
+
+            HeapFree(GetProcessHeap(), 0, This->data);
+            This->data = pIconData;
+            This->datalen = iDataSize;
         }
+
+        header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
+        header[1] = This->datalen;
+        IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+        IStream_Write(pStm, This->data, This->datalen, &dummy);
+        hResult = S_OK;
         break;
     case PICTYPE_METAFILE:
         FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty);
@@ -1843,7 +1857,7 @@ static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface(
 {
   OLEPictureImpl *This = impl_from_IDispatch(iface);
 
-  return IPicture_QueryInterface((IPicture *)This, riid, ppvoid);
+  return IPicture_QueryInterface(&This->IPicture_iface, riid, ppvoid);
 }
 
 /************************************************************************
@@ -1856,7 +1870,7 @@ static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef(
 {
   OLEPictureImpl *This = impl_from_IDispatch(iface);
 
-  return IPicture_AddRef((IPicture *)This);
+  return IPicture_AddRef(&This->IPicture_iface);
 }
 
 /************************************************************************
@@ -1869,7 +1883,7 @@ static ULONG WINAPI OLEPictureImpl_IDispatch_Release(
 {
   OLEPictureImpl *This = impl_from_IDispatch(iface);
 
-  return IPicture_Release((IPicture *)This);
+  return IPicture_Release(&This->IPicture_iface);
 }
 
 /************************************************************************
@@ -2025,7 +2039,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
     {
       TRACE("DISPID_PICT_HANDLE\n");
       V_VT(pVarResult) = VT_I4;
-      return IPicture_get_Handle((IPicture *)&This->lpVtbl, &V_UINT(pVarResult));
+      return IPicture_get_Handle(&This->IPicture_iface, &V_UINT(pVarResult));
     }
     break;
   case DISPID_PICT_HPAL:
@@ -2033,7 +2047,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
     {
       TRACE("DISPID_PICT_HPAL\n");
       V_VT(pVarResult) = VT_I4;
-      return IPicture_get_hPal((IPicture *)&This->lpVtbl, &V_UINT(pVarResult));
+      return IPicture_get_hPal(&This->IPicture_iface, &V_UINT(pVarResult));
     }
     else if (wFlags & DISPATCH_PROPERTYPUT)
     {
@@ -2046,7 +2060,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
       if (FAILED(hr))
         return hr;
 
-      hr = IPicture_set_hPal((IPicture *)&This->lpVtbl, V_I4(&vararg));
+      hr = IPicture_set_hPal(&This->IPicture_iface, V_I4(&vararg));
 
       VariantClear(&vararg);
       return hr;
@@ -2057,7 +2071,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
     {
       TRACE("DISPID_PICT_TYPE\n");
       V_VT(pVarResult) = VT_I2;
-      return OLEPictureImpl_get_Type((IPicture *)&This->lpVtbl, &V_I2(pVarResult));
+      return OLEPictureImpl_get_Type(&This->IPicture_iface, &V_I2(pVarResult));
     }
     break;
   case DISPID_PICT_WIDTH:
@@ -2065,7 +2079,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
     {
       TRACE("DISPID_PICT_WIDTH\n");
       V_VT(pVarResult) = VT_I4;
-      return IPicture_get_Width((IPicture *)&This->lpVtbl, &V_I4(pVarResult));
+      return IPicture_get_Width(&This->IPicture_iface, &V_I4(pVarResult));
     }
     break;
   case DISPID_PICT_HEIGHT:
@@ -2073,7 +2087,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
     {
       TRACE("DISPID_PICT_HEIGHT\n");
       V_VT(pVarResult) = VT_I4;
-      return IPicture_get_Height((IPicture *)&This->lpVtbl, &V_I4(pVarResult));
+      return IPicture_get_Height(&This->IPicture_iface, &V_I4(pVarResult));
     }
     break;
   }
@@ -2140,25 +2154,16 @@ static const IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContai
  * OleCreatePictureIndirect (OLEAUT32.419)
  */
 HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
-                           BOOL fOwn, LPVOID *ppvObj )
+                           BOOL Own, void **ppvObj )
 {
-  OLEPictureImpl* newPict = NULL;
-  HRESULT      hr         = S_OK;
-
-  TRACE("(%p,%s,%d,%p)\n", lpPictDesc, debugstr_guid(riid), fOwn, ppvObj);
+  OLEPictureImpl* newPict;
+  HRESULT hr;
 
-  /*
-   * Sanity check
-   */
-  if (ppvObj==0)
-    return E_POINTER;
+  TRACE("(%p,%s,%d,%p)\n", lpPictDesc, debugstr_guid(riid), Own, ppvObj);
 
   *ppvObj = NULL;
 
-  /*
-   * Try to construct a new instance of the class.
-   */
-  newPict = OLEPictureImpl_Construct(lpPictDesc, fOwn);
+  newPict = OLEPictureImpl_Construct(lpPictDesc, Own);
 
   if (newPict == NULL)
     return E_OUTOFMEMORY;
@@ -2166,13 +2171,13 @@ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
   /*
    * Make sure it supports the interface required by the caller.
    */
-  hr = IPicture_QueryInterface((IPicture*)newPict, riid, ppvObj);
+  hr = IPicture_QueryInterface(&newPict->IPicture_iface, riid, ppvObj);
 
   /*
    * Release the reference obtained in the constructor. If
    * the QueryInterface was unsuccessful, it will free the class.
    */
-  IPicture_Release((IPicture*)newPict);
+  IPicture_Release(&newPict->IPicture_iface);
 
   return hr;
 }
@@ -2192,10 +2197,10 @@ HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
        lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj);
 
   hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
-  if (hr)
+  if (hr != S_OK)
     return hr;
   hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
-  if (hr) {
+  if (hr != S_OK) {
       ERR("Could not get IPersistStream iface from Ole Picture?\n");
       IPicture_Release(newpic);
       *ppvObj = NULL;
@@ -2211,7 +2216,7 @@ HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
       return hr;
   }
   hr = IPicture_QueryInterface(newpic,riid,ppvObj);
-  if (hr)
+  if (hr != S_OK)
       ERR("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
   IPicture_Release(newpic);
   return hr;
@@ -2231,10 +2236,10 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
        lpstream, lSize, fRunmode, debugstr_guid(riid), xsiz, ysiz, flags, ppvObj);
 
   hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
-  if (hr)
+  if (hr != S_OK)
     return hr;
   hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
-  if (hr) {
+  if (hr != S_OK) {
       ERR("Could not get IPersistStream iface from Ole Picture?\n");
       IPicture_Release(newpic);
       *ppvObj = NULL;
@@ -2250,7 +2255,7 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
       return hr;
   }
   hr = IPicture_QueryInterface(newpic,riid,ppvObj);
-  if (hr)
+  if (hr != S_OK)
       ERR("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
   IPicture_Release(newpic);
   return hr;
@@ -2304,7 +2309,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
       hFile = CreateFileW(file_candidate, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                           0, NULL);
       if (hFile == INVALID_HANDLE_VALUE)
-          return E_UNEXPECTED;
+          return INET_E_RESOURCE_NOT_FOUND;
 
       dwFileSize = GetFileSize(hFile, NULL);
       if (dwFileSize != INVALID_FILE_SIZE )
@@ -2323,7 +2328,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
       CloseHandle(hFile);
       
       if (!hGlobal)
-         return E_UNEXPECTED;
+         return INET_E_RESOURCE_NOT_FOUND;
 
       hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream);
       if (FAILED(hRes)) 
@@ -2385,13 +2390,18 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
 typedef struct
 {
     /* IUnknown fields */
-    const IClassFactoryVtbl    *lpVtbl;
-    LONG                        ref;
+    IClassFactory IClassFactory_iface;
+    LONG          ref;
 } IClassFactoryImpl;
 
+static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
+{
+       return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
+}
+
 static HRESULT WINAPI
 SPCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
 
        FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
        return E_NOINTERFACE;
@@ -2399,12 +2409,12 @@ SPCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
 
 static ULONG WINAPI
 SPCF_AddRef(LPCLASSFACTORY iface) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
        return InterlockedIncrement(&This->ref);
 }
 
 static ULONG WINAPI SPCF_Release(LPCLASSFACTORY iface) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
        /* static class, won't be  freed */
        return InterlockedDecrement(&This->ref);
 }
@@ -2418,7 +2428,7 @@ static HRESULT WINAPI SPCF_CreateInstance(
 }
 
 static HRESULT WINAPI SPCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
-       IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+       IClassFactoryImpl *This = impl_from_IClassFactory(iface);
        FIXME("(%p)->(%d),stub!\n",This,dolock);
        return S_OK;
 }
@@ -2430,6 +2440,6 @@ static const IClassFactoryVtbl SPCF_Vtbl = {
        SPCF_CreateInstance,
        SPCF_LockServer
 };
-static IClassFactoryImpl STDPIC_CF = {&SPCF_Vtbl, 1 };
+static IClassFactoryImpl STDPIC_CF = {{&SPCF_Vtbl}, 1 };
 
 void _get_STDPIC_CF(LPVOID *ppv) { *ppv = &STDPIC_CF; }
diff --git a/reactos/dll/win32/oleaut32/olepropframe.c b/reactos/dll/win32/oleaut32/olepropframe.c
new file mode 100644 (file)
index 0000000..8111e6b
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Copyright 1999 Corel Corporation
+ * Sean Langley
+ * Copyright 2010  Geoffrey Hausheer
+ * Copyright 2010 Piotr Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "ole2.h"
+#include "olectl.h"
+#include "oledlg.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+typedef struct {
+    IPropertyPageSite IPropertyPageSite_iface;
+    LCID lcid;
+    LONG ref;
+} PropertyPageSite;
+
+static inline PropertyPageSite *impl_from_IPropertyPageSite(IPropertyPageSite *iface)
+{
+    return CONTAINING_RECORD(iface, PropertyPageSite, IPropertyPageSite_iface);
+}
+
+static INT_PTR CALLBACK property_sheet_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    IPropertyPage *property_page = (IPropertyPage*)GetWindowLongPtrW(hwnd, DWLP_USER);
+
+    switch(msg) {
+    case WM_INITDIALOG: {
+        RECT rect;
+
+        property_page = (IPropertyPage*)((LPPROPSHEETPAGEW)lparam)->lParam;
+
+        GetClientRect(hwnd, &rect);
+        IPropertyPage_Activate(property_page, hwnd, &rect, TRUE);
+        IPropertyPage_Show(property_page, SW_SHOW);
+
+        SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)property_page);
+        return FALSE;
+    }
+    case WM_DESTROY:
+        IPropertyPage_Show(property_page, SW_HIDE);
+        IPropertyPage_Deactivate(property_page);
+        return FALSE;
+    default:
+        return FALSE;
+    }
+}
+
+static HRESULT WINAPI PropertyPageSite_QueryInterface(IPropertyPageSite*  iface,
+        REFIID  riid, void**  ppv)
+{
+    TRACE("(%p riid: %s)\n",iface, debugstr_guid(riid));
+
+    if(IsEqualGUID(&IID_IUnknown, riid)
+            || IsEqualGUID(&IID_IPropertyPageSite, riid))
+        *ppv = iface;
+    else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI PropertyPageSite_AddRef(IPropertyPageSite* iface)
+{
+    PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
+    LONG ref = InterlockedIncrement(&this->ref);
+
+    TRACE("(%p) ref=%d\n", this, ref);
+    return ref;
+}
+
+static ULONG WINAPI PropertyPageSite_Release(IPropertyPageSite* iface)
+{
+    PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
+    LONG ref = InterlockedDecrement(&this->ref);
+
+    TRACE("(%p) ref=%d\n", this, ref);
+    if(!ref)
+        HeapFree(GetProcessHeap(), 0, this);
+    return ref;
+}
+
+static HRESULT WINAPI PropertyPageSite_OnStatusChange(
+        IPropertyPageSite *iface, DWORD dwFlags)
+{
+    TRACE("(%p, %x)\n", iface, dwFlags);
+    return S_OK;
+}
+
+static HRESULT WINAPI PropertyPageSite_GetLocaleID(
+        IPropertyPageSite *iface, LCID *pLocaleID)
+{
+    PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
+
+    TRACE("(%p, %p)\n", iface, pLocaleID);
+    *pLocaleID = this->lcid;
+    return S_OK;
+}
+
+static HRESULT WINAPI PropertyPageSite_GetPageContainer(
+        IPropertyPageSite* iface, IUnknown** ppUnk)
+{
+    FIXME("(%p, %p)\n", iface, ppUnk);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI PropertyPageSite_TranslateAccelerator(
+        IPropertyPageSite* iface, MSG *pMsg)
+{
+    FIXME("(%p, %p)\n", iface, pMsg);
+    return E_NOTIMPL;
+}
+
+IPropertyPageSiteVtbl PropertyPageSiteVtbl = {
+    PropertyPageSite_QueryInterface,
+    PropertyPageSite_AddRef,
+    PropertyPageSite_Release,
+    PropertyPageSite_OnStatusChange,
+    PropertyPageSite_GetLocaleID,
+    PropertyPageSite_GetPageContainer,
+    PropertyPageSite_TranslateAccelerator
+};
+
+/***********************************************************************
+ * OleCreatePropertyFrameIndirect (OLEAUT32.416)
+ */
+HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams)
+{
+    static const WCHAR comctlW[] = { 'c','o','m','c','t','l','3','2','.','d','l','l',0 };
+
+    PROPSHEETHEADERW property_sheet;
+    PROPSHEETPAGEW property_sheet_page;
+    struct {
+        DLGTEMPLATE template;
+        WORD menu;
+        WORD class;
+        WORD title;
+    } *dialogs;
+    IPropertyPage **property_page;
+    PropertyPageSite *property_page_site;
+    HRESULT res;
+    int i;
+    HMODULE hcomctl;
+    HRSRC property_sheet_dialog_find = NULL;
+    HGLOBAL property_sheet_dialog_load = NULL;
+    WCHAR *property_sheet_dialog_data = NULL;
+    HDC hdc;
+    LOGFONTW font_desc;
+    HFONT hfont;
+    LONG font_width = 4, font_height = 8;
+
+    if(!lpParams)
+        return E_POINTER;
+
+    TRACE("(%d %p %d %d %s %d %p %d %p %d %d)\n", lpParams->cbStructSize,
+            lpParams->hWndOwner, lpParams->x, lpParams->y,
+            debugstr_w(lpParams->lpszCaption), lpParams->cObjects,
+            lpParams->lplpUnk, lpParams->cPages, lpParams->lpPages,
+            lpParams->lcid, lpParams->dispidInitialProperty);
+
+    if(!lpParams->lplpUnk || !lpParams->lpPages)
+        return E_POINTER;
+
+    if(lpParams->cbStructSize != sizeof(OCPFIPARAMS)) {
+        WARN("incorrect structure size\n");
+        return E_INVALIDARG;
+    }
+
+    if(lpParams->dispidInitialProperty)
+        FIXME("dispidInitialProperty not yet implemented\n");
+
+    hdc = GetDC(NULL);
+    hcomctl = LoadLibraryW(comctlW);
+    if(hcomctl)
+        property_sheet_dialog_find = FindResourceW(hcomctl,
+                MAKEINTRESOURCEW(1006 /*IDD_PROPSHEET*/), (LPWSTR)RT_DIALOG);
+    if(property_sheet_dialog_find)
+        property_sheet_dialog_load = LoadResource(hcomctl, property_sheet_dialog_find);
+    if(property_sheet_dialog_load)
+        property_sheet_dialog_data = LockResource(property_sheet_dialog_load);
+
+    if(property_sheet_dialog_data) {
+        if(property_sheet_dialog_data[1] == 0xffff) {
+            ERR("Expected DLGTEMPLATE structure\n");
+            return E_OUTOFMEMORY;
+        }
+
+        property_sheet_dialog_data += sizeof(DLGTEMPLATE)/sizeof(WCHAR);
+        /* Skip menu, class and title */
+        property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
+        property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
+        property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
+
+        memset(&font_desc, 0, sizeof(LOGFONTW));
+        /* Calculate logical height */
+        font_desc.lfHeight = -MulDiv(property_sheet_dialog_data[0],
+                GetDeviceCaps(hdc, LOGPIXELSY), 72);
+        font_desc.lfCharSet = DEFAULT_CHARSET;
+        memcpy(font_desc.lfFaceName, property_sheet_dialog_data+1,
+                sizeof(WCHAR)*(lstrlenW(property_sheet_dialog_data+1)+1));
+        hfont = CreateFontIndirectW(&font_desc);
+
+        if(hfont) {
+            hfont = SelectObject(hdc, hfont);
+            font_width = GdiGetCharDimensions(hdc, NULL, &font_height);
+            SelectObject(hdc, hfont);
+        }
+    }
+    if(hcomctl)
+        FreeLibrary(hcomctl);
+    ReleaseDC(NULL, hdc);
+
+    memset(&property_sheet, 0, sizeof(property_sheet));
+    property_sheet.dwSize = sizeof(property_sheet);
+    if(lpParams->lpszCaption) {
+        property_sheet.dwFlags = PSH_PROPTITLE;
+        property_sheet.pszCaption = lpParams->lpszCaption;
+    }
+
+    property_sheet.u3.phpage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            lpParams->cPages*sizeof(HPROPSHEETPAGE));
+    property_page = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            lpParams->cPages*sizeof(IPropertyPage*));
+    dialogs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            lpParams->cPages*sizeof(*dialogs));
+    if(!property_sheet.u3.phpage || !property_page || !dialogs) {
+        HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
+        HeapFree(GetProcessHeap(), 0, property_page);
+        HeapFree(GetProcessHeap(), 0, dialogs);
+        return E_OUTOFMEMORY;
+    }
+
+    memset(&property_sheet_page, 0, sizeof(PROPSHEETPAGEW));
+    property_sheet_page.dwSize = sizeof(PROPSHEETPAGEW);
+    property_sheet_page.dwFlags = PSP_DLGINDIRECT|PSP_USETITLE;
+    property_sheet_page.pfnDlgProc = property_sheet_proc;
+
+    for(i=0; i<lpParams->cPages; i++) {
+        PROPPAGEINFO page_info;
+
+        res = CoCreateInstance(&lpParams->lpPages[i], NULL, CLSCTX_INPROC_SERVER,
+                &IID_IPropertyPage, (void**)&property_page[i]);
+        if(FAILED(res))
+            continue;
+
+        property_page_site = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyPageSite));
+        if(!property_page_site)
+            continue;
+        property_page_site->IPropertyPageSite_iface.lpVtbl = &PropertyPageSiteVtbl;
+        property_page_site->ref = 1;
+        property_page_site->lcid = lpParams->lcid;
+
+        res = IPropertyPage_SetPageSite(property_page[i],
+                &property_page_site->IPropertyPageSite_iface);
+        IPropertyPageSite_Release(&property_page_site->IPropertyPageSite_iface);
+        if(FAILED(res))
+            continue;
+
+        res = IPropertyPage_SetObjects(property_page[i],
+                lpParams->cObjects, lpParams->lplpUnk);
+        if(FAILED(res))
+            continue;
+
+        res = IPropertyPage_GetPageInfo(property_page[i], &page_info);
+        if(FAILED(res))
+            continue;
+
+        dialogs[i].template.cx = MulDiv(page_info.size.cx, 4, font_width);
+        dialogs[i].template.cy = MulDiv(page_info.size.cy, 8, font_height);
+
+        property_sheet_page.u.pResource = &dialogs[i].template;
+        property_sheet_page.lParam = (LPARAM)property_page[i];
+        property_sheet_page.pszTitle = page_info.pszTitle;
+
+        property_sheet.u3.phpage[property_sheet.nPages++] =
+            CreatePropertySheetPageW(&property_sheet_page);
+    }
+
+    PropertySheetW(&property_sheet);
+
+    for(i=0; i<lpParams->cPages; i++) {
+        if(property_page[i]) {
+            IPropertyPage_SetPageSite(property_page[i], NULL);
+            IPropertyPage_Release(property_page[i]);
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, dialogs);
+    HeapFree(GetProcessHeap(), 0, property_page);
+    HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
+    return S_OK;
+}
+
+/***********************************************************************
+ * OleCreatePropertyFrame (OLEAUT32.417)
+ */
+HRESULT WINAPI OleCreatePropertyFrame(
+        HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption, ULONG cObjects,
+        LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
+        DWORD dwReserved, LPVOID pvReserved)
+{
+    OCPFIPARAMS ocpf;
+
+    ocpf.cbStructSize =  sizeof(OCPFIPARAMS);
+    ocpf.hWndOwner    = hwndOwner;
+    ocpf.x            = x;
+    ocpf.y            = y;
+    ocpf.lpszCaption  = lpszCaption;
+    ocpf.cObjects     = cObjects;
+    ocpf.lplpUnk      = ppUnk;
+    ocpf.cPages       = cPages;
+    ocpf.lpPages      = pPageClsID;
+    ocpf.lcid         = lcid;
+    ocpf.dispidInitialProperty = 0;
+
+    return OleCreatePropertyFrameIndirect(&ocpf);
+}
index c23aad7..f6f5653 100644 (file)
@@ -41,7 +41,7 @@ typedef struct {
 } fieldstr;
 
 typedef struct {
-    const IRecordInfoVtbl *lpVtbl;
+    IRecordInfo IRecordInfo_iface;
     LONG ref;
 
     GUID guid;
@@ -53,6 +53,11 @@ typedef struct {
     ITypeInfo *pTypeInfo;
 } IRecordInfoImpl;
 
+static inline IRecordInfoImpl *impl_from_IRecordInfo(IRecordInfo *iface)
+{
+    return CONTAINING_RECORD(iface, IRecordInfoImpl, IRecordInfo_iface);
+}
+
 static HRESULT copy_to_variant(void *src, VARIANT *pvar, enum VARENUM vt)
 {
     TRACE("%p %p %d\n", src, pvar, vt);
@@ -155,7 +160,7 @@ static HRESULT WINAPI IRecordInfoImpl_QueryInterface(IRecordInfo *iface, REFIID
 
 static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     ULONG ref = InterlockedIncrement(&This->ref);
     TRACE("(%p) -> %d\n", This, ref);
     return ref;
@@ -163,7 +168,7 @@ static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface)
 
 static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
     TRACE("(%p) -> %d\n", This, ref);
@@ -182,7 +187,7 @@ static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface)
 
 static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     TRACE("(%p)->(%p)\n", This, pvNew);
 
     if(!pvNew)
@@ -194,7 +199,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew
 
 static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvExisting)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     int i;
     PVOID var;
 
@@ -251,7 +256,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvEx
 static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting,
                                                 PVOID pvNew)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
 
     TRACE("(%p)->(%p %p)\n", This, pvExisting, pvNew);
     
@@ -264,7 +269,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExi
 
 static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
 
     TRACE("(%p)->(%p)\n", This, pguid);
 
@@ -277,7 +282,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid)
 
 static HRESULT WINAPI IRecordInfoImpl_GetName(IRecordInfo *iface, BSTR *pbstrName)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
 
     TRACE("(%p)->(%p)\n", This, pbstrName);
 
@@ -290,8 +295,8 @@ static HRESULT WINAPI IRecordInfoImpl_GetName(IRecordInfo *iface, BSTR *pbstrNam
 
 static HRESULT WINAPI IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG *pcbSize)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
-    
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
+
     TRACE("(%p)->(%p)\n", This, pcbSize);
 
     if(!pcbSize)
@@ -303,7 +308,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG *pcbSize
 
 static HRESULT WINAPI IRecordInfoImpl_GetTypeInfo(IRecordInfo *iface, ITypeInfo **ppTypeInfo)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
 
     TRACE("(%p)->(%p)\n", This, ppTypeInfo);
 
@@ -319,7 +324,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetTypeInfo(IRecordInfo *iface, ITypeInfo
 static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData,
                                                 LPCOLESTR szFieldName, VARIANT *pvarField)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     int i;
 
     TRACE("(%p)->(%p %s %p)\n", This, pvData, debugstr_w(szFieldName), pvarField);
@@ -341,7 +346,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData,
 static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData,
                             LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     int i;
 
     TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray);
@@ -365,7 +370,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID p
 static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData,
                                             LPCOLESTR szFieldName, VARIANT *pvarField)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     int i;
 
     TRACE("(%p)->(%08x %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName),
@@ -393,7 +398,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags,
 static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags,
                 PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     int i;
 
     FIXME("(%p)->(%08x %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
@@ -414,7 +419,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG w
 static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *pcNames,
                                                 BSTR *rgBstrNames)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     ULONG n = This->n_vars, i;
 
     TRACE("(%p)->(%p %p)\n", This, pcNames, rgBstrNames);
@@ -434,18 +439,25 @@ static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *p
     return S_OK;
 }
 
-static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *pRecordInfo)
+static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *info2)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
+    GUID guid2;
+
+    TRACE( "(%p)->(%p)\n", This, info2 );
 
-    FIXME("(%p)->(%p) stub\n", This, pRecordInfo);
+    IRecordInfo_GetGuid( info2, &guid2 );
+    if (IsEqualGUID( &This->guid, &guid2 )) return TRUE;
+
+    FIXME( "records have different guids (%s %s) but could still match\n",
+           debugstr_guid( &This->guid ), debugstr_guid( &guid2 ) );
 
     return FALSE;
 }
 
 static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
 
     TRACE("(%p)\n", This);
 
@@ -455,7 +467,7 @@ static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface)
 static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource,
                                                     PVOID *ppvDest)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
 
     TRACE("(%p)->(%p %p)\n", This, pvSource, ppvDest);
 
@@ -468,7 +480,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID
 
 static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord)
 {
-    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    IRecordInfoImpl *This = impl_from_IRecordInfo(iface);
     HRESULT hres;
 
     TRACE("(%p)->(%p)\n", This, pvRecord);
@@ -585,7 +597,7 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo
     }
 
     ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
-    ret->lpVtbl = &IRecordInfoImplVtbl;
+    ret->IRecordInfo_iface.lpVtbl = &IRecordInfoImplVtbl;
     ret->ref = 1;
     ret->pTypeInfo = pTypeInfo;
     ret->n_vars = typeattr->cVars;
@@ -621,8 +633,8 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo
             WARN("GetDocumentation failed: %08x\n", hres);
         ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc);
     }
-        
-    *ppRecInfo = (IRecordInfo*)ret;
+
+    *ppRecInfo = &ret->IRecordInfo_iface;
 
     return S_OK;
 }
diff --git a/reactos/dll/win32/oleaut32/regsvr.c b/reactos/dll/win32/oleaut32/regsvr.c
deleted file mode 100644 (file)
index f97544f..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- *     self-registerable dll functions for oleaut32.dll
- *
- * Copyright (C) 2003 John K. Hohm
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-#include <string.h>
-
-#define COBJMACROS
-#include "windef.h"
-#include "winbase.h"
-#include "winuser.h"
-#include "winreg.h"
-#include "winerror.h"
-
-#include "ole2.h"
-#include "olectl.h"
-#include "oleauto.h"
-#include "initguid.h"
-#include "typelib.h"
-#include "wincodec.h"
-
-#include "wine/debug.h"
-#include "wine/unicode.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
-/*
- * Near the bottom of this file are the exported DllRegisterServer and
- * DllUnregisterServer, which make all this worthwhile.
- */
-
-/***********************************************************************
- *             interface for self-registering
- */
-struct regsvr_interface
-{
-    IID const *iid;            /* NULL for end of list */
-    LPCSTR name;               /* can be NULL to omit */
-    IID const *base_iid;       /* can be NULL to omit */
-    int num_methods;           /* can be <0 to omit */
-    CLSID const *ps_clsid;     /* can be NULL to omit */
-    CLSID const *ps_clsid32;   /* can be NULL to omit */
-};
-
-static HRESULT register_interfaces(struct regsvr_interface const *list);
-static HRESULT unregister_interfaces(struct regsvr_interface const *list);
-
-struct regsvr_coclass
-{
-    CLSID const *clsid;                /* NULL for end of list */
-    LPCSTR name;               /* can be NULL to omit */
-    LPCSTR ips;                        /* can be NULL to omit */
-    LPCSTR ips32;              /* can be NULL to omit */
-    LPCSTR ips32_tmodel;       /* can be NULL to omit */
-    LPCSTR clsid_str;          /* can be NULL to omit */
-    LPCSTR progid;             /* can be NULL to omit */
-};
-
-static HRESULT register_coclasses(struct regsvr_coclass const *list);
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
-
-/***********************************************************************
- *             static string constants
- */
-static WCHAR const interface_keyname[10] = {
-    'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
-static WCHAR const base_ifa_keyname[14] = {
-    'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
-    'e', 0 };
-static WCHAR const num_methods_keyname[11] = {
-    'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
-static WCHAR const ps_clsid_keyname[15] = {
-    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
-    'i', 'd', 0 };
-static WCHAR const ps_clsid32_keyname[17] = {
-    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
-    'i', 'd', '3', '2', 0 };
-static WCHAR const clsid_keyname[6] = {
-    'C', 'L', 'S', 'I', 'D', 0 };
-static WCHAR const ips_keyname[13] = {
-    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
-    0 };
-static WCHAR const ips32_keyname[15] = {
-    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
-    '3', '2', 0 };
-static WCHAR const progid_keyname[7] = {
-    'P', 'r', 'o', 'g', 'I', 'D', 0 };
-static char const tmodel_valuename[] = "ThreadingModel";
-
-/***********************************************************************
- *             static helper functions
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
-static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
-                                  WCHAR const *value);
-static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
-                                  char const *value);
-
-/***********************************************************************
- *             register_interfaces
- */
-static HRESULT register_interfaces(struct regsvr_interface const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY interface_key;
-
-    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->iid; ++list) {
-       WCHAR buf[39];
-       HKEY iid_key;
-
-       StringFromGUID2(list->iid, buf, 39);
-       res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
-                             KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
-       if (res != ERROR_SUCCESS) goto error_close_interface_key;
-
-       if (list->name) {
-           res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)(list->name),
-                                strlen(list->name) + 1);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (list->base_iid) {
-           res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (0 <= list->num_methods) {
-           static WCHAR const fmt[3] = { '%', 'd', 0 };
-           HKEY key;
-
-           res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
-                                 KEY_READ | KEY_WRITE, NULL, &key, NULL);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-
-           sprintfW(buf, fmt, list->num_methods);
-           res = RegSetValueExW(key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)buf,
-                                (lstrlenW(buf) + 1) * sizeof(WCHAR));
-           RegCloseKey(key);
-
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (list->ps_clsid) {
-           res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (list->ps_clsid32) {
-           res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-    error_close_iid_key:
-       RegCloseKey(iid_key);
-    }
-
-error_close_interface_key:
-    RegCloseKey(interface_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             unregister_interfaces
- */
-static HRESULT unregister_interfaces(struct regsvr_interface const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY interface_key;
-
-    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
-                       KEY_READ | KEY_WRITE, &interface_key);
-    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->iid; ++list) {
-       WCHAR buf[39];
-
-       StringFromGUID2(list->iid, buf, 39);
-       res = RegDeleteTreeW(interface_key, buf);
-       if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
-    }
-
-    RegCloseKey(interface_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             register_coclasses
- */
-static HRESULT register_coclasses(struct regsvr_coclass const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY coclass_key;
-
-    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
-       WCHAR buf[39];
-       HKEY clsid_key;
-
-       StringFromGUID2(list->clsid, buf, 39);
-       res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
-                             KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
-       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
-       if (list->name) {
-           res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)(list->name),
-                                strlen(list->name) + 1);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->ips) {
-           res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->ips32) {
-           HKEY ips32_key;
-
-           res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
-                                 KEY_READ | KEY_WRITE, NULL,
-                                 &ips32_key, NULL);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
-           res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)list->ips32,
-                                lstrlenA(list->ips32) + 1);
-           if (res == ERROR_SUCCESS && list->ips32_tmodel)
-               res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
-                                    (CONST BYTE*)list->ips32_tmodel,
-                                    strlen(list->ips32_tmodel) + 1);
-           RegCloseKey(ips32_key);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->clsid_str) {
-           res = register_key_defvalueA(clsid_key, clsid_keyname,
-                                        list->clsid_str);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->progid) {
-           HKEY progid_key;
-
-           res = register_key_defvalueA(clsid_key, progid_keyname,
-                                        list->progid);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
-           res = RegCreateKeyExA(HKEY_CLASSES_ROOT, list->progid, 0,
-                                 NULL, 0, KEY_READ | KEY_WRITE, NULL,
-                                 &progid_key, NULL);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
-           res = register_key_defvalueW(progid_key, clsid_keyname, buf);
-           RegCloseKey(progid_key);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-    error_close_clsid_key:
-       RegCloseKey(clsid_key);
-    }
-
-error_close_coclass_key:
-    RegCloseKey(coclass_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             unregister_coclasses
- */
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY coclass_key;
-
-    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
-                       KEY_READ | KEY_WRITE, &coclass_key);
-    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
-       WCHAR buf[39];
-
-       StringFromGUID2(list->clsid, buf, 39);
-       res = RegDeleteTreeW(coclass_key, buf);
-       if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
-       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
-       if (list->progid) {
-           res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
-           if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
-           if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-       }
-    }
-
-error_close_coclass_key:
-    RegCloseKey(coclass_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             regsvr_key_guid
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
-{
-    WCHAR buf[39];
-
-    StringFromGUID2(guid, buf, 39);
-    return register_key_defvalueW(base, name, buf);
-}
-
-/***********************************************************************
- *             regsvr_key_defvalueW
- */
-static LONG register_key_defvalueW(
-    HKEY base,
-    WCHAR const *name,
-    WCHAR const *value)
-{
-    LONG res;
-    HKEY key;
-
-    res = RegCreateKeyExW(base, name, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
-    if (res != ERROR_SUCCESS) return res;
-    res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
-                        (lstrlenW(value) + 1) * sizeof(WCHAR));
-    RegCloseKey(key);
-    return res;
-}
-
-/***********************************************************************
- *             regsvr_key_defvalueA
- */
-static LONG register_key_defvalueA(
-    HKEY base,
-    WCHAR const *name,
-    char const *value)
-{
-    LONG res;
-    HKEY key;
-
-    res = RegCreateKeyExW(base, name, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
-    if (res != ERROR_SUCCESS) return res;
-    res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
-                        lstrlenA(value) + 1);
-    RegCloseKey(key);
-    return res;
-}
-
-/***********************************************************************
- *             register_typelib
- */
-static HRESULT register_typelib( const WCHAR *name )
-{
-    static const WCHAR backslash[] = {'\\',0};
-    HRESULT hr;
-    ITypeLib *typelib;
-    WCHAR *path;
-    DWORD len;
-
-    len = GetSystemDirectoryW( NULL, 0 ) + strlenW( name ) + 1;
-    if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
-    GetSystemDirectoryW( path, len );
-    strcatW( path, backslash );
-    strcatW( path, name );
-    hr = LoadTypeLib( path, &typelib );
-    if (SUCCEEDED(hr))
-    {
-        hr = RegisterTypeLib( typelib, path, NULL );
-        ITypeLib_Release( typelib );
-    }
-    HeapFree( GetProcessHeap(), 0, path );
-    return hr;
-}
-
-/***********************************************************************
- *             coclass list
- */
-static GUID const CLSID_RecordInfo = {
-    0x0000002F, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
-
-static GUID const CLSID_OldFont = {
-    0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} };
-
-static struct regsvr_coclass const coclass_list[] = {
-    {   &CLSID_RecordInfo,
-       "CLSID_RecordInfo",
-       NULL,
-       "oleaut32.dll",
-       "Both"
-    },
-    {   &CLSID_PSDispatch,
-       "PSDispatch",
-       "ole2disp.dll",
-       "oleaut32.dll",
-       "Both"
-    },
-    {   &CLSID_StdFont,
-       "CLSID_StdFont",
-       NULL,
-       "oleaut32.dll",
-       "Both",
-       "Standard Font",
-       "StdFont"
-    },
-    {   &CLSID_StdPicture,
-       "CLSID_StdPict",
-       NULL,
-       "oleaut32.dll",
-       "Apartment",
-       "Standard Picture",
-       "StdPicture"
-    },
-    {   &CLSID_PSEnumVariant,
-       "PSEnumVariant",
-       "ole2disp.dll",
-       "oleaut32.dll",
-       "Both"
-    },
-    {   &CLSID_PSTypeInfo,
-       "PSTypeInfo",
-       "ole2disp.dll",
-       "oleaut32.dll",
-       "Both"
-    },
-    {   &CLSID_PSTypeLib,
-       "PSTypeLib",
-       "ole2disp.dll",
-       "oleaut32.dll",
-       "Both"
-    },
-    {   &CLSID_PSOAInterface,
-       "PSOAInterface",
-       "ole2disp.dll",
-       "oleaut32.dll",
-       "Both"
-    },
-    {   &CLSID_PSTypeComp,
-       "PSTypeComp",
-       "ole2disp.dll",
-       "oleaut32.dll",
-       "Both"
-    },
-    {   &CLSID_OldFont,
-       "Obsolete Font",
-       NULL,
-       "oleaut32.dll",
-       NULL,
-       "Obsolete Font",
-       "OldFont"
-    },
-    {   &IID_ISupportErrorInfo,
-       "PSSupportErrorInfo",
-       "ole2disp.dll",
-       "oleaut32.dll",
-       NULL
-    },
-    { NULL }                   /* list terminator */
-};
-
-/***********************************************************************
- *             interface list
- */
-#define INTERFACE_ENTRY(interface, clsid16, clsid32) { &IID_##interface, #interface, NULL, sizeof(interface##Vtbl)/sizeof(void*), clsid16, clsid32 }
-#define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL)
-#define CLSID_INTERFACE_ENTRY(interface,clsid) INTERFACE_ENTRY(interface, clsid, clsid)
-
-static struct regsvr_interface const interface_list[] = {
-    LCL_INTERFACE_ENTRY(ICreateTypeInfo),
-    LCL_INTERFACE_ENTRY(ICreateTypeLib),
-    CLSID_INTERFACE_ENTRY(IDispatch,&CLSID_PSDispatch),
-    CLSID_INTERFACE_ENTRY(IEnumVARIANT,&CLSID_PSEnumVariant),
-    CLSID_INTERFACE_ENTRY(ITypeComp,&CLSID_PSTypeComp),
-    CLSID_INTERFACE_ENTRY(ITypeInfo,&CLSID_PSTypeInfo),
-    CLSID_INTERFACE_ENTRY(ITypeLib,&CLSID_PSTypeLib),
-    INTERFACE_ENTRY(ISupportErrorInfo,NULL,&CLSID_PSDispatch),
-    INTERFACE_ENTRY(ITypeFactory,NULL,&CLSID_PSDispatch),
-    INTERFACE_ENTRY(ITypeInfo2,NULL,&CLSID_PSDispatch),
-    INTERFACE_ENTRY(ITypeLib2,NULL,&CLSID_PSDispatch),
-    { NULL }                   /* list terminator */
-};
-
-extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN;
-extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN;
-
-/***********************************************************************
- *             DllRegisterServer (OLEAUT32.@)
- */
-HRESULT WINAPI DllRegisterServer(void)
-{
-    HRESULT hr;
-
-    TRACE("\n");
-
-    hr = OLEAUTPS_DllRegisterServer();
-    if (SUCCEEDED(hr))
-        hr = register_coclasses(coclass_list);
-    if (SUCCEEDED(hr))
-       hr = register_interfaces(interface_list);
-    if (SUCCEEDED(hr))
-    {
-        const WCHAR stdole32W[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};
-        const WCHAR stdole2W[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
-        hr = register_typelib( stdole2W );
-        if (SUCCEEDED(hr)) hr = register_typelib( stdole32W );
-    }
-    return hr;
-}
-
-/***********************************************************************
- *             DllUnregisterServer (OLEAUT32.@)
- */
-HRESULT WINAPI DllUnregisterServer(void)
-{
-    HRESULT hr;
-
-    TRACE("\n");
-
-    hr = unregister_coclasses(coclass_list);
-    if (SUCCEEDED(hr))
-       hr = unregister_interfaces(interface_list);
-    if (SUCCEEDED(hr))
-        hr = OLEAUTPS_DllUnregisterServer();
-    return hr;
-}
index f8f87eb..57a0d10 100644 (file)
@@ -172,11 +172,15 @@ static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa)
 /* Allocate a descriptor for an array */
 static HRESULT SAFEARRAY_AllocDescriptor(ULONG ulSize, SAFEARRAY **ppsaOut)
 {
-  *ppsaOut = (SAFEARRAY*)((char*)SAFEARRAY_Malloc(ulSize + SAFEARRAY_HIDDEN_SIZE) + SAFEARRAY_HIDDEN_SIZE);
+  char *ptr = SAFEARRAY_Malloc(ulSize + SAFEARRAY_HIDDEN_SIZE);
 
-  if (!*ppsaOut)
-    return E_UNEXPECTED;
+  if (!ptr)
+  {
+      *ppsaOut = NULL;
+      return E_UNEXPECTED;
+  }
 
+  *ppsaOut = (SAFEARRAY*)(ptr + SAFEARRAY_HIDDEN_SIZE);
   return S_OK;
 }
 
@@ -1012,7 +1016,7 @@ HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
  *
  * PARAMS
  *  psa      [I] Array to get dimension lower bound from
- *  nDim     [I] The dimension number to get the lowe bound of
+ *  nDim     [I] The dimension number to get the lower bound of
  *  plLbound [O] Destination for the lower bound
  *
  * RETURNS
@@ -1352,10 +1356,7 @@ HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut)
     return S_OK; /* Handles copying of NULL arrays */
 
   if (!psa->cbElements)
-  {
-    ERR("not copying an array of 0 elements\n");
     return E_INVALIDARG;
-  }
 
   if (psa->fFeatures & (FADF_RECORD|FADF_HAVEIID|FADF_HAVEVARTYPE))
   {
diff --git a/reactos/dll/win32/oleaut32/stubs.c b/reactos/dll/win32/oleaut32/stubs.c
deleted file mode 100644 (file)
index d87e76e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * OlePro32 Stubs
- *
- * Copyright 1999 Corel Corporation
- *
- * Sean Langley
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "wine/debug.h"
-#include "ole2.h"
-#include "olectl.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
-/***********************************************************************
- * OleCreatePropertyFrameIndirect (OLEAUT32.416)
- */
-HRESULT WINAPI OleCreatePropertyFrameIndirect( LPOCPFIPARAMS lpParams)
-{
-       FIXME("(%p), not implemented (olepro32.dll)\n",lpParams);
-       return S_OK;
-}
-
-/***********************************************************************
- * OleCreatePropertyFrame (OLEAUT32.417)
- */
-HRESULT WINAPI OleCreatePropertyFrame(
-    HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects,
-    LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
-    DWORD dwReserved, LPVOID pvReserved )
-{
-       FIXME("(%p,%d,%d,%s,%d,%p,%d,%p,%x,%d,%p), not implemented (olepro32.dll)\n",
-               hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,ppUnk,cPages,
-               pPageClsID, (int)lcid,dwReserved,pvReserved);
-       return S_OK;
-}
index db1a6c9..1c5326b 100644 (file)
@@ -54,8 +54,6 @@ static const WCHAR IDispatchW[] = { 'I','D','i','s','p','a','t','c','h',0};
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 WINE_DECLARE_DEBUG_CHANNEL(olerelay);
 
-#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
-
 static HRESULT TMarshalDispatchChannel_Create(
     IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid,
     IRpcChannelBuffer **ppChannel);
@@ -155,6 +153,7 @@ _unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) {
     hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res);
     if (hres) {
         ERR("stream write %x\n",hres);
+        IStream_Release(pStm);
         return hres;
     }
 
@@ -162,12 +161,14 @@ _unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) {
     hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
     if (hres) {
         ERR("Failed Seek %x\n",hres);
+        IStream_Release(pStm);
         return hres;
     }
 
     hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk);
     if (hres) {
        ERR("Unmarshalling interface %s failed with %x\n",debugstr_guid(riid),hres);
+       IStream_Release(pStm);
        return hres;
     }
 
@@ -245,7 +246,7 @@ _marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) {
 fail:
     xsize = 0;
     xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize));
-    if (pStm) IUnknown_Release(pStm);
+    if (pStm) IStream_Release(pStm);
     HeapFree(GetProcessHeap(), 0, tempbuf);
     return hres;
 }
@@ -322,48 +323,85 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
 }
 
 /*
- * Determine the number of functions including all inherited functions.
+ * Determine the number of functions including all inherited functions
+ * and well as the size of the vtbl.
  * Note for non-dual dispinterfaces we simply return the size of IDispatch.
  */
-static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num)
+static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num,
+                            unsigned int *vtbl_size)
 {
-    HRESULT hres;
+    HRESULT hr;
     TYPEATTR *attr;
     ITypeInfo *tinfo2;
+    UINT inherited_funcs = 0, i;
 
     *num = 0;
-    hres = ITypeInfo_GetTypeAttr(tinfo, &attr);
-    if (hres) {
-        ERR("GetTypeAttr failed with %x\n",hres);
-        return hres;
+    if(vtbl_size) *vtbl_size = 0;
+
+    hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
+    if (hr)
+    {
+        ERR("GetTypeAttr failed with %x\n", hr);
+        return hr;
     }
 
-    if(attr->typekind == TKIND_DISPATCH && (attr->wTypeFlags & TYPEFLAG_FDUAL))
+    if(attr->typekind == TKIND_DISPATCH)
     {
-        HREFTYPE href;
-        hres = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
-        if(FAILED(hres))
+        if(attr->wTypeFlags & TYPEFLAG_FDUAL)
         {
-            ERR("Unable to get interface href from dual dispinterface\n");
-            goto end;
+            HREFTYPE href;
+
+            ITypeInfo_ReleaseTypeAttr(tinfo, attr);
+            hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
+            if(FAILED(hr))
+            {
+                ERR("Unable to get interface href from dual dispinterface\n");
+                return hr;
+            }
+            hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
+            if(FAILED(hr))
+            {
+                ERR("Unable to get interface from dual dispinterface\n");
+                return hr;
+            }
+            hr = num_of_funcs(tinfo2, num, vtbl_size);
+            ITypeInfo_Release(tinfo2);
+            return hr;
         }
-        hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
-        if(FAILED(hres))
+        else /* non-dual dispinterface */
         {
-            ERR("Unable to get interface from dual dispinterface\n");
-            goto end;
+            /* These will be the size of IDispatchVtbl */
+            *num = attr->cbSizeVft / sizeof(void *);
+            if(vtbl_size) *vtbl_size = attr->cbSizeVft;
+            ITypeInfo_ReleaseTypeAttr(tinfo, attr);
+            return hr;
         }
-        hres = num_of_funcs(tinfo2, num);
-        ITypeInfo_Release(tinfo2);
     }
-    else
+
+    for (i = 0; i < attr->cImplTypes; i++)
     {
-        *num = attr->cbSizeVft / 4;
+        HREFTYPE href;
+        ITypeInfo *pSubTypeInfo;
+        UINT sub_funcs;
+
+        hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
+        if (FAILED(hr)) goto end;
+        hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
+        if (FAILED(hr)) goto end;
+
+        hr = num_of_funcs(pSubTypeInfo, &sub_funcs, NULL);
+        ITypeInfo_Release(pSubTypeInfo);
+
+        if(FAILED(hr)) goto end;
+        inherited_funcs += sub_funcs;
     }
 
+    *num = inherited_funcs + attr->cFuncs;
+    if(vtbl_size) *vtbl_size = attr->cbSizeVft;
+
  end:
     ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-    return hres;
+    return hr;
 }
 
 #ifdef __i386__
@@ -397,7 +435,7 @@ typedef struct _TMAsmProxy {
 
 typedef struct _TMProxyImpl {
     LPVOID                             *lpvtbl;
-    const IRpcProxyBufferVtbl          *lpvtbl2;
+    IRpcProxyBuffer                     IRpcProxyBuffer_iface;
     LONG                               ref;
 
     TMAsmProxy                         *asmstubs;
@@ -410,6 +448,11 @@ typedef struct _TMProxyImpl {
     IRpcProxyBuffer                    *dispatch_proxy;
 } TMProxyImpl;
 
+static inline TMProxyImpl *impl_from_IRpcProxyBuffer( IRpcProxyBuffer *iface )
+{
+    return CONTAINING_RECORD(iface, TMProxyImpl, IRpcProxyBuffer_iface);
+}
+
 static HRESULT WINAPI
 TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv)
 {
@@ -426,7 +469,7 @@ TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv)
 static ULONG WINAPI
 TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface)
 {
-    ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface);
+    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
     ULONG refCount = InterlockedIncrement(&This->ref);
 
     TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
@@ -437,7 +480,7 @@ TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface)
 static ULONG WINAPI
 TMProxyImpl_Release(LPRPCPROXYBUFFER iface)
 {
-    ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface);
+    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
     ULONG refCount = InterlockedDecrement(&This->ref);
 
     TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
@@ -460,7 +503,7 @@ static HRESULT WINAPI
 TMProxyImpl_Connect(
     LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer)
 {
-    ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface);
+    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
 
     TRACE("(%p)\n", pRpcChannelBuffer);
 
@@ -488,7 +531,7 @@ TMProxyImpl_Connect(
 static void WINAPI
 TMProxyImpl_Disconnect(LPRPCPROXYBUFFER iface)
 {
-    ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface);
+    TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface );
 
     TRACE("()\n");
 
@@ -558,9 +601,8 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
        return sizeof(DATE);
     case VT_CY:
         return sizeof(CY);
-    /* FIXME: VT_BOOL should return 2? */
     case VT_VARIANT:
-       return sizeof(VARIANT)+3; /* FIXME: why the +3? */
+       return sizeof(VARIANT);
     case VT_CARRAY: {
        int i, arrsize = 1;
        const ARRAYDESC *adesc = td->u.lpadesc;
@@ -575,6 +617,7 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
        return 8;
     case VT_UI2:
     case VT_I2:
+    case VT_BOOL:
        return 2;
     case VT_UI1:
     case VT_I1:
@@ -600,6 +643,17 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
     }
 }
 
+/* Whether we pass this type by reference or by value */
+static int
+_passbyref(const TYPEDESC *td, ITypeInfo *tinfo) {
+    if (td->vt == VT_USERDEFINED ||
+        td->vt == VT_VARIANT     ||
+        td->vt == VT_PTR)
+        return 1;
+
+    return 0;
+}
+
 static HRESULT
 serialize_param(
     ITypeInfo          *tinfo,
@@ -620,6 +674,7 @@ serialize_param(
         vartype = VT_SAFEARRAY;
 
     switch (vartype) {
+    case VT_DATE:
     case VT_I8:
     case VT_UI8:
     case VT_R8:
@@ -629,7 +684,6 @@ serialize_param(
        if (writeit)
            hres = xbuf_add(buf,(LPBYTE)arg,8);
        return hres;
-    case VT_BOOL:
     case VT_ERROR:
     case VT_INT:
     case VT_UINT:
@@ -643,6 +697,7 @@ serialize_param(
        return hres;
     case VT_I2:
     case VT_UI2:
+    case VT_BOOL:
        hres = S_OK;
        if (debugout) TRACE_(olerelay)("%04x\n",*arg & 0xffff);
        if (writeit)
@@ -673,7 +728,7 @@ serialize_param(
         return S_OK;
     }
     case VT_BSTR: {
-       if (debugout) {
+       if (writeit && debugout) {
            if (*arg)
                    TRACE_(olerelay)("%s",relaystr((WCHAR*)*arg));
            else
@@ -798,7 +853,7 @@ serialize_param(
                ELEMDESC *elem2;
                TYPEDESC *tdesc2;
 
-               hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc);
+               hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc);
                if (hres) {
                    ERR("Could not get vardesc of %d\n",i);
                    return hres;
@@ -853,7 +908,8 @@ serialize_param(
        if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt));
        if (debugout) TRACE_(olerelay)("[");
        for (i=0;i<arrsize;i++) {
-           hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf);
+            LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg;
+           hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf);
            if (hres)
                return hres;
            if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
@@ -916,6 +972,7 @@ deserialize_param(
            }
            return S_OK;
        }
+        case VT_DATE:
         case VT_I8:
         case VT_UI8:
         case VT_R8:
@@ -927,7 +984,6 @@ deserialize_param(
            if (debugout) TRACE_(olerelay)("%x%x",arg[0],arg[1]);
            return hres;
         case VT_ERROR:
-       case VT_BOOL:
         case VT_I4:
         case VT_INT:
         case VT_UINT:
@@ -941,6 +997,7 @@ deserialize_param(
            return hres;
         case VT_I2:
         case VT_UI2:
+        case VT_BOOL:
            if (readit) {
                DWORD x;
                hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
@@ -1015,7 +1072,7 @@ deserialize_param(
                ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
                ITypeInfo_Release(tinfo2);
            }
-           /* read it in all cases, we need to know if we have
+           /* read it in all cases, we need to know if we have 
             * NULL pointer or not.
             */
            hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
@@ -1086,7 +1143,7 @@ deserialize_param(
                    for (i=0;i<tattr->cVars;i++) {
                        VARDESC *vdesc;
 
-                       hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc);
+                       hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc);
                        if (hres) {
                            ERR("Could not get vardesc of %d\n",i);
                            ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
@@ -1102,7 +1159,7 @@ deserialize_param(
                            (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
                            buf
                        );
-                        ITypeInfo2_ReleaseVarDesc(tinfo2, vdesc);
+                        ITypeInfo_ReleaseVarDesc(tinfo2, vdesc);
                        if (debugout && (i<tattr->cVars-1)) TRACE_(olerelay)(",");
                    }
                    if (debugout) TRACE_(olerelay)("}");
@@ -1132,13 +1189,18 @@ deserialize_param(
        }
        case VT_CARRAY: {
            /* arg is pointing to the start of the array. */
+            LPBYTE base = (LPBYTE) arg;
            ARRAYDESC *adesc = tdesc->u.lpadesc;
            int         arrsize,i;
            arrsize = 1;
            if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
            for (i=0;i<adesc->cDims;i++)
                arrsize *= adesc->rgbounds[i].cElements;
-           *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
+            if (_passbyref(&adesc->tdescElem, tinfo))
+            {
+               base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
+                *arg = (DWORD) base;
+            }
            for (i=0;i<arrsize;i++)
                deserialize_param(
                    tinfo,
@@ -1146,7 +1208,7 @@ deserialize_param(
                    debugout,
                    alloc,
                    &adesc->tdescElem,
-                   (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)),
+                   (DWORD*)(base + i*_xsize(&adesc->tdescElem, tinfo)),
                    buf
                );
            return S_OK;
@@ -1345,11 +1407,20 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
                TRACE_(olerelay)("%s=",relaystr(names[i+1]));
        }
        /* No need to marshal other data than FIN and any VT_PTR. */
-       if (!is_in_elem(elem) && (elem->tdesc.vt != VT_PTR)) {
-           xargs+=_argsize(&elem->tdesc, tinfo);
-           if (relaydeb) TRACE_(olerelay)("[out]");
-           continue;
-       }
+        if (!is_in_elem(elem))
+        {
+            if (elem->tdesc.vt != VT_PTR)
+            {
+                xargs+=_argsize(&elem->tdesc, tinfo);
+                if (relaydeb) TRACE_(olerelay)("[out]");
+                continue;
+            }
+            else
+            {
+                memset( *(void **)xargs, 0, _xsize( elem->tdesc.u.lptdesc, tinfo ) );
+            }
+        }
+
        hres = serialize_param(
            tinfo,
            is_in_elem(elem),
@@ -1526,20 +1597,25 @@ static HRESULT WINAPI ProxyIDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMembe
 
 typedef struct
 {
-    const IRpcChannelBufferVtbl *lpVtbl;
+    IRpcChannelBuffer     IRpcChannelBuffer_iface;
     LONG                  refs;
     /* the IDispatch-derived interface we are handling */
-       IID                   tmarshal_iid;
+    IID                   tmarshal_iid;
     IRpcChannelBuffer    *pDelegateChannel;
 } TMarshalDispatchChannel;
 
-static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(LPRPCCHANNELBUFFER iface, REFIID riid, LPVOID *ppv)
+static inline TMarshalDispatchChannel *impl_from_IRpcChannelBuffer(IRpcChannelBuffer *iface)
+{
+    return CONTAINING_RECORD(iface, TMarshalDispatchChannel, IRpcChannelBuffer_iface);
+}
+
+static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(IRpcChannelBuffer *iface, REFIID riid, LPVOID *ppv)
 {
     *ppv = NULL;
     if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown))
     {
         *ppv = iface;
-        IUnknown_AddRef(iface);
+        IRpcChannelBuffer_AddRef(iface);
         return S_OK;
     }
     return E_NOINTERFACE;
@@ -1547,13 +1623,13 @@ static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(LPRPCCHANNELBUFFER
 
 static ULONG WINAPI TMarshalDispatchChannel_AddRef(LPRPCCHANNELBUFFER iface)
 {
-    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
+    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
     return InterlockedIncrement(&This->refs);
 }
 
 static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface)
 {
-    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
+    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
     ULONG ref;
 
     ref = InterlockedDecrement(&This->refs);
@@ -1567,7 +1643,7 @@ static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface)
 
 static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg, REFIID riid)
 {
-    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
+    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
     TRACE("(%p, %s)\n", olemsg, debugstr_guid(riid));
     /* Note: we are pretending to invoke a method on the interface identified
      * by tmarshal_iid so that we can re-use the IDispatch proxy/stub code
@@ -1577,28 +1653,28 @@ static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface
 
 static HRESULT WINAPI TMarshalDispatchChannel_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus)
 {
-    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
+    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
     TRACE("(%p, %p)\n", olemsg, pstatus);
     return IRpcChannelBuffer_SendReceive(This->pDelegateChannel, olemsg, pstatus);
 }
 
 static HRESULT WINAPI TMarshalDispatchChannel_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg)
 {
-    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
+    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
     TRACE("(%p)\n", olemsg);
     return IRpcChannelBuffer_FreeBuffer(This->pDelegateChannel, olemsg);
 }
 
 static HRESULT WINAPI TMarshalDispatchChannel_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* pdwDestContext, void** ppvDestContext)
 {
-    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
+    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
     TRACE("(%p,%p)\n", pdwDestContext, ppvDestContext);
     return IRpcChannelBuffer_GetDestCtx(This->pDelegateChannel, pdwDestContext, ppvDestContext);
 }
 
 static HRESULT WINAPI TMarshalDispatchChannel_IsConnected(LPRPCCHANNELBUFFER iface)
 {
-    TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface;
+    TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface);
     TRACE("()\n");
     return IRpcChannelBuffer_IsConnected(This->pDelegateChannel);
 }
@@ -1623,13 +1699,13 @@ static HRESULT TMarshalDispatchChannel_Create(
     if (!This)
         return E_OUTOFMEMORY;
 
-    This->lpVtbl = &TMarshalDispatchChannelVtbl;
+    This->IRpcChannelBuffer_iface.lpVtbl = &TMarshalDispatchChannelVtbl;
     This->refs = 1;
     IRpcChannelBuffer_AddRef(pDelegateChannel);
     This->pDelegateChannel = pDelegateChannel;
     This->tmarshal_iid = *tmarshal_riid;
 
-    *ppChannel = (IRpcChannelBuffer *)&This->lpVtbl;
+    *ppChannel = &This->IRpcChannelBuffer_iface;
     return S_OK;
 }
 
@@ -1690,7 +1766,7 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
     xasm->lret          = 0xc2;
     xasm->bytestopop    = (nrofargs+2)*4; /* pop args, This, iMethod */
     xasm->nop           = 0x90;
-    proxy->lpvtbl[num]  = xasm;
+    proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
 #else
     FIXME("not implemented on non i386\n");
     return E_FAIL;
@@ -1705,7 +1781,7 @@ PSFacBuf_CreateProxy(
 {
     HRESULT    hres;
     ITypeInfo  *tinfo;
-    unsigned int i, nroffuncs;
+    unsigned int i, nroffuncs, vtbl_size;
     TMProxyImpl        *proxy;
     TYPEATTR   *typeattr;
     BOOL        defer_to_dispatch = FALSE;
@@ -1717,7 +1793,9 @@ PSFacBuf_CreateProxy(
        return hres;
     }
 
-    hres = num_of_funcs(tinfo, &nroffuncs);
+    hres = num_of_funcs(tinfo, &nroffuncs, &vtbl_size);
+    TRACE("Got %d funcs, vtbl size %d\n", nroffuncs, vtbl_size);
+
     if (FAILED(hres)) {
         ERR("Cannot get number of functions for typeinfo %s\n",debugstr_guid(riid));
         ITypeInfo_Release(tinfo);
@@ -1738,7 +1816,7 @@ PSFacBuf_CreateProxy(
         CoTaskMemFree(proxy);
         return E_OUTOFMEMORY;
     }
-    proxy->lpvtbl2     = &tmproxyvtable;
+    proxy->IRpcProxyBuffer_iface.lpVtbl = &tmproxyvtable;
     /* one reference for the proxy */
     proxy->ref         = 1;
     proxy->tinfo       = tinfo;
@@ -1748,7 +1826,7 @@ PSFacBuf_CreateProxy(
     InitializeCriticalSection(&proxy->crit);
     proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit");
 
-    proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs);
+    proxy->lpvtbl = HeapAlloc(GetProcessHeap(), 0, vtbl_size);
 
     /* if we derive from IDispatch then defer to its proxy for its methods */
     hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
@@ -1830,17 +1908,17 @@ PSFacBuf_CreateProxy(
     if (hres == S_OK)
     {
         *ppv = proxy;
-        *ppProxy = (IRpcProxyBuffer *)&(proxy->lpvtbl2);
+        *ppProxy = &proxy->IRpcProxyBuffer_iface;
         IUnknown_AddRef((IUnknown *)*ppv);
         return S_OK;
     }
     else
-        TMProxyImpl_Release((IRpcProxyBuffer *)&proxy->lpvtbl2);
+        TMProxyImpl_Release(&proxy->IRpcProxyBuffer_iface);
     return hres;
 }
 
 typedef struct _TMStubImpl {
-    const IRpcStubBufferVtbl   *lpvtbl;
+    IRpcStubBuffer              IRpcStubBuffer_iface;
     LONG                       ref;
 
     LPUNKNOWN                  pUnk;
@@ -1850,6 +1928,11 @@ typedef struct _TMStubImpl {
     BOOL                       dispatch_derivative;
 } TMStubImpl;
 
+static inline TMStubImpl *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface)
+{
+    return CONTAINING_RECORD(iface, TMStubImpl, IRpcStubBuffer_iface);
+}
+
 static HRESULT WINAPI
 TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv)
 {
@@ -1865,7 +1948,7 @@ TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv)
 static ULONG WINAPI
 TMStubImpl_AddRef(LPRPCSTUBBUFFER iface)
 {
-    TMStubImpl *This = (TMStubImpl *)iface;
+    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
     ULONG refCount = InterlockedIncrement(&This->ref);
 
     TRACE("(%p)->(ref before=%u)\n", This, refCount - 1);
@@ -1876,7 +1959,7 @@ TMStubImpl_AddRef(LPRPCSTUBBUFFER iface)
 static ULONG WINAPI
 TMStubImpl_Release(LPRPCSTUBBUFFER iface)
 {
-    TMStubImpl *This = (TMStubImpl *)iface;
+    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
     ULONG refCount = InterlockedDecrement(&This->ref);
 
     TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
@@ -1895,7 +1978,7 @@ TMStubImpl_Release(LPRPCSTUBBUFFER iface)
 static HRESULT WINAPI
 TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer)
 {
-    TMStubImpl *This = (TMStubImpl *)iface;
+    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
 
     TRACE("(%p)->(%p)\n", This, pUnkServer);
 
@@ -1911,7 +1994,7 @@ TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer)
 static void WINAPI
 TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface)
 {
-    TMStubImpl *This = (TMStubImpl *)iface;
+    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
 
     TRACE("(%p)->()\n", This);
 
@@ -1932,7 +2015,7 @@ TMStubImpl_Invoke(
 #ifdef __i386__
     int                i;
     const FUNCDESC *fdesc;
-    TMStubImpl *This = (TMStubImpl *)iface;
+    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
     HRESULT    hres;
     DWORD      *args = NULL, res, *xargs, nrofargs;
     marshal_state      buf;
@@ -1950,16 +2033,19 @@ TMStubImpl_Invoke(
 
     if (This->dispatch_derivative && xmsg->iMethod < sizeof(IDispatchVtbl)/sizeof(void *))
     {
-        IPSFactoryBuffer *factory_buffer;
-        hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
-        if (hres == S_OK)
+        if (!This->dispatch_stub)
         {
-            hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch,
-                This->pUnk, &This->dispatch_stub);
-            IPSFactoryBuffer_Release(factory_buffer);
+            IPSFactoryBuffer *factory_buffer;
+            hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer);
+            if (hres == S_OK)
+            {
+                hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch,
+                    This->pUnk, &This->dispatch_stub);
+                IPSFactoryBuffer_Release(factory_buffer);
+            }
+            if (hres != S_OK)
+                return hres;
         }
-        if (hres != S_OK)
-            return hres;
         return IRpcStubBuffer_Invoke(This->dispatch_stub, xmsg, rpcchanbuf);
     }
 
@@ -2108,7 +2194,7 @@ TMStubImpl_IsIIDSupported(LPRPCSTUBBUFFER iface, REFIID riid) {
 
 static ULONG WINAPI
 TMStubImpl_CountRefs(LPRPCSTUBBUFFER iface) {
-    TMStubImpl *This = (TMStubImpl *)iface;
+    TMStubImpl *This = impl_from_IRpcStubBuffer(iface);
 
     FIXME("()\n");
     return This->ref; /*FIXME? */
@@ -2158,14 +2244,14 @@ PSFacBuf_CreateStub(
     stub = CoTaskMemAlloc(sizeof(TMStubImpl));
     if (!stub)
        return E_OUTOFMEMORY;
-    stub->lpvtbl       = &tmstubvtbl;
+    stub->IRpcStubBuffer_iface.lpVtbl = &tmstubvtbl;
     stub->ref          = 1;
     stub->tinfo                = tinfo;
     stub->dispatch_stub = NULL;
     stub->dispatch_derivative = FALSE;
     stub->iid          = *riid;
-    hres = IRpcStubBuffer_Connect((LPRPCSTUBBUFFER)stub,pUnkServer);
-    *ppStub            = (LPRPCSTUBBUFFER)stub;
+    hres = IRpcStubBuffer_Connect(&stub->IRpcStubBuffer_iface,pUnkServer);
+    *ppStub = &stub->IRpcStubBuffer_iface;
     TRACE("IRpcStubBuffer: %p\n", stub);
     if (hres)
        ERR("Connect to pUnkServer failed?\n");
index 46c0d28..fa9b050 100644 (file)
@@ -367,6 +367,11 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin,
  */
 HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path )
 {
+#ifdef _WIN64
+    HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path );
+    if(SUCCEEDED(hres))
+        return hres;
+#endif
     return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path );
 }
 
@@ -441,7 +446,7 @@ HRESULT WINAPI LoadTypeLibEx(
             case REGKIND_REGISTER:
                 if (FAILED(res = RegisterTypeLib(*pptLib, szPath, NULL)))
                 {
-                    IUnknown_Release(*pptLib);
+                    ITypeLib_Release(*pptLib);
                     *pptLib = 0;
                 }
                 break;
@@ -813,7 +818,7 @@ HRESULT WINAPI UnRegisterTypeLib(
     }
 
     /* Try and load the type library */
-    if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib)) {
+    if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib) != S_OK) {
         result = TYPE_E_INVALIDSTATE;
         goto end;
     }
@@ -952,7 +957,7 @@ typedef struct tagTLBCustData
 {
     GUID guid;
     VARIANT data;
-    struct tagTLBCustData* next;
+    struct list entry;
 } TLBCustData;
 
 /* data structure for import typelibs */
@@ -972,7 +977,7 @@ typedef struct tagTLBImpLib
 
     struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib, or
                                            NULL if not yet loaded */
-    struct tagTLBImpLib * next;
+    struct list entry;
 } TLBImpLib;
 
 /* internal ITypeLib data */
@@ -993,10 +998,9 @@ typedef struct tagITypeLibImpl
     BSTR HelpStringDll;
     DWORD dwHelpContext;
     int TypeInfoCount;          /* nr of typeinfo's in librarry */
-    struct tagITypeInfoImpl *pTypeInfo;   /* linked list of type info data */
-    int ctCustData;             /* number of items in cust data list */
-    TLBCustData * pCustData;    /* linked list to cust data */
-    TLBImpLib   * pImpLibs;     /* linked list to all imported typelibs */
+    struct tagITypeInfoImpl **typeinfos;
+    struct list custdata_list;
+    struct list implib_list;
     int ctTypeDesc;             /* number of items in type desc array */
     TYPEDESC * pTypeDesc;       /* array of TypeDescriptions found in the
                                   library. Only used while reading MSFT
@@ -1006,7 +1010,7 @@ typedef struct tagITypeLibImpl
 
 
     /* typelibs are cached, keyed by path and index, so store the linked list info within them */
-    struct tagITypeLibImpl *next, *prev;
+    struct list entry;
     WCHAR *path;
     INT index;
 } ITypeLibImpl;
@@ -1052,8 +1056,7 @@ typedef struct tagTLBRefType
 typedef struct tagTLBParDesc
 {
     BSTR Name;
-    int ctCustData;
-    TLBCustData * pCustData;        /* linked list to cust data */
+    struct list custdata_list;
 } TLBParDesc;
 
 /* internal Function data */
@@ -1066,9 +1069,7 @@ typedef struct tagTLBFuncDesc
     int HelpStringContext;
     BSTR HelpString;
     BSTR Entry;            /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */
-    int ctCustData;
-    TLBCustData * pCustData;        /* linked list to cust data; */
-    struct tagTLBFuncDesc * next;
+    struct list custdata_list;
 } TLBFuncDesc;
 
 /* internal Variable data */
@@ -1077,11 +1078,9 @@ typedef struct tagTLBVarDesc
     VARDESC vardesc;        /* lots of info on the variable and its attributes. */
     BSTR Name;             /* the name of this variable */
     int HelpContext;
-    int HelpStringContext;  /* FIXME: where? */
+    int HelpStringContext;
     BSTR HelpString;
-    int ctCustData;
-    TLBCustData * pCustData;/* linked list to cust data; */
-    struct tagTLBVarDesc * next;
+    struct list custdata_list;
 } TLBVarDesc;
 
 /* internal implemented interface data */
@@ -1089,9 +1088,7 @@ typedef struct tagTLBImplType
 {
     HREFTYPE hRef;          /* hRef of interface */
     int implflags;          /* IMPLFLAG_*s */
-    int ctCustData;
-    TLBCustData * pCustData;/* linked list to custom data; */
-    struct tagTLBImplType *next;
+    struct list custdata_list;
 } TLBImplType;
 
 /* internal TypeInfo data */
@@ -1115,17 +1112,15 @@ typedef struct tagITypeInfoImpl
     DWORD dwHelpStringContext;
 
     /* functions  */
-    TLBFuncDesc * funclist;     /* linked list with function descriptions */
+    TLBFuncDesc *funcdescs;
 
     /* variables  */
-    TLBVarDesc * varlist;       /* linked list with variable descriptions */
+    TLBVarDesc *vardescs;
 
     /* Implemented Interfaces  */
-    TLBImplType * impltypelist;
+    TLBImplType *impltypes;
 
-    int ctCustData;
-    TLBCustData * pCustData;        /* linked list to cust data; */
-    struct tagITypeInfoImpl * next;
+    struct list custdata_list;
 } ITypeInfoImpl;
 
 static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface )
@@ -1136,8 +1131,8 @@ static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface )
 static const ITypeInfo2Vtbl tinfvt;
 static const ITypeCompVtbl  tcompvt;
 
-static ITypeInfo2 * ITypeInfo_Constructor(void);
-static void ITypeInfo_fnDestroy(ITypeInfoImpl *This);
+static ITypeInfoImpl* ITypeInfoImpl_Constructor(void);
+static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This);
 
 typedef struct tagTLBContext
 {
@@ -1285,21 +1280,23 @@ static void dump_TLBFuncDescOne(const TLBFuncDesc * pfd)
   MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString));
   MESSAGE("\tentry: %s\n", (pfd->Entry == (void *)-1) ? "invalid" : debugstr_w(pfd->Entry));
 }
-static void dump_TLBFuncDesc(const TLBFuncDesc * pfd)
+static void dump_TLBFuncDesc(const TLBFuncDesc * pfd, UINT n)
 {
-       while (pfd)
+       while (n)
        {
          dump_TLBFuncDescOne(pfd);
-         pfd = pfd->next;
-       };
+         ++pfd;
+         --n;
+       }
 }
-static void dump_TLBVarDesc(const TLBVarDesc * pvd)
+static void dump_TLBVarDesc(const TLBVarDesc * pvd, UINT n)
 {
-       while (pvd)
+       while (n)
        {
          TRACE_(typelib)("%s\n", debugstr_w(pvd->Name));
-         pvd = pvd->next;
-       };
+         ++pvd;
+         --n;
+       }
 }
 
 static void dump_TLBImpLib(const TLBImpLib *import)
@@ -1330,13 +1327,15 @@ static void dump_TLBRefType(const ITypeLibImpl *pTL)
     }
 }
 
-static void dump_TLBImplType(const TLBImplType * impl)
+static void dump_TLBImplType(const TLBImplType * impl, UINT n)
 {
-    while (impl) {
-        TRACE_(typelib)(
-               "implementing/inheriting interface hRef = %x implflags %x\n",
-               impl->hRef, impl->implflags);
-       impl = impl->next;
+    if(!impl)
+        return;
+    while (n) {
+        TRACE_(typelib)("implementing/inheriting interface hRef = %x implflags %x\n",
+            impl->hRef, impl->implflags);
+        ++impl;
+        --n;
     }
 }
 
@@ -1428,9 +1427,9 @@ static void dump_TypeInfo(const ITypeInfoImpl * pty)
     TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
     if (pty->TypeAttr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(pty->DllName));
     if (TRACE_ON(ole))
-        dump_TLBFuncDesc(pty->funclist);
-    dump_TLBVarDesc(pty->varlist);
-    dump_TLBImplType(pty->impltypelist);
+        dump_TLBFuncDesc(pty->funcdescs, pty->TypeAttr.cFuncs);
+    dump_TLBVarDesc(pty->vardescs, pty->TypeAttr.cVars);
+    dump_TLBImplType(pty->impltypes, pty->TypeAttr.cImplTypes);
 }
 
 static void dump_VARDESC(const VARDESC *v)
@@ -1443,17 +1442,17 @@ static void dump_VARDESC(const VARDESC *v)
     MESSAGE("varkind %d\n",v->varkind);
 }
 
-static TYPEDESC stndTypeDesc[VT_LPWSTR+1]=
+static TYPEDESC std_typedesc[VT_LPWSTR+1] =
 {
-    /* VT_LPWSTR is largest type that */
-    /* may appear in type description*/
-    {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
-    {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
-    {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
-    {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
-    {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
-    {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
-    {{0},30},{{0},31}
+    /* VT_LPWSTR is largest type that, may appear in type description */
+    {{0}, VT_EMPTY},  {{0}, VT_NULL},        {{0}, VT_I2},      {{0}, VT_I4},
+    {{0}, VT_R4},     {{0}, VT_R8},          {{0}, VT_CY},      {{0}, VT_DATE},
+    {{0}, VT_BSTR},   {{0}, VT_DISPATCH},    {{0}, VT_ERROR},   {{0}, VT_BOOL},
+    {{0}, VT_VARIANT},{{0}, VT_UNKNOWN},     {{0}, VT_DECIMAL}, {{0}, 15}, /* unused in VARENUM */
+    {{0}, VT_I1},     {{0}, VT_UI1},         {{0}, VT_UI2},     {{0}, VT_UI4},
+    {{0}, VT_I8},     {{0}, VT_UI8},         {{0}, VT_INT},     {{0}, VT_UINT},
+    {{0}, VT_VOID},   {{0}, VT_HRESULT},     {{0}, VT_PTR},     {{0}, VT_SAFEARRAY},
+    {{0}, VT_CARRAY}, {{0}, VT_USERDEFINED}, {{0}, VT_LPSTR},   {{0}, VT_LPWSTR}
 };
 
 static void TLB_abort(void)
@@ -1461,18 +1460,26 @@ static void TLB_abort(void)
     DebugBreak();
 }
 
-static void * TLB_Alloc(unsigned size) __WINE_ALLOC_SIZE(1);
-static void * TLB_Alloc(unsigned size)
+void* __WINE_ALLOC_SIZE(1) heap_alloc_zero(unsigned size)
 {
-    void * ret;
-    if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
-        /* FIXME */
-        ERR("cannot allocate memory\n");
-    }
+    void *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+    if (!ret) ERR("cannot allocate memory\n");
+    return ret;
+}
+
+void* __WINE_ALLOC_SIZE(1) heap_alloc(unsigned size)
+{
+    void *ret = HeapAlloc(GetProcessHeap(), 0, size);
+    if (!ret) ERR("cannot allocate memory\n");
     return ret;
 }
 
-static void TLB_Free(void * ptr)
+void* __WINE_ALLOC_SIZE(2) heap_realloc(void *ptr, unsigned size)
+{
+    return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
+}
+
+void heap_free(void *ptr)
 {
     HeapFree(GetProcessHeap(), 0, ptr);
 }
@@ -1529,15 +1536,14 @@ static void *TLB_CopyTypeDesc( TYPEDESC *dest, const TYPEDESC *src, void *buffer
 }
 
 /* free custom data allocated by MSFT_CustData */
-static inline void TLB_FreeCustData(TLBCustData *pCustData)
+static inline void TLB_FreeCustData(struct list *custdata_list)
 {
-    TLBCustData *pCustDataNext;
-    for (; pCustData; pCustData = pCustDataNext)
+    TLBCustData *cd, *cdn;
+    LIST_FOR_EACH_ENTRY_SAFE(cd, cdn, custdata_list, TLBCustData, entry)
     {
-        VariantClear(&pCustData->data);
-
-        pCustDataNext = pCustData->next;
-        TLB_Free(pCustData);
+        list_remove(&cd->entry);
+        VariantClear(&cd->data);
+        heap_free(cd);
     }
 }
 
@@ -1553,6 +1559,127 @@ static BSTR TLB_MultiByteToBSTR(const char *ptr)
     return ret;
 }
 
+static inline TLBFuncDesc *TLB_get_funcdesc_by_memberid(TLBFuncDesc *funcdescs,
+        UINT n, MEMBERID memid)
+{
+    while(n){
+        if(funcdescs->funcdesc.memid == memid)
+            return funcdescs;
+        ++funcdescs;
+        --n;
+    }
+    return NULL;
+}
+
+static inline TLBFuncDesc *TLB_get_funcdesc_by_name(TLBFuncDesc *funcdescs,
+        UINT n, const OLECHAR *name)
+{
+    while(n){
+        if(!lstrcmpiW(funcdescs->Name, name))
+            return funcdescs;
+        ++funcdescs;
+        --n;
+    }
+    return NULL;
+}
+
+static inline TLBVarDesc *TLB_get_vardesc_by_memberid(TLBVarDesc *vardescs,
+        UINT n, MEMBERID memid)
+{
+    while(n){
+        if(vardescs->vardesc.memid == memid)
+            return vardescs;
+        ++vardescs;
+        --n;
+    }
+    return NULL;
+}
+
+static inline TLBVarDesc *TLB_get_vardesc_by_name(TLBVarDesc *vardescs,
+        UINT n, const OLECHAR *name)
+{
+    while(n){
+        if(!lstrcmpiW(vardescs->Name, name))
+            return vardescs;
+        ++vardescs;
+        --n;
+    }
+    return NULL;
+}
+
+static inline TLBCustData *TLB_get_custdata_by_guid(struct list *custdata_list, REFGUID guid)
+{
+    TLBCustData *cust_data;
+    LIST_FOR_EACH_ENTRY(cust_data, custdata_list, TLBCustData, entry)
+        if(IsEqualIID(&cust_data->guid, guid))
+            return cust_data;
+    return NULL;
+}
+
+static TLBVarDesc *TLBVarDesc_Constructor(UINT n)
+{
+    TLBVarDesc *ret;
+
+    ret = heap_alloc_zero(sizeof(TLBVarDesc) * n);
+    if(!ret)
+        return NULL;
+
+    while(n){
+        list_init(&ret[n-1].custdata_list);
+        --n;
+    }
+
+    return ret;
+}
+
+static TLBParDesc *TLBParDesc_Constructor(UINT n)
+{
+    TLBParDesc *ret;
+
+    ret = heap_alloc_zero(sizeof(TLBParDesc) * n);
+    if(!ret)
+        return NULL;
+
+    while(n){
+        list_init(&ret[n-1].custdata_list);
+        --n;
+    }
+
+    return ret;
+}
+
+static TLBFuncDesc *TLBFuncDesc_Constructor(UINT n)
+{
+    TLBFuncDesc *ret;
+
+    ret = heap_alloc_zero(sizeof(TLBFuncDesc) * n);
+    if(!ret)
+        return NULL;
+
+    while(n){
+        list_init(&ret[n-1].custdata_list);
+        --n;
+    }
+
+    return ret;
+}
+
+static TLBImplType *TLBImplType_Constructor(UINT n)
+{
+    TLBImplType *ret;
+
+    ret = heap_alloc_zero(sizeof(TLBImplType) * n);
+    if(!ret)
+        return NULL;
+
+    while(n){
+        list_init(&ret[n-1].custdata_list);
+        --n;
+    }
+
+    return ret;
+}
+
 /**********************************************************************
  *
  *  Functions for reading MSFT typelibs (those created by CreateTypeLib2)
@@ -1656,7 +1783,7 @@ static BSTR MSFT_ReadName( TLBContext *pcx, int offset)
     MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
                      pcx->pTblDir->pNametab.offset+offset);
     niName.namelen &= 0xFF; /* FIXME: correct ? */
-    name=TLB_Alloc((niName.namelen & 0xff) +1);
+    name = heap_alloc_zero((niName.namelen & 0xff) +1);
     MSFT_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
     name[niName.namelen & 0xff]='\0';
 
@@ -1671,7 +1798,7 @@ static BSTR MSFT_ReadName( TLBContext *pcx, int offset)
         /* don't check for invalid character since this has been done previously */
         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, bstrName, lengthInChars);
     }
-    TLB_Free(name);
+    heap_free(name);
 
     TRACE_(typelib)("%s %d\n", debugstr_w(bstrName), lengthInChars);
     return bstrName;
@@ -1687,7 +1814,7 @@ static BSTR MSFT_ReadString( TLBContext *pcx, int offset)
     if(offset<0) return NULL;
     MSFT_ReadLEWords(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
     if(length <= 0) return 0;
-    string=TLB_Alloc(length +1);
+    string = heap_alloc_zero(length +1);
     MSFT_Read(string, length, pcx, DO_NOT_SEEK);
     string[length]='\0';
 
@@ -1702,7 +1829,7 @@ static BSTR MSFT_ReadString( TLBContext *pcx, int offset)
         /* don't check for invalid character since this has been done previously */
         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, bstr, lengthInChars);
     }
-    TLB_Free(string);
+    heap_free(string);
 
     TRACE_(typelib)("%s %d\n", debugstr_w(bstr), lengthInChars);
     return bstr;
@@ -1764,13 +1891,13 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
                 size = nullPos - origPos;
                 MSFT_Seek(pcx, origPos);
            }
-            ptr=TLB_Alloc(size);/* allocate temp buffer */
+            ptr = heap_alloc_zero(size);/* allocate temp buffer */
             MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */
             V_BSTR(pVar)=SysAllocStringLen(NULL,size);
             /* FIXME: do we need a AtoW conversion here? */
             V_UNION(pVar, bstrVal[size])='\0';
             while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
-            TLB_Free(ptr);
+            heap_free(ptr);
        }
        size=-4; break;
     /* FIXME: this will not work AT ALL when the variant contains a pointer */
@@ -1804,7 +1931,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
 /*
  * create a linked list with custom data
  */
-static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
+static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_list)
 {
     MSFT_CDGuid entry;
     TLBCustData* pNew;
@@ -1812,15 +1939,15 @@ static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData
 
     TRACE_(typelib)("\n");
 
+    if (pcx->pTblDir->pCDGuids.offset < 0) return 0;
+
     while(offset >=0){
         count++;
-        pNew=TLB_Alloc(sizeof(TLBCustData));
+        pNew=heap_alloc_zero(sizeof(TLBCustData));
         MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
         MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
         MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
-        /* add new custom data at head of the list */
-        pNew->next=*ppCustData;
-        *ppCustData=pNew;
+        list_add_head(custdata_list, &pNew->entry);
         offset = entry.next;
     }
     return count;
@@ -1901,20 +2028,22 @@ MSFT_DoFuncs(TLBContext*     pcx,
      * in the first part of this file segment.
      */
 
-    int infolen, nameoffset, reclength, nrattributes, i;
+    int infolen, nameoffset, reclength, i;
     int recoffset = offset + sizeof(INT);
 
-    char *recbuf = HeapAlloc(GetProcessHeap(), 0, 0xffff);
-    MSFT_FuncRecord * pFuncRec=(MSFT_FuncRecord *) recbuf;
-    TLBFuncDesc *ptfd_prev = NULL;
+    char *recbuf = heap_alloc(0xffff);
+    MSFT_FuncRecord *pFuncRec = (MSFT_FuncRecord*)recbuf;
+    TLBFuncDesc *ptfd_prev = NULL, *ptfd;
 
     TRACE_(typelib)("\n");
 
     MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
 
+    *pptfd = TLBFuncDesc_Constructor(cFuncs);
+    ptfd = *pptfd;
     for ( i = 0; i < cFuncs ; i++ )
     {
-        *pptfd = TLB_Alloc(sizeof(TLBFuncDesc));
+        int optional;
 
         /* name, eventually add to a hash table */
         MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
@@ -1923,79 +2052,63 @@ MSFT_DoFuncs(TLBContext*     pcx,
         /* nameoffset is sometimes -1 on the second half of a propget/propput
          * pair of functions */
         if ((nameoffset == -1) && (i > 0))
-            (*pptfd)->Name = SysAllocString(ptfd_prev->Name);
+            ptfd->Name = SysAllocString(ptfd_prev->Name);
         else
-            (*pptfd)->Name = MSFT_ReadName(pcx, nameoffset);
+            ptfd->Name = MSFT_ReadName(pcx, nameoffset);
 
         /* read the function information record */
-        MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
+        MSFT_ReadLEDWords(&reclength, sizeof(pFuncRec->Info), pcx, recoffset);
 
         reclength &= 0xffff;
 
-        MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
-
-        /* do the attributes */
-        nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18)
-                       / sizeof(int);
+        MSFT_ReadLEDWords(&pFuncRec->DataType, reclength - FIELD_OFFSET(MSFT_FuncRecord, DataType), pcx, DO_NOT_SEEK);
 
-        if ( nrattributes > 0 )
-        {
-            (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
+        /* size without argument data */
+        optional = reclength - pFuncRec->nrargs*sizeof(MSFT_ParameterInfo);
 
-            if ( nrattributes > 1 )
-            {
-                (*pptfd)->HelpString = MSFT_ReadString(pcx,
-                                                      pFuncRec->OptAttr[1]) ;
+        if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpContext))
+            ptfd->helpcontext = pFuncRec->HelpContext;
 
-                if ( nrattributes > 2 )
-                {
-                    if ( pFuncRec->FKCCIC & 0x2000 )
-                    {
-                       if (!IS_INTRESOURCE(pFuncRec->OptAttr[2]))
-                           ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->OptAttr[2]);
-                       (*pptfd)->Entry = (BSTR)(DWORD_PTR)LOWORD(pFuncRec->OptAttr[2]);
-                    }
-                    else
-                    {
-                        (*pptfd)->Entry = MSFT_ReadString(pcx,
-                                                         pFuncRec->OptAttr[2]);
-                    }
-                    if( nrattributes > 5 )
-                    {
-                        (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
+        if (optional > FIELD_OFFSET(MSFT_FuncRecord, oHelpString))
+            ptfd->HelpString = MSFT_ReadString(pcx, pFuncRec->oHelpString);
 
-                        if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 )
-                        {
-                            MSFT_CustData(pcx,
-                                         pFuncRec->OptAttr[6],
-                                         &(*pptfd)->pCustData);
-                        }
-                    }
-                }
-                else
-                {
-                    (*pptfd)->Entry = (BSTR)-1;
-                }
+        if (optional > FIELD_OFFSET(MSFT_FuncRecord, oEntry))
+        {
+            if (pFuncRec->FKCCIC & 0x2000 )
+            {
+                if (!IS_INTRESOURCE(pFuncRec->oEntry))
+                    ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->oEntry);
+                ptfd->Entry = (BSTR)(DWORD_PTR)LOWORD(pFuncRec->oEntry);
             }
+            else
+                ptfd->Entry = MSFT_ReadString(pcx, pFuncRec->oEntry);
         }
+        else
+            ptfd->Entry = (BSTR)-1;
+
+        if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpStringContext))
+            ptfd->HelpStringContext = pFuncRec->HelpStringContext;
+
+        if (optional > FIELD_OFFSET(MSFT_FuncRecord, oCustData) && pFuncRec->FKCCIC & 0x80)
+            MSFT_CustData(pcx, pFuncRec->oCustData, &ptfd->custdata_list);
 
         /* fill the FuncDesc Structure */
-        MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid, sizeof(INT), pcx,
+        MSFT_ReadLEDWords( & ptfd->funcdesc.memid, sizeof(INT), pcx,
                            offset + infolen + ( i + 1) * sizeof(INT));
 
-        (*pptfd)->funcdesc.funckind   =  (pFuncRec->FKCCIC)      & 0x7;
-        (*pptfd)->funcdesc.invkind    =  (pFuncRec->FKCCIC) >> 3 & 0xF;
-        (*pptfd)->funcdesc.callconv   =  (pFuncRec->FKCCIC) >> 8 & 0xF;
-        (*pptfd)->funcdesc.cParams    =   pFuncRec->nrargs  ;
-        (*pptfd)->funcdesc.cParamsOpt =   pFuncRec->nroargs ;
-        (*pptfd)->funcdesc.oVft       =   pFuncRec->VtableOffset;
-        (*pptfd)->funcdesc.wFuncFlags =   LOWORD(pFuncRec->Flags) ;
+        ptfd->funcdesc.funckind   =  (pFuncRec->FKCCIC)      & 0x7;
+        ptfd->funcdesc.invkind    =  (pFuncRec->FKCCIC) >> 3 & 0xF;
+        ptfd->funcdesc.callconv   =  (pFuncRec->FKCCIC) >> 8 & 0xF;
+        ptfd->funcdesc.cParams    =   pFuncRec->nrargs  ;
+        ptfd->funcdesc.cParamsOpt =   pFuncRec->nroargs ;
+        ptfd->funcdesc.oVft       =   pFuncRec->VtableOffset & ~1;
+        ptfd->funcdesc.wFuncFlags =   LOWORD(pFuncRec->Flags) ;
 
         MSFT_GetTdesc(pcx,
                      pFuncRec->DataType,
-                     &(*pptfd)->funcdesc.elemdescFunc.tdesc,
+                     &ptfd->funcdesc.elemdescFunc.tdesc,
                      pTI);
-        MSFT_ResolveReferencedTypes(pcx, pTI, &(*pptfd)->funcdesc.elemdescFunc.tdesc);
+        MSFT_ResolveReferencedTypes(pcx, pTI, &ptfd->funcdesc.elemdescFunc.tdesc);
 
         /* do the parameters/arguments */
         if(pFuncRec->nrargs)
@@ -2003,18 +2116,17 @@ MSFT_DoFuncs(TLBContext*     pcx,
             int j = 0;
             MSFT_ParameterInfo paraminfo;
 
-            (*pptfd)->funcdesc.lprgelemdescParam =
-                TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
+            ptfd->funcdesc.lprgelemdescParam =
+                heap_alloc_zero(pFuncRec->nrargs * sizeof(ELEMDESC));
 
-            (*pptfd)->pParamDesc =
-                TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));
+            ptfd->pParamDesc = TLBParDesc_Constructor(pFuncRec->nrargs);
 
             MSFT_ReadLEDWords(&paraminfo, sizeof(paraminfo), pcx,
                               recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
 
             for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
             {
-                ELEMDESC *elemdesc = &(*pptfd)->funcdesc.lprgelemdescParam[j];
+                ELEMDESC *elemdesc = &ptfd->funcdesc.lprgelemdescParam[j];
 
                 MSFT_GetTdesc(pcx,
                              paraminfo.DataType,
@@ -2028,11 +2140,11 @@ MSFT_DoFuncs(TLBContext*     pcx,
                     /* this occurs for [propput] or [propget] methods, so
                      * we should just set the name of the parameter to the
                      * name of the method. */
-                    (*pptfd)->pParamDesc[j].Name = SysAllocString((*pptfd)->Name);
+                    ptfd->pParamDesc[j].Name = SysAllocString(ptfd->Name);
                 else
-                    (*pptfd)->pParamDesc[j].Name =
+                    ptfd->pParamDesc[j].Name =
                         MSFT_ReadName( pcx, paraminfo.oName );
-                TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w((*pptfd)->pParamDesc[j].Name));
+                TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(ptfd->pParamDesc[j].Name));
 
                 MSFT_ResolveReferencedTypes(pcx, pTI, &elemdesc->tdesc);
 
@@ -2042,11 +2154,11 @@ MSFT_DoFuncs(TLBContext*     pcx,
                 {
                     INT* pInt = (INT *)((char *)pFuncRec +
                                    reclength -
-                                   (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
+                                   (pFuncRec->nrargs * 4) * sizeof(INT) );
 
                     PARAMDESC* pParamDesc = &elemdesc->u.paramdesc;
 
-                    pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
+                    pParamDesc->pparamdescex = heap_alloc_zero(sizeof(PARAMDESCEX));
                     pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
 
                    MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
@@ -2054,12 +2166,15 @@ MSFT_DoFuncs(TLBContext*     pcx,
                 }
                 else
                     elemdesc->u.paramdesc.pparamdescex = NULL;
+
                 /* custom info */
-                if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 )
+                if (optional > (FIELD_OFFSET(MSFT_FuncRecord, oArgCustData) +
+                                j*sizeof(pFuncRec->oArgCustData[0])) &&
+                    pFuncRec->FKCCIC & 0x80 )
                 {
                     MSFT_CustData(pcx,
-                                 pFuncRec->OptAttr[7+j],
-                                 &(*pptfd)->pParamDesc[j].pCustData);
+                                 pFuncRec->oArgCustData[j],
+                                 &ptfd->pParamDesc[j].custdata_list);
                 }
 
                 /* SEEK value = jump to offset,
@@ -2074,14 +2189,14 @@ MSFT_DoFuncs(TLBContext*     pcx,
         }
 
         /* scode is not used: archaic win16 stuff FIXME: right? */
-        (*pptfd)->funcdesc.cScodes   = 0 ;
-        (*pptfd)->funcdesc.lprgscode = NULL ;
+        ptfd->funcdesc.cScodes   = 0 ;
+        ptfd->funcdesc.lprgscode = NULL ;
 
-        ptfd_prev = *pptfd;
-        pptfd      = & ((*pptfd)->next);
+        ptfd_prev = ptfd;
+        ++ptfd;
         recoffset += reclength;
     }
-    HeapFree(GetProcessHeap(), 0, recbuf);
+    heap_free(recbuf);
 }
 
 static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
@@ -2089,53 +2204,57 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
 {
     int infolen, nameoffset, reclength;
     char recbuf[256];
-    MSFT_VarRecord * pVarRec=(MSFT_VarRecord *) recbuf;
+    MSFT_VarRecord *pVarRec = (MSFT_VarRecord*)recbuf;
+    TLBVarDesc *ptvd;
     int i;
     int recoffset;
 
     TRACE_(typelib)("\n");
 
+    ptvd = *pptvd = TLBVarDesc_Constructor(cVars);
     MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
     MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
                       ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
     recoffset += offset+sizeof(INT);
-    for(i=0;i<cVars;i++){
-        *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
+    for(i=0;i<cVars;i++, ++ptvd){
     /* name, eventually add to a hash table */
         MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
                           offset + infolen + (2*cFuncs + cVars + i + 1) * sizeof(INT));
-        (*pptvd)->Name=MSFT_ReadName(pcx, nameoffset);
+        ptvd->Name=MSFT_ReadName(pcx, nameoffset);
     /* read the variable information record */
-        MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
-        reclength &=0xff;
-        MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
-    /* Optional data */
-        if(reclength >(6*sizeof(INT)) )
-            (*pptvd)->HelpContext=pVarRec->HelpContext;
-        if(reclength >(7*sizeof(INT)) )
-            (*pptvd)->HelpString = MSFT_ReadString(pcx, pVarRec->oHelpString) ;
-        if(reclength >(8*sizeof(INT)) )
-        if(reclength >(9*sizeof(INT)) )
-            (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
+        MSFT_ReadLEDWords(&reclength, sizeof(pVarRec->Info), pcx, recoffset);
+        reclength &= 0xff;
+        MSFT_ReadLEDWords(&pVarRec->DataType, reclength - FIELD_OFFSET(MSFT_VarRecord, DataType), pcx, DO_NOT_SEEK);
+
+        /* optional data */
+        if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpContext))
+            ptvd->HelpContext = pVarRec->HelpContext;
+
+        if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpString))
+            ptvd->HelpString = MSFT_ReadString(pcx, pVarRec->HelpString);
+
+        if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpStringContext))
+            ptvd->HelpStringContext = pVarRec->HelpStringContext;
+
     /* fill the VarDesc Structure */
-        MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
+        MSFT_ReadLEDWords(&ptvd->vardesc.memid, sizeof(INT), pcx,
                           offset + infolen + (cFuncs + i + 1) * sizeof(INT));
-        (*pptvd)->vardesc.varkind = pVarRec->VarKind;
-        (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
+        ptvd->vardesc.varkind = pVarRec->VarKind;
+        ptvd->vardesc.wVarFlags = pVarRec->Flags;
         MSFT_GetTdesc(pcx, pVarRec->DataType,
-            &(*pptvd)->vardesc.elemdescVar.tdesc, pTI);
-/*   (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
+            &ptvd->vardesc.elemdescVar.tdesc, pTI);
+/*   ptvd->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
         if(pVarRec->VarKind == VAR_CONST ){
-            (*pptvd)->vardesc.u.lpvarValue=TLB_Alloc(sizeof(VARIANT));
-            MSFT_ReadValue((*pptvd)->vardesc.u.lpvarValue,
+            ptvd->vardesc.u.lpvarValue = heap_alloc_zero(sizeof(VARIANT));
+            MSFT_ReadValue(ptvd->vardesc.u.lpvarValue,
                 pVarRec->OffsValue, pcx);
         } else
-            (*pptvd)->vardesc.u.oInst=pVarRec->OffsValue;
-        MSFT_ResolveReferencedTypes(pcx, pTI, &(*pptvd)->vardesc.elemdescVar.tdesc);
-        pptvd=&((*pptvd)->next);
+            ptvd->vardesc.u.oInst=pVarRec->OffsValue;
+        MSFT_ResolveReferencedTypes(pcx, pTI, &ptvd->vardesc.elemdescVar.tdesc);
         recoffset += reclength;
     }
 }
+
 /* fill in data for a hreftype (offset). When the referenced type is contained
  * in the typelib, it's just an (file) offset in the type info base dir.
  * If comes from import, it's an offset+1 in the ImpInfo table
@@ -2152,23 +2271,24 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL,
         if(ref->reference == offset) return;
     }
 
-    ref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref));
+    ref = heap_alloc_zero(sizeof(TLBRefType));
     list_add_tail(&pTL->ref_list, &ref->entry);
 
     if(!MSFT_HREFTYPE_INTHISFILE( offset)) {
         /* external typelib */
         MSFT_ImpInfo impinfo;
-        TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
+        TLBImpLib *pImpLib;
 
         TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
 
         MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx,
                           pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
-        while (pImpLib){   /* search the known offsets of all import libraries */
-            if(pImpLib->offset==impinfo.oImpFile) break;
-            pImpLib=pImpLib->next;
-        }
-        if(pImpLib){
+
+        LIST_FOR_EACH_ENTRY(pImpLib, &pcx->pLibInfo->implib_list, TLBImpLib, entry)
+            if(pImpLib->offset==impinfo.oImpFile)
+                break;
+
+        if(&pImpLib->entry != &pcx->pLibInfo->implib_list){
             ref->reference = offset;
             ref->pImpTLInfo = pImpLib;
             if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
@@ -2196,21 +2316,21 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
 {
     int i;
     MSFT_RefRecord refrec;
-    TLBImplType **ppImpl = &pTI->impltypelist;
+    TLBImplType *pImpl;
 
     TRACE_(typelib)("\n");
 
+    pTI->impltypes = TLBImplType_Constructor(count);
+    pImpl = pTI->impltypes;
     for(i=0;i<count;i++){
         if(offset<0) break; /* paranoia */
-        *ppImpl=TLB_Alloc(sizeof(**ppImpl));
         MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
         MSFT_DoRefType(pcx, pTI->pTypeLib, refrec.reftype);
-       (*ppImpl)->hRef = refrec.reftype;
-       (*ppImpl)->implflags=refrec.flags;
-        (*ppImpl)->ctCustData=
-            MSFT_CustData(pcx, refrec.oCustData, &(*ppImpl)->pCustData);
+        pImpl->hRef = refrec.reftype;
+        pImpl->implflags=refrec.flags;
+        MSFT_CustData(pcx, refrec.oCustData, &pImpl->custdata_list);
         offset=refrec.onext;
-        ppImpl=&((*ppImpl)->next);
+        ++pImpl;
     }
 }
 /*
@@ -2226,7 +2346,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
 
     TRACE_(typelib)("count=%u\n", count);
 
-    ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
+    ptiRet = ITypeInfoImpl_Constructor();
     MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
                       pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
 
@@ -2274,12 +2394,12 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
     if(ptiRet->TypeAttr.cFuncs >0 )
         MSFT_DoFuncs(pcx, ptiRet, ptiRet->TypeAttr.cFuncs,
                    ptiRet->TypeAttr.cVars,
-                   tiBase.memoffset, & ptiRet->funclist);
+                   tiBase.memoffset, &ptiRet->funcdescs);
     /* variables */
     if(ptiRet->TypeAttr.cVars >0 )
         MSFT_DoVars(pcx, ptiRet, ptiRet->TypeAttr.cFuncs,
                   ptiRet->TypeAttr.cVars,
-                  tiBase.memoffset, & ptiRet->varlist);
+                  tiBase.memoffset, &ptiRet->vardescs);
     if(ptiRet->TypeAttr.cImplTypes >0 ) {
         switch(ptiRet->TypeAttr.typekind)
         {
@@ -2296,20 +2416,19 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
 
             if (tiBase.datatype1 != -1)
             {
-                ptiRet->impltypelist = TLB_Alloc(sizeof(TLBImplType));
-                ptiRet->impltypelist->hRef = tiBase.datatype1;
+                ptiRet->impltypes = TLBImplType_Constructor(1);
+                ptiRet->impltypes[0].hRef = tiBase.datatype1;
                 MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
             }
-          break;
+            break;
         default:
-            ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
+            ptiRet->impltypes = TLBImplType_Constructor(1);
             MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1);
-           ptiRet->impltypelist->hRef = tiBase.datatype1;
+            ptiRet->impltypes[0].hRef = tiBase.datatype1;
             break;
        }
     }
-    ptiRet->ctCustData=
-        MSFT_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
+    MSFT_CustData(pcx, tiBase.oCustData, &ptiRet->custdata_list);
 
     TRACE_(typelib)("%s guid: %s kind:%s\n",
        debugstr_w(ptiRet->Name),
@@ -2326,7 +2445,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
  * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable
  * tradeoff here.
  */
-static ITypeLibImpl *tlb_cache_first;
+static struct list tlb_cache = LIST_INIT(tlb_cache);
 static CRITICAL_SECTION cache_section;
 static CRITICAL_SECTION_DEBUG cache_section_debug =
 {
@@ -2375,7 +2494,7 @@ static ULONG WINAPI TLB_PEFile_Release(IUnknown *iface)
             FreeResource(This->typelib_global);
         if (This->dll)
             FreeLibrary(This->dll);
-        HeapFree(GetProcessHeap(), 0, This);
+        heap_free(This);
     }
     return refs;
 }
@@ -2390,8 +2509,9 @@ static const IUnknownVtbl TLB_PEFile_Vtable =
 static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
 {
     TLB_PEFile *This;
+    HRESULT hr = TYPE_E_CANTLOADLIBRARY;
 
-    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+    This = heap_alloc(sizeof(TLB_PEFile));
     if (!This)
         return E_OUTOFMEMORY;
 
@@ -2424,11 +2544,13 @@ static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p
                     return S_OK;
                 }
             }
+
+            hr = E_FAIL;
         }
     }
 
     TLB_PEFile_Release((IUnknown *)&This->lpvtbl);
-    return TYPE_E_CANTLOADLIBRARY;
+    return hr;
 }
 
 typedef struct TLB_NEFile
@@ -2462,8 +2584,8 @@ static ULONG WINAPI TLB_NEFile_Release(IUnknown *iface)
     ULONG refs = InterlockedDecrement(&This->refs);
     if (!refs)
     {
-        HeapFree(GetProcessHeap(), 0, This->typelib_base);
-        HeapFree(GetProcessHeap(), 0, This);
+        heap_free(This->typelib_base);
+        heap_free(This);
     }
     return refs;
 }
@@ -2532,13 +2654,13 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
     }
 
     /* Read in resource table */
-    resTab = HeapAlloc( GetProcessHeap(), 0, resTabSize );
+    resTab = heap_alloc( resTabSize );
     if ( !resTab ) return FALSE;
 
     LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET );
     if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) )
     {
-        HeapFree( GetProcessHeap(), 0, resTab );
+        heap_free( resTab );
         return FALSE;
     }
 
@@ -2570,7 +2692,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
         }
     }
     TRACE("No typeid entry found for %p\n", typeid );
-    HeapFree( GetProcessHeap(), 0, resTab );
+    heap_free( resTab );
     return FALSE;
 
  found_type:
@@ -2593,7 +2715,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
             if (nameInfo->id == id) goto found_name;
     }
     TRACE("No resid entry found for %p\n", typeid );
-    HeapFree( GetProcessHeap(), 0, resTab );
+    heap_free( resTab );
     return FALSE;
 
  found_name:
@@ -2601,7 +2723,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
     if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab;
     if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab;
 
-    HeapFree( GetProcessHeap(), 0, resTab );
+    heap_free( resTab );
     return TRUE;
 }
 
@@ -2610,9 +2732,9 @@ static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p
     HFILE lzfd = -1;
     OFSTRUCT ofs;
     HRESULT hr = TYPE_E_CANTLOADLIBRARY;
-    TLB_NEFile *This = NULL;
+    TLB_NEFile *This;
 
-    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+    This = heap_alloc(sizeof(TLB_NEFile));
     if (!This) return E_OUTOFMEMORY;
 
     This->lpvtbl = &TLB_NEFile_Vtable;
@@ -2625,7 +2747,7 @@ static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p
         DWORD reslen, offset;
         if( find_ne_resource( lzfd, "TYPELIB", MAKEINTRESOURCEA(index), &reslen, &offset ) )
         {
-            This->typelib_base = HeapAlloc(GetProcessHeap(), 0, reslen);
+            This->typelib_base = heap_alloc(reslen);
             if( !This->typelib_base )
                 hr = E_OUTOFMEMORY;
             else
@@ -2685,7 +2807,7 @@ static ULONG WINAPI TLB_Mapping_Release(IUnknown *iface)
             CloseHandle(This->mapping);
         if (This->file != INVALID_HANDLE_VALUE)
             CloseHandle(This->file);
-        HeapFree(GetProcessHeap(), 0, This);
+        heap_free(This);
     }
     return refs;
 }
@@ -2701,7 +2823,7 @@ static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLengt
 {
     TLB_Mapping *This;
 
-    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+    This = heap_alloc(sizeof(TLB_Mapping));
     if (!This)
         return E_OUTOFMEMORY;
 
@@ -2739,7 +2861,7 @@ static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLengt
  * find the type of the typelib file and map the typelib resource into
  * the memory
  */
-#define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
+
 #define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
 static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib)
 {
@@ -2762,7 +2884,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
         {
             int str_len = index_str - pszFileName - 1;
             index = idx;
-            file = HeapAlloc(GetProcessHeap(), 0, (str_len + 1) * sizeof(WCHAR));
+            file = heap_alloc((str_len + 1) * sizeof(WCHAR));
             memcpy(file, pszFileName, str_len * sizeof(WCHAR));
             file[str_len] = 0;
         }
@@ -2782,19 +2904,19 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
         }
     }
 
-    if(file != pszFileName) HeapFree(GetProcessHeap(), 0, file);
+    if(file != pszFileName) heap_free(file);
 
     TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index);
 
     /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */
     EnterCriticalSection(&cache_section);
-    for (entry = tlb_cache_first; entry != NULL; entry = entry->next)
+    LIST_FOR_EACH_ENTRY(entry, &tlb_cache, ITypeLibImpl, entry)
     {
         if (!strcmpiW(entry->path, pszPath) && entry->index == index)
         {
             TRACE("cache hit\n");
             *ppTypeLib = (ITypeLib2*)entry;
-            ITypeLib_AddRef(*ppTypeLib);
+            ITypeLib2_AddRef(*ppTypeLib);
             LeaveCriticalSection(&cache_section);
             return S_OK;
         }
@@ -2827,21 +2949,21 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath
             ret = TYPE_E_CANTLOADLIBRARY;
         IUnknown_Release(pFile);
     }
+    else
+        ret = TYPE_E_CANTLOADLIBRARY;
 
     if(*ppTypeLib) {
        ITypeLibImpl *impl = (ITypeLibImpl*)*ppTypeLib;
 
        TRACE("adding to cache\n");
-       impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszPath)+1) * sizeof(WCHAR));
+       impl->path = heap_alloc((strlenW(pszPath)+1) * sizeof(WCHAR));
        lstrcpyW(impl->path, pszPath);
        /* We should really canonicalise the path here. */
         impl->index = index;
 
         /* FIXME: check if it has added already in the meantime */
         EnterCriticalSection(&cache_section);
-        if ((impl->next = tlb_cache_first) != NULL) impl->next->prev = impl;
-        impl->prev = NULL;
-        tlb_cache_first = impl;
+        list_add_head(&tlb_cache, &impl->entry);
         LeaveCriticalSection(&cache_section);
         ret = S_OK;
     } else
@@ -2856,13 +2978,15 @@ static ITypeLibImpl* TypeLibImpl_Constructor(void)
 {
     ITypeLibImpl* pTypeLibImpl;
 
-    pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
+    pTypeLibImpl = heap_alloc_zero(sizeof(ITypeLibImpl));
     if (!pTypeLibImpl) return NULL;
 
     pTypeLibImpl->lpVtbl = &tlbvt;
     pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
     pTypeLibImpl->ref = 1;
 
+    list_init(&pTypeLibImpl->implib_list);
+    list_init(&pTypeLibImpl->custdata_list);
     list_init(&pTypeLibImpl->ref_list);
     pTypeLibImpl->dispatch_href = -1;
 
@@ -2918,7 +3042,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
     if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
     {
         ERR("cannot find the table directory, ptr=0x%x\n",lPSegDir);
-       HeapFree(GetProcessHeap(),0,pTypeLibImpl);
+       heap_free(pTypeLibImpl);
        return NULL;
     }
 
@@ -2953,7 +3077,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
     /* custom data */
     if(tlbHeader.CustomDataOffset >= 0)
     {
-        pTypeLibImpl->ctCustData = MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData);
+        MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->custdata_list);
     }
 
     /* fill in type descriptions */
@@ -2962,7 +3086,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
         int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
         INT16 td[4];
         pTypeLibImpl->ctTypeDesc = cTD;
-        pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
+        pTypeLibImpl->pTypeDesc = heap_alloc_zero( cTD * sizeof(TYPEDESC));
         MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
         for(i=0; i<cTD; )
        {
@@ -2972,9 +3096,9 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
            {
                /* FIXME: check safearray */
                 if(td[3] < 0)
-                    pTypeLibImpl->pTypeDesc[i].u.lptdesc= & stndTypeDesc[td[2]];
+                    pTypeLibImpl->pTypeDesc[i].u.lptdesc = &std_typedesc[td[2]];
                 else
-                    pTypeLibImpl->pTypeDesc[i].u.lptdesc= & pTypeLibImpl->pTypeDesc[td[2]/8];
+                    pTypeLibImpl->pTypeDesc[i].u.lptdesc = &pTypeLibImpl->pTypeDesc[td[2]/8];
             }
            else if(td[0] == VT_CARRAY)
             {
@@ -2995,7 +3119,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
             if(tlbSegDir.pArrayDescriptions.offset>0)
            {
                 MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (INT_PTR)pTypeLibImpl->pTypeDesc[i].u.lpadesc);
-                pTypeLibImpl->pTypeDesc[i].u.lpadesc = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
+                pTypeLibImpl->pTypeDesc[i].u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
 
                 if(td[1]<0)
                     pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK;
@@ -3023,7 +3147,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
     /* imported type libs */
     if(tlbSegDir.pImpFiles.offset>0)
     {
-        TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs);
+        TLBImpLib *pImpLib;
         int oGuid, offset = tlbSegDir.pImpFiles.offset;
         UINT16 size;
 
@@ -3031,25 +3155,25 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
        {
             char *name;
 
-            *ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
-            (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
+            pImpLib = heap_alloc_zero(sizeof(TLBImpLib));
+            pImpLib->offset = offset - tlbSegDir.pImpFiles.offset;
             MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset);
 
-            MSFT_ReadLEDWords(&(*ppImpLib)->lcid,         sizeof(LCID),   &cx, DO_NOT_SEEK);
-            MSFT_ReadLEWords(&(*ppImpLib)->wVersionMajor, sizeof(WORD),   &cx, DO_NOT_SEEK);
-            MSFT_ReadLEWords(&(*ppImpLib)->wVersionMinor, sizeof(WORD),   &cx, DO_NOT_SEEK);
+            MSFT_ReadLEDWords(&pImpLib->lcid,         sizeof(LCID),   &cx, DO_NOT_SEEK);
+            MSFT_ReadLEWords(&pImpLib->wVersionMajor, sizeof(WORD),   &cx, DO_NOT_SEEK);
+            MSFT_ReadLEWords(&pImpLib->wVersionMinor, sizeof(WORD),   &cx, DO_NOT_SEEK);
             MSFT_ReadLEWords(& size,                      sizeof(UINT16), &cx, DO_NOT_SEEK);
 
             size >>= 2;
-            name = TLB_Alloc(size+1);
+            name = heap_alloc_zero(size+1);
             MSFT_Read(name, size, &cx, DO_NOT_SEEK);
-            (*ppImpLib)->name = TLB_MultiByteToBSTR(name);
-            TLB_Free(name);
+            pImpLib->name = TLB_MultiByteToBSTR(name);
+            heap_free(name);
 
-            MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
+            MSFT_ReadGuid(&pImpLib->guid, oGuid, &cx);
             offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;
 
-            ppImpLib = &(*ppImpLib)->next;
+            list_add_tail(&pTypeLibImpl->implib_list, &pImpLib->entry);
         }
     }
 
@@ -3057,18 +3181,19 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
     if(pTypeLibImpl->dispatch_href != -1)
         MSFT_DoRefType(&cx, pTypeLibImpl, pTypeLibImpl->dispatch_href);
 
-    /* type info's */
+    /* type infos */
     if(tlbHeader.nrtypeinfos >= 0 )
     {
-        /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
-        ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo);
+        ITypeInfoImpl **ppTI;
         int i;
 
+        ppTI = pTypeLibImpl->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*) * tlbHeader.nrtypeinfos);
+
         for(i = 0; i < tlbHeader.nrtypeinfos; i++)
         {
             *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);
 
-            ppTI = &((*ppTI)->next);
+            ++ppTI;
             (pTypeLibImpl->TypeInfoCount)++;
         }
     }
@@ -3122,7 +3247,7 @@ static WORD SLTG_ReadStringA(const char *ptr, char **str)
     *str = NULL;
     bytelen = *(const WORD*)ptr;
     if(bytelen == 0xffff) return 2;
-    *str = HeapAlloc(GetProcessHeap(), 0, bytelen + 1);
+    *str = heap_alloc(bytelen + 1);
     memcpy(*str, ptr + 2, bytelen);
     (*str)[bytelen] = '\0';
     return bytelen + 2;
@@ -3206,15 +3331,13 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_
     while(!done) {
         if((*pType & 0xe00) == 0xe00) {
            pTD->vt = VT_PTR;
-           pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                      sizeof(TYPEDESC));
+           pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
            pTD = pTD->u.lptdesc;
        }
        switch(*pType & 0x3f) {
        case VT_PTR:
            pTD->vt = VT_PTR;
-           pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                      sizeof(TYPEDESC));
+           pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
            pTD = pTD->u.lptdesc;
            break;
 
@@ -3232,9 +3355,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_
            SAFEARRAY *pSA = (SAFEARRAY *)(pBlk + *(++pType));
 
            pTD->vt = VT_CARRAY;
-           pTD->u.lpadesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                               sizeof(ARRAYDESC) +
-                               (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND));
+           pTD->u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC) + (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND));
            pTD->u.lpadesc->cDims = pSA->cDims;
            memcpy(pTD->u.lpadesc->rgbounds, pSA->rgsabound,
                   pSA->cDims * sizeof(SAFEARRAYBOUND));
@@ -3250,8 +3371,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_
 
            pType++;
            pTD->vt = VT_SAFEARRAY;
-           pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                      sizeof(TYPEDESC));
+           pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
            pTD = pTD->u.lptdesc;
            break;
          }
@@ -3303,7 +3423,7 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
     }
     name = ( (char*)pRef->names + pRef->number);
 
-    table = HeapAlloc(GetProcessHeap(), 0, sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0]));
+    table = heap_alloc(sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0]));
     table->num = pRef->number >> 3;
 
     /* FIXME should scan the existing list and reuse matching refs added by previous typeinfos */
@@ -3315,32 +3435,30 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
         char *refname;
        unsigned int lib_offs, type_num;
 
-       ref_type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref_type));
+       ref_type = heap_alloc_zero(sizeof(TLBRefType));
 
        name += SLTG_ReadStringA(name, &refname);
        if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2)
            FIXME_(typelib)("Can't sscanf ref\n");
        if(lib_offs != 0xffff) {
-           TLBImpLib **import = &pTL->pImpLibs;
+           TLBImpLib *import;
 
-           while(*import) {
-               if((*import)->offset == lib_offs)
-                   break;
-               import = &(*import)->next;
-           }
-           if(!*import) {
+            LIST_FOR_EACH_ENTRY(import, &pTL->implib_list, TLBImpLib, entry)
+                if(import->offset == lib_offs)
+                    break;
+
+            if(&import->entry == &pTL->implib_list) {
                char fname[MAX_PATH+1];
                int len;
 
-               *import = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                   sizeof(**import));
-               (*import)->offset = lib_offs;
+               import = heap_alloc_zero(sizeof(*import));
+               import->offset = lib_offs;
                TLB_GUIDFromString( pNameTable + lib_offs + 4,
-                                   &(*import)->guid);
+                                   &import->guid);
                if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%x#%s",
-                         &(*import)->wVersionMajor,
-                         &(*import)->wVersionMinor,
-                         &(*import)->lcid, fname) != 4) {
+                         &import->wVersionMajor,
+                         &import->wVersionMinor,
+                         &import->lcid, fname) != 4) {
                  FIXME_(typelib)("can't sscanf ref %s\n",
                        pNameTable + lib_offs + 40);
                }
@@ -3348,12 +3466,13 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
                if(fname[len-1] != '#')
                    FIXME("fname = %s\n", fname);
                fname[len-1] = '\0';
-               (*import)->name = TLB_MultiByteToBSTR(fname);
+               import->name = TLB_MultiByteToBSTR(fname);
+               list_add_tail(&pTL->implib_list, &import->entry);
            }
-           ref_type->pImpTLInfo = *import;
+           ref_type->pImpTLInfo = import;
 
             /* Store a reference to IDispatch */
-            if(pTL->dispatch_href == -1 && IsEqualGUID(&(*import)->guid, &IID_StdOle) && type_num == 4)
+            if(pTL->dispatch_href == -1 && IsEqualGUID(&import->guid, &IID_StdOle) && type_num == 4)
                 pTL->dispatch_href = typelib_ref;
 
        } else { /* internal ref */
@@ -3362,7 +3481,7 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
        ref_type->reference = typelib_ref;
        ref_type->index = type_num;
 
-       HeapFree(GetProcessHeap(), 0, refname);
+       heap_free(refname);
         list_add_tail(&pTL->ref_list, &ref_type->entry);
 
         table->refs[ref] = typelib_ref;
@@ -3378,7 +3497,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
                          BOOL OneOnly, const sltg_ref_lookup_t *ref_lookup)
 {
     SLTG_ImplInfo *info;
-    TLBImplType **ppImplType = &pTI->impltypelist;
+    TLBImplType *pImplType;
     /* I don't really get this structure, usually it's 0x16 bytes
        long, but iuser.tlb contains some that are 0x18 bytes long.
        That's ok because we can use the next ptr to jump to the next
@@ -3387,15 +3506,22 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
        the last one is the regular 0x16 bytes. */
 
     info = (SLTG_ImplInfo*)pBlk;
+    while(1){
+        pTI->TypeAttr.cImplTypes++;
+        if(info->next == 0xffff)
+            break;
+        info = (SLTG_ImplInfo*)(pBlk + info->next);
+    }
+
+    info = (SLTG_ImplInfo*)pBlk;
+    pTI->impltypes = TLBImplType_Constructor(pTI->TypeAttr.cImplTypes);
+    pImplType = pTI->impltypes;
     while(1) {
-       *ppImplType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                               sizeof(**ppImplType));
-        sltg_get_typelib_ref(ref_lookup, info->ref, &(*ppImplType)->hRef);
-       (*ppImplType)->implflags = info->impltypeflags;
-       pTI->TypeAttr.cImplTypes++;
-       ppImplType = &(*ppImplType)->next;
+       sltg_get_typelib_ref(ref_lookup, info->ref, &pImplType->hRef);
+       pImplType->implflags = info->impltypeflags;
+       ++pImplType;
 
-        if(info->next == 0xffff)
+       if(info->next == 0xffff)
            break;
        if(OneOnly)
            FIXME_(typelib)("Interface inheriting more than one interface\n");
@@ -3408,18 +3534,18 @@ 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)
 {
-  TLBVarDesc **ppVarDesc = &pTI->varlist;
+  TLBVarDesc *pVarDesc;
   BSTR bstrPrevName = NULL;
   SLTG_Variable *pItem;
   unsigned short i;
   WORD *pType;
 
+  pVarDesc = pTI->vardescs = TLBVarDesc_Constructor(cVars);
+
   for(pItem = (SLTG_Variable *)pFirstItem, i = 0; i < cVars;
-      pItem = (SLTG_Variable *)(pBlk + pItem->next), i++) {
+      pItem = (SLTG_Variable *)(pBlk + pItem->next), i++, ++pVarDesc) {
 
-      *ppVarDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                            sizeof(**ppVarDesc));
-      (*ppVarDesc)->vardesc.memid = pItem->memid;
+      pVarDesc->vardesc.memid = pItem->memid;
 
       if (pItem->magic != SLTG_VAR_MAGIC &&
           pItem->magic != SLTG_VAR_WITH_FLAGS_MAGIC) {
@@ -3428,11 +3554,11 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
       }
 
       if (pItem->name == 0xfffe)
-        (*ppVarDesc)->Name = SysAllocString(bstrPrevName);
+        pVarDesc->Name = SysAllocString(bstrPrevName);
       else
-        (*ppVarDesc)->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable);
+        pVarDesc->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable);
 
-      TRACE_(typelib)("name: %s\n", debugstr_w((*ppVarDesc)->Name));
+      TRACE_(typelib)("name: %s\n", debugstr_w(pVarDesc->Name));
       TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs);
       TRACE_(typelib)("memid = 0x%x\n", pItem->memid);
 
@@ -3445,28 +3571,27 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
         FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xda);
 
       SLTG_DoElem(pType, pBlk,
-                 &(*ppVarDesc)->vardesc.elemdescVar, ref_lookup);
+                 &pVarDesc->vardesc.elemdescVar, ref_lookup);
 
       if (TRACE_ON(typelib)) {
           char buf[300];
-          dump_TypeDesc(&(*ppVarDesc)->vardesc.elemdescVar.tdesc, buf);
+          dump_TypeDesc(&pVarDesc->vardesc.elemdescVar.tdesc, buf);
           TRACE_(typelib)("elemdescVar: %s\n", buf);
       }
 
       if (pItem->flags & 0x40) {
         TRACE_(typelib)("VAR_DISPATCH\n");
-        (*ppVarDesc)->vardesc.varkind = VAR_DISPATCH;
+        pVarDesc->vardesc.varkind = VAR_DISPATCH;
       }
       else if (pItem->flags & 0x10) {
         TRACE_(typelib)("VAR_CONST\n");
-        (*ppVarDesc)->vardesc.varkind = VAR_CONST;
-        (*ppVarDesc)->vardesc.u.lpvarValue = HeapAlloc(GetProcessHeap(), 0,
-                                                      sizeof(VARIANT));
-        V_VT((*ppVarDesc)->vardesc.u.lpvarValue) = VT_INT;
+        pVarDesc->vardesc.varkind = VAR_CONST;
+        pVarDesc->vardesc.u.lpvarValue = heap_alloc(sizeof(VARIANT));
+        V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_INT;
         if (pItem->flags & 0x08)
-          V_INT((*ppVarDesc)->vardesc.u.lpvarValue) = pItem->byte_offs;
+          V_INT(pVarDesc->vardesc.u.lpvarValue) = pItem->byte_offs;
         else {
-          switch ((*ppVarDesc)->vardesc.elemdescVar.tdesc.vt)
+          switch (pVarDesc->vardesc.elemdescVar.tdesc.vt)
           {
             case VT_LPSTR:
             case VT_LPWSTR:
@@ -3482,8 +3607,8 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
                 str = SysAllocStringLen(NULL, alloc_len);
                 MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, str, alloc_len);
               }
-              V_VT((*ppVarDesc)->vardesc.u.lpvarValue) = VT_BSTR;
-              V_BSTR((*ppVarDesc)->vardesc.u.lpvarValue) = str;
+              V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_BSTR;
+              V_BSTR(pVarDesc->vardesc.u.lpvarValue) = str;
               break;
             }
             case VT_I2:
@@ -3492,28 +3617,27 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
             case VT_UI4:
             case VT_INT:
             case VT_UINT:
-              V_INT((*ppVarDesc)->vardesc.u.lpvarValue) =
+              V_INT(pVarDesc->vardesc.u.lpvarValue) =
                 *(INT*)(pBlk + pItem->byte_offs);
               break;
             default:
-              FIXME_(typelib)("VAR_CONST unimplemented for type %d\n", (*ppVarDesc)->vardesc.elemdescVar.tdesc.vt);
+              FIXME_(typelib)("VAR_CONST unimplemented for type %d\n", pVarDesc->vardesc.elemdescVar.tdesc.vt);
           }
         }
       }
       else {
         TRACE_(typelib)("VAR_PERINSTANCE\n");
-        (*ppVarDesc)->vardesc.u.oInst = pItem->byte_offs;
-        (*ppVarDesc)->vardesc.varkind = VAR_PERINSTANCE;
+        pVarDesc->vardesc.u.oInst = pItem->byte_offs;
+        pVarDesc->vardesc.varkind = VAR_PERINSTANCE;
       }
 
       if (pItem->magic == SLTG_VAR_WITH_FLAGS_MAGIC)
-        (*ppVarDesc)->vardesc.wVarFlags = pItem->varflags;
+        pVarDesc->vardesc.wVarFlags = pItem->varflags;
 
       if (pItem->flags & 0x80)
-        (*ppVarDesc)->vardesc.wVarFlags |= VARFLAG_FREADONLY;
+        pVarDesc->vardesc.wVarFlags |= VARFLAG_FREADONLY;
 
-      bstrPrevName = (*ppVarDesc)->Name;
-      ppVarDesc = &((*ppVarDesc)->next);
+      bstrPrevName = pVarDesc->Name;
   }
   pTI->TypeAttr.cVars = cVars;
 }
@@ -3523,62 +3647,57 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
 {
     SLTG_Function *pFunc;
     unsigned short i;
-    TLBFuncDesc **ppFuncDesc = &pTI->funclist;
+    TLBFuncDesc *pFuncDesc;
+
+    pTI->funcdescs = TLBFuncDesc_Constructor(cFuncs);
 
-    for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs;
-       pFunc = (SLTG_Function*)(pBlk + pFunc->next), i++) {
+    pFuncDesc = pTI->funcdescs;
+    for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs && pFunc != (SLTG_Function*)0xFFFF;
+       pFunc = (SLTG_Function*)(pBlk + pFunc->next), i++, ++pFuncDesc) {
 
         int param;
        WORD *pType, *pArg;
 
-       *ppFuncDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                               sizeof(**ppFuncDesc));
-
         switch (pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT) {
         case SLTG_FUNCTION_MAGIC:
-            (*ppFuncDesc)->funcdesc.funckind = FUNC_PUREVIRTUAL;
+            pFuncDesc->funcdesc.funckind = FUNC_PUREVIRTUAL;
             break;
         case SLTG_DISPATCH_FUNCTION_MAGIC:
-            (*ppFuncDesc)->funcdesc.funckind = FUNC_DISPATCH;
+            pFuncDesc->funcdesc.funckind = FUNC_DISPATCH;
             break;
         case SLTG_STATIC_FUNCTION_MAGIC:
-            (*ppFuncDesc)->funcdesc.funckind = FUNC_STATIC;
+            pFuncDesc->funcdesc.funckind = FUNC_STATIC;
             break;
         default:
            FIXME("unimplemented func magic = %02x\n", pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT);
-            HeapFree(GetProcessHeap(), 0, *ppFuncDesc);
-            *ppFuncDesc = NULL;
-           return;
+           continue;
        }
-       (*ppFuncDesc)->Name = TLB_MultiByteToBSTR(pFunc->name + pNameTable);
+       pFuncDesc->Name = TLB_MultiByteToBSTR(pFunc->name + pNameTable);
 
-       (*ppFuncDesc)->funcdesc.memid = pFunc->dispid;
-       (*ppFuncDesc)->funcdesc.invkind = pFunc->inv >> 4;
-       (*ppFuncDesc)->funcdesc.callconv = pFunc->nacc & 0x7;
-       (*ppFuncDesc)->funcdesc.cParams = pFunc->nacc >> 3;
-       (*ppFuncDesc)->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
-       (*ppFuncDesc)->funcdesc.oVft = pFunc->vtblpos;
+       pFuncDesc->funcdesc.memid = pFunc->dispid;
+       pFuncDesc->funcdesc.invkind = pFunc->inv >> 4;
+       pFuncDesc->funcdesc.callconv = pFunc->nacc & 0x7;
+       pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
+       pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
+       pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1;
 
        if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT)
-           (*ppFuncDesc)->funcdesc.wFuncFlags = pFunc->funcflags;
+           pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
 
        if(pFunc->retnextopt & 0x80)
            pType = &pFunc->rettype;
        else
            pType = (WORD*)(pBlk + pFunc->rettype);
 
-       SLTG_DoElem(pType, pBlk, &(*ppFuncDesc)->funcdesc.elemdescFunc, ref_lookup);
+       SLTG_DoElem(pType, pBlk, &pFuncDesc->funcdesc.elemdescFunc, ref_lookup);
 
-       (*ppFuncDesc)->funcdesc.lprgelemdescParam =
-         HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                   (*ppFuncDesc)->funcdesc.cParams * sizeof(ELEMDESC));
-       (*ppFuncDesc)->pParamDesc =
-         HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                   (*ppFuncDesc)->funcdesc.cParams * sizeof(TLBParDesc));
+       pFuncDesc->funcdesc.lprgelemdescParam =
+         heap_alloc_zero(pFuncDesc->funcdesc.cParams * sizeof(ELEMDESC));
+       pFuncDesc->pParamDesc = TLBParDesc_Constructor(pFuncDesc->funcdesc.cParams);
 
        pArg = (WORD*)(pBlk + pFunc->arg_off);
 
-       for(param = 0; param < (*ppFuncDesc)->funcdesc.cParams; param++) {
+       for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
            char *paramName = pNameTable + *pArg;
            BOOL HaveOffs;
            /* If arg type follows then paramName points to the 2nd
@@ -3605,31 +3724,28 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
            if(HaveOffs) { /* the next word is an offset to type */
                pType = (WORD*)(pBlk + *pArg);
                SLTG_DoElem(pType, pBlk,
-                           &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup);
+                           &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
                pArg++;
            } else {
                if(paramName)
                  paramName--;
                pArg = SLTG_DoElem(pArg, pBlk,
-                                   &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup);
+                                   &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
            }
 
            /* Are we an optional param ? */
-           if((*ppFuncDesc)->funcdesc.cParams - param <=
-              (*ppFuncDesc)->funcdesc.cParamsOpt)
-             (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT;
+           if(pFuncDesc->funcdesc.cParams - param <=
+              pFuncDesc->funcdesc.cParamsOpt)
+             pFuncDesc->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT;
 
            if(paramName) {
-               (*ppFuncDesc)->pParamDesc[param].Name =
+               pFuncDesc->pParamDesc[param].Name =
                  TLB_MultiByteToBSTR(paramName);
            } else {
-               (*ppFuncDesc)->pParamDesc[param].Name =
-                  SysAllocString((*ppFuncDesc)->Name);
+               pFuncDesc->pParamDesc[param].Name =
+                  SysAllocString(pFuncDesc->Name);
            }
        }
-
-       ppFuncDesc = &((*ppFuncDesc)->next);
-       if(pFunc->next == 0xffff) break;
     }
     pTI->TypeAttr.cFuncs = cFuncs;
 }
@@ -3651,7 +3767,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
     if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
         SLTG_DoImpls(pFirstItem, pTI, FALSE, ref_lookup);
     }
-    HeapFree(GetProcessHeap(), 0, ref_lookup);
+    heap_free(ref_lookup);
 }
 
 
@@ -3676,10 +3792,10 @@ 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);
 
-    HeapFree(GetProcessHeap(), 0, ref_lookup);
+    heap_free(ref_lookup);
 
     if (TRACE_ON(typelib))
-        dump_TLBFuncDesc(pTI->funclist);
+        dump_TLBFuncDesc(pTI->funcdescs, pTI->TypeAttr.cFuncs);
 }
 
 static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
@@ -3712,7 +3828,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
 
   SLTG_DoType(pType, pBlk, &pTI->TypeAttr.tdescAlias, ref_lookup);
 
-  HeapFree(GetProcessHeap(), 0, ref_lookup);
+  heap_free(ref_lookup);
 }
 
 static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
@@ -3738,9 +3854,9 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
    * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
   pTI->TypeAttr.cbSizeVft = pTI->TypeAttr.cFuncs * sizeof(void *);
 
-  HeapFree(GetProcessHeap(), 0, ref_lookup);
+  heap_free(ref_lookup);
   if (TRACE_ON(typelib))
-      dump_TLBFuncDesc(pTI->funclist);
+      dump_TLBFuncDesc(pTI->funcdescs, pTI->TypeAttr.cFuncs);
 }
 
 static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
@@ -3764,13 +3880,13 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
 
   if (pTITail->funcs_off != 0xffff)
     SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
-  HeapFree(GetProcessHeap(), 0, ref_lookup);
+  heap_free(ref_lookup);
   if (TRACE_ON(typelib))
     dump_TypeInfo(pTI);
 }
 
 /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
-   managable copy of it into this */
+   manageable copy of it into this */
 typedef struct {
   WORD small_no;
   char *index_name;
@@ -3869,9 +3985,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
 
     /* And now TypeInfoCount of SLTG_OtherTypeInfo */
 
-    pOtherTypeInfoBlks = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                  sizeof(*pOtherTypeInfoBlks) *
-                                  pTypeLibImpl->TypeInfoCount);
+    pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount);
 
 
     ptr = (char*)pLibBlk + len;
@@ -3885,8 +3999,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
        w = *(WORD*)(ptr + 2);
        if(w != 0xffff) {
            len += w;
-           pOtherTypeInfoBlks[i].index_name = HeapAlloc(GetProcessHeap(),0,
-                                                        w+1);
+           pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1);
            memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w);
            pOtherTypeInfoBlks[i].index_name[w] = '\0';
        }
@@ -3894,8 +4007,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
        if(w != 0xffff) {
            TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w));
            len += w;
-           pOtherTypeInfoBlks[i].other_name = HeapAlloc(GetProcessHeap(),0,
-                                                        w+1);
+           pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1);
            memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w);
            pOtherTypeInfoBlks[i].other_name[w] = '\0';
        }
@@ -3903,8 +4015,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
        pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8);
        extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len);
        if(extra) {
-           pOtherTypeInfoBlks[i].extra = HeapAlloc(GetProcessHeap(),0,
-                                                   extra);
+           pOtherTypeInfoBlks[i].extra = heap_alloc(extra);</