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

reactos/dll/win32/ole32/clipboard.c
reactos/dll/win32/ole32/comcat.c
reactos/dll/win32/ole32/compobj.c
reactos/dll/win32/ole32/defaulthandler.c
reactos/dll/win32/ole32/hglobalstream.c
reactos/dll/win32/ole32/ifs.c
reactos/dll/win32/ole32/ole2.c
reactos/dll/win32/ole32/storage32.c
reactos/media/doc/README.WINE

index 12a1058..e2f3af3 100644 (file)
@@ -155,6 +155,15 @@ typedef struct PresentationDataHeader
  */
 static ole_clipbrd* theOleClipboard;
 
+static CRITICAL_SECTION latest_snapshot_cs;
+static CRITICAL_SECTION_DEBUG latest_snapshot_cs_debug =
+{
+        0, 0, &latest_snapshot_cs,
+        { &latest_snapshot_cs_debug.ProcessLocksList, &latest_snapshot_cs_debug.ProcessLocksList },
+        0, 0, { (DWORD_PTR)(__FILE__ ": clipboard last snapshot") }
+};
+static CRITICAL_SECTION latest_snapshot_cs = { &latest_snapshot_cs_debug, -1, 0, 0, 0, 0 };
+
 static inline HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd)
 {
     struct oletls *info = COM_CurrentInfo();
@@ -1023,13 +1032,17 @@ static ULONG WINAPI snapshot_Release(IDataObject *iface)
 
     if (ref == 0)
     {
-        ole_clipbrd *clipbrd;
-        HRESULT hr = get_ole_clipbrd(&clipbrd);
+        EnterCriticalSection(&latest_snapshot_cs);
+        if (This->ref)
+        {
+            LeaveCriticalSection(&latest_snapshot_cs);
+            return ref;
+        }
+        if (theOleClipboard->latest_snapshot == This)
+            theOleClipboard->latest_snapshot = NULL;
+        LeaveCriticalSection(&latest_snapshot_cs);
 
         if(This->data) IDataObject_Release(This->data);
-
-        if(SUCCEEDED(hr) && clipbrd->latest_snapshot == This)
-            clipbrd->latest_snapshot = NULL;
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -2169,21 +2182,28 @@ HRESULT WINAPI OleGetClipboard(IDataObject **obj)
     TRACE("(%p)\n", obj);
 
     if(!obj) return E_INVALIDARG;
+    *obj = NULL;
 
     if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
 
     seq_no = GetClipboardSequenceNumber();
+    EnterCriticalSection(&latest_snapshot_cs);
     if(clipbrd->latest_snapshot && clipbrd->latest_snapshot->seq_no != seq_no)
         clipbrd->latest_snapshot = NULL;
 
     if(!clipbrd->latest_snapshot)
     {
         clipbrd->latest_snapshot = snapshot_construct(seq_no);
-        if(!clipbrd->latest_snapshot) return E_OUTOFMEMORY;
+        if(!clipbrd->latest_snapshot)
+        {
+            LeaveCriticalSection(&latest_snapshot_cs);
+            return E_OUTOFMEMORY;
+        }
     }
 
     *obj = &clipbrd->latest_snapshot->IDataObject_iface;
     IDataObject_AddRef(*obj);
+    LeaveCriticalSection(&latest_snapshot_cs);
 
     return S_OK;
 }
index a1fe995..bd66187 100644 (file)
@@ -229,7 +229,11 @@ static HRESULT COMCAT_IsClassOfCategories(
        if (res != ERROR_SUCCESS) return S_FALSE;
        for (string = impl_strings; *string; string += CHARS_IN_GUID) {
            HKEY catkey;
+#ifdef __REACTOS__
            res = open_classes_key(subkey, string, READ_CONTROL, &catkey);
+#else
+           res = open_classes_key(subkey, string, 0, &catkey);
+#endif
            if (res != ERROR_SUCCESS) {
                RegCloseKey(subkey);
                return S_FALSE;
index 40ceb77..9b3c68d 100644 (file)
@@ -308,7 +308,8 @@ static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES
 static const WCHAR classes_rootW[] = L"\\REGISTRY\\Machine\\Software\\Classes";
 #else
 static const WCHAR classes_rootW[] =
-    {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s',0};
+    {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e',
+     '\\','S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s',0};
 #endif
 
 static HKEY classes_root_hkey;
@@ -443,8 +444,7 @@ struct apartment_loaded_dll
     BOOL multi_threaded;
 };
 
-static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','e','a','d','W','n','d','C','l','a','s','s',' ',
-                                       '0','x','#','#','#','#','#','#','#','#',' ',0};
+static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','e','a','d','W','n','d','C','l','a','s','s',0};
 
 /*****************************************************************************
  * This section contains OpenDllList implementation
@@ -1950,6 +1950,8 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
 
   if (!--info->inits)
   {
+    if (info->ole_inits)
+      WARN("uninitializing apartment while Ole is still initialized\n");
     apartment_release(info->apt);
     info->apt = NULL;
   }
@@ -5004,6 +5006,35 @@ HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
     return CLASS_E_CLASSNOTAVAILABLE;
 }
 
+/***********************************************************************
+ *           CoGetApartmentType [OLE32.@]
+ */
+HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier)
+{
+    struct oletls *info = COM_CurrentInfo();
+
+    FIXME("(%p %p): semi-stub\n", type, qualifier);
+
+    if (!type || !qualifier)
+        return E_INVALIDARG;
+
+    if (!info)
+        return E_OUTOFMEMORY;
+
+    if (!info->apt)
+        *type = APTTYPE_CURRENT;
+    else if (info->apt->multi_threaded)
+        *type = APTTYPE_MTA;
+    else if (info->apt->main)
+        *type = APTTYPE_MAINSTA;
+    else
+        *type = APTTYPE_STA;
+
+    *qualifier = APTTYPEQUALIFIER_NONE;
+
+    return info->apt ? ERROR_SUCCESS : CO_E_NOTINITIALIZED;
+}
+
 /***********************************************************************
  *             DllMain (OLE32.@)
  */
index 4e5bb21..2aec79e 100644 (file)
@@ -239,7 +239,7 @@ static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
   /* Check that we obtained an interface. */
   if (*ppvObject == NULL)
   {
-    WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
+    WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
     return E_NOINTERFACE;
   }
 
index 732e6c6..6a82b71 100644 (file)
@@ -5,6 +5,7 @@
  * for streams contained supported by an HGLOBAL pointer.
  *
  * Copyright 1999 Francis Beaudet
+ * Copyright 2016 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 #include "precomp.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(storage);
+WINE_DEFAULT_DEBUG_CHANNEL(hglobalstream);
+
+struct handle_wrapper
+{
+    LONG ref;
+    HGLOBAL hglobal;
+    ULONG size;
+    BOOL delete_on_release;
+    CRITICAL_SECTION lock;
+};
+
+static void handle_addref(struct handle_wrapper *handle)
+{
+    InterlockedIncrement(&handle->ref);
+}
+
+static void handle_release(struct handle_wrapper *handle)
+{
+    ULONG ref = InterlockedDecrement(&handle->ref);
+
+    if (!ref)
+    {
+        if (handle->delete_on_release)
+        {
+            GlobalFree(handle->hglobal);
+            handle->hglobal = NULL;
+        }
+
+        handle->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&handle->lock);
+        HeapFree(GetProcessHeap(), 0, handle);
+    }
+}
+
+static ULONG handle_read(struct handle_wrapper *handle, ULONG *pos, void *dest, ULONG len)
+{
+    void *source;
+
+    EnterCriticalSection(&handle->lock);
+
+    if (*pos < handle->size)
+        len = min(handle->size - *pos, len);
+    else
+        len = 0;
+
+    source = GlobalLock(handle->hglobal);
+    if (source)
+    {
+        memcpy(dest, (char *)source + *pos, len);
+        *pos += len;
+        GlobalUnlock(handle->hglobal);
+    }
+    else
+    {
+        WARN("read from invalid hglobal %p\n", handle->hglobal);
+        len = 0;
+    }
+
+    LeaveCriticalSection(&handle->lock);
+    return len;
+}
+
+static ULONG handle_write(struct handle_wrapper *handle, ULONG *pos, const void *source, ULONG len)
+{
+    void *dest;
+
+    if (!len)
+        return 0;
+
+    EnterCriticalSection(&handle->lock);
+
+    if (*pos + len > handle->size)
+    {
+        HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, *pos + len, GMEM_MOVEABLE);
+        if (hglobal)
+        {
+            handle->hglobal = hglobal;
+            handle->size = *pos + len;
+        }
+        else
+        {
+            len = 0;
+            goto done;
+        }
+    }
+
+    dest = GlobalLock(handle->hglobal);
+    if (dest)
+    {
+        memcpy((char *)dest + *pos, source, len);
+        *pos += len;
+        GlobalUnlock(handle->hglobal);
+    }
+    else
+    {
+        WARN("write to invalid hglobal %p\n", handle->hglobal);
+        /* len = 0; */
+    }
+
+done:
+    LeaveCriticalSection(&handle->lock);
+    return len;
+}
+
+static HGLOBAL handle_gethglobal(struct handle_wrapper *handle)
+{
+    return handle->hglobal;
+}
+
+static HRESULT handle_setsize(struct handle_wrapper *handle, ULONG size)
+{
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection(&handle->lock);
+
+    if (handle->size != size)
+    {
+        HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, size, GMEM_MOVEABLE);
+        if (hglobal)
+        {
+            handle->hglobal = hglobal;
+            handle->size = size;
+        }
+        else
+            hr = E_OUTOFMEMORY;
+    }
+
+    LeaveCriticalSection(&handle->lock);
+    return hr;
+}
+
+static ULONG handle_getsize(struct handle_wrapper *handle)
+{
+    return handle->size;
+}
+
+static struct handle_wrapper *handle_create(HGLOBAL hglobal, BOOL delete_on_release)
+{
+    struct handle_wrapper *handle;
+
+    handle = HeapAlloc(GetProcessHeap(), 0, sizeof(*handle));
+    if (handle)
+    {
+        handle->ref = 1;
+        handle->hglobal = hglobal;
+        handle->size = GlobalSize(hglobal);
+        handle->delete_on_release = delete_on_release;
+        InitializeCriticalSection(&handle->lock);
+        handle->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": handle_wrapper.lock");
+    }
+    return handle;
+}
 
 /****************************************************************************
  * HGLOBALStreamImpl definition.
@@ -36,14 +188,7 @@ typedef struct
   IStream IStream_iface;
   LONG ref;
 
-  /* support for the stream */
-  HGLOBAL supportHandle;
-
-  /* if TRUE the HGLOBAL is destroyed when the stream is finally released */
-  BOOL deleteOnRelease;
-
-  /* size of the stream */
-  ULARGE_INTEGER streamSize;
+  struct handle_wrapper *handle;
 
   /* current position of the cursor */
   ULARGE_INTEGER currentPosition;
