[PATCH 1/2] ole32: Implement chained IInitializeSpy support.
Huw Davies
huw at codeweavers.com
Thu Jan 24 06:00:08 CST 2019
On Wed, Jan 23, 2019 at 11:41:44AM +0300, Nikolay Sivov wrote:
> Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
> ---
> dlls/ole32/compobj.c | 123 +++++++++++++++++++++++++++--------
> dlls/ole32/compobj_private.h | 27 +++++++-
> dlls/ole32/tests/compobj.c | 15 ++---
> 3 files changed, 126 insertions(+), 39 deletions(-)
>
> diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
> index 66b1683d98..c65250442d 100644
> --- a/dlls/ole32/compobj.c
> +++ b/dlls/ole32/compobj.c
> @@ -1827,14 +1856,42 @@ HRESULT WINAPI CoRegisterInitializeSpy(IInitializeSpy *spy, ULARGE_INTEGER *cook
> HRESULT WINAPI CoRevokeInitializeSpy(ULARGE_INTEGER cookie)
> {
> struct oletls *info = COM_CurrentInfo();
> + struct init_spy *spy;
> +
> TRACE("(%s)\n", wine_dbgstr_longlong(cookie.QuadPart));
>
> - if (!info || !info->spy || cookie.QuadPart != (DWORD_PTR)info->spy)
> + if (!info || list_empty(&info->spies.active))
> return E_INVALIDARG;
>
> - IInitializeSpy_Release(info->spy);
> - info->spy = NULL;
> - return S_OK;
> + if (cookie.HighPart != GetCurrentThreadId() || cookie.LowPart >= info->spies.next_id)
> + return E_INVALIDARG;
> +
> + LIST_FOR_EACH_ENTRY(spy, &info->spies.active, struct init_spy, entry)
> + {
> + if (cookie.LowPart == spy->id)
> + {
> + IInitializeSpy_Release(spy->spy);
> + spy->spy = NULL;
> + list_remove(&spy->entry);
> +
> + /* Move to freed list, unless it was latest item id or last item in the active list. */
> + if (spy->id == info->spies.next_id - 1)
> + info->spies.next_id--;
> + else if (list_empty(&info->spies.active))
> + oletls_release_spy_list(&info->spies.freed);
> + else
> + {
> + list_add_tail(&info->spies.freed, &spy->entry);
> + spy = NULL;
> + }
> +
> + heap_free(spy);
> +
> + return S_OK;
> + }
> + }
> +
> + return E_INVALIDARG;
> }
I don't think the extra complication of a free list is worth it. How
about just keeping the active list sorted, when you register a new
spy just iterate through until you find a missing id and insert the
new node at that point? This stuff is not going to be performance
critical.
> diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
> index 1e564a3de1..1829866bff 100644
> --- a/dlls/ole32/compobj_private.h
> +++ b/dlls/ole32/compobj_private.h
> struct oletls
> {
> @@ -160,7 +174,7 @@ struct oletls
> IErrorInfo *errorinfo; /* see errorinfo.c */
> IUnknown *state; /* see CoSetState */
> DWORD apt_mask; /* apartment mask (+0Ch on x86) */
> - IInitializeSpy *spy; /* The "SPY" from CoInitializeSpy */
> + void *unknown0; /* The "SPY" from CoInitializeSpy */
Could you remove the comment?
> DWORD inits; /* number of times CoInitializeEx called */
> DWORD ole_inits; /* number of times OleInitialize called */
> GUID causality_id; /* unique identifier for each COM call */
> @@ -171,6 +185,7 @@ struct oletls
> IUnknown *call_state; /* current call context (+3Ch on x86) */
> DWORD unknown2[46];
> IUnknown *cancel_object; /* cancel object set by CoSetCancelObject (+F8h on x86) */
> + struct spy_chain spies; /* Spies from CoRegisterInitializeSpy */
> };
FWIW, it's not clear whether anything needs compatiblity with native's
layout, some things appear to have changed anyway. For example,
'inits' is at 0x18 in 32-bit Windows 7; we have it at 0x14.
Huw.
More information about the wine-devel
mailing list