Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/Makefile.in | 1 + dlls/combase/combase.spec | 12 +- dlls/combase/malloc.c | 456 +++++++++++++++++++++++++++++++++ dlls/ole32/ifs.c | 515 -------------------------------------- dlls/ole32/ole32.spec | 12 +- 5 files changed, 469 insertions(+), 527 deletions(-) create mode 100644 dlls/combase/malloc.c
diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in index 83c71ce9493..f2174f4e3eb 100644 --- a/dlls/combase/Makefile.in +++ b/dlls/combase/Makefile.in @@ -7,6 +7,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ errorinfo.c \ + malloc.c \ roapi.c \ string.c \ usrmarshal.c diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index cb073ef2fcc..aa1c04ce0ac 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -109,7 +109,7 @@ @ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) ole32.CoGetInstanceFromFile @ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr) ole32.CoGetInstanceFromIStorage @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) ole32.CoGetInterfaceAndReleaseStream -@ stdcall CoGetMalloc(long ptr) ole32.CoGetMalloc +@ stdcall CoGetMalloc(long ptr) @ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long) ole32.CoGetMarshalSizeMax @ stub CoGetModuleType @ stdcall CoGetObjectContext(ptr ptr) ole32.CoGetObjectContext @@ -139,7 +139,7 @@ @ stub CoRegisterActivationFilter @ stdcall CoRegisterClassObject(ptr ptr long long ptr) ole32.CoRegisterClassObject @ stdcall CoRegisterInitializeSpy(ptr ptr) ole32.CoRegisterInitializeSpy -@ stdcall CoRegisterMallocSpy(ptr) ole32.CoRegisterMallocSpy +@ stdcall CoRegisterMallocSpy(ptr) @ stdcall CoRegisterMessageFilter(ptr ptr) ole32.CoRegisterMessageFilter @ stdcall CoRegisterPSClsid(ptr ptr) ole32.CoRegisterPSClsid @ stdcall CoRegisterSurrogate(ptr) ole32.CoRegisterSurrogate @@ -151,15 +151,15 @@ @ stdcall CoRevertToSelf() ole32.CoRevertToSelf @ stdcall CoRevokeClassObject(long) ole32.CoRevokeClassObject @ stdcall CoRevokeInitializeSpy(int64) ole32.CoRevokeInitializeSpy -@ stdcall CoRevokeMallocSpy() ole32.CoRevokeMallocSpy +@ stdcall CoRevokeMallocSpy() @ stub CoSetCancelObject @ stub CoSetErrorInfo @ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long) ole32.CoSetProxyBlanket @ stdcall CoSuspendClassObjects() ole32.CoSuspendClassObjects @ stdcall CoSwitchCallContext(ptr ptr) ole32.CoSwitchCallContext -@ stdcall CoTaskMemAlloc(long) ole32.CoTaskMemAlloc -@ stdcall CoTaskMemFree(ptr) ole32.CoTaskMemFree -@ stdcall CoTaskMemRealloc(ptr long) ole32.CoTaskMemRealloc +@ stdcall CoTaskMemAlloc(long) +@ stdcall CoTaskMemFree(ptr) +@ stdcall CoTaskMemRealloc(ptr long) @ stub CoTestCancel @ stdcall CoUninitialize() ole32.CoUninitialize @ stub CoUnloadingWOW diff --git a/dlls/combase/malloc.c b/dlls/combase/malloc.c new file mode 100644 index 00000000000..2be03ae1e31 --- /dev/null +++ b/dlls/combase/malloc.c @@ -0,0 +1,456 @@ +/* + * Copyright 1997 Marcus Meissner + * + * 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 + */ + +#define COBJMACROS + +#include "oleauto.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +WINE_DEFAULT_DEBUG_CHANNEL(olemalloc); + +static const IMallocVtbl allocator_vtbl; + +struct allocator +{ + IMalloc IMalloc_iface; + IMallocSpy *spy; + DWORD spyed_allocations; + BOOL spy_release_pending; /* CoRevokeMallocSpy called with spyed allocations left */ + void **blocks; + DWORD blocks_length; +}; + +static struct allocator allocator = { .IMalloc_iface.lpVtbl = &allocator_vtbl }; + +static CRITICAL_SECTION allocspy_cs; +static CRITICAL_SECTION_DEBUG allocspy_cs_debug = +{ + 0, 0, &allocspy_cs, + { &allocspy_cs_debug.ProcessLocksList, &allocspy_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": allocspy_cs") } +}; +static CRITICAL_SECTION allocspy_cs = { &allocspy_cs_debug, -1, 0, 0, 0, 0 }; + +static BOOL mallocspy_grow(DWORD length) +{ + void **blocks; + + if (!allocator.blocks) blocks = LocalAlloc(LMEM_ZEROINIT, length * sizeof(void *)); + else blocks = LocalReAlloc(allocator.blocks, length * sizeof(void *), LMEM_ZEROINIT | LMEM_MOVEABLE); + if (blocks) + { + allocator.blocks = blocks; + allocator.blocks_length = length; + } + + return blocks != NULL; +} + +static void mallocspy_add_mem(void *mem) +{ + void **current; + + if (!mem || (!allocator.blocks_length && !mallocspy_grow(0x1000))) + return; + + /* Find a free location */ + current = allocator.blocks; + while (*current) + { + current++; + if (current >= allocator.blocks + allocator.blocks_length) + { + DWORD old_length = allocator.blocks_length; + if (!mallocspy_grow(allocator.blocks_length + 0x1000)) + return; + current = allocator.blocks + old_length; + } + } + + *current = mem; + allocator.spyed_allocations++; +} + +static void** mallocspy_is_allocation_spyed(const void *mem) +{ + void **current = allocator.blocks; + + while (*current != mem) + { + current++; + if (current >= allocator.blocks + allocator.blocks_length) + return NULL; + } + + return current; +} + +static BOOL mallocspy_remove_spyed_memory(const void *mem) +{ + void **current; + + if (!allocator.blocks_length) + return FALSE; + + if (!(current = mallocspy_is_allocation_spyed(mem))) + return FALSE; + + allocator.spyed_allocations--; + *current = NULL; + return TRUE; +} + +static HRESULT WINAPI allocator_QueryInterface(IMalloc *iface, REFIID riid, void **obj) +{ + TRACE("%s, %p.\n", debugstr_guid(riid), obj); + + if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IMalloc, riid)) + { + *obj = &allocator.IMalloc_iface; + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI allocator_AddRef(IMalloc *iface) +{ + return 2; +} + +static ULONG WINAPI allocator_Release(IMalloc *iface) +{ + return 1; +} + +static void * WINAPI allocator_Alloc(IMalloc *iface, SIZE_T cb) +{ + void *addr; + + TRACE("%ld.\n", cb); + + if (allocator.spy) + { + SIZE_T preAllocResult; + + EnterCriticalSection(&allocspy_cs); + preAllocResult = IMallocSpy_PreAlloc(allocator.spy, cb); + if (cb && !preAllocResult) + { + /* PreAlloc can force Alloc to fail, but not if cb == 0 */ + TRACE("returning null\n"); + LeaveCriticalSection(&allocspy_cs); + return NULL; + } + } + + addr = HeapAlloc(GetProcessHeap(), 0, cb); + + if (allocator.spy) + { + addr = IMallocSpy_PostAlloc(allocator.spy, addr); + mallocspy_add_mem(addr); + LeaveCriticalSection(&allocspy_cs); + } + + TRACE("%p.\n",addr); + return addr; +} + +static void * WINAPI allocator_Realloc(IMalloc *iface, void *pv, SIZE_T cb) +{ + void *addr; + + TRACE("%p, %ld.\n",pv,cb); + + if (allocator.spy) + { + void *real_mem; + BOOL spyed; + + EnterCriticalSection(&allocspy_cs); + spyed = mallocspy_remove_spyed_memory(pv); + cb = IMallocSpy_PreRealloc(allocator.spy, pv, cb, &real_mem, spyed); + + /* check if can release the spy */ + if (allocator.spy_release_pending && !allocator.spyed_allocations) + { + IMallocSpy_Release(allocator.spy); + allocator.spy_release_pending = FALSE; + allocator.spy = NULL; + LeaveCriticalSection(&allocspy_cs); + } + + if (!cb) + { + /* PreRealloc can force Realloc to fail */ + if (allocator.spy) + LeaveCriticalSection(&allocspy_cs); + return NULL; + } + + pv = real_mem; + } + + if (!pv) addr = HeapAlloc(GetProcessHeap(), 0, cb); + else if (cb) addr = HeapReAlloc(GetProcessHeap(), 0, pv, cb); + else + { + HeapFree(GetProcessHeap(), 0, pv); + addr = NULL; + } + + if (allocator.spy) + { + addr = IMallocSpy_PostRealloc(allocator.spy, addr, TRUE); + mallocspy_add_mem(addr); + LeaveCriticalSection(&allocspy_cs); + } + + TRACE("%p.\n", addr); + return addr; +} + +static void WINAPI allocator_Free(IMalloc *iface, void *mem) +{ + BOOL spyed_block = FALSE, spy_active = FALSE; + + TRACE("%p.\n", mem); + + if (!mem) + return; + + if (allocator.spy) + { + EnterCriticalSection(&allocspy_cs); + spyed_block = mallocspy_remove_spyed_memory(mem); + spy_active = TRUE; + mem = IMallocSpy_PreFree(allocator.spy, mem, spyed_block); + } + + HeapFree(GetProcessHeap(), 0, mem); + + if (spy_active) + { + IMallocSpy_PostFree(allocator.spy, spyed_block); + + /* check if can release the spy */ + if (allocator.spy_release_pending && !allocator.spyed_allocations) + { + IMallocSpy_Release(allocator.spy); + allocator.spy_release_pending = FALSE; + allocator.spy = NULL; + } + + LeaveCriticalSection(&allocspy_cs); + } +} + +/****************************************************************************** + * NOTES + * FIXME returns: + * win95: size allocated (4 byte boundaries) + * win2k: size originally requested !!! (allocated on 8 byte boundaries) + */ +static SIZE_T WINAPI allocator_GetSize(IMalloc *iface, void *mem) +{ + BOOL spyed_block = FALSE, spy_active = FALSE; + SIZE_T size; + + TRACE("%p.\n", mem); + + if (!mem) + return (SIZE_T)-1; + + if (allocator.spy) + { + EnterCriticalSection(&allocspy_cs); + spyed_block = !!mallocspy_is_allocation_spyed(mem); + spy_active = TRUE; + mem = IMallocSpy_PreGetSize(allocator.spy, mem, spyed_block); + } + + size = HeapSize(GetProcessHeap(), 0, mem); + + if (spy_active) + { + size = IMallocSpy_PostGetSize(allocator.spy, size, spyed_block); + LeaveCriticalSection(&allocspy_cs); + } + + return size; +} + +static INT WINAPI allocator_DidAlloc(IMalloc *iface, void *mem) +{ + BOOL spyed_block = FALSE, spy_active = FALSE; + int did_alloc; + + TRACE("%p.\n", mem); + + if (!mem) + return -1; + + if (allocator.spy) + { + EnterCriticalSection(&allocspy_cs); + spyed_block = !!mallocspy_is_allocation_spyed(mem); + spy_active = TRUE; + mem = IMallocSpy_PreDidAlloc(allocator.spy, mem, spyed_block); + } + + did_alloc = HeapValidate(GetProcessHeap(), 0, mem); + + if (spy_active) + { + did_alloc = IMallocSpy_PostDidAlloc(allocator.spy, mem, spyed_block, did_alloc); + LeaveCriticalSection(&allocspy_cs); + } + + return did_alloc; +} + +static void WINAPI allocator_HeapMinimize(IMalloc *iface) +{ + BOOL spy_active = FALSE; + + TRACE("\n"); + + if (allocator.spy) + { + EnterCriticalSection(&allocspy_cs); + spy_active = TRUE; + IMallocSpy_PreHeapMinimize(allocator.spy); + } + + if (spy_active) + { + IMallocSpy_PostHeapMinimize(allocator.spy); + LeaveCriticalSection(&allocspy_cs); + } +} + +static const IMallocVtbl allocator_vtbl = +{ + allocator_QueryInterface, + allocator_AddRef, + allocator_Release, + allocator_Alloc, + allocator_Realloc, + allocator_Free, + allocator_GetSize, + allocator_DidAlloc, + allocator_HeapMinimize +}; + +/****************************************************************************** + * CoGetMalloc (combase.@) + */ +HRESULT WINAPI CoGetMalloc(DWORD context, IMalloc **imalloc) +{ + if (context != MEMCTX_TASK) + { + *imalloc = NULL; + return E_INVALIDARG; + } + + *imalloc = &allocator.IMalloc_iface; + + return S_OK; +} + +/*********************************************************************** + * CoTaskMemAlloc (combase.@) + */ +void * WINAPI CoTaskMemAlloc(SIZE_T size) +{ + return IMalloc_Alloc(&allocator.IMalloc_iface, size); +} + +/*********************************************************************** + * CoTaskMemFree (combase.@) + */ +void WINAPI CoTaskMemFree(void *ptr) +{ + IMalloc_Free(&allocator.IMalloc_iface, ptr); +} + +/*********************************************************************** + * CoTaskMemRealloc (combase.@) + */ +void * WINAPI CoTaskMemRealloc(void *ptr, SIZE_T size) +{ + return IMalloc_Realloc(&allocator.IMalloc_iface, ptr, size); +} + +/*********************************************************************** + * CoRegisterMallocSpy (combase.@) + */ +HRESULT WINAPI CoRegisterMallocSpy(IMallocSpy *spy) +{ + HRESULT hr = E_INVALIDARG; + + TRACE("%p.\n", spy); + + if (!spy) return E_INVALIDARG; + + EnterCriticalSection(&allocspy_cs); + + if (allocator.spy) + hr = CO_E_OBJISREG; + else if (SUCCEEDED(IMallocSpy_QueryInterface(spy, &IID_IMallocSpy, (void **)&spy))) + { + allocator.spy = spy; + hr = S_OK; + } + + LeaveCriticalSection(&allocspy_cs); + + return hr; +} + +/*********************************************************************** + * CoRevokeMallocSpy (combase.@) + */ +HRESULT WINAPI CoRevokeMallocSpy(void) +{ + HRESULT hr = S_OK; + + TRACE("\n"); + + EnterCriticalSection(&allocspy_cs); + + if (!allocator.spy) + hr = CO_E_OBJNOTREG; + else if (allocator.spyed_allocations) + { + allocator.spy_release_pending = TRUE; + hr = E_ACCESSDENIED; + } + else + { + IMallocSpy_Release(allocator.spy); + allocator.spy = NULL; + } + + LeaveCriticalSection(&allocspy_cs); + + return hr; +} diff --git a/dlls/ole32/ifs.c b/dlls/ole32/ifs.c index a144833c7af..845bdeea4a5 100644 --- a/dlls/ole32/ifs.c +++ b/dlls/ole32/ifs.c @@ -32,521 +32,6 @@ #include "ole2.h" #include "winerror.h"
-#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(olemalloc); - -/****************************************************************************** - * IMalloc32 implementation - * - * NOTES - * For supporting CoRegisterMallocSpy the IMalloc implementation must know if - * a given memory block was allocated with a spy active. - * - *****************************************************************************/ -/* set the vtable later */ -static const IMallocVtbl VT_IMalloc32; - -struct allocator -{ - IMalloc IMalloc_iface; - IMallocSpy * pSpy; /* the spy when active */ - DWORD SpyedAllocationsLeft; /* number of spyed allocations left */ - BOOL SpyReleasePending; /* CoRevokeMallocSpy called with spyed allocations left*/ - LPVOID * SpyedBlocks; /* root of the table */ - DWORD SpyedBlockTableLength;/* size of the table*/ -}; - -static struct allocator Malloc32 = { .IMalloc_iface.lpVtbl = &VT_IMalloc32 }; - -/* with a spy active all calls from pre to post methods are threadsafe */ -static CRITICAL_SECTION IMalloc32_SpyCS; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &IMalloc32_SpyCS, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": IMalloc32_SpyCS") } -}; -static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 }; - -/* resize the old table */ -static BOOL SetSpyedBlockTableLength ( DWORD NewLength ) -{ - LPVOID *NewSpyedBlocks; - - if (!Malloc32.SpyedBlocks) NewSpyedBlocks = LocalAlloc(LMEM_ZEROINIT, NewLength * sizeof(PVOID)); - else NewSpyedBlocks = LocalReAlloc(Malloc32.SpyedBlocks, NewLength * sizeof(PVOID), LMEM_ZEROINIT | LMEM_MOVEABLE); - if (NewSpyedBlocks) { - Malloc32.SpyedBlocks = NewSpyedBlocks; - Malloc32.SpyedBlockTableLength = NewLength; - } - - return NewSpyedBlocks != NULL; -} - -/* add a location to the table */ -static BOOL AddMemoryLocation(LPVOID * pMem) -{ - LPVOID * Current; - - /* allocate the table if not already allocated */ - if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000)) - return FALSE; - - /* find a free location */ - Current = Malloc32.SpyedBlocks; - while (*Current) { - Current++; - if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) { - /* no more space in table, grow it */ - DWORD old_length = Malloc32.SpyedBlockTableLength; - if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000)) - return FALSE; - Current = Malloc32.SpyedBlocks + old_length; - } - }; - - /* put the location in our table */ - *Current = pMem; - Malloc32.SpyedAllocationsLeft++; - /*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/ - return TRUE; -} - -static void** mallocspy_is_allocation_spyed(const void *mem) -{ - void **current = Malloc32.SpyedBlocks; - - while (*current != mem) - { - current++; - if (current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) - return NULL; - } - - return current; -} - -static BOOL mallocspy_remove_spyed_memory(const void *mem) -{ - void **current; - - if (!Malloc32.SpyedBlockTableLength) - return FALSE; - - if (!(current = mallocspy_is_allocation_spyed(mem))) - return FALSE; - - Malloc32.SpyedAllocationsLeft--; - *current = NULL; - return TRUE; -} - -/****************************************************************************** - * IMalloc32_QueryInterface [VTABLE] - */ -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)) { - *obj = &Malloc32; - return S_OK; - } - return E_NOINTERFACE; -} - -/****************************************************************************** - * IMalloc32_AddRefRelease [VTABLE] - */ -static ULONG WINAPI IMalloc_fnAddRefRelease(IMalloc *iface) -{ - return 1; -} - -/****************************************************************************** - * IMalloc32_Alloc [VTABLE] - */ -static void * WINAPI IMalloc_fnAlloc(IMalloc *iface, SIZE_T cb) -{ - void *addr; - - TRACE("(%ld)\n",cb); - - if(Malloc32.pSpy) { - SIZE_T preAllocResult; - - EnterCriticalSection(&IMalloc32_SpyCS); - preAllocResult = IMallocSpy_PreAlloc(Malloc32.pSpy, cb); - if ((cb != 0) && (preAllocResult == 0)) { - /* PreAlloc can force Alloc to fail, but not if cb == 0 */ - TRACE("returning null\n"); - LeaveCriticalSection(&IMalloc32_SpyCS); - return NULL; - } - } - - addr = HeapAlloc(GetProcessHeap(),0,cb); - - if(Malloc32.pSpy) { - addr = IMallocSpy_PostAlloc(Malloc32.pSpy, addr); - if (addr) AddMemoryLocation(addr); - LeaveCriticalSection(&IMalloc32_SpyCS); - } - - TRACE("--(%p)\n",addr); - return addr; -} - -/****************************************************************************** - * IMalloc32_Realloc [VTABLE] - */ -static void * WINAPI IMalloc_fnRealloc(IMalloc *iface, void *pv, SIZE_T cb) -{ - void *pNewMemory; - - TRACE("(%p,%ld)\n",pv,cb); - - if(Malloc32.pSpy) { - void *pRealMemory; - BOOL fSpyed; - - EnterCriticalSection(&IMalloc32_SpyCS); - fSpyed = mallocspy_remove_spyed_memory(pv); - cb = IMallocSpy_PreRealloc(Malloc32.pSpy, pv, cb, &pRealMemory, fSpyed); - - /* check if can release the spy */ - if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) { - IMallocSpy_Release(Malloc32.pSpy); - Malloc32.SpyReleasePending = FALSE; - Malloc32.pSpy = NULL; - LeaveCriticalSection(&IMalloc32_SpyCS); - } - - if (0==cb) { - /* PreRealloc can force Realloc to fail */ - if (Malloc32.pSpy) - LeaveCriticalSection(&IMalloc32_SpyCS); - return NULL; - } - - pv = pRealMemory; - } - - if (!pv) pNewMemory = HeapAlloc(GetProcessHeap(),0,cb); - else if (cb) pNewMemory = HeapReAlloc(GetProcessHeap(),0,pv,cb); - else { - HeapFree(GetProcessHeap(),0,pv); - pNewMemory = NULL; - } - - if(Malloc32.pSpy) { - pNewMemory = IMallocSpy_PostRealloc(Malloc32.pSpy, pNewMemory, TRUE); - if (pNewMemory) AddMemoryLocation(pNewMemory); - LeaveCriticalSection(&IMalloc32_SpyCS); - } - - TRACE("--(%p)\n",pNewMemory); - return pNewMemory; -} - -/****************************************************************************** - * IMalloc32_Free [VTABLE] - */ -static void WINAPI IMalloc_fnFree(IMalloc *iface, void *mem) -{ - BOOL spyed_block = FALSE, spy_active = FALSE; - - TRACE("(%p)\n", mem); - - if (!mem) - return; - - if (Malloc32.pSpy) - { - EnterCriticalSection(&IMalloc32_SpyCS); - spyed_block = mallocspy_remove_spyed_memory(mem); - spy_active = TRUE; - mem = IMallocSpy_PreFree(Malloc32.pSpy, mem, spyed_block); - } - - HeapFree(GetProcessHeap(), 0, mem); - - if (spy_active) - { - IMallocSpy_PostFree(Malloc32.pSpy, spyed_block); - - /* check if can release the spy */ - if (Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) - { - IMallocSpy_Release(Malloc32.pSpy); - Malloc32.SpyReleasePending = FALSE; - Malloc32.pSpy = NULL; - } - - LeaveCriticalSection(&IMalloc32_SpyCS); - } -} - -/****************************************************************************** - * IMalloc32_GetSize [VTABLE] - * - * NOTES - * FIXME returns: - * win95: size allocated (4 byte boundaries) - * win2k: size originally requested !!! (allocated on 8 byte boundaries) - */ -static SIZE_T WINAPI IMalloc_fnGetSize(IMalloc *iface, void *mem) -{ - BOOL spyed_block = FALSE, spy_active = FALSE; - SIZE_T size; - - TRACE("(%p)\n", mem); - - if (!mem) - return (SIZE_T)-1; - - if (Malloc32.pSpy) - { - EnterCriticalSection(&IMalloc32_SpyCS); - spyed_block = !!mallocspy_is_allocation_spyed(mem); - spy_active = TRUE; - mem = IMallocSpy_PreGetSize(Malloc32.pSpy, mem, spyed_block); - } - - size = HeapSize(GetProcessHeap(), 0, mem); - - if (spy_active) - { - size = IMallocSpy_PostGetSize(Malloc32.pSpy, size, spyed_block); - LeaveCriticalSection(&IMalloc32_SpyCS); - } - - return size; -} - -/****************************************************************************** - * IMalloc32_DidAlloc [VTABLE] - */ -static INT WINAPI IMalloc_fnDidAlloc(IMalloc *iface, void *mem) -{ - BOOL spyed_block = FALSE, spy_active = FALSE; - int did_alloc; - - TRACE("(%p)\n", mem); - - if (!mem) - return -1; - - if (Malloc32.pSpy) - { - EnterCriticalSection(&IMalloc32_SpyCS); - spyed_block = !!mallocspy_is_allocation_spyed(mem); - spy_active = TRUE; - mem = IMallocSpy_PreDidAlloc(Malloc32.pSpy, mem, spyed_block); - } - - did_alloc = HeapValidate(GetProcessHeap(), 0, mem); - - if (spy_active) - { - did_alloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, mem, spyed_block, did_alloc); - LeaveCriticalSection(&IMalloc32_SpyCS); - } - - return did_alloc; -} - -/****************************************************************************** - * IMalloc32_HeapMinimize [VTABLE] - */ -static void WINAPI IMalloc_fnHeapMinimize(IMalloc *iface) -{ - BOOL spy_active = FALSE; - - TRACE("()\n"); - - if (Malloc32.pSpy) - { - EnterCriticalSection(&IMalloc32_SpyCS); - spy_active = TRUE; - IMallocSpy_PreHeapMinimize(Malloc32.pSpy); - } - - if (spy_active) - { - IMallocSpy_PostHeapMinimize(Malloc32.pSpy); - LeaveCriticalSection(&IMalloc32_SpyCS); - } -} - -static const IMallocVtbl VT_IMalloc32 = -{ - IMalloc_fnQueryInterface, - IMalloc_fnAddRefRelease, - IMalloc_fnAddRefRelease, - IMalloc_fnAlloc, - IMalloc_fnRealloc, - IMalloc_fnFree, - IMalloc_fnGetSize, - IMalloc_fnDidAlloc, - IMalloc_fnHeapMinimize -}; - -/****************************************************************************** - * CoGetMalloc [OLE32.@] - * - * Retrieves the current IMalloc interface for the process. - * - * PARAMS - * 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 context, IMalloc **imalloc) -{ - if (context != MEMCTX_TASK) { - *imalloc = NULL; - return E_INVALIDARG; - } - - *imalloc = &Malloc32.IMalloc_iface; - return S_OK; -} - -/*********************************************************************** - * CoTaskMemAlloc [OLE32.@] - * - * Allocates memory using the current process memory allocator. - * - * PARAMS - * size [I] Size of the memory block to allocate. - * - * RETURNS - * Success: Pointer to newly allocated memory block. - * Failure: NULL. - */ -LPVOID WINAPI CoTaskMemAlloc(SIZE_T size) -{ - return IMalloc_Alloc(&Malloc32.IMalloc_iface,size); -} - -/*********************************************************************** - * CoTaskMemFree [OLE32.@] - * - * Frees memory allocated from the current process memory allocator. - * - * PARAMS - * ptr [I] Memory block to free. - * - * RETURNS - * Nothing. - */ -VOID WINAPI CoTaskMemFree(LPVOID ptr) -{ - IMalloc_Free(&Malloc32.IMalloc_iface, ptr); -} - -/*********************************************************************** - * CoTaskMemRealloc [OLE32.@] - * - * Allocates memory using the current process memory allocator. - * - * PARAMS - * pvOld [I] Pointer to old memory block. - * size [I] Size of the new memory block. - * - * RETURNS - * Success: Pointer to newly allocated memory block. - * Failure: NULL. - */ -LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, SIZE_T size) -{ - return IMalloc_Realloc(&Malloc32.IMalloc_iface, pvOld, size); -} - -/*********************************************************************** - * CoRegisterMallocSpy [OLE32.@] - * - * Registers an object that receives notifications on memory allocations and - * frees. - * - * PARAMS - * pMallocSpy [I] New spy object. - * - * RETURNS - * Success: S_OK. - * Failure: HRESULT code. - * - * NOTES - * if a mallocspy is already registered, we can't do it again since - * only the spy knows, how to free a memory block - */ -HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy) -{ - IMallocSpy* pSpy; - HRESULT hres = E_INVALIDARG; - - TRACE("%p\n", pMallocSpy); - - if(!pMallocSpy) return E_INVALIDARG; - - EnterCriticalSection(&IMalloc32_SpyCS); - - if (Malloc32.pSpy) - hres = CO_E_OBJISREG; - else if (SUCCEEDED(IMallocSpy_QueryInterface(pMallocSpy, &IID_IMallocSpy, (void**)&pSpy))) { - Malloc32.pSpy = pSpy; - hres = S_OK; - } - - LeaveCriticalSection(&IMalloc32_SpyCS); - - return hres; -} - -/*********************************************************************** - * CoRevokeMallocSpy [OLE32.@] - * - * Revokes a previously registered object that receives notifications on memory - * allocations and frees. - * - * PARAMS - * pMallocSpy [I] New spy object. - * - * RETURNS - * Success: S_OK. - * Failure: HRESULT code. - * - * NOTES - * we can't revoke a malloc spy as long as memory blocks allocated with - * the spy are active since only the spy knows how to free them - */ -HRESULT WINAPI CoRevokeMallocSpy(void) -{ - HRESULT hres = S_OK; - TRACE("\n"); - - EnterCriticalSection(&IMalloc32_SpyCS); - - if (!Malloc32.pSpy) - hres = CO_E_OBJNOTREG; - else if (Malloc32.SpyedAllocationsLeft) { - TRACE("SpyReleasePending with %u allocations left\n", Malloc32.SpyedAllocationsLeft); - Malloc32.SpyReleasePending = TRUE; - hres = E_ACCESSDENIED; - } else { - IMallocSpy_Release(Malloc32.pSpy); - Malloc32.pSpy = NULL; - } - LeaveCriticalSection(&IMalloc32_SpyCS); - - return hres; -} - /****************************************************************************** * IsValidInterface [OLE32.@] * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 927a98ea123..78e8641cf36 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -38,7 +38,7 @@ @ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) @ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr) @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) -@ stdcall CoGetMalloc(long ptr) +@ stdcall CoGetMalloc(long ptr) combase.CoGetMalloc @ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long) @ stdcall CoGetObject(wstr ptr ptr ptr) @ stdcall CoGetObjectContext(ptr ptr) @@ -67,7 +67,7 @@ @ stdcall CoRegisterChannelHook(ptr ptr) @ stdcall CoRegisterClassObject(ptr ptr long long ptr) @ stdcall CoRegisterInitializeSpy(ptr ptr) -@ stdcall CoRegisterMallocSpy (ptr) +@ stdcall CoRegisterMallocSpy(ptr) combase.CoRegisterMallocSpy @ stdcall CoRegisterMessageFilter(ptr ptr) @ stdcall CoRegisterPSClsid(ptr ptr) @ stdcall CoRegisterSurrogate(ptr) @@ -78,14 +78,14 @@ @ stdcall CoRevertToSelf() @ stdcall CoRevokeClassObject(long) @ stdcall CoRevokeInitializeSpy(int64) -@ stdcall CoRevokeMallocSpy() +@ stdcall CoRevokeMallocSpy() combase.CoRevokeMallocSpy @ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long) @ stdcall CoSetState(ptr) @ stdcall CoSuspendClassObjects() @ stdcall CoSwitchCallContext(ptr ptr) -@ stdcall CoTaskMemAlloc(long) -@ stdcall CoTaskMemFree(ptr) -@ stdcall CoTaskMemRealloc(ptr long) +@ stdcall CoTaskMemAlloc(long) combase.CoTaskMemAlloc +@ stdcall CoTaskMemFree(ptr) combase.CoTaskMemFree +@ stdcall CoTaskMemRealloc(ptr long) combase.CoTaskMemRealloc @ stdcall CoTreatAsClass(ptr ptr) @ stdcall CoUninitialize() @ stub CoUnloadingWOW
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/Makefile.in | 1 - dlls/ole32/ifs.c | 54 ----------------------------------------- dlls/ole32/ole32_main.c | 21 ++++++++++++++++ 3 files changed, 21 insertions(+), 55 deletions(-) delete mode 100644 dlls/ole32/ifs.c
diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index 4738407d7fd..86f13e188cf 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -23,7 +23,6 @@ C_SRCS = \ ftmarshal.c \ git.c \ hglobalstream.c \ - ifs.c \ itemmoniker.c \ marshal.c \ memlockbytes.c \ diff --git a/dlls/ole32/ifs.c b/dlls/ole32/ifs.c deleted file mode 100644 index 845bdeea4a5..00000000000 --- a/dlls/ole32/ifs.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * basic interfaces - * - * Copyright 1997 Marcus Meissner - * - * 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 <ctype.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "ole2.h" -#include "winerror.h" - -/****************************************************************************** - * IsValidInterface [OLE32.@] - * - * Determines whether a pointer is a valid interface. - * - * PARAMS - * punk [I] Interface to be tested. - * - * RETURNS - * TRUE, if the passed pointer is a valid interface, or FALSE otherwise. - */ -BOOL WINAPI IsValidInterface(LPUNKNOWN punk) -{ - return !( - IsBadReadPtr(punk,4) || - IsBadReadPtr(punk->lpVtbl,4) || - IsBadReadPtr(punk->lpVtbl->QueryInterface,9) || - IsBadCodePtr((FARPROC)punk->lpVtbl->QueryInterface) - ); -} diff --git a/dlls/ole32/ole32_main.c b/dlls/ole32/ole32_main.c index c38c525d5a6..e321afe3390 100644 --- a/dlls/ole32/ole32_main.c +++ b/dlls/ole32/ole32_main.c @@ -175,3 +175,24 @@ HRESULT WINAPI CoGetCallState(int unknown, PULONG unknown2) FIXME("%d, %p\n", unknown, unknown2); return E_NOTIMPL; } + +/****************************************************************************** + * IsValidInterface [OLE32.@] + * + * Determines whether a pointer is a valid interface. + * + * PARAMS + * punk [I] Interface to be tested. + * + * RETURNS + * TRUE, if the passed pointer is a valid interface, or FALSE otherwise. + */ +BOOL WINAPI IsValidInterface(LPUNKNOWN punk) +{ + return !( + IsBadReadPtr(punk,4) || + IsBadReadPtr(punk->lpVtbl,4) || + IsBadReadPtr(punk->lpVtbl->QueryInterface,9) || + IsBadCodePtr((FARPROC)punk->lpVtbl->QueryInterface) + ); +}
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=76510
Your paranoid android.
=== debiant (32 bit WoW report) ===
ole32: clipboard.c:1051: Test failed: OleIsCurrentClipboard returned 0 clipboard.c:1119: Test failed: 1 WM_DRAWCLIPBOARD received
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/Makefile.in | 1 + dlls/combase/combase.c | 253 ++++++++++++++++++++++++++++++++++++++ dlls/combase/combase.spec | 4 +- dlls/ole32/ole2.c | 151 ----------------------- dlls/ole32/ole32.spec | 4 +- 5 files changed, 258 insertions(+), 155 deletions(-) create mode 100644 dlls/combase/combase.c
diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in index f2174f4e3eb..87bb149b594 100644 --- a/dlls/combase/Makefile.in +++ b/dlls/combase/Makefile.in @@ -6,6 +6,7 @@ DELAYIMPORTS = oleaut32 EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ + combase.c \ errorinfo.c \ malloc.c \ roapi.c \ diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c new file mode 100644 index 00000000000..521bfdbf834 --- /dev/null +++ b/dlls/combase/combase.c @@ -0,0 +1,253 @@ +/* + * Copyright 2005 Juan Lang + * Copyright 2005-2006 Robert Shearman (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 + */ + +#define COBJMACROS +#define NONAMELESSUNION + +#include "oleauto.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/*********************************************************************** + * FreePropVariantArray (combase.@) + */ +HRESULT WINAPI FreePropVariantArray(ULONG count, PROPVARIANT *rgvars) +{ + ULONG i; + + TRACE("%u, %p.\n", count, rgvars); + + if (!rgvars) + return E_INVALIDARG; + + for (i = 0; i < count; ++i) + PropVariantClear(&rgvars[i]); + + return S_OK; +} + +static HRESULT propvar_validatetype(VARTYPE vt) +{ + switch (vt) + { + case VT_EMPTY: + case VT_NULL: + case VT_I1: + case VT_I2: + case VT_I4: + case VT_I8: + case VT_R4: + case VT_R8: + case VT_CY: + case VT_DATE: + case VT_BSTR: + case VT_ERROR: + case VT_BOOL: + case VT_DECIMAL: + case VT_UI1: + case VT_UI2: + case VT_UI4: + case VT_UI8: + case VT_INT: + case VT_UINT: + case VT_LPSTR: + case VT_LPWSTR: + case VT_FILETIME: + case VT_BLOB: + case VT_DISPATCH: + case VT_UNKNOWN: + case VT_STREAM: + case VT_STORAGE: + case VT_STREAMED_OBJECT: + case VT_STORED_OBJECT: + case VT_BLOB_OBJECT: + case VT_CF: + case VT_CLSID: + case VT_I1|VT_VECTOR: + case VT_I2|VT_VECTOR: + case VT_I4|VT_VECTOR: + case VT_I8|VT_VECTOR: + case VT_R4|VT_VECTOR: + case VT_R8|VT_VECTOR: + case VT_CY|VT_VECTOR: + case VT_DATE|VT_VECTOR: + case VT_BSTR|VT_VECTOR: + case VT_ERROR|VT_VECTOR: + case VT_BOOL|VT_VECTOR: + case VT_VARIANT|VT_VECTOR: + case VT_UI1|VT_VECTOR: + case VT_UI2|VT_VECTOR: + case VT_UI4|VT_VECTOR: + case VT_UI8|VT_VECTOR: + case VT_LPSTR|VT_VECTOR: + case VT_LPWSTR|VT_VECTOR: + case VT_FILETIME|VT_VECTOR: + case VT_CF|VT_VECTOR: + case VT_CLSID|VT_VECTOR: + case VT_ARRAY|VT_I1: + case VT_ARRAY|VT_UI1: + case VT_ARRAY|VT_I2: + case VT_ARRAY|VT_UI2: + case VT_ARRAY|VT_I4: + case VT_ARRAY|VT_UI4: + case VT_ARRAY|VT_INT: + case VT_ARRAY|VT_UINT: + case VT_ARRAY|VT_R4: + case VT_ARRAY|VT_R8: + case VT_ARRAY|VT_CY: + case VT_ARRAY|VT_DATE: + case VT_ARRAY|VT_BSTR: + case VT_ARRAY|VT_BOOL: + case VT_ARRAY|VT_DECIMAL: + case VT_ARRAY|VT_DISPATCH: + case VT_ARRAY|VT_UNKNOWN: + case VT_ARRAY|VT_ERROR: + case VT_ARRAY|VT_VARIANT: + return S_OK; + } + WARN("Bad type %d\n", vt); + return STG_E_INVALIDPARAMETER; +} + +static void propvar_free_cf_array(ULONG count, CLIPDATA *data) +{ + ULONG i; + for (i = 0; i < count; ++i) + CoTaskMemFree(data[i].pClipData); +} + +/*********************************************************************** + * PropVariantClear (combase.@) + */ +HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar) +{ + HRESULT hr; + + TRACE("%p.\n", pvar); + + if (!pvar) + return S_OK; + + hr = propvar_validatetype(pvar->vt); + if (FAILED(hr)) + { + memset(pvar, 0, sizeof(*pvar)); + return hr; + } + + switch (pvar->vt) + { + case VT_EMPTY: + case VT_NULL: + case VT_I1: + case VT_I2: + case VT_I4: + case VT_I8: + case VT_R4: + case VT_R8: + case VT_CY: + case VT_DATE: + case VT_ERROR: + case VT_BOOL: + case VT_DECIMAL: + case VT_UI1: + case VT_UI2: + case VT_UI4: + case VT_UI8: + case VT_INT: + case VT_UINT: + case VT_FILETIME: + break; + case VT_DISPATCH: + case VT_UNKNOWN: + case VT_STREAM: + case VT_STREAMED_OBJECT: + case VT_STORAGE: + case VT_STORED_OBJECT: + if (pvar->u.pStream) + IStream_Release(pvar->u.pStream); + break; + case VT_CLSID: + case VT_LPSTR: + case VT_LPWSTR: + /* pick an arbitrary typed pointer - we don't care about the type + * as we are just freeing it */ + CoTaskMemFree(pvar->u.puuid); + break; + case VT_BLOB: + case VT_BLOB_OBJECT: + CoTaskMemFree(pvar->u.blob.pBlobData); + break; + case VT_BSTR: + SysFreeString(pvar->u.bstrVal); + break; + case VT_CF: + if (pvar->u.pclipdata) + { + propvar_free_cf_array(1, pvar->u.pclipdata); + CoTaskMemFree(pvar->u.pclipdata); + } + break; + default: + if (pvar->vt & VT_VECTOR) + { + ULONG i; + + switch (pvar->vt & ~VT_VECTOR) + { + case VT_VARIANT: + FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems); + break; + case VT_CF: + propvar_free_cf_array(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems); + break; + case VT_BSTR: + for (i = 0; i < pvar->u.cabstr.cElems; i++) + SysFreeString(pvar->u.cabstr.pElems[i]); + break; + case VT_LPSTR: + for (i = 0; i < pvar->u.calpstr.cElems; i++) + CoTaskMemFree(pvar->u.calpstr.pElems[i]); + break; + case VT_LPWSTR: + for (i = 0; i < pvar->u.calpwstr.cElems; i++) + CoTaskMemFree(pvar->u.calpwstr.pElems[i]); + break; + } + if (pvar->vt & ~VT_VECTOR) + { + /* pick an arbitrary VT_VECTOR structure - they all have the same + * memory layout */ + CoTaskMemFree(pvar->u.capropvar.pElems); + } + } + else if (pvar->vt & VT_ARRAY) + hr = SafeArrayDestroy(pvar->u.parray); + else + { + WARN("Invalid/unsupported type %d\n", pvar->vt); + hr = STG_E_INVALIDPARAMETER; + } + } + + memset(pvar, 0, sizeof(*pvar)); + return hr; +} diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index aa1c04ce0ac..4711934dca6 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -177,7 +177,7 @@ @ stdcall DllGetActivationFactory(ptr ptr) @ stdcall -private DllGetClassObject(ptr ptr ptr) ole32.DllGetClassObject @ stub EnableHookObject -@ stdcall FreePropVariantArray(long ptr) ole32.FreePropVariantArray +@ stdcall FreePropVariantArray(long ptr) @ stub FreePropVariantArrayWorker @ stub GetCatalogHelper @ stdcall GetErrorInfo(long ptr) ole32.GetErrorInfo @@ -279,7 +279,7 @@ @ stub NdrOleDllGetClassObject @ stub NdrpFindInterface @ stdcall ProgIDFromCLSID(ptr ptr) ole32.ProgIDFromCLSID -@ stdcall PropVariantClear(ptr) ole32.PropVariantClear +@ stdcall PropVariantClear(ptr) @ stdcall PropVariantCopy(ptr ptr) ole32.PropVariantCopy @ stub ReleaseFuncDescs @ stdcall RoActivateInstance(ptr ptr) diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c index 6653fac3422..7829435244a 100644 --- a/dlls/ole32/ole2.c +++ b/dlls/ole32/ole2.c @@ -2710,20 +2710,6 @@ HRESULT WINAPI OleNoteObjectVisible(LPUNKNOWN pUnknown, BOOL bVisible) return CoLockObjectExternal(pUnknown, bVisible, TRUE); }
- -/*********************************************************************** - * OLE_FreeClipDataArray [internal] - * - * NOTES: - * frees the data associated with an array of CLIPDATAs - */ -static void OLE_FreeClipDataArray(ULONG count, CLIPDATA * pClipDataArray) -{ - ULONG i; - for (i = 0; i < count; i++) - CoTaskMemFree(pClipDataArray[i].pClipData); -} - /*********************************************************************** * PropSysAllocString [OLE32.@] * NOTES @@ -2830,124 +2816,6 @@ static inline HRESULT PROPVARIANT_ValidateType(VARTYPE vt) return STG_E_INVALIDPARAMETER; }
-/*********************************************************************** - * PropVariantClear [OLE32.@] - */ -HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */ -{ - HRESULT hr; - - TRACE("(%p)\n", pvar); - - if (!pvar) - return S_OK; - - hr = PROPVARIANT_ValidateType(pvar->vt); - if (FAILED(hr)) - { - memset(pvar, 0, sizeof(*pvar)); - return hr; - } - - switch(pvar->vt) - { - case VT_EMPTY: - case VT_NULL: - case VT_I1: - case VT_I2: - case VT_I4: - case VT_I8: - case VT_R4: - case VT_R8: - case VT_CY: - case VT_DATE: - case VT_ERROR: - case VT_BOOL: - case VT_DECIMAL: - case VT_UI1: - case VT_UI2: - case VT_UI4: - case VT_UI8: - case VT_INT: - case VT_UINT: - case VT_FILETIME: - break; - case VT_DISPATCH: - case VT_UNKNOWN: - case VT_STREAM: - case VT_STREAMED_OBJECT: - case VT_STORAGE: - case VT_STORED_OBJECT: - if (pvar->u.pStream) - IStream_Release(pvar->u.pStream); - break; - case VT_CLSID: - case VT_LPSTR: - case VT_LPWSTR: - /* pick an arbitrary typed pointer - we don't care about the type - * as we are just freeing it */ - CoTaskMemFree(pvar->u.puuid); - break; - case VT_BLOB: - case VT_BLOB_OBJECT: - CoTaskMemFree(pvar->u.blob.pBlobData); - break; - case VT_BSTR: - PropSysFreeString(pvar->u.bstrVal); - break; - case VT_CF: - if (pvar->u.pclipdata) - { - OLE_FreeClipDataArray(1, pvar->u.pclipdata); - CoTaskMemFree(pvar->u.pclipdata); - } - break; - default: - if (pvar->vt & VT_VECTOR) - { - ULONG i; - - switch (pvar->vt & ~VT_VECTOR) - { - case VT_VARIANT: - FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems); - break; - case VT_CF: - OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems); - break; - case VT_BSTR: - for (i = 0; i < pvar->u.cabstr.cElems; i++) - PropSysFreeString(pvar->u.cabstr.pElems[i]); - break; - case VT_LPSTR: - for (i = 0; i < pvar->u.calpstr.cElems; i++) - CoTaskMemFree(pvar->u.calpstr.pElems[i]); - break; - case VT_LPWSTR: - for (i = 0; i < pvar->u.calpwstr.cElems; i++) - CoTaskMemFree(pvar->u.calpwstr.pElems[i]); - break; - } - if (pvar->vt & ~VT_VECTOR) - { - /* pick an arbitrary VT_VECTOR structure - they all have the same - * memory layout */ - CoTaskMemFree(pvar->u.capropvar.pElems); - } - } - else if (pvar->vt & VT_ARRAY) - hr = SafeArrayDestroy(pvar->u.parray); - else - { - WARN("Invalid/unsupported type %d\n", pvar->vt); - hr = STG_E_INVALIDPARAMETER; - } - } - - memset(pvar, 0, sizeof(*pvar)); - return hr; -} - /*********************************************************************** * PropVariantCopy [OLE32.@] */ @@ -3129,25 +2997,6 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ return S_OK; }
-/*********************************************************************** - * FreePropVariantArray [OLE32.@] - */ -HRESULT WINAPI FreePropVariantArray(ULONG cVariants, /* [in] */ - PROPVARIANT *rgvars) /* [in/out] */ -{ - ULONG i; - - TRACE("(%u, %p)\n", cVariants, rgvars); - - if (!rgvars) - return E_INVALIDARG; - - for(i = 0; i < cVariants; i++) - PropVariantClear(&rgvars[i]); - - return S_OK; -} - /****************************************************************************** * DllDebugObjectRPCHook (OLE32.@) * turns on and off internal debugging, pointer is only used on macintosh diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 78e8641cf36..86b4023081c 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -114,7 +114,7 @@ @ stdcall DoDragDrop(ptr ptr long ptr) @ stub EnableHookObject @ stdcall FmtIdToPropStgName(ptr wstr) -@ stdcall FreePropVariantArray(long ptr) +@ stdcall FreePropVariantArray(long ptr) combase.FreePropVariantArray @ stdcall GetClassFile(wstr ptr) @ stdcall GetConvertStg(ptr) @ stub GetDocumentBitStg @@ -241,7 +241,7 @@ @ stdcall PropStgNameToFmtId(wstr ptr) @ stdcall PropSysAllocString(wstr) @ stdcall PropSysFreeString(wstr) -@ stdcall PropVariantClear(ptr) +@ stdcall PropVariantClear(ptr) combase.PropVariantClear @ stdcall PropVariantCopy(ptr ptr) @ stdcall ReadClassStg(ptr ptr) @ stdcall ReadClassStm(ptr ptr)
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/combase.c | 180 +++++++++++++++++++++++++ dlls/combase/combase.spec | 2 +- dlls/ole32/ole2.c | 267 -------------------------------------- dlls/ole32/ole32.spec | 2 +- 4 files changed, 182 insertions(+), 269 deletions(-)
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index 521bfdbf834..74a76437090 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -251,3 +251,183 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar) memset(pvar, 0, sizeof(*pvar)); return hr; } + +/*********************************************************************** + * PropVariantCopy (combase.@) + */ +HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc) +{ + ULONG len; + HRESULT hr; + + TRACE("%p, %p vt %04x.\n", pvarDest, pvarSrc, pvarSrc->vt); + + hr = propvar_validatetype(pvarSrc->vt); + if (FAILED(hr)) + return DISP_E_BADVARTYPE; + + /* this will deal with most cases */ + *pvarDest = *pvarSrc; + + switch (pvarSrc->vt) + { + case VT_EMPTY: + case VT_NULL: + case VT_I1: + case VT_UI1: + case VT_I2: + case VT_UI2: + case VT_BOOL: + case VT_DECIMAL: + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_ERROR: + case VT_I8: + case VT_UI8: + case VT_INT: + case VT_UINT: + case VT_R8: + case VT_CY: + case VT_DATE: + case VT_FILETIME: + break; + case VT_DISPATCH: + case VT_UNKNOWN: + case VT_STREAM: + case VT_STREAMED_OBJECT: + case VT_STORAGE: + case VT_STORED_OBJECT: + if (pvarDest->u.pStream) + IStream_AddRef(pvarDest->u.pStream); + break; + case VT_CLSID: + pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID)); + *pvarDest->u.puuid = *pvarSrc->u.puuid; + break; + case VT_LPSTR: + if (pvarSrc->u.pszVal) + { + len = strlen(pvarSrc->u.pszVal); + pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR)); + CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR)); + } + break; + case VT_LPWSTR: + if (pvarSrc->u.pwszVal) + { + len = lstrlenW(pvarSrc->u.pwszVal); + pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); + CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR)); + } + break; + case VT_BLOB: + case VT_BLOB_OBJECT: + if (pvarSrc->u.blob.pBlobData) + { + len = pvarSrc->u.blob.cbSize; + pvarDest->u.blob.pBlobData = CoTaskMemAlloc(len); + CopyMemory(pvarDest->u.blob.pBlobData, pvarSrc->u.blob.pBlobData, len); + } + break; + case VT_BSTR: + pvarDest->u.bstrVal = SysAllocString(pvarSrc->u.bstrVal); + break; + case VT_CF: + if (pvarSrc->u.pclipdata) + { + len = pvarSrc->u.pclipdata->cbSize - sizeof(pvarSrc->u.pclipdata->ulClipFmt); + pvarDest->u.pclipdata = CoTaskMemAlloc(sizeof (CLIPDATA)); + pvarDest->u.pclipdata->cbSize = pvarSrc->u.pclipdata->cbSize; + pvarDest->u.pclipdata->ulClipFmt = pvarSrc->u.pclipdata->ulClipFmt; + pvarDest->u.pclipdata->pClipData = CoTaskMemAlloc(len); + CopyMemory(pvarDest->u.pclipdata->pClipData, pvarSrc->u.pclipdata->pClipData, len); + } + break; + default: + if (pvarSrc->vt & VT_VECTOR) + { + int elemSize; + ULONG i; + + switch (pvarSrc->vt & ~VT_VECTOR) + { + case VT_I1: elemSize = sizeof(pvarSrc->u.cVal); break; + case VT_UI1: elemSize = sizeof(pvarSrc->u.bVal); break; + case VT_I2: elemSize = sizeof(pvarSrc->u.iVal); break; + case VT_UI2: elemSize = sizeof(pvarSrc->u.uiVal); break; + case VT_BOOL: elemSize = sizeof(pvarSrc->u.boolVal); break; + case VT_I4: elemSize = sizeof(pvarSrc->u.lVal); break; + case VT_UI4: elemSize = sizeof(pvarSrc->u.ulVal); break; + case VT_R4: elemSize = sizeof(pvarSrc->u.fltVal); break; + case VT_R8: elemSize = sizeof(pvarSrc->u.dblVal); break; + case VT_ERROR: elemSize = sizeof(pvarSrc->u.scode); break; + case VT_I8: elemSize = sizeof(pvarSrc->u.hVal); break; + case VT_UI8: elemSize = sizeof(pvarSrc->u.uhVal); break; + case VT_CY: elemSize = sizeof(pvarSrc->u.cyVal); break; + case VT_DATE: elemSize = sizeof(pvarSrc->u.date); break; + case VT_FILETIME: elemSize = sizeof(pvarSrc->u.filetime); break; + case VT_CLSID: elemSize = sizeof(*pvarSrc->u.puuid); break; + case VT_CF: elemSize = sizeof(*pvarSrc->u.pclipdata); break; + case VT_BSTR: elemSize = sizeof(pvarSrc->u.bstrVal); break; + case VT_LPSTR: elemSize = sizeof(pvarSrc->u.pszVal); break; + case VT_LPWSTR: elemSize = sizeof(pvarSrc->u.pwszVal); break; + case VT_VARIANT: elemSize = sizeof(*pvarSrc->u.pvarVal); break; + + default: + FIXME("Invalid element type: %ul\n", pvarSrc->vt & ~VT_VECTOR); + return E_INVALIDARG; + } + len = pvarSrc->u.capropvar.cElems; + pvarDest->u.capropvar.pElems = len ? CoTaskMemAlloc(len * elemSize) : NULL; + if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT)) + { + for (i = 0; i < len; i++) + PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[i]); + } + else if (pvarSrc->vt == (VT_VECTOR | VT_CF)) + { + FIXME("Copy clipformats\n"); + } + else if (pvarSrc->vt == (VT_VECTOR | VT_BSTR)) + { + for (i = 0; i < len; i++) + pvarDest->u.cabstr.pElems[i] = SysAllocString(pvarSrc->u.cabstr.pElems[i]); + } + else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR)) + { + size_t strLen; + for (i = 0; i < len; i++) + { + strLen = lstrlenA(pvarSrc->u.calpstr.pElems[i]) + 1; + pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen); + memcpy(pvarDest->u.calpstr.pElems[i], + pvarSrc->u.calpstr.pElems[i], strLen); + } + } + else if (pvarSrc->vt == (VT_VECTOR | VT_LPWSTR)) + { + size_t strLen; + for (i = 0; i < len; i++) + { + strLen = (lstrlenW(pvarSrc->u.calpwstr.pElems[i]) + 1) * + sizeof(WCHAR); + pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen); + memcpy(pvarDest->u.calpstr.pElems[i], + pvarSrc->u.calpstr.pElems[i], strLen); + } + } + else + CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize); + } + else if (pvarSrc->vt & VT_ARRAY) + { + pvarDest->u.uhVal.QuadPart = 0; + return SafeArrayCopy(pvarSrc->u.parray, &pvarDest->u.parray); + } + else + WARN("Invalid/unsupported type %d\n", pvarSrc->vt); + } + + return S_OK; +} diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 4711934dca6..70f7b17244b 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -280,7 +280,7 @@ @ stub NdrpFindInterface @ stdcall ProgIDFromCLSID(ptr ptr) ole32.ProgIDFromCLSID @ stdcall PropVariantClear(ptr) -@ stdcall PropVariantCopy(ptr ptr) ole32.PropVariantCopy +@ stdcall PropVariantCopy(ptr ptr) @ stub ReleaseFuncDescs @ stdcall RoActivateInstance(ptr ptr) @ stub RoCaptureErrorContext diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c index 7829435244a..4f4a1378b1e 100644 --- a/dlls/ole32/ole2.c +++ b/dlls/ole32/ole2.c @@ -2730,273 +2730,6 @@ void WINAPI PropSysFreeString(LPOLESTR str) SysFreeString(str); }
-/****************************************************************************** - * Check if a PROPVARIANT's type is valid. - */ -static inline HRESULT PROPVARIANT_ValidateType(VARTYPE vt) -{ - switch (vt) - { - case VT_EMPTY: - case VT_NULL: - case VT_I1: - case VT_I2: - case VT_I4: - case VT_I8: - case VT_R4: - case VT_R8: - case VT_CY: - case VT_DATE: - case VT_BSTR: - case VT_ERROR: - case VT_BOOL: - case VT_DECIMAL: - case VT_UI1: - case VT_UI2: - case VT_UI4: - case VT_UI8: - case VT_INT: - case VT_UINT: - case VT_LPSTR: - case VT_LPWSTR: - case VT_FILETIME: - case VT_BLOB: - case VT_DISPATCH: - case VT_UNKNOWN: - case VT_STREAM: - case VT_STORAGE: - case VT_STREAMED_OBJECT: - case VT_STORED_OBJECT: - case VT_BLOB_OBJECT: - case VT_CF: - case VT_CLSID: - case VT_I1|VT_VECTOR: - case VT_I2|VT_VECTOR: - case VT_I4|VT_VECTOR: - case VT_I8|VT_VECTOR: - case VT_R4|VT_VECTOR: - case VT_R8|VT_VECTOR: - case VT_CY|VT_VECTOR: - case VT_DATE|VT_VECTOR: - case VT_BSTR|VT_VECTOR: - case VT_ERROR|VT_VECTOR: - case VT_BOOL|VT_VECTOR: - case VT_VARIANT|VT_VECTOR: - case VT_UI1|VT_VECTOR: - case VT_UI2|VT_VECTOR: - case VT_UI4|VT_VECTOR: - case VT_UI8|VT_VECTOR: - case VT_LPSTR|VT_VECTOR: - case VT_LPWSTR|VT_VECTOR: - case VT_FILETIME|VT_VECTOR: - case VT_CF|VT_VECTOR: - case VT_CLSID|VT_VECTOR: - case VT_ARRAY|VT_I1: - case VT_ARRAY|VT_UI1: - case VT_ARRAY|VT_I2: - case VT_ARRAY|VT_UI2: - case VT_ARRAY|VT_I4: - case VT_ARRAY|VT_UI4: - case VT_ARRAY|VT_INT: - case VT_ARRAY|VT_UINT: - case VT_ARRAY|VT_R4: - case VT_ARRAY|VT_R8: - case VT_ARRAY|VT_CY: - case VT_ARRAY|VT_DATE: - case VT_ARRAY|VT_BSTR: - case VT_ARRAY|VT_BOOL: - case VT_ARRAY|VT_DECIMAL: - case VT_ARRAY|VT_DISPATCH: - case VT_ARRAY|VT_UNKNOWN: - case VT_ARRAY|VT_ERROR: - case VT_ARRAY|VT_VARIANT: - return S_OK; - } - WARN("Bad type %d\n", vt); - return STG_E_INVALIDPARAMETER; -} - -/*********************************************************************** - * PropVariantCopy [OLE32.@] - */ -HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ - const PROPVARIANT *pvarSrc) /* [in] */ -{ - ULONG len; - HRESULT hr; - - TRACE("(%p, %p vt %04x)\n", pvarDest, pvarSrc, pvarSrc->vt); - - hr = PROPVARIANT_ValidateType(pvarSrc->vt); - if (FAILED(hr)) - return DISP_E_BADVARTYPE; - - /* this will deal with most cases */ - *pvarDest = *pvarSrc; - - switch(pvarSrc->vt) - { - case VT_EMPTY: - case VT_NULL: - case VT_I1: - case VT_UI1: - case VT_I2: - case VT_UI2: - case VT_BOOL: - case VT_DECIMAL: - case VT_I4: - case VT_UI4: - case VT_R4: - case VT_ERROR: - case VT_I8: - case VT_UI8: - case VT_INT: - case VT_UINT: - case VT_R8: - case VT_CY: - case VT_DATE: - case VT_FILETIME: - break; - case VT_DISPATCH: - case VT_UNKNOWN: - case VT_STREAM: - case VT_STREAMED_OBJECT: - case VT_STORAGE: - case VT_STORED_OBJECT: - if (pvarDest->u.pStream) - IStream_AddRef(pvarDest->u.pStream); - break; - case VT_CLSID: - pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID)); - *pvarDest->u.puuid = *pvarSrc->u.puuid; - break; - case VT_LPSTR: - if (pvarSrc->u.pszVal) - { - len = strlen(pvarSrc->u.pszVal); - pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR)); - CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR)); - } - break; - case VT_LPWSTR: - if (pvarSrc->u.pwszVal) - { - len = lstrlenW(pvarSrc->u.pwszVal); - pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); - CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR)); - } - break; - case VT_BLOB: - case VT_BLOB_OBJECT: - if (pvarSrc->u.blob.pBlobData) - { - len = pvarSrc->u.blob.cbSize; - pvarDest->u.blob.pBlobData = CoTaskMemAlloc(len); - CopyMemory(pvarDest->u.blob.pBlobData, pvarSrc->u.blob.pBlobData, len); - } - break; - case VT_BSTR: - pvarDest->u.bstrVal = PropSysAllocString(pvarSrc->u.bstrVal); - break; - case VT_CF: - if (pvarSrc->u.pclipdata) - { - len = pvarSrc->u.pclipdata->cbSize - sizeof(pvarSrc->u.pclipdata->ulClipFmt); - pvarDest->u.pclipdata = CoTaskMemAlloc(sizeof (CLIPDATA)); - pvarDest->u.pclipdata->cbSize = pvarSrc->u.pclipdata->cbSize; - pvarDest->u.pclipdata->ulClipFmt = pvarSrc->u.pclipdata->ulClipFmt; - pvarDest->u.pclipdata->pClipData = CoTaskMemAlloc(len); - CopyMemory(pvarDest->u.pclipdata->pClipData, pvarSrc->u.pclipdata->pClipData, len); - } - break; - default: - if (pvarSrc->vt & VT_VECTOR) - { - int elemSize; - ULONG i; - - switch(pvarSrc->vt & ~VT_VECTOR) - { - case VT_I1: elemSize = sizeof(pvarSrc->u.cVal); break; - case VT_UI1: elemSize = sizeof(pvarSrc->u.bVal); break; - case VT_I2: elemSize = sizeof(pvarSrc->u.iVal); break; - case VT_UI2: elemSize = sizeof(pvarSrc->u.uiVal); break; - case VT_BOOL: elemSize = sizeof(pvarSrc->u.boolVal); break; - case VT_I4: elemSize = sizeof(pvarSrc->u.lVal); break; - case VT_UI4: elemSize = sizeof(pvarSrc->u.ulVal); break; - case VT_R4: elemSize = sizeof(pvarSrc->u.fltVal); break; - case VT_R8: elemSize = sizeof(pvarSrc->u.dblVal); break; - case VT_ERROR: elemSize = sizeof(pvarSrc->u.scode); break; - case VT_I8: elemSize = sizeof(pvarSrc->u.hVal); break; - case VT_UI8: elemSize = sizeof(pvarSrc->u.uhVal); break; - case VT_CY: elemSize = sizeof(pvarSrc->u.cyVal); break; - case VT_DATE: elemSize = sizeof(pvarSrc->u.date); break; - case VT_FILETIME: elemSize = sizeof(pvarSrc->u.filetime); break; - case VT_CLSID: elemSize = sizeof(*pvarSrc->u.puuid); break; - case VT_CF: elemSize = sizeof(*pvarSrc->u.pclipdata); break; - case VT_BSTR: elemSize = sizeof(pvarSrc->u.bstrVal); break; - case VT_LPSTR: elemSize = sizeof(pvarSrc->u.pszVal); break; - case VT_LPWSTR: elemSize = sizeof(pvarSrc->u.pwszVal); break; - case VT_VARIANT: elemSize = sizeof(*pvarSrc->u.pvarVal); break; - - default: - FIXME("Invalid element type: %ul\n", pvarSrc->vt & ~VT_VECTOR); - return E_INVALIDARG; - } - len = pvarSrc->u.capropvar.cElems; - pvarDest->u.capropvar.pElems = len ? CoTaskMemAlloc(len * elemSize) : NULL; - if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT)) - { - for (i = 0; i < len; i++) - PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[i]); - } - else if (pvarSrc->vt == (VT_VECTOR | VT_CF)) - { - FIXME("Copy clipformats\n"); - } - else if (pvarSrc->vt == (VT_VECTOR | VT_BSTR)) - { - for (i = 0; i < len; i++) - pvarDest->u.cabstr.pElems[i] = PropSysAllocString(pvarSrc->u.cabstr.pElems[i]); - } - else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR)) - { - size_t strLen; - for (i = 0; i < len; i++) - { - strLen = lstrlenA(pvarSrc->u.calpstr.pElems[i]) + 1; - pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen); - memcpy(pvarDest->u.calpstr.pElems[i], - pvarSrc->u.calpstr.pElems[i], strLen); - } - } - else if (pvarSrc->vt == (VT_VECTOR | VT_LPWSTR)) - { - size_t strLen; - for (i = 0; i < len; i++) - { - strLen = (lstrlenW(pvarSrc->u.calpwstr.pElems[i]) + 1) * - sizeof(WCHAR); - pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen); - memcpy(pvarDest->u.calpstr.pElems[i], - pvarSrc->u.calpstr.pElems[i], strLen); - } - } - else - CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize); - } - else if (pvarSrc->vt & VT_ARRAY) - { - pvarDest->u.uhVal.QuadPart = 0; - return SafeArrayCopy(pvarSrc->u.parray, &pvarDest->u.parray); - } - else - WARN("Invalid/unsupported type %d\n", pvarSrc->vt); - } - - return S_OK; -} - /****************************************************************************** * DllDebugObjectRPCHook (OLE32.@) * turns on and off internal debugging, pointer is only used on macintosh diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 86b4023081c..6699d797b02 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -242,7 +242,7 @@ @ stdcall PropSysAllocString(wstr) @ stdcall PropSysFreeString(wstr) @ stdcall PropVariantClear(ptr) combase.PropVariantClear -@ stdcall PropVariantCopy(ptr ptr) +@ stdcall PropVariantCopy(ptr ptr) combase.PropVariantCopy @ stdcall ReadClassStg(ptr ptr) @ stdcall ReadClassStm(ptr ptr) @ stdcall ReadFmtUserTypeStg(ptr ptr ptr)
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/combase.c | 9 +++++++++ dlls/combase/combase.spec | 1 + dlls/ole32/compobj.c | 17 ----------------- dlls/ole32/ole32.spec | 2 +- 4 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index 74a76437090..bf1228a1f24 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -431,3 +431,12 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc
return S_OK; } + +/*********************************************************************** + * CoFileTimeNow (combase.@) + */ +HRESULT WINAPI CoFileTimeNow(FILETIME *filetime) +{ + GetSystemTimeAsFileTime(filetime); + return S_OK; +} diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 70f7b17244b..9940229c46f 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -90,6 +90,7 @@ @ stub CoDisconnectContext @ stdcall CoDisconnectObject(ptr long) ole32.CoDisconnectObject @ stdcall CoEnableCallCancellation(ptr) ole32.CoEnableCallCancellation +@ stdcall CoFileTimeNow(ptr) @ stdcall CoFreeUnusedLibraries() ole32.CoFreeUnusedLibraries @ stdcall CoFreeUnusedLibrariesEx(long long) ole32.CoFreeUnusedLibrariesEx @ stdcall CoGetActivationState(int128 long ptr) ole32.CoGetActivationState diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 6d9904a1650..29c8ca6e13a 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -3701,23 +3701,6 @@ void WINAPI DECLSPEC_HOTPATCH CoFreeUnusedLibraries(void) CoFreeUnusedLibrariesEx(INFINITE, 0); }
-/*********************************************************************** - * CoFileTimeNow [OLE32.@] - * - * Retrieves the current time in FILETIME format. - * - * PARAMS - * lpFileTime [O] The current time. - * - * RETURNS - * S_OK. - */ -HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime ) -{ - GetSystemTimeAsFileTime( lpFileTime ); - return S_OK; -} - /****************************************************************************** * CoLockObjectExternal [OLE32.@] * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 6699d797b02..87c950cf438 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -19,7 +19,7 @@ @ stdcall CoDisconnectObject(ptr long) @ stdcall CoDosDateTimeToFileTime(long long ptr) kernel32.DosDateTimeToFileTime @ stdcall CoEnableCallCancellation(ptr) -@ stdcall CoFileTimeNow(ptr) +@ stdcall CoFileTimeNow(ptr) combase.CoFileTimeNow @ stdcall CoFileTimeToDosDateTime(ptr ptr ptr) kernel32.FileTimeToDosDateTime @ stdcall CoFreeAllLibraries() @ stdcall CoFreeLibrary(long)
Signed-off-by: Huw Davies huw@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=76509
Your paranoid android.
=== debiant (32 bit WoW report) ===
ole32: clipboard.c:1051: Test failed: OleIsCurrentClipboard returned 0 clipboard.c:1119: Test failed: 1 WM_DRAWCLIPBOARD received