Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/combase.spec | 4 + dlls/combase/usrmarshal.c | 219 ++++++++++++++++++++++++++++++++++++++ dlls/ole32/ole32.spec | 8 +- dlls/ole32/usrmarshal.c | 219 -------------------------------------- 4 files changed, 227 insertions(+), 223 deletions(-)
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 9d0bad29f0d..3c0955f705d 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -197,6 +197,10 @@ @ stdcall HDC_UserMarshal(ptr ptr ptr) @ stdcall HDC_UserSize(ptr long ptr) @ stdcall HDC_UserUnmarshal(ptr ptr ptr) +@ stdcall HGLOBAL_UserFree(ptr ptr) +@ stdcall HGLOBAL_UserMarshal(ptr ptr ptr) +@ stdcall HGLOBAL_UserSize(ptr long ptr) +@ stdcall HGLOBAL_UserUnmarshal(ptr ptr ptr) @ stdcall HICON_UserFree(ptr ptr) @ stdcall HICON_UserMarshal(ptr ptr ptr) @ stdcall HICON_UserSize(ptr long ptr) diff --git a/dlls/combase/usrmarshal.c b/dlls/combase/usrmarshal.c index c88e8c57cd0..7c77cc1a80e 100644 --- a/dlls/combase/usrmarshal.c +++ b/dlls/combase/usrmarshal.c @@ -617,6 +617,225 @@ unsigned char * __RPC_USER HPALETTE_UserUnmarshal(ULONG *pFlags, unsigned char * return pBuffer; }
+/****************************************************************************** + * HGLOBAL_UserSize (combase.@) + * + * Calculates the buffer size required to marshal an HGLOBAL. + * + * PARAMS + * pFlags [I] Flags. See notes. + * StartingSize [I] Starting size of the buffer. This value is added on to + * the buffer size required for the clip format. + * phGlobal [I] HGLOBAL to size. + * + * RETURNS + * The buffer size required to marshal an HGLOBAL plus the starting size. + * + * NOTES + * Even though the function is documented to take a pointer to a ULONG in + * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which + * the first parameter is a ULONG. + * This function is only intended to be called by the RPC runtime. + */ +ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal) +{ + ULONG size = StartingSize; + + TRACE("%s, %u, %p.\n", debugstr_user_flags(pFlags), StartingSize, phGlobal); + + ALIGN_LENGTH(size, 3); + + size += sizeof(ULONG); + + if (LOWORD(*pFlags) == MSHCTX_INPROC) + size += sizeof(HGLOBAL); + else + { + size += sizeof(ULONG); + if (*phGlobal) + { + SIZE_T ret; + size += 3 * sizeof(ULONG); + ret = GlobalSize(*phGlobal); + size += (ULONG)ret; + } + } + + return size; +} + +/****************************************************************************** + * HGLOBAL_UserMarshal (combase.@) + * + * Marshals an HGLOBAL into a buffer. + * + * PARAMS + * pFlags [I] Flags. See notes. + * pBuffer [I] Buffer to marshal the clip format into. + * phGlobal [I] HGLOBAL to marshal. + * + * RETURNS + * The end of the marshaled data in the buffer. + * + * NOTES + * Even though the function is documented to take a pointer to a ULONG in + * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which + * the first parameter is a ULONG. + * This function is only intended to be called by the RPC runtime. + */ +unsigned char * __RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal) +{ + TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal); + + ALIGN_POINTER(pBuffer, 3); + + if (LOWORD(*pFlags) == MSHCTX_INPROC) + { + if (sizeof(*phGlobal) == 8) + *(ULONG *)pBuffer = WDT_INPROC64_CALL; + else + *(ULONG *)pBuffer = WDT_INPROC_CALL; + pBuffer += sizeof(ULONG); + *(HGLOBAL *)pBuffer = *phGlobal; + pBuffer += sizeof(HGLOBAL); + } + else + { + *(ULONG *)pBuffer = WDT_REMOTE_CALL; + pBuffer += sizeof(ULONG); + *(ULONG *)pBuffer = HandleToULong(*phGlobal); + pBuffer += sizeof(ULONG); + if (*phGlobal) + { + const unsigned char *memory; + SIZE_T size = GlobalSize(*phGlobal); + *(ULONG *)pBuffer = (ULONG)size; + pBuffer += sizeof(ULONG); + *(ULONG *)pBuffer = HandleToULong(*phGlobal); + pBuffer += sizeof(ULONG); + *(ULONG *)pBuffer = (ULONG)size; + pBuffer += sizeof(ULONG); + + memory = GlobalLock(*phGlobal); + memcpy(pBuffer, memory, size); + pBuffer += size; + GlobalUnlock(*phGlobal); + } + } + + return pBuffer; +} + +/****************************************************************************** + * HGLOBAL_UserUnmarshal (combase.@) + * + * Unmarshals an HGLOBAL from a buffer. + * + * PARAMS + * pFlags [I] Flags. See notes. + * pBuffer [I] Buffer to marshal the clip format from. + * phGlobal [O] Address that receive the unmarshaled HGLOBAL. + * + * RETURNS + * The end of the marshaled data in the buffer. + * + * NOTES + * Even though the function is documented to take a pointer to an ULONG in + * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which + * the first parameter is an ULONG. + * This function is only intended to be called by the RPC runtime. + */ +unsigned char * __RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal) +{ + ULONG fContext; + + TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal); + + ALIGN_POINTER(pBuffer, 3); + + fContext = *(ULONG *)pBuffer; + pBuffer += sizeof(ULONG); + + if (((fContext == WDT_INPROC_CALL) && (sizeof(*phGlobal) < 8)) || + ((fContext == WDT_INPROC64_CALL) && (sizeof(*phGlobal) == 8))) + { + *phGlobal = *(HGLOBAL *)pBuffer; + pBuffer += sizeof(*phGlobal); + } + else if (fContext == WDT_REMOTE_CALL) + { + ULONG handle; + + handle = *(ULONG *)pBuffer; + pBuffer += sizeof(ULONG); + + if (handle) + { + ULONG size; + void *memory; + + size = *(ULONG *)pBuffer; + pBuffer += sizeof(ULONG); + /* redundancy is bad - it means you have to check consistency like + * this: */ + if (*(ULONG *)pBuffer != handle) + { + RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL); + return pBuffer; + } + pBuffer += sizeof(ULONG); + /* redundancy is bad - it means you have to check consistency like + * this: */ + if (*(ULONG *)pBuffer != size) + { + RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL); + return pBuffer; + } + pBuffer += sizeof(ULONG); + + /* FIXME: check size is not too big */ + + *phGlobal = GlobalAlloc(GMEM_MOVEABLE, size); + memory = GlobalLock(*phGlobal); + memcpy(memory, pBuffer, size); + pBuffer += size; + GlobalUnlock(*phGlobal); + } + else + *phGlobal = NULL; + } + else + RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); + + return pBuffer; +} + +/****************************************************************************** + * HGLOBAL_UserFree (combase.@) + * + * Frees an unmarshaled HGLOBAL. + * + * PARAMS + * pFlags [I] Flags. See notes. + * phGlobal [I] HGLOBAL to free. + * + * RETURNS + * The end of the marshaled data in the buffer. + * + * NOTES + * Even though the function is documented to take a pointer to a ULONG in + * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of + * which the first parameter is a ULONG. + * This function is only intended to be called by the RPC runtime. + */ +void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal) +{ + TRACE("%s, &%p.\n", debugstr_user_flags(pFlags), *phGlobal); + + if (LOWORD(*pFlags) != MSHCTX_INPROC && *phGlobal) + GlobalFree(*phGlobal); +} + /****************************************************************************** * HPALETTE_UserFree (combase.@) * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 97618e08935..c3ee8f27f23 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -143,10 +143,10 @@ @ stdcall HENHMETAFILE_UserMarshal(ptr ptr ptr) @ stdcall HENHMETAFILE_UserSize(ptr long ptr) @ stdcall HENHMETAFILE_UserUnmarshal(ptr ptr ptr) -@ stdcall HGLOBAL_UserFree(ptr ptr) -@ stdcall HGLOBAL_UserMarshal(ptr ptr ptr) -@ stdcall HGLOBAL_UserSize(ptr long ptr) -@ stdcall HGLOBAL_UserUnmarshal(ptr ptr ptr) +@ stdcall HGLOBAL_UserFree(ptr ptr) combase.HGLOBAL_UserFree +@ stdcall HGLOBAL_UserMarshal(ptr ptr ptr) combase.HGLOBAL_UserMarshal +@ stdcall HGLOBAL_UserSize(ptr long ptr) combase.HGLOBAL_UserSize +@ stdcall HGLOBAL_UserUnmarshal(ptr ptr ptr) combase.HGLOBAL_UserUnmarshal @ stdcall HICON_UserFree(ptr ptr) combase.HICON_UserFree @ stdcall HICON_UserMarshal(ptr ptr ptr) combase.HICON_UserMarshal @ stdcall HICON_UserSize(ptr long ptr) combase.HICON_UserSize diff --git a/dlls/ole32/usrmarshal.c b/dlls/ole32/usrmarshal.c index 694ef60764f..a5daa949830 100644 --- a/dlls/ole32/usrmarshal.c +++ b/dlls/ole32/usrmarshal.c @@ -156,225 +156,6 @@ static void handle_UserFree(ULONG *pFlags, HANDLE *handle)
IMPL_WIREM_HANDLE(HACCEL)
-/****************************************************************************** - * HGLOBAL_UserSize [OLE32.@] - * - * Calculates the buffer size required to marshal an HGLOBAL. - * - * PARAMS - * pFlags [I] Flags. See notes. - * StartingSize [I] Starting size of the buffer. This value is added on to - * the buffer size required for the clip format. - * phGlobal [I] HGLOBAL to size. - * - * RETURNS - * The buffer size required to marshal an HGLOBAL plus the starting size. - * - * NOTES - * Even though the function is documented to take a pointer to a ULONG in - * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which - * the first parameter is a ULONG. - * This function is only intended to be called by the RPC runtime. - */ -ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal) -{ - ULONG size = StartingSize; - - TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, phGlobal); - - ALIGN_LENGTH(size, 3); - - size += sizeof(ULONG); - - if (LOWORD(*pFlags) == MSHCTX_INPROC) - size += sizeof(HGLOBAL); - else - { - size += sizeof(ULONG); - if (*phGlobal) - { - SIZE_T ret; - size += 3 * sizeof(ULONG); - ret = GlobalSize(*phGlobal); - size += (ULONG)ret; - } - } - - return size; -} - -/****************************************************************************** - * HGLOBAL_UserMarshal [OLE32.@] - * - * Marshals an HGLOBAL into a buffer. - * - * PARAMS - * pFlags [I] Flags. See notes. - * pBuffer [I] Buffer to marshal the clip format into. - * phGlobal [I] HGLOBAL to marshal. - * - * RETURNS - * The end of the marshaled data in the buffer. - * - * NOTES - * Even though the function is documented to take a pointer to a ULONG in - * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which - * the first parameter is a ULONG. - * This function is only intended to be called by the RPC runtime. - */ -unsigned char * __RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal) -{ - TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal); - - ALIGN_POINTER(pBuffer, 3); - - if (LOWORD(*pFlags) == MSHCTX_INPROC) - { - if (sizeof(*phGlobal) == 8) - *(ULONG *)pBuffer = WDT_INPROC64_CALL; - else - *(ULONG *)pBuffer = WDT_INPROC_CALL; - pBuffer += sizeof(ULONG); - *(HGLOBAL *)pBuffer = *phGlobal; - pBuffer += sizeof(HGLOBAL); - } - else - { - *(ULONG *)pBuffer = WDT_REMOTE_CALL; - pBuffer += sizeof(ULONG); - *(ULONG *)pBuffer = HandleToULong(*phGlobal); - pBuffer += sizeof(ULONG); - if (*phGlobal) - { - const unsigned char *memory; - SIZE_T size = GlobalSize(*phGlobal); - *(ULONG *)pBuffer = (ULONG)size; - pBuffer += sizeof(ULONG); - *(ULONG *)pBuffer = HandleToULong(*phGlobal); - pBuffer += sizeof(ULONG); - *(ULONG *)pBuffer = (ULONG)size; - pBuffer += sizeof(ULONG); - - memory = GlobalLock(*phGlobal); - memcpy(pBuffer, memory, size); - pBuffer += size; - GlobalUnlock(*phGlobal); - } - } - - return pBuffer; -} - -/****************************************************************************** - * HGLOBAL_UserUnmarshal [OLE32.@] - * - * Unmarshals an HGLOBAL from a buffer. - * - * PARAMS - * pFlags [I] Flags. See notes. - * pBuffer [I] Buffer to marshal the clip format from. - * phGlobal [O] Address that receive the unmarshaled HGLOBAL. - * - * RETURNS - * The end of the marshaled data in the buffer. - * - * NOTES - * Even though the function is documented to take a pointer to an ULONG in - * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which - * the first parameter is an ULONG. - * This function is only intended to be called by the RPC runtime. - */ -unsigned char * __RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal) -{ - ULONG fContext; - - TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal); - - ALIGN_POINTER(pBuffer, 3); - - fContext = *(ULONG *)pBuffer; - pBuffer += sizeof(ULONG); - - if (((fContext == WDT_INPROC_CALL) && (sizeof(*phGlobal) < 8)) || - ((fContext == WDT_INPROC64_CALL) && (sizeof(*phGlobal) == 8))) - { - *phGlobal = *(HGLOBAL *)pBuffer; - pBuffer += sizeof(*phGlobal); - } - else if (fContext == WDT_REMOTE_CALL) - { - ULONG handle; - - handle = *(ULONG *)pBuffer; - pBuffer += sizeof(ULONG); - - if (handle) - { - ULONG size; - void *memory; - - size = *(ULONG *)pBuffer; - pBuffer += sizeof(ULONG); - /* redundancy is bad - it means you have to check consistency like - * this: */ - if (*(ULONG *)pBuffer != handle) - { - RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL); - return pBuffer; - } - pBuffer += sizeof(ULONG); - /* redundancy is bad - it means you have to check consistency like - * this: */ - if (*(ULONG *)pBuffer != size) - { - RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL); - return pBuffer; - } - pBuffer += sizeof(ULONG); - - /* FIXME: check size is not too big */ - - *phGlobal = GlobalAlloc(GMEM_MOVEABLE, size); - memory = GlobalLock(*phGlobal); - memcpy(memory, pBuffer, size); - pBuffer += size; - GlobalUnlock(*phGlobal); - } - else - *phGlobal = NULL; - } - else - RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); - - return pBuffer; -} - -/****************************************************************************** - * HGLOBAL_UserFree [OLE32.@] - * - * Frees an unmarshaled HGLOBAL. - * - * PARAMS - * pFlags [I] Flags. See notes. - * phGlobal [I] HGLOBAL to free. - * - * RETURNS - * The end of the marshaled data in the buffer. - * - * NOTES - * Even though the function is documented to take a pointer to a ULONG in - * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of - * which the first parameter is a ULONG. - * This function is only intended to be called by the RPC runtime. - */ -void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal) -{ - TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phGlobal); - - if (LOWORD(*pFlags) != MSHCTX_INPROC && *phGlobal) - GlobalFree(*phGlobal); -} - /****************************************************************************** * HMETAFILE_UserSize [OLE32.@] *
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/combase.spec | 4 +++ dlls/combase/usrmarshal.c | 1 + dlls/ole32/ole32.spec | 8 ++--- dlls/ole32/usrmarshal.c | 74 --------------------------------------- 4 files changed, 9 insertions(+), 78 deletions(-)
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 3c0955f705d..f1aaa44205d 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -185,6 +185,10 @@ @ stdcall GetHGlobalFromStream(ptr ptr) ole32.GetHGlobalFromStream @ stub GetHookInterface @ stdcall GetRestrictedErrorInfo(ptr) +@ stdcall HACCEL_UserFree(ptr ptr) +@ stdcall HACCEL_UserMarshal(ptr ptr ptr) +@ stdcall HACCEL_UserSize(ptr long ptr) +@ stdcall HACCEL_UserUnmarshal(ptr ptr ptr) @ stdcall HBITMAP_UserFree(ptr ptr) @ stdcall HBITMAP_UserMarshal(ptr ptr ptr) @ stdcall HBITMAP_UserSize(ptr long ptr) diff --git a/dlls/combase/usrmarshal.c b/dlls/combase/usrmarshal.c index 7c77cc1a80e..8bea32cdd54 100644 --- a/dlls/combase/usrmarshal.c +++ b/dlls/combase/usrmarshal.c @@ -134,6 +134,7 @@ static void handle_UserFree(ULONG *pFlags, HANDLE *handle) handle_UserFree(pFlags, (HANDLE *)handle); \ }
+IMPL_WIREM_HANDLE(HACCEL) IMPL_WIREM_HANDLE(HBRUSH) IMPL_WIREM_HANDLE(HDC) IMPL_WIREM_HANDLE(HICON) diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index c3ee8f27f23..9a6ec7cb719 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -123,10 +123,10 @@ @ stdcall GetHGlobalFromStream(ptr ptr) @ stub GetHookInterface @ stdcall GetRunningObjectTable(long ptr) -@ stdcall HACCEL_UserFree(ptr ptr) -@ stdcall HACCEL_UserMarshal(ptr ptr ptr) -@ stdcall HACCEL_UserSize(ptr long ptr) -@ stdcall HACCEL_UserUnmarshal(ptr ptr ptr) +@ stdcall HACCEL_UserFree(ptr ptr) combase.HACCEL_UserFree +@ stdcall HACCEL_UserMarshal(ptr ptr ptr) combase.HACCEL_UserMarshal +@ stdcall HACCEL_UserSize(ptr long ptr) combase.HACCEL_UserSize +@ stdcall HACCEL_UserUnmarshal(ptr ptr ptr) combase.HACCEL_UserUnmarshal @ stdcall HBITMAP_UserFree(ptr ptr) combase.HBITMAP_UserFree @ stdcall HBITMAP_UserMarshal(ptr ptr ptr) combase.HBITMAP_UserMarshal @ stdcall HBITMAP_UserSize(ptr long ptr) combase.HBITMAP_UserSize diff --git a/dlls/ole32/usrmarshal.c b/dlls/ole32/usrmarshal.c index a5daa949830..c58053489be 100644 --- a/dlls/ole32/usrmarshal.c +++ b/dlls/ole32/usrmarshal.c @@ -82,80 +82,6 @@ static const char* debugstr_user_flags(ULONG *pFlags) return wine_dbg_sprintf("MAKELONG(%s, 0x%04x)", loword, HIWORD(*pFlags)); }
-static ULONG handle_UserSize(ULONG *pFlags, ULONG StartingSize, HANDLE *handle) -{ - if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE) - { - ERR("can't remote a local handle\n"); - RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); - return StartingSize; - } - - ALIGN_LENGTH(StartingSize, 3); - return StartingSize + sizeof(RemotableHandle); -} - -static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle) -{ - RemotableHandle *remhandle; - if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE) - { - ERR("can't remote a local handle\n"); - RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); - return pBuffer; - } - - ALIGN_POINTER(pBuffer, 3); - remhandle = (RemotableHandle *)pBuffer; - remhandle->fContext = WDT_INPROC_CALL; - remhandle->u.hInproc = (LONG_PTR)*handle; - return pBuffer + sizeof(RemotableHandle); -} - -static unsigned char * handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle) -{ - RemotableHandle *remhandle; - - ALIGN_POINTER(pBuffer, 3); - remhandle = (RemotableHandle *)pBuffer; - if (remhandle->fContext != WDT_INPROC_CALL) - RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL); - *handle = (HANDLE)(LONG_PTR)remhandle->u.hInproc; - return pBuffer + sizeof(RemotableHandle); -} - -static void handle_UserFree(ULONG *pFlags, HANDLE *handle) -{ - /* nothing to do */ -} - -#define IMPL_WIREM_HANDLE(type) \ - ULONG __RPC_USER type##_UserSize(ULONG *pFlags, ULONG StartingSize, type *handle) \ - { \ - TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, handle); \ - return handle_UserSize(pFlags, StartingSize, (HANDLE *)handle); \ - } \ - \ - unsigned char * __RPC_USER type##_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \ - { \ - TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *handle); \ - return handle_UserMarshal(pFlags, pBuffer, (HANDLE *)handle); \ - } \ - \ - unsigned char * __RPC_USER type##_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \ - { \ - TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, handle); \ - return handle_UserUnmarshal(pFlags, pBuffer, (HANDLE *)handle); \ - } \ - \ - void __RPC_USER type##_UserFree(ULONG *pFlags, type *handle) \ - { \ - TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *handle); \ - handle_UserFree(pFlags, (HANDLE *)handle); \ - } - -IMPL_WIREM_HANDLE(HACCEL) - /****************************************************************************** * HMETAFILE_UserSize [OLE32.@] *
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=76478
Your paranoid android.
=== debiant (32 bit Chinese:China report) ===
ole32: clipboard.c:1745: Test failed: got 800401d0 clipboard.c:1748: Test failed: called 4 clipboard.c:1760: Test failed: called 6 clipboard.c:1770: Test failed: called 7 clipboard.c:1780: Test failed: called 8 clipboard.c:1792: Test failed: called 10 clipboard.c:1802: Test failed: called 11 clipboard.c:1812: Test failed: called 12
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/Makefile.in | 2 + dlls/combase/combase.spec | 2 +- dlls/combase/errorinfo.c | 356 ++++++++++++++++++++++++++++++++++++++ dlls/ole32/errorinfo.c | 356 -------------------------------------- dlls/ole32/ole32.spec | 2 +- 5 files changed, 360 insertions(+), 358 deletions(-) create mode 100644 dlls/combase/errorinfo.c
diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in index 954dc629973..83c71ce9493 100644 --- a/dlls/combase/Makefile.in +++ b/dlls/combase/Makefile.in @@ -1,10 +1,12 @@ MODULE = combase.dll IMPORTLIB = combase IMPORTS = advapi32 ole32 user32 gdi32 uuid +DELAYIMPORTS = oleaut32
EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ + errorinfo.c \ roapi.c \ string.c \ usrmarshal.c diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index f1aaa44205d..cb073ef2fcc 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -170,7 +170,7 @@ @ stub CoVrfReleaseThreadState @ stdcall CoWaitForMultipleHandles(long long long ptr ptr) ole32.CoWaitForMultipleHandles @ stub CoWaitForMultipleObjects -@ stdcall CreateErrorInfo(ptr) ole32.CreateErrorInfo +@ stdcall CreateErrorInfo(ptr) @ stdcall CreateStreamOnHGlobal(ptr long ptr) ole32.CreateStreamOnHGlobal @ stub DcomChannelSetHResult @ stdcall DllDebugObjectRPCHook(long ptr) ole32.DllDebugObjectRPCHook diff --git a/dlls/combase/errorinfo.c b/dlls/combase/errorinfo.c new file mode 100644 index 00000000000..3fcc65a31e1 --- /dev/null +++ b/dlls/combase/errorinfo.c @@ -0,0 +1,356 @@ +/* + * ErrorInfo API + * + * Copyright 2000 Patrik Stridvall, Juergen Schmied + * + * 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(ole); + +static WCHAR *heap_strdupW(const WCHAR *str) +{ + WCHAR *ret = NULL; + + if (str) + { + size_t size; + + size = (lstrlenW(str)+1)*sizeof(WCHAR); + ret = heap_alloc(size); + if (ret) + memcpy(ret, str, size); + } + + return ret; +} + +struct error_info +{ + IErrorInfo IErrorInfo_iface; + ICreateErrorInfo ICreateErrorInfo_iface; + ISupportErrorInfo ISupportErrorInfo_iface; + LONG refcount; + + GUID guid; + WCHAR *source; + WCHAR *description; + WCHAR *help_file; + DWORD help_context; +}; + +static struct error_info *impl_from_IErrorInfo(IErrorInfo *iface) +{ + return CONTAINING_RECORD(iface, struct error_info, IErrorInfo_iface); +} + +static struct error_info *impl_from_ICreateErrorInfo(ICreateErrorInfo *iface) +{ + return CONTAINING_RECORD(iface, struct error_info, ICreateErrorInfo_iface); +} + +static struct error_info *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface) +{ + return CONTAINING_RECORD(iface, struct error_info, ISupportErrorInfo_iface); +} + +static HRESULT WINAPI errorinfo_QueryInterface(IErrorInfo *iface, REFIID riid, void **obj) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + *obj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IErrorInfo)) + { + *obj = &error_info->IErrorInfo_iface; + } + else if (IsEqualIID(riid, &IID_ICreateErrorInfo)) + { + *obj = &error_info->ICreateErrorInfo_iface; + } + else if (IsEqualIID(riid, &IID_ISupportErrorInfo)) + { + *obj = &error_info->ISupportErrorInfo_iface; + } + + if (*obj) + { + IUnknown_AddRef((IUnknown *)*obj); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI errorinfo_AddRef(IErrorInfo *iface) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + ULONG refcount = InterlockedIncrement(&error_info->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI errorinfo_Release(IErrorInfo *iface) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + ULONG refcount = InterlockedDecrement(&error_info->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(error_info->source); + heap_free(error_info->description); + heap_free(error_info->help_file); + heap_free(error_info); + } + + return refcount; +} + +static HRESULT WINAPI errorinfo_GetGUID(IErrorInfo *iface, GUID *guid) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + + TRACE("%p, %p.\n", iface, guid); + + if (!guid) return E_INVALIDARG; + *guid = error_info->guid; + return S_OK; +} + +static HRESULT WINAPI errorinfo_GetSource(IErrorInfo* iface, BSTR *source) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + + TRACE("%p, %p.\n", iface, source); + + if (!source) + return E_INVALIDARG; + *source = SysAllocString(error_info->source); + return S_OK; +} + +static HRESULT WINAPI errorinfo_GetDescription(IErrorInfo *iface, BSTR *description) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + + TRACE("%p, %p.\n", iface, description); + + if (!description) + return E_INVALIDARG; + *description = SysAllocString(error_info->description); + return S_OK; +} + +static HRESULT WINAPI errorinfo_GetHelpFile(IErrorInfo *iface, BSTR *helpfile) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + + TRACE("%p, %p.\n", iface, helpfile); + + if (!helpfile) + return E_INVALIDARG; + *helpfile = SysAllocString(error_info->help_file); + return S_OK; +} + +static HRESULT WINAPI errorinfo_GetHelpContext(IErrorInfo *iface, DWORD *help_context) +{ + struct error_info *error_info = impl_from_IErrorInfo(iface); + + TRACE("%p, %p.\n", iface, help_context); + + if (!help_context) + return E_INVALIDARG; + *help_context = error_info->help_context; + + return S_OK; +} + +static const IErrorInfoVtbl errorinfo_vtbl = +{ + errorinfo_QueryInterface, + errorinfo_AddRef, + errorinfo_Release, + errorinfo_GetGUID, + errorinfo_GetSource, + errorinfo_GetDescription, + errorinfo_GetHelpFile, + errorinfo_GetHelpContext +}; + +static HRESULT WINAPI create_errorinfo_QueryInterface(ICreateErrorInfo *iface, REFIID riid, void **obj) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + return IErrorInfo_QueryInterface(&error_info->IErrorInfo_iface, riid, obj); +} + +static ULONG WINAPI create_errorinfo_AddRef(ICreateErrorInfo *iface) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + return IErrorInfo_AddRef(&error_info->IErrorInfo_iface); +} + +static ULONG WINAPI create_errorinfo_Release(ICreateErrorInfo *iface) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + return IErrorInfo_Release(&error_info->IErrorInfo_iface); +} + +static HRESULT WINAPI create_errorinfo_SetGUID(ICreateErrorInfo *iface, REFGUID guid) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + + TRACE("%p, %s.\n", iface, debugstr_guid(guid)); + + error_info->guid = *guid; + + return S_OK; +} + +static HRESULT WINAPI create_errorinfo_SetSource(ICreateErrorInfo *iface, LPOLESTR source) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(source)); + + heap_free(error_info->source); + error_info->source = heap_strdupW(source); + + return S_OK; +} + +static HRESULT WINAPI create_errorinfo_SetDescription(ICreateErrorInfo *iface, LPOLESTR description) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(description)); + + heap_free(error_info->description); + error_info->description = heap_strdupW(description); + + return S_OK; +} + +static HRESULT WINAPI create_errorinfo_SetHelpFile(ICreateErrorInfo *iface, LPOLESTR helpfile) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(helpfile)); + + heap_free(error_info->help_file); + error_info->help_file = heap_strdupW(helpfile); + + return S_OK; +} + +static HRESULT WINAPI create_errorinfo_SetHelpContext(ICreateErrorInfo *iface, DWORD help_context) +{ + struct error_info *error_info = impl_from_ICreateErrorInfo(iface); + + TRACE("%p, %#x.\n", iface, help_context); + + error_info->help_context = help_context; + + return S_OK; +} + +static const ICreateErrorInfoVtbl create_errorinfo_vtbl = +{ + create_errorinfo_QueryInterface, + create_errorinfo_AddRef, + create_errorinfo_Release, + create_errorinfo_SetGUID, + create_errorinfo_SetSource, + create_errorinfo_SetDescription, + create_errorinfo_SetHelpFile, + create_errorinfo_SetHelpContext +}; + +static HRESULT WINAPI support_errorinfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **obj) +{ + struct error_info *error_info = impl_from_ISupportErrorInfo(iface); + return IErrorInfo_QueryInterface(&error_info->IErrorInfo_iface, riid, obj); +} + +static ULONG WINAPI support_errorinfo_AddRef(ISupportErrorInfo *iface) +{ + struct error_info *error_info = impl_from_ISupportErrorInfo(iface); + return IErrorInfo_AddRef(&error_info->IErrorInfo_iface); +} + +static ULONG WINAPI support_errorinfo_Release(ISupportErrorInfo *iface) +{ + struct error_info *error_info = impl_from_ISupportErrorInfo(iface); + return IErrorInfo_Release(&error_info->IErrorInfo_iface); +} + +static HRESULT WINAPI support_errorinfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid) +{ + struct error_info *error_info = impl_from_ISupportErrorInfo(iface); + + TRACE("%p, %s.\n", iface, debugstr_guid(riid)); + + return IsEqualIID(riid, &error_info->guid) ? S_OK : S_FALSE; +} + +static const ISupportErrorInfoVtbl support_errorinfo_vtbl = +{ + support_errorinfo_QueryInterface, + support_errorinfo_AddRef, + support_errorinfo_Release, + support_errorinfo_InterfaceSupportsErrorInfo +}; + +/*********************************************************************** + * CreateErrorInfo (combase.@) + */ +HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **ret) +{ + struct error_info *error_info; + + TRACE("%p.\n", ret); + + if (!ret) return E_INVALIDARG; + + if (!(error_info = heap_alloc(sizeof(*error_info)))) + return E_OUTOFMEMORY; + + error_info->IErrorInfo_iface.lpVtbl = &errorinfo_vtbl; + error_info->ICreateErrorInfo_iface.lpVtbl = &create_errorinfo_vtbl; + error_info->ISupportErrorInfo_iface.lpVtbl = &support_errorinfo_vtbl; + error_info->refcount = 1; + error_info->source = NULL; + error_info->description = NULL; + error_info->help_file = NULL; + error_info->help_context = 0; + + *ret = &error_info->ICreateErrorInfo_iface; + + return S_OK; +} diff --git a/dlls/ole32/errorinfo.c b/dlls/ole32/errorinfo.c index 6aa3a336b8d..45591ba4a1f 100644 --- a/dlls/ole32/errorinfo.c +++ b/dlls/ole32/errorinfo.c @@ -40,362 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-static inline WCHAR *heap_strdupW(const WCHAR *str) -{ - WCHAR *ret = NULL; - - if(str) { - size_t size; - - size = (lstrlenW(str)+1)*sizeof(WCHAR); - ret = heap_alloc(size); - if(ret) - memcpy(ret, str, size); - } - - return ret; -} - -typedef struct ErrorInfoImpl -{ - IErrorInfo IErrorInfo_iface; - ICreateErrorInfo ICreateErrorInfo_iface; - ISupportErrorInfo ISupportErrorInfo_iface; - LONG ref; - - GUID m_Guid; - WCHAR *source; - WCHAR *description; - WCHAR *help_file; - DWORD m_dwHelpContext; -} ErrorInfoImpl; - -static inline ErrorInfoImpl *impl_from_IErrorInfo( IErrorInfo *iface ) -{ - return CONTAINING_RECORD(iface, ErrorInfoImpl, IErrorInfo_iface); -} - -static inline ErrorInfoImpl *impl_from_ICreateErrorInfo( ICreateErrorInfo *iface ) -{ - return CONTAINING_RECORD(iface, ErrorInfoImpl, ICreateErrorInfo_iface); -} - -static inline ErrorInfoImpl *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface ) -{ - return CONTAINING_RECORD(iface, ErrorInfoImpl, ISupportErrorInfo_iface); -} - -static HRESULT WINAPI IErrorInfoImpl_QueryInterface( - IErrorInfo* iface, - REFIID riid, - void** ppvoid) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid),ppvoid); - - *ppvoid = NULL; - - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IErrorInfo)) - { - *ppvoid = &This->IErrorInfo_iface; - } - else if(IsEqualIID(riid, &IID_ICreateErrorInfo)) - { - *ppvoid = &This->ICreateErrorInfo_iface; - } - else if(IsEqualIID(riid, &IID_ISupportErrorInfo)) - { - *ppvoid = &This->ISupportErrorInfo_iface; - } - - if(*ppvoid) - { - IUnknown_AddRef( (IUnknown*)*ppvoid ); - TRACE("-- Interface: (%p)->(%p)\n",ppvoid,*ppvoid); - return S_OK; - } - TRACE("-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -static ULONG WINAPI IErrorInfoImpl_AddRef( - IErrorInfo* iface) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - TRACE("(%p)->(count=%u)\n",This,This->ref); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI IErrorInfoImpl_Release( - IErrorInfo* iface) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(count=%u)\n",This,ref+1); - - if (!ref) - { - TRACE("-- destroying IErrorInfo(%p)\n",This); - - heap_free(This->source); - heap_free(This->description); - heap_free(This->help_file); - heap_free(This); - } - return ref; -} - -static HRESULT WINAPI IErrorInfoImpl_GetGUID( - IErrorInfo* iface, - GUID * pGUID) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - TRACE("(%p)->(count=%u)\n",This,This->ref); - if(!pGUID )return E_INVALIDARG; - *pGUID = This->m_Guid; - return S_OK; -} - -static HRESULT WINAPI IErrorInfoImpl_GetSource( - IErrorInfo* iface, - BSTR *pBstrSource) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - TRACE("(%p)->(pBstrSource=%p)\n",This,pBstrSource); - if (pBstrSource == NULL) - return E_INVALIDARG; - *pBstrSource = SysAllocString(This->source); - return S_OK; -} - -static HRESULT WINAPI IErrorInfoImpl_GetDescription( - IErrorInfo* iface, - BSTR *pBstrDescription) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - - TRACE("(%p)->(pBstrDescription=%p)\n",This,pBstrDescription); - if (pBstrDescription == NULL) - return E_INVALIDARG; - *pBstrDescription = SysAllocString(This->description); - - return S_OK; -} - -static HRESULT WINAPI IErrorInfoImpl_GetHelpFile( - IErrorInfo* iface, - BSTR *pBstrHelpFile) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - - TRACE("(%p)->(pBstrHelpFile=%p)\n",This, pBstrHelpFile); - if (pBstrHelpFile == NULL) - return E_INVALIDARG; - *pBstrHelpFile = SysAllocString(This->help_file); - - return S_OK; -} - -static HRESULT WINAPI IErrorInfoImpl_GetHelpContext( - IErrorInfo* iface, - DWORD *pdwHelpContext) -{ - ErrorInfoImpl *This = impl_from_IErrorInfo(iface); - TRACE("(%p)->(pdwHelpContext=%p)\n",This, pdwHelpContext); - if (pdwHelpContext == NULL) - return E_INVALIDARG; - *pdwHelpContext = This->m_dwHelpContext; - - return S_OK; -} - -static const IErrorInfoVtbl ErrorInfoVtbl = -{ - IErrorInfoImpl_QueryInterface, - IErrorInfoImpl_AddRef, - IErrorInfoImpl_Release, - IErrorInfoImpl_GetGUID, - IErrorInfoImpl_GetSource, - IErrorInfoImpl_GetDescription, - IErrorInfoImpl_GetHelpFile, - IErrorInfoImpl_GetHelpContext -}; - - -static HRESULT WINAPI ICreateErrorInfoImpl_QueryInterface( - ICreateErrorInfo* iface, - REFIID riid, - VOID** ppvoid) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - return IErrorInfo_QueryInterface(&This->IErrorInfo_iface, riid, ppvoid); -} - -static ULONG WINAPI ICreateErrorInfoImpl_AddRef( - ICreateErrorInfo* iface) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - return IErrorInfo_AddRef(&This->IErrorInfo_iface); -} - -static ULONG WINAPI ICreateErrorInfoImpl_Release( - ICreateErrorInfo* iface) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - return IErrorInfo_Release(&This->IErrorInfo_iface); -} - - -static HRESULT WINAPI ICreateErrorInfoImpl_SetGUID( - ICreateErrorInfo* iface, - REFGUID rguid) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - TRACE("(%p)->(%s)\n", This, debugstr_guid(rguid)); - This->m_Guid = *rguid; - return S_OK; -} - -static HRESULT WINAPI ICreateErrorInfoImpl_SetSource( - ICreateErrorInfo* iface, - LPOLESTR szSource) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - TRACE("(%p): %s\n",This, debugstr_w(szSource)); - - heap_free(This->source); - This->source = heap_strdupW(szSource); - - return S_OK; -} - -static HRESULT WINAPI ICreateErrorInfoImpl_SetDescription( - ICreateErrorInfo* iface, - LPOLESTR szDescription) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - TRACE("(%p): %s\n",This, debugstr_w(szDescription)); - - heap_free(This->description); - This->description = heap_strdupW(szDescription); - return S_OK; -} - -static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpFile( - ICreateErrorInfo* iface, - LPOLESTR szHelpFile) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - TRACE("(%p,%s)\n",This,debugstr_w(szHelpFile)); - heap_free(This->help_file); - This->help_file = heap_strdupW(szHelpFile); - return S_OK; -} - -static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext( - ICreateErrorInfo* iface, - DWORD dwHelpContext) -{ - ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); - TRACE("(%p,%d)\n",This,dwHelpContext); - This->m_dwHelpContext = dwHelpContext; - return S_OK; -} - -static const ICreateErrorInfoVtbl CreateErrorInfoVtbl = -{ - ICreateErrorInfoImpl_QueryInterface, - ICreateErrorInfoImpl_AddRef, - ICreateErrorInfoImpl_Release, - ICreateErrorInfoImpl_SetGUID, - ICreateErrorInfoImpl_SetSource, - ICreateErrorInfoImpl_SetDescription, - ICreateErrorInfoImpl_SetHelpFile, - ICreateErrorInfoImpl_SetHelpContext -}; - -static HRESULT WINAPI ISupportErrorInfoImpl_QueryInterface( - ISupportErrorInfo* iface, - REFIID riid, - VOID** ppvoid) -{ - ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); - return IErrorInfo_QueryInterface(&This->IErrorInfo_iface, riid, ppvoid); -} - -static ULONG WINAPI ISupportErrorInfoImpl_AddRef(ISupportErrorInfo* iface) -{ - ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); - return IErrorInfo_AddRef(&This->IErrorInfo_iface); -} - -static ULONG WINAPI ISupportErrorInfoImpl_Release(ISupportErrorInfo* iface) -{ - ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); - return IErrorInfo_Release(&This->IErrorInfo_iface); -} - -static HRESULT WINAPI ISupportErrorInfoImpl_InterfaceSupportsErrorInfo( - ISupportErrorInfo* iface, - REFIID riid) -{ - ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); - TRACE("(%p)->(%s)\n", This, debugstr_guid(riid)); - return (IsEqualIID(riid, &This->m_Guid)) ? S_OK : S_FALSE; -} - -static const ISupportErrorInfoVtbl SupportErrorInfoVtbl = -{ - ISupportErrorInfoImpl_QueryInterface, - ISupportErrorInfoImpl_AddRef, - ISupportErrorInfoImpl_Release, - ISupportErrorInfoImpl_InterfaceSupportsErrorInfo -}; - -static IErrorInfo* IErrorInfoImpl_Constructor(void) -{ - ErrorInfoImpl *This = heap_alloc(sizeof(ErrorInfoImpl)); - - if (!This) return NULL; - - This->IErrorInfo_iface.lpVtbl = &ErrorInfoVtbl; - This->ICreateErrorInfo_iface.lpVtbl = &CreateErrorInfoVtbl; - This->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl; - This->ref = 1; - This->source = NULL; - This->description = NULL; - This->help_file = NULL; - This->m_dwHelpContext = 0; - - return &This->IErrorInfo_iface; -} - -/*********************************************************************** - * CreateErrorInfo (OLE32.@) - * - * Creates an object used to set details for an error info object. - * - * PARAMS - * pperrinfo [O]. Address where error info creation object will be stored. - * - * RETURNS - * Success: S_OK. - * Failure: HRESULT code. - */ -HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo) -{ - IErrorInfo * pei; - HRESULT res; - TRACE("(%p)\n", pperrinfo); - if(! pperrinfo ) return E_INVALIDARG; - if(!(pei=IErrorInfoImpl_Constructor()))return E_OUTOFMEMORY; - - res = IErrorInfo_QueryInterface(pei, &IID_ICreateErrorInfo, (LPVOID*)pperrinfo); - IErrorInfo_Release(pei); - return res; -} - /*********************************************************************** * GetErrorInfo (OLE32.@) * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 9a6ec7cb719..927a98ea123 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -97,7 +97,7 @@ @ stdcall CreateClassMoniker(ptr ptr) @ stdcall CreateDataAdviseHolder(ptr) @ stdcall CreateDataCache(ptr ptr ptr ptr) -@ stdcall CreateErrorInfo(ptr) +@ stdcall CreateErrorInfo(ptr) combase.CreateErrorInfo @ stdcall CreateFileMoniker(wstr ptr) @ stdcall CreateGenericComposite(ptr ptr ptr) @ stdcall CreateILockBytesOnHGlobal(ptr long ptr)
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=76479
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.spec | 12 +- dlls/combase/malloc.c | 457 +++++++++++++++++++++++++++++++++ dlls/ole32/ifs.c | 515 -------------------------------------- dlls/ole32/ole32.spec | 12 +- 5 files changed, 470 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..8d0f70c513c --- /dev/null +++ b/dlls/combase/malloc.c @@ -0,0 +1,457 @@ +/* + * 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(ole); +WINE_DECLARE_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_(olemalloc)("%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_(olemalloc)("%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_(olemalloc)("%p.\n",addr); + return addr; +} + +static void * WINAPI allocator_Realloc(IMalloc *iface, void *pv, SIZE_T cb) +{ + void *addr; + + TRACE_(olemalloc)("%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_(olemalloc)("%p.\n", addr); + return addr; +} + +static void WINAPI allocator_Free(IMalloc *iface, void *mem) +{ + BOOL spyed_block = FALSE, spy_active = FALSE; + + TRACE_(olemalloc)("%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_(olemalloc)("%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_(olemalloc)("%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_(olemalloc)("\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
On Tue, Aug 04, 2020 at 05:02:39PM +0300, Nikolay Sivov wrote:
diff --git a/dlls/combase/malloc.c b/dlls/combase/malloc.c new file mode 100644 index 00000000000..8d0f70c513c --- /dev/null +++ b/dlls/combase/malloc.c @@ -0,0 +1,457 @@ +/*
- 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(ole); +WINE_DECLARE_DEBUG_CHANNEL(olemalloc);
I think this could all go to olemalloc.
Huw.
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) + ); +}