@@ -95,12 +240,7 @@ static ULONG WINAPI HGLOBALStreamImpl_Release(
 
   if (!ref)
   {
-    if (This->deleteOnRelease)
-    {
-      GlobalFree(This->supportHandle);
-      This->supportHandle = NULL;
-    }
-
+    handle_release(This->handle);
     HeapFree(GetProcessHeap(), 0, This);
   }
 
@@ -123,59 +263,12 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
                  ULONG*         pcbRead)   /* [out] */
 {
   HGLOBALStreamImpl* This = impl_from_IStream(iface);
+  ULONG num_bytes;
 
-  void* supportBuffer;
-  ULONG bytesReadBuffer;
-  ULONG bytesToReadFromBuffer;
-
-  TRACE("(%p, %p, %d, %p)\n", iface,
-       pv, cb, pcbRead);
-
-  /*
-   * If the caller is not interested in the number of bytes read,
-   * we use another buffer to avoid "if" statements in the code.
-   */
-  if (pcbRead==0)
-    pcbRead = &bytesReadBuffer;
-
-  /*
-   * Using the known size of the stream, calculate the number of bytes
-   * to read from the block chain
-   */
-  bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
-
-  /*
-   * Lock the buffer in position and copy the data.
-   */
-  supportBuffer = GlobalLock(This->supportHandle);
-  if (!supportBuffer)
-  {
-      WARN("read from invalid hglobal %p\n", This->supportHandle);
-      *pcbRead = 0;
-      return S_OK;
-  }
-
-  memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
+  TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbRead);
 
