combase: Move CoWaitForMultipleHandles().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c9586634d4
commit
e56061bb4c
|
@ -25,6 +25,7 @@
|
||||||
#define USE_COM_CONTEXT_DEF
|
#define USE_COM_CONTEXT_DEF
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
#include "oleauto.h"
|
#include "oleauto.h"
|
||||||
|
#include "dde.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
|
||||||
#include "combase_private.h"
|
#include "combase_private.h"
|
||||||
|
@ -1521,3 +1522,165 @@ HRESULT WINAPI CoRevokeInitializeSpy(ULARGE_INTEGER cookie)
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL com_peek_message(struct apartment *apt, MSG *msg)
|
||||||
|
{
|
||||||
|
/* First try to retrieve messages for incoming COM calls to the apartment window */
|
||||||
|
return (apt->win && PeekMessageW(msg, apt->win, 0, 0, PM_REMOVE | PM_NOYIELD)) ||
|
||||||
|
/* Next retrieve other messages necessary for the app to remain responsive */
|
||||||
|
PeekMessageW(msg, NULL, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE | PM_NOYIELD) ||
|
||||||
|
PeekMessageW(msg, NULL, 0, 0, PM_QS_PAINT | PM_QS_SENDMESSAGE | PM_REMOVE | PM_NOYIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* CoWaitForMultipleHandles (combase.@)
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI CoWaitForMultipleHandles(DWORD flags, DWORD timeout, ULONG handle_count, HANDLE *handles,
|
||||||
|
DWORD *index)
|
||||||
|
{
|
||||||
|
BOOL check_apc = !!(flags & COWAIT_ALERTABLE), post_quit = FALSE, message_loop;
|
||||||
|
DWORD start_time, wait_flags = 0;
|
||||||
|
struct tlsdata *tlsdata;
|
||||||
|
struct apartment *apt;
|
||||||
|
UINT exit_code;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE("%#x, %#x, %u, %p, %p\n", flags, timeout, handle_count, handles, index);
|
||||||
|
|
||||||
|
if (!index)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
*index = 0;
|
||||||
|
|
||||||
|
if (!handles)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!handle_count)
|
||||||
|
return RPC_E_NO_SYNC;
|
||||||
|
|
||||||
|
if (FAILED(hr = com_get_tlsdata(&tlsdata)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
apt = com_get_current_apt();
|
||||||
|
message_loop = apt && !apt->multi_threaded;
|
||||||
|
|
||||||
|
if (flags & COWAIT_WAITALL)
|
||||||
|
wait_flags |= MWMO_WAITALL;
|
||||||
|
if (flags & COWAIT_ALERTABLE)
|
||||||
|
wait_flags |= MWMO_ALERTABLE;
|
||||||
|
|
||||||
|
start_time = GetTickCount();
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
DWORD now = GetTickCount(), res;
|
||||||
|
|
||||||
|
if (now - start_time > timeout)
|
||||||
|
{
|
||||||
|
hr = RPC_S_CALLPENDING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message_loop)
|
||||||
|
{
|
||||||
|
TRACE("waiting for rpc completion or window message\n");
|
||||||
|
|
||||||
|
res = WAIT_TIMEOUT;
|
||||||
|
|
||||||
|
if (check_apc)
|
||||||
|
{
|
||||||
|
res = WaitForMultipleObjectsEx(handle_count, handles, !!(flags & COWAIT_WAITALL), 0, TRUE);
|
||||||
|
check_apc = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == WAIT_TIMEOUT)
|
||||||
|
res = MsgWaitForMultipleObjectsEx(handle_count, handles,
|
||||||
|
timeout == INFINITE ? INFINITE : start_time + timeout - now,
|
||||||
|
QS_SENDMESSAGE | QS_ALLPOSTMESSAGE | QS_PAINT, wait_flags);
|
||||||
|
|
||||||
|
if (res == WAIT_OBJECT_0 + handle_count) /* messages available */
|
||||||
|
{
|
||||||
|
int msg_count = 0;
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
/* call message filter */
|
||||||
|
|
||||||
|
if (apt->filter)
|
||||||
|
{
|
||||||
|
PENDINGTYPE pendingtype = tlsdata->pending_call_count_server ? PENDINGTYPE_NESTED : PENDINGTYPE_TOPLEVEL;
|
||||||
|
DWORD be_handled = IMessageFilter_MessagePending(apt->filter, 0 /* FIXME */, now - start_time, pendingtype);
|
||||||
|
|
||||||
|
TRACE("IMessageFilter_MessagePending returned %d\n", be_handled);
|
||||||
|
|
||||||
|
switch (be_handled)
|
||||||
|
{
|
||||||
|
case PENDINGMSG_CANCELCALL:
|
||||||
|
WARN("call canceled\n");
|
||||||
|
hr = RPC_E_CALL_CANCELED;
|
||||||
|
break;
|
||||||
|
case PENDINGMSG_WAITNOPROCESS:
|
||||||
|
case PENDINGMSG_WAITDEFPROCESS:
|
||||||
|
default:
|
||||||
|
/* FIXME: MSDN is very vague about the difference
|
||||||
|
* between WAITNOPROCESS and WAITDEFPROCESS - there
|
||||||
|
* appears to be none, so it is possibly a left-over
|
||||||
|
* from the 16-bit world. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!apt->win)
|
||||||
|
{
|
||||||
|
/* If window is NULL on apartment, peek at messages so that it will not trigger
|
||||||
|
* MsgWaitForMultipleObjects next time. */
|
||||||
|
PeekMessageW(NULL, NULL, 0, 0, PM_QS_POSTMESSAGE | PM_NOREMOVE | PM_NOYIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some apps (e.g. Visio 2010) don't handle WM_PAINT properly and loop forever,
|
||||||
|
* so after processing 100 messages we go back to checking the wait handles */
|
||||||
|
while (msg_count++ < 100 && com_peek_message(apt, &msg))
|
||||||
|
{
|
||||||
|
if (msg.message == WM_QUIT)
|
||||||
|
{
|
||||||
|
TRACE("Received WM_QUIT message\n");
|
||||||
|
post_quit = TRUE;
|
||||||
|
exit_code = msg.wParam;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE("Received message whilst waiting for RPC: 0x%04x\n", msg.message);
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessageW(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE("Waiting for rpc completion\n");
|
||||||
|
|
||||||
|
res = WaitForMultipleObjectsEx(handle_count, handles, !!(flags & COWAIT_WAITALL),
|
||||||
|
(timeout == INFINITE) ? INFINITE : start_time + timeout - now, !!(flags & COWAIT_ALERTABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (res)
|
||||||
|
{
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
hr = RPC_S_CALLPENDING;
|
||||||
|
break;
|
||||||
|
case WAIT_FAILED:
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*index = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (post_quit) PostQuitMessage(exit_code);
|
||||||
|
|
||||||
|
TRACE("-- 0x%08x\n", hr);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@
|
||||||
@ stub CoVrfCheckThreadState
|
@ stub CoVrfCheckThreadState
|
||||||
@ stub CoVrfGetThreadState
|
@ stub CoVrfGetThreadState
|
||||||
@ stub CoVrfReleaseThreadState
|
@ stub CoVrfReleaseThreadState
|
||||||
@ stdcall CoWaitForMultipleHandles(long long long ptr ptr) ole32.CoWaitForMultipleHandles
|
@ stdcall CoWaitForMultipleHandles(long long long ptr ptr)
|
||||||
@ stub CoWaitForMultipleObjects
|
@ stub CoWaitForMultipleObjects
|
||||||
@ stdcall CreateErrorInfo(ptr)
|
@ stdcall CreateErrorInfo(ptr)
|
||||||
@ stdcall CreateStreamOnHGlobal(ptr long ptr) ole32.CreateStreamOnHGlobal
|
@ stdcall CreateStreamOnHGlobal(ptr long ptr) ole32.CreateStreamOnHGlobal
|
||||||
|
|
|
@ -15,10 +15,41 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
#include "wine/orpc.h"
|
||||||
|
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
|
||||||
struct apartment;
|
struct apartment
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
|
||||||
|
LONG refs; /* refcount of the apartment (LOCK) */
|
||||||
|
BOOL multi_threaded; /* multi-threaded or single-threaded apartment? (RO) */
|
||||||
|
DWORD tid; /* thread id (RO) */
|
||||||
|
OXID oxid; /* object exporter ID (RO) */
|
||||||
|
LONG ipidc; /* interface pointer ID counter, starts at 1 (LOCK) */
|
||||||
|
CRITICAL_SECTION cs; /* thread safety */
|
||||||
|
struct list proxies; /* imported objects (CS cs) */
|
||||||
|
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
|
||||||
|
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
|
||||||
|
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
|
||||||
|
struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
|
||||||
|
DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
|
||||||
|
HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */
|
||||||
|
struct local_server *local_server; /* A marshallable object exposing local servers (CS cs) */
|
||||||
|
BOOL being_destroyed; /* is currently being destroyed */
|
||||||
|
|
||||||
|
/* FIXME: OIDs should be given out by RPCSS */
|
||||||
|
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
|
||||||
|
|
||||||
|
/* STA-only fields */
|
||||||
|
HWND win; /* message window (LOCK) */
|
||||||
|
IMessageFilter *filter; /* message filter (CS cs) */
|
||||||
|
BOOL main; /* is this a main-threaded-apartment? (RO) */
|
||||||
|
|
||||||
|
/* MTA-only */
|
||||||
|
struct list usage_cookies; /* Used for refcount control with CoIncrementMTAUsage()/CoDecrementMTAUsage(). */
|
||||||
|
};
|
||||||
|
|
||||||
/* this is what is stored in TEB->ReservedForOle */
|
/* this is what is stored in TEB->ReservedForOle */
|
||||||
struct tlsdata
|
struct tlsdata
|
||||||
|
@ -50,3 +81,10 @@ static inline HRESULT com_get_tlsdata(struct tlsdata **data)
|
||||||
*data = NtCurrentTeb()->ReservedForOle;
|
*data = NtCurrentTeb()->ReservedForOle;
|
||||||
return *data ? S_OK : InternalTlsAllocData(data);
|
return *data ? S_OK : InternalTlsAllocData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct apartment* com_get_current_apt(void)
|
||||||
|
{
|
||||||
|
struct tlsdata *tlsdata = NULL;
|
||||||
|
com_get_tlsdata(&tlsdata);
|
||||||
|
return tlsdata->apt;
|
||||||
|
}
|
||||||
|
|
|
@ -22,9 +22,10 @@
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
|
|
||||||
|
#include "combase_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/heap.h"
|
#include "wine/heap.h"
|
||||||
#include "wine/orpc.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
|
||||||
|
|
|
@ -3348,185 +3348,6 @@ HRESULT WINAPI CoAllowSetForegroundWindow(IUnknown *pUnk, void *pvReserved)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL COM_PeekMessage(struct apartment *apt, MSG *msg)
|
|
||||||
{
|
|
||||||
/* first try to retrieve messages for incoming COM calls to the apartment window */
|
|
||||||
return (apt->win && PeekMessageW(msg, apt->win, 0, 0, PM_REMOVE|PM_NOYIELD)) ||
|
|
||||||
/* next retrieve other messages necessary for the app to remain responsive */
|
|
||||||
PeekMessageW(msg, NULL, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE|PM_NOYIELD) ||
|
|
||||||
PeekMessageW(msg, NULL, 0, 0, PM_QS_PAINT|PM_QS_SENDMESSAGE|PM_REMOVE|PM_NOYIELD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* CoWaitForMultipleHandles [OLE32.@]
|
|
||||||
*
|
|
||||||
* Waits for one or more handles to become signaled.
|
|
||||||
*
|
|
||||||
* PARAMS
|
|
||||||
* dwFlags [I] Flags. See notes.
|
|
||||||
* dwTimeout [I] Timeout in milliseconds.
|
|
||||||
* cHandles [I] Number of handles pointed to by pHandles.
|
|
||||||
* pHandles [I] Handles to wait for.
|
|
||||||
* lpdwindex [O] Index of handle that was signaled.
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* Success: S_OK.
|
|
||||||
* Failure: RPC_S_CALLPENDING on timeout.
|
|
||||||
*
|
|
||||||
* NOTES
|
|
||||||
*
|
|
||||||
* The dwFlags parameter can be zero or more of the following:
|
|
||||||
*| COWAIT_WAITALL - Wait for all of the handles to become signaled.
|
|
||||||
*| COWAIT_ALERTABLE - Allows a queued APC to run during the wait.
|
|
||||||
*
|
|
||||||
* SEE ALSO
|
|
||||||
* MsgWaitForMultipleObjects, WaitForMultipleObjects.
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
|
|
||||||
ULONG cHandles, LPHANDLE pHandles, LPDWORD lpdwindex)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
DWORD start_time = GetTickCount();
|
|
||||||
APARTMENT *apt = COM_CurrentApt();
|
|
||||||
BOOL message_loop = apt && !apt->multi_threaded;
|
|
||||||
BOOL check_apc = (dwFlags & COWAIT_ALERTABLE) != 0;
|
|
||||||
BOOL post_quit = FALSE;
|
|
||||||
UINT exit_code;
|
|
||||||
|
|
||||||
TRACE("(0x%08x, 0x%08x, %d, %p, %p)\n", dwFlags, dwTimeout, cHandles,
|
|
||||||
pHandles, lpdwindex);
|
|
||||||
|
|
||||||
if (!lpdwindex)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
*lpdwindex = 0;
|
|
||||||
|
|
||||||
if (!pHandles)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
if (!cHandles)
|
|
||||||
return RPC_E_NO_SYNC;
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
DWORD now = GetTickCount();
|
|
||||||
DWORD res;
|
|
||||||
|
|
||||||
if (now - start_time > dwTimeout)
|
|
||||||
{
|
|
||||||
hr = RPC_S_CALLPENDING;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message_loop)
|
|
||||||
{
|
|
||||||
DWORD wait_flags = ((dwFlags & COWAIT_WAITALL) ? MWMO_WAITALL : 0) |
|
|
||||||
((dwFlags & COWAIT_ALERTABLE ) ? MWMO_ALERTABLE : 0);
|
|
||||||
|
|
||||||
TRACE("waiting for rpc completion or window message\n");
|
|
||||||
|
|
||||||
res = WAIT_TIMEOUT;
|
|
||||||
|
|
||||||
if (check_apc)
|
|
||||||
{
|
|
||||||
res = WaitForMultipleObjectsEx(cHandles, pHandles,
|
|
||||||
(dwFlags & COWAIT_WAITALL) != 0, 0, TRUE);
|
|
||||||
check_apc = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == WAIT_TIMEOUT)
|
|
||||||
res = MsgWaitForMultipleObjectsEx(cHandles, pHandles,
|
|
||||||
(dwTimeout == INFINITE) ? INFINITE : start_time + dwTimeout - now,
|
|
||||||
QS_SENDMESSAGE | QS_ALLPOSTMESSAGE | QS_PAINT, wait_flags);
|
|
||||||
|
|
||||||
if (res == WAIT_OBJECT_0 + cHandles) /* messages available */
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
/* call message filter */
|
|
||||||
|
|
||||||
if (COM_CurrentApt()->filter)
|
|
||||||
{
|
|
||||||
PENDINGTYPE pendingtype =
|
|
||||||
COM_CurrentInfo()->pending_call_count_server ?
|
|
||||||
PENDINGTYPE_NESTED : PENDINGTYPE_TOPLEVEL;
|
|
||||||
DWORD be_handled = IMessageFilter_MessagePending(
|
|
||||||
COM_CurrentApt()->filter, 0 /* FIXME */,
|
|
||||||
now - start_time, pendingtype);
|
|
||||||
TRACE("IMessageFilter_MessagePending returned %d\n", be_handled);
|
|
||||||
switch (be_handled)
|
|
||||||
{
|
|
||||||
case PENDINGMSG_CANCELCALL:
|
|
||||||
WARN("call canceled\n");
|
|
||||||
hr = RPC_E_CALL_CANCELED;
|
|
||||||
break;
|
|
||||||
case PENDINGMSG_WAITNOPROCESS:
|
|
||||||
case PENDINGMSG_WAITDEFPROCESS:
|
|
||||||
default:
|
|
||||||
/* FIXME: MSDN is very vague about the difference
|
|
||||||
* between WAITNOPROCESS and WAITDEFPROCESS - there
|
|
||||||
* appears to be none, so it is possibly a left-over
|
|
||||||
* from the 16-bit world. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!apt->win)
|
|
||||||
{
|
|
||||||
/* If window is NULL on apartment, peek at messages so that it will not trigger
|
|
||||||
* MsgWaitForMultipleObjects next time. */
|
|
||||||
PeekMessageW(NULL, NULL, 0, 0, PM_QS_POSTMESSAGE | PM_NOREMOVE | PM_NOYIELD);
|
|
||||||
}
|
|
||||||
/* some apps (e.g. Visio 2010) don't handle WM_PAINT properly and loop forever,
|
|
||||||
* so after processing 100 messages we go back to checking the wait handles */
|
|
||||||
while (count++ < 100 && COM_PeekMessage(apt, &msg))
|
|
||||||
{
|
|
||||||
if (msg.message == WM_QUIT)
|
|
||||||
{
|
|
||||||
TRACE("received WM_QUIT message\n");
|
|
||||||
post_quit = TRUE;
|
|
||||||
exit_code = msg.wParam;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE("received message whilst waiting for RPC: 0x%04x\n", msg.message);
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessageW(&msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE("waiting for rpc completion\n");
|
|
||||||
|
|
||||||
res = WaitForMultipleObjectsEx(cHandles, pHandles, (dwFlags & COWAIT_WAITALL) != 0,
|
|
||||||
(dwTimeout == INFINITE) ? INFINITE : start_time + dwTimeout - now,
|
|
||||||
(dwFlags & COWAIT_ALERTABLE) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (res)
|
|
||||||
{
|
|
||||||
case WAIT_TIMEOUT:
|
|
||||||
hr = RPC_S_CALLPENDING;
|
|
||||||
break;
|
|
||||||
case WAIT_FAILED:
|
|
||||||
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*lpdwindex = res;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (post_quit) PostQuitMessage(exit_code);
|
|
||||||
TRACE("-- 0x%08x\n", hr);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CoGetObject [OLE32.@]
|
* CoGetObject [OLE32.@]
|
||||||
*
|
*
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
@ stub CoUnloadingWOW
|
@ stub CoUnloadingWOW
|
||||||
@ stdcall CoUnmarshalHresult(ptr ptr) combase.CoUnmarshalHresult
|
@ stdcall CoUnmarshalHresult(ptr ptr) combase.CoUnmarshalHresult
|
||||||
@ stdcall CoUnmarshalInterface(ptr ptr ptr)
|
@ stdcall CoUnmarshalInterface(ptr ptr ptr)
|
||||||
@ stdcall CoWaitForMultipleHandles(long long long ptr ptr)
|
@ stdcall CoWaitForMultipleHandles(long long long ptr ptr) combase.CoWaitForMultipleHandles
|
||||||
@ stdcall CreateAntiMoniker(ptr)
|
@ stdcall CreateAntiMoniker(ptr)
|
||||||
@ stdcall CreateBindCtx(long ptr)
|
@ stdcall CreateBindCtx(long ptr)
|
||||||
@ stdcall CreateClassMoniker(ptr ptr)
|
@ stdcall CreateClassMoniker(ptr ptr)
|
||||||
|
|
Loading…
Reference in New Issue