-  /*
-   * Move the current position to the new position
-   */
-  This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
-
-  /*
-   * Return the number of bytes read.
-   */
-  *pcbRead = bytesToReadFromBuffer;
-
-  /*
-   * Cleanup
-   */
-  GlobalUnlock(This->supportHandle);
-
-  /*
-   * Always returns S_OK even if the end of the stream is reached before the
-   * buffer is filled
-   */
+  num_bytes = handle_read(This->handle, &This->currentPosition.u.LowPart, pv, cb);
+  if (pcbRead) *pcbRead = num_bytes;
 
   return S_OK;
 }
@@ -197,71 +290,14 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
                  ULONG*         pcbWritten)  /* [out] */
 {
   HGLOBALStreamImpl* This = impl_from_IStream(iface);
-
-  void*          supportBuffer;
-  ULARGE_INTEGER newSize;
-  ULONG          bytesWritten = 0;
+  ULONG num_bytes;
 
   TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten);
 
-  /*
-   * If the caller is not interested in the number of bytes written,
-   * we use another buffer to avoid "if" statements in the code.
-   */
-  if (pcbWritten == 0)
-    pcbWritten = &bytesWritten;
-
-  if (cb == 0)
-    goto out;
-
-  *pcbWritten = 0;
-
-  newSize.u.HighPart = 0;
-  newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
-
-  /*
-   * Verify if we need to grow the stream
-   */
-  if (newSize.u.LowPart > This->streamSize.u.LowPart)
-  {
-    /* grow stream */
-    HRESULT hr = IStream_SetSize(iface, newSize);
-    if (FAILED(hr))
-    {
-      ERR("IStream_SetSize failed with error 0x%08x\n", hr);
-      return hr;
-    }
-  }
-
-  /*
-   * Lock the buffer in position and copy the data.
-   */
-  supportBuffer = GlobalLock(This->supportHandle);
-  if (!supportBuffer)
-  {
-      WARN("write to invalid hglobal %p\n", This->supportHandle);
-      return S_OK;
-  }
-
-  memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
+  num_bytes = handle_write(This->handle, &This->currentPosition.u.LowPart, pv, cb);
+  if (pcbWritten) *pcbWritten = num_bytes;
 
-  /*
-   * Move the current position to the new position
-   */
-  This->currentPosition.u.LowPart+=cb;
-
-  /*
-   * Cleanup
-   */
-  GlobalUnlock(This->supportHandle);
-
-out:
-  /*
-   * Return the number of bytes read.
-   */
-  *pcbWritten = cb;
-
-  return S_OK;
+  return (num_bytes < cb) ? E_OUTOFMEMORY : S_OK;
 }
 
 /***
@@ -299,7 +335,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
     case STREAM_SEEK_CUR:
       break;
     case STREAM_SEEK_END:
-      newPosition = This->streamSize;
+      newPosition.QuadPart = handle_getsize(This->handle);
       break;
     default:
       hr = STG_E_SEEKERROR;
@@ -344,29 +380,13 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
                                     ULARGE_INTEGER  libNewSize)   /* [in] */
 {
   HGLOBALStreamImpl* This = impl_from_IStream(iface);
-  HGLOBAL supportHandle;
 
   TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
 
   /*
    * HighPart is ignored as shown in tests
    */
-
-  if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
-    return S_OK;
-
-  /*
-   * Re allocate the HGlobal to fit the new size of the stream.
-   */
-  supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
-
-  if (supportHandle == 0)
-    return E_OUTOFMEMORY;
-
-  This->supportHandle = supportHandle;
-  This->streamSize.u.LowPart = libNewSize.u.LowPart;
-
-  return S_OK;
+  return handle_setsize(This->handle, libNewSize.u.LowPart);
 }
 
 /***
@@ -514,24 +534,49 @@ static HRESULT WINAPI HGLOBALStreamImpl_Stat(
 
   pstatstg->pwcsName = NULL;
   pstatstg->type     = STGTY_STREAM;
-  pstatstg->cbSize   = This->streamSize;
+  pstatstg->cbSize.QuadPart = handle_getsize(This->handle);
 
   return S_OK;
 }
 
+static const IStreamVtbl HGLOBALStreamImplVtbl;
+
+static HGLOBALStreamImpl *HGLOBALStreamImpl_Create(void)
+{
+    HGLOBALStreamImpl *This;
+
+    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+    if (This)
+    {
+        This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl;
+        This->ref = 1;
+    }
+    return This;
+}
+
 static HRESULT WINAPI HGLOBALStreamImpl_Clone(
                  IStream*     iface,
                  IStream**    ppstm) /* [out] */
 {
   HGLOBALStreamImpl* This = impl_from_IStream(iface);
+  HGLOBALStreamImpl* clone;
   ULARGE_INTEGER dummy;
   LARGE_INTEGER offset;
-  HRESULT hr;
 
-  TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart);
-  hr = CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm);
-  if(FAILED(hr))
-    return hr;
+  if (!ppstm) return E_INVALIDARG;
+
+  *ppstm = NULL;
+
+  TRACE(" Cloning %p (seek position=%d)\n", iface, This->currentPosition.u.LowPart);
+
+  clone = HGLOBALStreamImpl_Create();
+  if (!clone) return E_OUTOFMEMORY;
+
+  *ppstm = &clone->IStream_iface;
+
+  handle_addref(This->handle);
+  clone->handle = This->handle;
+
   offset.QuadPart = (LONGLONG)This->currentPosition.QuadPart;
   IStream_Seek(*ppstm, offset, STREAM_SEEK_SET, &dummy);
   return S_OK;
@@ -568,28 +613,19 @@ HRESULT WINAPI CreateStreamOnHGlobal(
   if (!ppstm)
     return E_INVALIDARG;
 
-  This = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
+  This = HGLOBALStreamImpl_Create();
   if (!This) return E_OUTOFMEMORY;
 
-  This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl;
-  This->ref = 1;
-
-  /* initialize the support */
-  This->supportHandle = hGlobal;
-  This->deleteOnRelease = fDeleteOnRelease;
-
   /* allocate a handle if one is not supplied */
-  if (!This->supportHandle)
-    This->supportHandle = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0);
+  if (!hGlobal)
+    hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0);
+
+  This->handle = handle_create(hGlobal, fDeleteOnRelease);
 
   /* start at the beginning */
   This->currentPosition.u.HighPart = 0;
   This->currentPosition.u.LowPart = 0;
 
-  /* initialize the size of the stream to the size of the handle */
-  This->streamSize.u.HighPart = 0;
-  This->streamSize.u.LowPart = GlobalSize(This->supportHandle);
-
   *ppstm = &This->IStream_iface;
 
   return S_OK;
@@ -602,16 +638,16 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
 {
   HGLOBALStreamImpl* pStream;
 
-  if (pstm == NULL)
+  if (!pstm || !phglobal)
     return E_INVALIDARG;
 
-  pStream = (HGLOBALStreamImpl*) pstm;
+  pStream = impl_from_IStream(pstm);
 
   /*
    * Verify that the stream object was created with CreateStreamOnHGlobal.
    */
   if (pStream->IStream_iface.lpVtbl == &HGLOBALStreamImplVtbl)
-    *phglobal = pStream->supportHandle;
+    *phglobal = handle_gethglobal(pStream->handle);
   else
   {
     *phglobal = 0;
index ab6af13..25c63b3 100644 (file)
@@ -127,8 +127,8 @@ static BOOL RemoveMemoryLocation(LPCVOID pMem)
 /******************************************************************************
  *     IMalloc32_QueryInterface        [VTABLE]
  */
-static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) {
-
+static HRESULT WINAPI IMalloc_fnQueryInterface(IMalloc *iface, REFIID refiid, void **obj)
+{
        TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
 
        if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) {
@@ -141,21 +141,22 @@ static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVO
 /******************************************************************************
  *     IMalloc32_AddRefRelease         [VTABLE]
  */
-static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) {
+static ULONG WINAPI IMalloc_fnAddRefRelease(IMalloc *iface)
+{
        return 1;
 }
 
 /******************************************************************************
  *     IMalloc32_Alloc                 [VTABLE]
  */
-static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, SIZE_T cb) {
-
-       LPVOID addr;
+static void * WINAPI IMalloc_fnAlloc(IMalloc *iface, SIZE_T cb)
+{
+       void *addr;
 
-       TRACE("(%d)\n",cb);
+       TRACE("(%ld)\n",cb);
 
        if(Malloc32.pSpy) {
-           DWORD preAllocResult;
+           SIZE_T preAllocResult;
            
            EnterCriticalSection(&IMalloc32_SpyCS);
            preAllocResult = IMallocSpy_PreAlloc(Malloc32.pSpy, cb);
@@ -182,14 +183,14 @@ static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, SIZE_T cb) {
 /******************************************************************************
  * IMalloc32_Realloc [VTABLE]
  */
-static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,SIZE_T cb) {
-
-       LPVOID pNewMemory;
+static void * WINAPI IMalloc_fnRealloc(IMalloc *iface, void *pv, SIZE_T cb)
+{
+       void *pNewMemory;
 
-       TRACE("(%p,%d)\n",pv,cb);
+       TRACE("(%p,%ld)\n",pv,cb);
 
        if(Malloc32.pSpy) {
-           LPVOID pRealMemory;
+           void *pRealMemory;
            BOOL fSpyed;
 
            EnterCriticalSection(&IMalloc32_SpyCS);
@@ -234,8 +235,8 @@ static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,SIZE_T cb) {
 /******************************************************************************
  * IMalloc32_Free [VTABLE]
  */
-static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
-
+static void WINAPI IMalloc_fnFree(IMalloc *iface, void *pv)
+{
         BOOL fSpyed = FALSE;
 
        TRACE("(%p)\n",pv);
@@ -270,9 +271,9 @@ static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
  *      win95:  size allocated (4 byte boundarys)
  *      win2k:  size originally requested !!! (allocated on 8 byte boundarys)
  */
-static SIZE_T WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) {
-
-       DWORD cb;
+static SIZE_T WINAPI IMalloc_fnGetSize(IMalloc *iface, void *pv)
+{
+        SIZE_T cb;
         BOOL fSpyed = FALSE;
 
        TRACE("(%p)\n",pv);
@@ -295,8 +296,8 @@ static SIZE_T WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) {
 /******************************************************************************
  * IMalloc32_DidAlloc [VTABLE]
  */
-static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
-
+static INT WINAPI IMalloc_fnDidAlloc(IMalloc *iface, void *pv)
+{
         BOOL fSpyed = FALSE;
        int didAlloc;
 
@@ -319,7 +320,8 @@ static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
 /******************************************************************************
  * IMalloc32_HeapMinimize [VTABLE]
  */
-static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) {
+static void WINAPI IMalloc_fnHeapMinimize(IMalloc *iface)
+{
        TRACE("()\n");
 
        if(Malloc32.pSpy) {
@@ -352,17 +354,22 @@ static const IMallocVtbl VT_IMalloc32 =
  * Retrieves the current IMalloc interface for the process.
  *
  * PARAMS
- *  dwMemContext [I]
- *  lpMalloc     [O] Address where memory allocator object will be stored.
+ *  context [I] Should always be MEMCTX_TASK.
+ *  imalloc [O] Address where memory allocator object will be stored.
  *
  * RETURNS
  *     Success: S_OK.
  *  Failure: HRESULT code.
  */
-HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC *lpMalloc)
+HRESULT WINAPI CoGetMalloc(DWORD context, IMalloc **imalloc)
 {
-        *lpMalloc = &Malloc32.IMalloc_iface;
-        return S_OK;
+    if (context != MEMCTX_TASK) {
+        *imalloc = NULL;
+        return E_INVALIDARG;
+    }
+
+    *imalloc = &Malloc32.IMalloc_iface;
+    return S_OK;
 }
 
 /***********************************************************************
index 0c843fe..a736162 100644 (file)
@@ -95,11 +95,6 @@ static const WCHAR prop_oledroptarget[] =
 static const WCHAR prop_marshalleddroptarget[] =
   {'W','i','n','e','M','a','r','s','h','a','l','l','e','d','D','r','o','p','T','a','r','g','e','t',0};
 
-static const WCHAR clsidfmtW[] =
-  {'C','L','S','I','D','\\','{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
-   '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',
-    '%','0','2','x','%','0','2','x','}','\\',0};
-
 static const WCHAR emptyW[] = { 0 };
 
 /******************************************************************************
@@ -166,6 +161,8 @@ HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
 
   if (!COM_CurrentInfo()->ole_inits)
     hr = S_OK;
+  else
+    hr = S_FALSE;
 
   /*
    * Then, it has to initialize the OLE specific modules.
@@ -209,6 +206,11 @@ void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
 {
   TRACE("()\n");
 
+  if (COM_CurrentInfo()->ole_inits == 0)
+  {
+    WARN("ole_inits is already 0\n");
+    return ;
+  }
   /*
    * If we hit the bottom of the lock stack, free the libraries.
    */
@@ -641,88 +643,73 @@ HRESULT WINAPI RevokeDragDrop(HWND hwnd)
 
 /***********************************************************************
  *           OleRegGetUserType (OLE32.@)
- *
- * This implementation of OleRegGetUserType ignores the dwFormOfType
- * parameter and always returns the full name of the object. This is
- * not too bad since this is the case for many objects because of the
- * way they are registered.
- */
-HRESULT WINAPI OleRegGetUserType(
-       REFCLSID clsid,
-       DWORD dwFormOfType,
-       LPOLESTR* pszUserType)
-{
-  WCHAR   keyName[60];
-  DWORD   dwKeyType;
-  DWORD   cbData;
-  HKEY    clsidKey;
-  LONG    hres;
+ */
+HRESULT WINAPI OleRegGetUserType(REFCLSID clsid, DWORD form, LPOLESTR *usertype)
+{
+  static const WCHAR auxusertypeW[] = {'A','u','x','U','s','e','r','T','y','p','e','\\','%','d',0};
+  DWORD valuetype, valuelen;
+  WCHAR auxkeynameW[16];
+  HKEY    usertypekey;
+  HRESULT hres;
+  LONG    ret;
 
-  /*
-   * Initialize the out parameter.
-   */
-  *pszUserType = NULL;
+  TRACE("(%s, %u, %p)\n", debugstr_guid(clsid), form, usertype);
 
-  /*
-   * Build the key name we're looking for
-   */
-  sprintfW( keyName, clsidfmtW,
-            clsid->Data1, clsid->Data2, clsid->Data3,
-            clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3],
-            clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] );
+  if (!usertype)
+    return E_INVALIDARG;
 
-  TRACE("(%s, %d, %p)\n", debugstr_w(keyName), dwFormOfType, pszUserType);
+  *usertype = NULL;
 
-  /*
-   * Open the class id Key
-   */
-  hres = open_classes_key(HKEY_CLASSES_ROOT, keyName, MAXIMUM_ALLOWED, &clsidKey);
-  if (hres != ERROR_SUCCESS)
-    return REGDB_E_CLASSNOTREG;
+  /* Return immediately if it's not registered. */
+  hres = COM_OpenKeyForCLSID(clsid, NULL, KEY_READ, &usertypekey);
+  if (FAILED(hres))
+    return hres;
 
-  /*
-   * Retrieve the size of the name string.
-   */
-  cbData = 0;
+  valuelen = 0;
 
-  hres = RegQueryValueExW(clsidKey,
-                         emptyW,
-                         NULL,
-                         &dwKeyType,
-                         NULL,
-                         &cbData);
+  /* Try additional types if requested. If they don't exist fall back to USERCLASSTYPE_FULL. */
+  if (form != USERCLASSTYPE_FULL)
+  {
+    HKEY auxkey;
+
+    sprintfW(auxkeynameW, auxusertypeW, form);
+    if (COM_OpenKeyForCLSID(clsid, auxkeynameW, KEY_READ, &auxkey) == S_OK)
+    {
+      if (!RegQueryValueExW(auxkey, emptyW, NULL, &valuetype, NULL, &valuelen) && valuelen)
+      {
+        RegCloseKey(usertypekey);
+        usertypekey = auxkey;
+      }
+      else
+        RegCloseKey(auxkey);
+    }
+  }
 
-  if (hres!=ERROR_SUCCESS)
+  valuelen = 0;
+  if (RegQueryValueExW(usertypekey, emptyW, NULL, &valuetype, NULL, &valuelen))
   {
-    RegCloseKey(clsidKey);
+    RegCloseKey(usertypekey);
     return REGDB_E_READREGDB;
   }
 
-  /*
-   * Allocate a buffer for the registry value.
-   */
-  *pszUserType = CoTaskMemAlloc(cbData);
-
-  if (*pszUserType==NULL)
+  *usertype = CoTaskMemAlloc(valuelen);
+  if (!*usertype)
   {
-    RegCloseKey(clsidKey);
+    RegCloseKey(usertypekey);
     return E_OUTOFMEMORY;
   }
 
-  hres = RegQueryValueExW(clsidKey,
+  ret = RegQueryValueExW(usertypekey,
                          emptyW,
                          NULL,
-                         &dwKeyType,
-                         (LPBYTE) *pszUserType,
-                         &cbData);
-
-  RegCloseKey(clsidKey);
-
-  if (hres != ERROR_SUCCESS)
+                         &valuetype,
+                         (LPBYTE)*usertype,
+                         &valuelen);
+  RegCloseKey(usertypekey);
+  if (ret != ERROR_SUCCESS)
   {
-    CoTaskMemFree(*pszUserType);
-    *pszUserType = NULL;
-
+    CoTaskMemFree(*usertype);
+    *usertype = NULL;
     return REGDB_E_READREGDB;
   }
 
@@ -848,21 +835,13 @@ HRESULT WINAPI OleRegGetMiscStatus(
 {
   static const WCHAR miscstatusW[] = {'M','i','s','c','S','t','a','t','u','s',0};
   static const WCHAR dfmtW[] = {'%','d',0};
-  WCHAR   keyName[60];
-  HKEY    clsidKey;
+  WCHAR   keyName[16];
   HKEY    miscStatusKey;
   HKEY    aspectKey;
   LONG    result;
+  HRESULT hr;
 
-  /*
-   * Build the key name we're looking for
-   */
-  sprintfW( keyName, clsidfmtW,
-            clsid->Data1, clsid->Data2, clsid->Data3,
-            clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3],
-            clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] );
-
-  TRACE("(%s, %d, %p)\n", debugstr_w(keyName), dwAspect, pdwStatus);
+  TRACE("(%s, %d, %p)\n", debugstr_guid(clsid), dwAspect, pdwStatus);
 
   if (!pdwStatus) return E_INVALIDARG;
 
@@ -870,26 +849,11 @@ HRESULT WINAPI OleRegGetMiscStatus(
 
   if (actctx_get_miscstatus(clsid, dwAspect, pdwStatus)) return S_OK;
 
-  /*
-   * Open the class id Key
-   */
-  result = open_classes_key(HKEY_CLASSES_ROOT, keyName, MAXIMUM_ALLOWED, &clsidKey);
-  if (result != ERROR_SUCCESS)
-    return REGDB_E_CLASSNOTREG;
-
-  /*
-   * Get the MiscStatus
-   */
-  result = open_classes_key(clsidKey, miscstatusW, MAXIMUM_ALLOWED, &miscStatusKey);
-  if (result != ERROR_SUCCESS)
-  {
-    RegCloseKey(clsidKey);
-    return S_OK;
-  }
+  hr = COM_OpenKeyForCLSID(clsid, miscstatusW, KEY_READ, &miscStatusKey);
+  if (FAILED(hr))
+    /* missing key is not a failure */
+    return hr == REGDB_E_KEYMISSING ? S_OK : hr;
 
-  /*
-   * Read the default value
-   */
   OLEUTL_ReadRegistryDWORDValue(miscStatusKey, pdwStatus);
 
   /*
@@ -897,19 +861,14 @@ HRESULT WINAPI OleRegGetMiscStatus(
    */
   sprintfW(keyName, dfmtW, dwAspect);
 
-  result = open_classes_key(miscStatusKey, keyName, MAXIMUM_ALLOWED, &aspectKey);
+  result = open_classes_key(miscStatusKey, keyName, KEY_READ, &aspectKey);
   if (result == ERROR_SUCCESS)
   {
     OLEUTL_ReadRegistryDWORDValue(aspectKey, pdwStatus);
     RegCloseKey(aspectKey);
   }
 
-  /*
-   * Cleanup
-   */
   RegCloseKey(miscStatusKey);
-  RegCloseKey(clsidKey);
-
   return S_OK;
 }
 
@@ -2567,7 +2526,7 @@ HRESULT WINAPI OleCreate(
         if (SUCCEEDED(hres))
         {
             DWORD dwStatus;
-            hres = IOleObject_GetMiscStatus(pOleObject, DVASPECT_CONTENT, &dwStatus);
+            IOleObject_GetMiscStatus(pOleObject, DVASPECT_CONTENT, &dwStatus);
         }
     }
 
@@ -2596,21 +2555,12 @@ HRESULT WINAPI OleCreate(
     if (((renderopt == OLERENDER_DRAW) || (renderopt == OLERENDER_FORMAT)) &&
         SUCCEEDED(hres))
     {
-        IRunnableObject *pRunnable;
-        IOleCache *pOleCache;
-        HRESULT hres2;
-
-        hres2 = IUnknown_QueryInterface(pUnk, &IID_IRunnableObject, (void **)&pRunnable);
-        if (SUCCEEDED(hres2))
-        {
-            hres = IRunnableObject_Run(pRunnable, NULL);
-            IRunnableObject_Release(pRunnable);
-        }
-
+        hres = OleRun(pUnk);
         if (SUCCEEDED(hres))
         {
-            hres2 = IUnknown_QueryInterface(pUnk, &IID_IOleCache, (void **)&pOleCache);
-            if (SUCCEEDED(hres2))
+            IOleCache *pOleCache;
+
+            if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IOleCache, (void **)&pOleCache)))
             {
                 DWORD dwConnection;
                 if (renderopt == OLERENDER_DRAW && !pFormatEtc) {
index a151f70..6443197 100644 (file)
@@ -8882,7 +8882,7 @@ HRESULT WINAPI StgOpenStorage(
    * Refuse to open the file if it's too small to be a structured storage file
    * FIXME: verify the file when reading instead of here
    */
-  if (GetFileSize(hFile, NULL) < 0x100)
+  if (GetFileSize(hFile, NULL) < HEADER_SIZE)
   {
     CloseHandle(hFile);
     hr = STG_E_FILEALREADYEXISTS;
index 855df8f..fc3c460 100644 (file)
@@ -142,7 +142,7 @@ reactos/dll/win32/ntprint             # Synced to WineStaging-1.7.55
 reactos/dll/win32/objsel              # Synced to WineStaging-1.7.55
 reactos/dll/win32/odbc32              # Synced to WineStaging-1.9.4. Depends on port of Linux ODBC.
 reactos/dll/win32/odbccp32            # Synced to WineStaging-1.7.55
-reactos/dll/win32/ole32               # Synced to WineStaging-1.7.55
+reactos/dll/win32/ole32               # Synced to WineStaging-1.9.4
 reactos/dll/win32/oleacc              # Synced to WineStaging-1.7.55
 reactos/dll/win32/oleaut32            # Synced to WineStaging-1.7.55
 reactos/dll/win32/olecli32            # Synced to WineStaging-1.7.55