Vanara/PInvoke/Ole/Ole32/ComBaseApi.cs

4080 lines
231 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Vanara.InteropServices;
using static Vanara.PInvoke.Rpc;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
public static partial class Ole32
{
/// <summary>Specifies options for the RoGetAgileReference function.</summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/ne-combaseapi-agilereferenceoptions typedef enum
// AgileReferenceOptions { AGILEREFERENCE_DEFAULT, AGILEREFERENCE_DELAYEDMARSHAL } ;
[PInvokeData("combaseapi.h", MSDNShortId = "F46FD597-F278-4DA8-BC94-26836684AD7E")]
public enum AgileReferenceOptions
{
/// <summary>
/// Use the default marshaling behavior, which is to marshal interfaces when an agile reference to the interface is obtained.
/// </summary>
AGILEREFERENCE_DEFAULT,
/// <summary>
/// Marshaling happens on demand. Use this option only in situations where it's known that an object is only resolved from the
/// same apartment in which it was registered.
/// </summary>
AGILEREFERENCE_DELAYEDMARSHAL
}
/// <summary>
/// <para>Specifies the behavior of the CoWaitForMultipleHandles function.</para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/ne-combaseapi-tagcowait_flags typedef enum tagCOWAIT_FLAGS {
// COWAIT_DEFAULT, COWAIT_WAITALL, COWAIT_ALERTABLE, COWAIT_INPUTAVAILABLE, COWAIT_DISPATCH_CALLS, COWAIT_DISPATCH_WINDOW_MESSAGES } COWAIT_FLAGS;
[PInvokeData("combaseapi.h", MSDNShortId = "e6f8300c-f74b-4383-8ee5-519a0ed0b358")]
[Flags]
public enum COWAIT_FLAGS
{
/// <summary>Dispatch calls needed for marshaling without dispatching arbitrary calls.</summary>
COWAIT_DEFAULT = 0,
/// <summary>
/// If set, the call to CoWaitForMultipleHandles will return S_OK only when all handles associated with the synchronization
/// object have been signaled and an input event has been received, all at the same time. In this case, the behavior of
/// CoWaitForMultipleHandles corresponds to the behavior of the MsgWaitForMultipleObjectsEx function with the dwFlags parameter
/// set to MWMO_WAITALL. If COWAIT_WAITALL is not set, the call to CoWaitForMultipleHandles will return S_OK as soon as any
/// handle associated with the synchronization object has been signaled, regardless of whether an input event is received.
/// </summary>
COWAIT_WAITALL = 1,
/// <summary>
/// If set, the call to CoWaitForMultipleHandles will return S_OK if an asynchronous procedure call (APC) has been queued to the
/// calling thread with a call to the QueueUserAPC function, even if no handle has been signaled.
/// </summary>
COWAIT_ALERTABLE = 2,
/// <summary>
/// If set, the call to CoWaitForMultipleHandles will return S_OK if input exists for the queue, even if the input has been seen
/// (but not removed) using a call to another function, such as PeekMessage.
/// </summary>
COWAIT_INPUTAVAILABLE = 4,
/// <summary>
/// Dispatch calls from CoWaitForMultipleHandles in an ASTA. Default is no call dispatch. This value has no meaning in other
/// apartment types and is ignored.
/// </summary>
COWAIT_DISPATCH_CALLS = 8,
/// <summary>
/// Enables dispatch of window messages from CoWaitForMultipleHandles in an ASTA or STA. Default in ASTA is no window messages
/// dispatched, default in STA is only a small set of special-cased messages dispatched. The value has no meaning in MTA and is ignored.
/// </summary>
COWAIT_DISPATCH_WINDOW_MESSAGES = 0x10,
}
/// <summary>Provides flags for the CoWaitForMultipleObjects function.</summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/ne-combaseapi-cwmo_flags typedef enum CWMO_FLAGS { CWMO_DEFAULT,
// CWMO_DISPATCH_CALLS, CWMO_DISPATCH_WINDOW_MESSAGES } ;
[PInvokeData("combaseapi.h", MSDNShortId = "5FE605A9-DE92-4CD9-9390-6C9F5189A7CB")]
[Flags]
public enum CWMO_FLAGS
{
/// <summary>No call dispatch.</summary>
CWMO_DEFAULT = 0,
/// <summary>Dispatch calls from CoWaitForMultipleObjects (default is no call dispatch).</summary>
CWMO_DISPATCH_CALLS = 1,
/// <summary/>
CWMO_DISPATCH_WINDOW_MESSAGES = 2,
}
/// <summary>
/// <para>Controls the type of connections to a class object.</para>
/// </summary>
/// <remarks>
/// <para>
/// In CoRegisterClassObject, members of both the <c>REGCLS</c> and the CLSCTX enumerations, taken together, determine how the class
/// object is registered.
/// </para>
/// <para>
/// An EXE surrogate (in which DLL servers are run) calls CoRegisterClassObject to register a class factory using a new
/// <c>REGCLS</c> value, REGCLS_SURROGATE.
/// </para>
/// <para>
/// All class factories for DLL surrogates should be registered with REGCLS_SURROGATE set. Do not set REGCLS_SINGLUSE or
/// REGCLS_MULTIPLEUSE when you register a surrogate for DLL servers.
/// </para>
/// <para>
/// The following table summarizes the allowable <c>REGCLS</c> value combinations and the object registrations affected by the combinations.
/// </para>
/// <list type="table">
/// <listheader>
/// <term/>
/// <term>REGCLS_SINGLEUSE</term>
/// <term>REGCLS_MULTIPLEUSE</term>
/// <term>REGCLS_MULTI_SEPARATE</term>
/// <term>Other</term>
/// </listheader>
/// <item>
/// <term>CLSCTX_INPROC_SERVER</term>
/// <term>Error</term>
/// <term>In-process</term>
/// <term>In-process</term>
/// <term>Error</term>
/// </item>
/// <item>
/// <term>CLSCTX_LOCAL_SERVER</term>
/// <term>Local</term>
/// <term>In-process/local</term>
/// <term>Local</term>
/// <term>Error</term>
/// </item>
/// <item>
/// <term>Both of the above</term>
/// <term>Error</term>
/// <term>In-process/local</term>
/// <term>In-process/local</term>
/// <term>Error</term>
/// </item>
/// <item>
/// <term>Other</term>
/// <term>Error</term>
/// <term>Error</term>
/// <term>Error</term>
/// <term>Error</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/ne-combaseapi-tagregcls typedef enum tagREGCLS {
// REGCLS_SINGLEUSE, REGCLS_MULTIPLEUSE, REGCLS_MULTI_SEPARATE, REGCLS_SUSPENDED, REGCLS_SURROGATE, REGCLS_AGILE } REGCLS;
[PInvokeData("combaseapi.h", MSDNShortId = "16bca8e0-9999-4d51-b7f0-87deb7619d89")]
[Flags]
public enum REGCLS
{
/// <summary>
/// After an application is connected to a class object with CoGetClassObject, the class object is removed from public view so
/// that no other applications can connect to it. This value is commonly used for single document interface (SDI) applications.
/// Specifying this value does not affect the responsibility of the object application to call CoRevokeClassObject; it must
/// always call CoRevokeClassObject when it is finished with an object class.
/// </summary>
REGCLS_SINGLEUSE = 0,
/// <summary>
/// Multiple applications can connect to the class object through calls to CoGetClassObject. If both the REGCLS_MULTIPLEUSE and
/// CLSCTX_LOCAL_SERVER are set in a call to CoRegisterClassObject, the class object is also automatically registered as an
/// in-process server, whether CLSCTX_INPROC_SERVER is explicitly set.
/// </summary>
REGCLS_MULTIPLEUSE = 1,
/// <summary>
/// Useful for registering separate CLSCTX_LOCAL_SERVER and CLSCTX_INPROC_SERVER class factories through calls to
/// CoGetClassObject. If REGCLS_MULTI_SEPARATE is set, each execution context must be set separately; CoRegisterClassObject does
/// not automatically register an out-of-process server (for which CLSCTX_LOCAL_SERVER is set) as an in-process server. This
/// allows the EXE to create multiple instances of the object for in-process needs, such as self embeddings, without disturbing
/// its CLSCTX_LOCAL_SERVER registration. If an EXE registers a REGCLS_MULTI_SEPARATE class factory and a CLSCTX_INPROC_SERVER
/// class factory, instance creation calls that specify CLSCTX_INPROC_SERVER in the CLSCTX parameter executed by the EXE would
/// be satisfied locally without approaching the SCM. This mechanism is useful when the EXE uses functions such as OleCreate and
/// OleLoad to create embeddings, but at the same does not wish to launch a new instance of itself for the self-embedding case.
/// The distinction is important for embeddings because the default handler aggregates the proxy manager by default and the
/// application should override this default behavior by calling OleCreateEmbeddingHelper for the self-embedding case. If your
/// application need not distinguish between the local and inproc case, you need not register your class factory using
/// REGCLS_MULTI_SEPARATE. In fact, the application incurs an extra network round trip to the SCM when it registers its
/// MULTIPLEUSE class factory as MULTI_SEPARATE and does not register another class factory as INPROC_SERVER.
/// </summary>
REGCLS_MULTI_SEPARATE = 2,
/// <summary>
/// Suspends registration and activation requests for the specified CLSID until there is a call to CoResumeClassObjects. This is
/// used typically to register the CLSIDs for servers that can register multiple class objects to reduce the overall
/// registration time, and thus the server application startup time, by making a single call to the SCM, no matter how many
/// CLSIDs are registered for the server.
/// </summary>
REGCLS_SUSPENDED = 4,
/// <summary>
/// The class object is a surrogate process used to run DLL servers. The class factory registered by the surrogate process is
/// not the actual class factory implemented by the DLL server, but a generic class factory implemented by the surrogate. This
/// generic class factory delegates instance creation and marshaling to the class factory of the DLL server running in the
/// surrogate. For further information on DLL surrogates, see the DllSurrogate registry value.
/// </summary>
REGCLS_SURROGATE = 8,
/// <summary>
/// The class object aggregates the free-threaded marshaler and will be made visible to all inproc apartments. Can be used
/// together with other flags. For example, REGCLS_AGILE | REGCLS_MULTIPLEUSE to register a class object that can be used
/// multiple times from different apartments. Without other flags, behavior will retain REGCLS_SINGLEUSE semantics in that only
/// one instance can be generated.
/// </summary>
REGCLS_AGILE = 0x10,
}
/// <summary>Flags used by CoGetStdMarshalEx.</summary>
[PInvokeData("combaseapi.h", MSDNShortId = "405c5ff3-8702-48b3-9be9-df4a9461696e")]
public enum STDMSHLFLAGS
{
/// <summary>Indicates a client-side (handler) aggregated standard marshaler.</summary>
SMEXF_HANDLER = 0x0,
/// <summary>Indicates a server-side aggregated standard marshaler.</summary>
SMEXF_SERVER = 0x01,
}
/// <summary>Looks up a CLSID in the registry, given a ProgID.</summary>
/// <param name="lpszProgID">A pointer to the ProgID whose CLSID is requested.</param>
/// <param name="lpclsid">Receives a pointer to the retrieved CLSID on return.</param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The CLSID was retrieved successfully.</term>
/// </item>
/// <item>
/// <term>CO_E_CLASSSTRING</term>
/// <term>The registered CLSID for the ProgID is invalid.</term>
/// </item>
/// <item>
/// <term>REGDB_E_WRITEREGDB</term>
/// <term>An error occurred writing the CLSID to the registry. See Remarks below.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// Given a ProgID, <c>CLSIDFromProgID</c> looks up its associated CLSID in the registry. If the ProgID cannot be found in the
/// registry, <c>CLSIDFromProgID</c> creates an OLE 1 CLSID for the ProgID and a CLSID entry in the registry. Because of the
/// restrictions placed on OLE 1 CLSID values, <c>CLSIDFromProgID</c> and CLSIDFromString are the only two functions that can be
/// used to generate a CLSID for an OLE 1 object.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-clsidfromprogid HRESULT CLSIDFromProgID( LPCOLESTR
// lpszProgID, LPCLSID lpclsid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "89fb20af-65bf-4ed4-9f71-eb707ee8eb09")]
public static extern HRESULT CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] string lpszProgID, out Guid lpclsid);
/// <summary>
/// <para>Triggers automatic installation if the COMClassStore policy is enabled.</para>
/// <para>
/// This is analogous to the behavior of CoCreateInstance when neither CLSCTX_ENABLE_CODE_DOWNLOAD nor CLSCTX_NO_CODE_DOWNLOAD are specified.
/// </para>
/// </summary>
/// <param name="lpszProgID">A pointer to the ProgID whose CLSID is requested.</param>
/// <param name="lpclsid">Receives a pointer to the retrieved CLSID on return.</param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The CLSID was retrieved successfully.</term>
/// </item>
/// <item>
/// <term>CO_E_CLASSSTRING</term>
/// <term>The registered CLSID for the ProgID is invalid.</term>
/// </item>
/// <item>
/// <term>REGDB_E_WRITEREGDB</term>
/// <term>An error occurred writing the CLSID to the registry. See Remarks below.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// CLSCTX_ENABLE_CODE_DOWNLOAD enables automatic installation of missing classes through IntelliMirror/Application Management from
/// the Active Directory. If this flag is not specified, the COMClassStore Policy ("Download missing COM components") determines the
/// behavior (default: no download).
/// </para>
/// <para>
/// If the COMClassStore Policy enables automatic installation, CLSCTX_NO_CODE_DOWNLOAD can be used to explicitly disallow download
/// for an activation.
/// </para>
/// <para>If either of the following registry values are enabled (meaning set to 1), automatic download of missing classes is enabled:</para>
/// <list type="bullet">
/// <item>
/// <term><c>HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\App Management</c>\ <c>COMClassStore</c></term>
/// </item>
/// <item>
/// <term><c>HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\App Management</c>\ <c>COMClassStore</c></term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-clsidfromprogidex HRESULT CLSIDFromProgIDEx(
// LPCOLESTR lpszProgID, LPCLSID lpclsid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "2f937ac1-b214-482a-af4b-8cc8c0c585c3")]
public static extern HRESULT CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] string lpszProgID, out Guid lpclsid);
/// <summary>Converts a string generated by the StringFromCLSID function back into the original CLSID.</summary>
/// <param name="lpsz">The string representation of the CLSID.</param>
/// <param name="pclsid">A pointer to the CLSID.</param>
/// <returns>
/// <para>This function can return the standard return value E_INVALIDARG, as well as the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>NOERROR</term>
/// <term>The CLSID was obtained successfully.</term>
/// </item>
/// <item>
/// <term>CO_E_CLASSSTRING</term>
/// <term>The class string was improperly formatted.</term>
/// </item>
/// <item>
/// <term>REGDB_E_CLASSNOTREG</term>
/// <term>The CLSID corresponding to the class string was not found in the registry.</term>
/// </item>
/// <item>
/// <term>REGDB_E_READREGDB</term>
/// <term>The registry could not be opened for reading.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-clsidfromstring HRESULT CLSIDFromString( LPCOLESTR
// lpsz, LPCLSID pclsid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "36cc9037-480f-491f-a9bb-5aa1e707781e")]
public static extern HRESULT CLSIDFromString([MarshalAs(UnmanagedType.LPWStr)] string lpsz, out Guid pclsid);
/// <summary>Increments a global per-process reference count.</summary>
/// <returns>The current reference count.</returns>
/// <remarks>
/// <para>
/// Servers can call <c>CoAddRefServerProcess</c> to increment a global per-process reference count. This function is particularly
/// helpful to servers that are implemented with multiple threads, either multi-apartmented or free-threaded. Servers of these types
/// must coordinate the decision to shut down with activation requests across multiple threads. Calling <c>CoAddRefServerProcess</c>
/// increments a global per-process reference count, and calling CoReleaseServerProcess decrements that count.
/// </para>
/// <para>
/// When that count reaches zero, OLE automatically calls CoSuspendClassObjects, which prevents new activation requests from coming
/// in. This permits the server to deregister its class objects from its various threads without worry that another activation
/// request may come in. New activation requests result in launching a new instance of the local server process.
/// </para>
/// <para>
/// The simplest way for a local server application to make use of these functions is to call <c>CoAddRefServerProcess</c> in the
/// constructor for each of its instance objects, and in each of its IClassFactory::LockServer methods when the fLock parameter is
/// <c>TRUE</c>. The server application should also call CoReleaseServerProcess in the destruction of each of its instance objects,
/// and in each of its <c>LockServer</c> methods when the fLock parameter is <c>FALSE</c>. Finally, the server application should
/// pay attention to the return code from <c>CoReleaseServerProcess</c> and if it returns 0, the server application should initiate
/// its cleanup, which, for a server with multiple threads, typically means that it should signal its various threads to exit their
/// message loops and call CoRevokeClassObject and CoUninitialize.
/// </para>
/// <para>
/// If these functions are used at all, they must be called in both the object instances and the LockServer method, otherwise the
/// server application may be shut down prematurely. In-process servers typically should not call <c>CoAddRefServerProcess</c> or CoReleaseServerProcess.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coaddrefserverprocess ULONG CoAddRefServerProcess( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "79887f9d-cad1-492a-b406-d1753ffaf82b")]
public static extern uint CoAddRefServerProcess();
/// <summary>Adds an unmarshaler CLSID to the allowed list for the calling process only.</summary>
/// <param name="clsid">The CLSID of the unmarshaler to be added to the per-process allowed list.</param>
/// <returns>If this function succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</returns>
/// <remarks>
/// <para>
/// Don't call the <c>CoAllowUnmarshalerCLSID</c> function until after CoInitializeSecurity has been called in the current process.
/// </para>
/// <para>
/// The <c>CoAllowUnmarshalerCLSID</c> function provides more granular control over unmarshaling policy than is provided by the
/// policy options. If the process applies any unmarshaling policy, the effect of the <c>CoAllowUnmarshalerCLSID</c> function is to
/// make the policy comparatively weaker. For this reason, only call <c>CoAllowUnmarshalerCLSID</c> when the security impact is well
/// understood. Usually, this is used to facilitate applying a stronger unmarshaling policy option for the broad attack surface
/// reduction this provides, when a specific unmarshaler CLSID not allowed by that option is needed due to other constraints.
/// </para>
/// <para>
/// For example, it's appropriate to call the <c>CoAllowUnmarshalerCLSID</c> function when an unmarshaler is known or believed to
/// have a vulnerability but is required by an app. Also, it's appropriate to call <c>CoAllowUnmarshalerCLSID</c> if the unmarshaler
/// is used in multiple processes, but only as part of an uncommon feature. Don't use the <c>CoAllowUnmarshalerCLSID</c> function as
/// a replacement for hardening the unmarshaler.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coallowunmarshalerclsid HRESULT
// CoAllowUnmarshalerCLSID( REFCLSID clsid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "4655C6B6-02CE-42B2-A157-0C0325D1BE52")]
public static extern HRESULT CoAllowUnmarshalerCLSID(in Guid clsid);
/// <summary>Requests cancellation of an outbound DCOM method call pending on a specified thread.</summary>
/// <param name="dwThreadId">
/// The identifier of the thread on which the pending DCOM call is to be canceled. If this parameter is 0, the call is on the
/// current thread.
/// </param>
/// <param name="ulTimeout">
/// The number of seconds <c>CoCancelCall</c> waits for the server to complete the outbound call after the client requests cancellation.
/// </param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The cancellation request was made.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>There is no cancel object corresponding to the specified thread.</term>
/// </item>
/// <item>
/// <term>CO_E_CANCEL_DISABLED</term>
/// <term>Call cancellation is not enabled on the specified thread.</term>
/// </item>
/// <item>
/// <term>RPC_E_CALL_COMPLETE</term>
/// <term>The call was completed during the timeout interval.</term>
/// </item>
/// <item>
/// <term>RPC_E_CALL_CANCELED</term>
/// <term>The call was already canceled.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>CoCancelCall</c> calls CoGetCancelObject and then ICancelMethodCalls::Cancel on the cancel object for the call being executed.
/// </para>
/// <para>This function does not locate cancel objects for asynchronous calls.</para>
/// <para>
/// The object server can determine if the call has been canceled by periodically calling CoTestCancel. If the call has been
/// canceled, the object server should clean up and return control to the client.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocancelcall HRESULT CoCancelCall( DWORD
// dwThreadId, ULONG ulTimeout );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "1707261c-2d8d-4f35-865d-61c8870c0624")]
public static extern HRESULT CoCancelCall(uint dwThreadId, uint ulTimeout);
/// <summary>Makes a private copy of the specified proxy.</summary>
/// <param name="pProxy">A pointer to the IUnknown interface on the proxy to be copied. This parameter cannot be <c>NULL</c>.</param>
/// <param name="ppCopy">
/// Address of the pointer variable that receives the interface pointer to the copy of the proxy. This parameter cannot be <c>NULL</c>.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>Indicates success.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>One or more arguments are invalid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>CoCopyProxy</c> makes a private copy of the specified proxy. Typically, this function is called when a client needs to change
/// the authentication information of its proxy through a call to either CoSetProxyBlanket or IClientSecurity::SetBlanket without
/// changing this information for other clients. <c>CoSetProxyBlanket</c> affects all the users of an instance of a proxy, so
/// creating a private copy of the proxy through a call to <c>CoCopyProxy</c> and then calling <c>CoSetProxyBlanket</c> (or
/// <c>IClientSecurity::SetBlanket</c>) using the copy eliminates the problem.
/// </para>
/// <para>This helper function encapsulates the following sequence of common calls (error handling excluded):</para>
/// <para>Local interfaces may not be copied. IUnknown and IClientSecurity are examples of existing local interfaces.</para>
/// <para>
/// Copies of the same proxy have a special relationship with respect to QueryInterface. Given a proxy, a, of the IA interface of a
/// remote object, suppose a copy of a is created, called b. In this case, calling <c>QueryInterface</c> from the b proxy for IID_IA
/// will not retrieve the IA interface on b, but the one on a, the original proxy with the "default" security settings for the IA interface.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocopyproxy HRESULT CoCopyProxy( IUnknown *pProxy,
// IUnknown **ppCopy );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "26de7bac-8745-40c0-be0a-dcec88a3ecaf")]
public static extern HRESULT CoCopyProxy([MarshalAs(UnmanagedType.IUnknown)] object pProxy, [MarshalAs(UnmanagedType.IUnknown)] out object ppCopy);
/// <summary>Creates an aggregatable object capable of context-dependent marshaling.</summary>
/// <param name="punkOuter">A pointer to the aggregating object's controlling IUnknown.</param>
/// <param name="ppunkMarshal">Address of the pointer variable that receives the interface pointer to the aggregatable marshaler.</param>
/// <returns>
/// <para>This function can return the standard return value E_OUTOFMEMORY, as well as the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The marshaler was created.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CoCreateFreeThreadedMarshaler</c> function enables an object to efficiently marshal interface pointers between threads in
/// the same process. If your objects do not support interthread marshaling, you have no need to call this function. It is intended
/// for use by free-threaded DLL servers that must be accessed directly by all threads in a process, even those threads associated
/// with single-threaded apartments. It custom-marshals the real memory pointer over into other apartments as a bogus "proxy" and
/// thereby gives direct access to all callers, even if they are not free-threaded.
/// </para>
/// <para>The <c>CoCreateFreeThreadedMarshaler</c> function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>Creates a free-threaded marshaler object.</term>
/// </item>
/// <item>
/// <term>
/// Aggregates this marshaler to the object specified by the punkOuter parameter. This object is normally the one whose interface
/// pointers are to be marshaled.
/// </term>
/// </item>
/// </list>
/// <para>
/// The aggregating object's implementation of IMarshal should delegate QueryInterface calls for IID_IMarshal to the IUnknown of the
/// free-threaded marshaler. Upon receiving a call, the free-threaded marshaler performs the following tasks:
/// </para>
/// <list type="number">
/// <item>
/// <term>Checks the destination context specified by the CoMarshalInterface function's dwDestContext parameter.</term>
/// </item>
/// <item>
/// <term>If the destination context is MSHCTX_INPROC, copies the interface pointer into the marshaling stream.</term>
/// </item>
/// <item>
/// <term>
/// If the destination context is any other value, finds or creates an instance of COM's default (standard) marshaler and delegates
/// marshaling to it.
/// </term>
/// </item>
/// </list>
/// <para>
/// Values for dwDestContext come from the MSHCTX enumeration. MSHCTX_INPROC indicates that the interface pointer is to be marshaled
/// between different threads in the same process. Because both threads have access to the same address space, the client thread can
/// dereference the pointer directly rather than having to direct calls to a proxy. In all other cases, a proxy is required, so
/// <c>CoCreateFreeThreadedMarshaler</c> delegates the marshaling job to COM's default implementation.
/// </para>
/// <para>
/// Great care should be exercised in using the <c>CoCreateFreeThreadedMarshaler</c> function. This is because the performance of
/// objects which aggregate the free-threaded marshaler is obtained through a calculated violation of the rules of COM, with the
/// ever-present risk of undefined behavior unless the object operates within certain restrictions. The most important restrictions are:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// A free-threaded marshaler object cannot hold direct pointers to interfaces on an object that does not aggregate the
/// free-threaded marshaler as part of its state. If the object were to use direct references to ordinary single-threaded aggregate
/// objects, it may break their single threaded property. If the object were to use direct references to ordinary multithreaded
/// aggregate objects, these objects can behave in ways that show no sensitivity to the needs of direct single-threaded aggregate
/// clients. For example, these objects can spin new threads and pass parameters to the threads that are references to ordinary
/// single-threaded aggregate objects.
/// </term>
/// </item>
/// <item>
/// <term>
/// A free-threaded marshaler object cannot hold references to proxies to objects in other apartments. Proxies are sensitive to the
/// threading model and can return RPC_E_WRONG_THREAD if called by the wrong client.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocreatefreethreadedmarshaler HRESULT
// CoCreateFreeThreadedMarshaler( LPUNKNOWN punkOuter, LPUNKNOWN *ppunkMarshal );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "f97a2a39-7291-4a1d-b770-0a34f7f5b60f")]
public static extern HRESULT CoCreateFreeThreadedMarshaler([MarshalAs(UnmanagedType.IUnknown)] object punkOuter, [MarshalAs(UnmanagedType.IUnknown)] out object ppunkMarshal);
/// <summary>Creates a GUID, a unique 128-bit integer used for CLSIDs and interface identifiers.</summary>
/// <param name="pguid">A pointer to the requested GUID.</param>
/// <returns>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The GUID was successfully created.</term>
/// </item>
/// </list>
/// <para>Errors returned by UuidCreate are wrapped as an <c>HRESULT</c>.</para>
/// </returns>
/// <remarks>
/// The <c>CoCreateGuid</c> function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use
/// <c>CoCreateGuid</c> when you need an absolutely unique number that you will use as a persistent identifier in a distributed
/// environment.To a very high degree of certainty, this function returns a unique value no other invocation, on the same or any
/// other system (networked or not), should return the same value.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateguid HRESULT CoCreateGuid( GUID *pguid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "8d5cedea-8c2b-4918-99db-1a000989f178")]
public static extern HRESULT CoCreateGuid(out Guid pguid);
/// <summary>
/// <para>Creates a single uninitialized object of the class associated with a specified CLSID.</para>
/// <para>
/// Call <c>CoCreateInstance</c> when you want to create only one object on the local system. To create a single object on a remote
/// system, call the CoCreateInstanceEx function. To create multiple objects based on a single CLSID, call the CoGetClassObject function.
/// </para>
/// </summary>
/// <param name="rclsid">The CLSID associated with the data and code that will be used to create the object.</param>
/// <param name="pUnkOuter">
/// If <c>NULL</c>, indicates that the object is not being created as part of an aggregate. If non- <c>NULL</c>, pointer to the
/// aggregate object's IUnknown interface (the controlling <c>IUnknown</c>).
/// </param>
/// <param name="dwClsContext">
/// Context in which the code that manages the newly created object will run. The values are taken from the enumeration CLSCTX.
/// </param>
/// <param name="riid">A reference to the identifier of the interface to be used to communicate with the object.</param>
/// <param name="ppv">
/// Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the
/// requested interface pointer. Upon failure, *ppv contains <c>NULL</c>.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>An instance of the specified object class was successfully created.</term>
/// </item>
/// <item>
/// <term>REGDB_E_CLASSNOTREG</term>
/// <term>
/// A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the
/// CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt.
/// </term>
/// </item>
/// <item>
/// <term>CLASS_E_NOAGGREGATION</term>
/// <term>This class cannot be created as part of an aggregate.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>
/// The specified class does not implement the requested interface, or the controlling IUnknown does not expose the requested interface.
/// </term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The ppv parameter is NULL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CoCreateInstance</c> function provides a convenient shortcut by connecting to the class object associated with the
/// specified CLSID, creating an uninitialized instance, and releasing the class object. As such, it encapsulates the following functionality:
/// </para>
/// <para>
/// It is convenient to use <c>CoCreateInstance</c> when you need to create only a single instance of an object on the local
/// machine. If you are creating an instance on remote computer, call CoCreateInstanceEx. When you are creating multiple instances,
/// it is more efficient to obtain a pointer to the class object's IClassFactory interface and use its methods as needed. In the
/// latter case, you should use the CoGetClassObject function.
/// </para>
/// <para>
/// In the CLSCTX enumeration, you can specify the type of server used to manage the object. The constants can be
/// CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER or any combination of these values. The
/// constant CLSCTX_ALL is defined as the combination of all four. For more information about the use of one or a combination of
/// these constants, see CLSCTX.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocreateinstance HRESULT CoCreateInstance( REFCLSID
// rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "7295a55b-12c7-4ed0-a7a4-9ecee16afdec")]
public static extern HRESULT CoCreateInstance(in Guid rclsid, [MarshalAs(UnmanagedType.IUnknown), Optional] object pUnkOuter,
CLSCTX dwClsContext, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 3)] out object ppv);
/// <summary>
/// <para>Creates an instance of a specific class on a specific computer.</para>
/// </summary>
/// <param name="Clsid">
/// <para>The CLSID of the object to be created.</para>
/// </param>
/// <param name="punkOuter">
/// <para>
/// If this parameter non- <c>NULL</c>, indicates the instance is being created as part of an aggregate, and punkOuter is to be used
/// as the new instance's controlling IUnknown. Aggregation is currently not supported cross-process or cross-computer. When
/// instantiating an object out of process, CLASS_E_NOAGGREGATION will be returned if punkOuter is non- <c>NULL</c>.
/// </para>
/// </param>
/// <param name="dwClsCtx">
/// <para>A value from the CLSCTX enumeration.</para>
/// </param>
/// <param name="pServerInfo">
/// <para>
/// Information about the computer on which to instantiate the object. See COSERVERINFO. This parameter can be <c>NULL</c>, in which
/// case the object is instantiated on the local computer or at the computer specified in the registry under the class's
/// RemoteServerName value, according to the interpretation of the dwClsCtx parameter.
/// </para>
/// </param>
/// <param name="dwCount">
/// <para>The number of structures in pResults. This value must be greater than 0.</para>
/// </param>
/// <param name="pResults">
/// <para>
/// An array of MULTI_QI structures. Each structure has three members: the identifier for a requested interface ( <c>pIID</c>), the
/// location to return the interface pointer ( <c>pItf</c>) and the return value of the call to QueryInterface ( <c>hr</c>).
/// </para>
/// </param>
/// <returns>
/// <para>This function can return the standard return value E_INVALIDARG, as well as the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>Indicates success.</term>
/// </item>
/// <item>
/// <term>REGDB_E_CLASSNOTREG</term>
/// <term>
/// A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the
/// CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt.
/// </term>
/// </item>
/// <item>
/// <term>CLASS_E_NOAGGREGATION</term>
/// <term>This class cannot be created as part of an aggregate.</term>
/// </item>
/// <item>
/// <term>CO_S_NOTALLINTERFACES</term>
/// <term>
/// At least one, but not all of the interfaces requested in the pResults array were successfully retrieved. The hr member of each
/// of the MULTI_QI structures in pResults indicates with S_OK or E_NOINTERFACE whether the specific interface was returned.
/// </term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>None of the interfaces requested in the pResults array were successfully retrieved.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>CoCreateInstanceEx</c> creates a single uninitialized object associated with the given CLSID on a specified remote computer.
/// This is an extension of the function CoCreateInstance, which creates an object on the local computer only. In addition, rather
/// than requesting a single interface and obtaining a single pointer to that interface, <c>CoCreateInstanceEx</c> makes it possible
/// to specify an array of structures, each pointing to an interface identifier (IID) on input, and, on return, containing (if
/// available) a pointer to the requested interface and the return value of the QueryInterface call for that interface. This permits
/// fewer round trips between computers.
/// </para>
/// <para>
/// This function encapsulates three calls: first, to CoGetClassObject to connect to the class object associated with the specified
/// CLSID, specifying the location of the class; second, to IClassFactory::CreateInstance to create an uninitialized instance, and
/// finally, to IClassFactory::Release, to release the class object.
/// </para>
/// <para>
/// The object so created must still be initialized through a call to one of the initialization interfaces (such as
/// IPersistStorage::Load). Two functions, CoGetInstanceFromFile and CoGetInstanceFromIStorage encapsulate both the instance
/// creation and initialization from the obvious sources.
/// </para>
/// <para>
/// The COSERVERINFO structure passed as the pServerInfo parameter contains the security settings that COM will use when creating a
/// new instance of the specified object. Note that this parameter does not influence the security settings used when making method
/// calls on the instantiated object. Those security settings are configurable, on a per-interface basis, with the CoSetProxyBlanket
/// function. Also see, IClientSecurity::SetBlanket.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocreateinstanceex HRESULT CoCreateInstanceEx(
// REFCLSID Clsid, IUnknown *punkOuter, DWORD dwClsCtx, COSERVERINFO *pServerInfo, DWORD dwCount, MULTI_QI *pResults );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "3b414b95-e8d2-42e8-b4f2-5cc5189a3d08")]
public static extern HRESULT CoCreateInstanceEx(in Guid Clsid, [MarshalAs(UnmanagedType.IUnknown), Optional] object punkOuter,
CLSCTX dwClsCtx, [Optional] COSERVERINFO pServerInfo, uint dwCount,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] MULTI_QI[] pResults);
/// <summary>Creates an instance of a specific class on a specific computer from within an app container.</summary>
/// <param name="Clsid">The CLSID of the object to be created.</param>
/// <param name="punkOuter">
/// If this parameter non- <c>NULL</c>, indicates the instance is being created as part of an aggregate, and punkOuter is to be used
/// as the new instance's controlling IUnknown. Aggregation is currently not supported cross-process or cross-computer. When
/// instantiating an object out of process, CLASS_E_NOAGGREGATION will be returned if punkOuter is non- <c>NULL</c>.
/// </param>
/// <param name="dwClsCtx">A value from the CLSCTX enumeration.</param>
/// <param name="reserved">Reserved for future use.</param>
/// <param name="dwCount">The number of structures in pResults. This value must be greater than 0.</param>
/// <param name="pResults">
/// An array of MULTI_QI structures. Each structure has three members: the identifier for a requested interface ( <c>pIID</c>), the
/// location to return the interface pointer ( <c>pItf</c>) and the return value of the call to QueryInterface ( <c>hr</c>).
/// </param>
/// <returns>
/// <para>This function can return the standard return value E_INVALIDARG, as well as the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>Indicates success.</term>
/// </item>
/// <item>
/// <term>REGDB_E_CLASSNOTREG</term>
/// <term>
/// A specified class is not registered in the registration database, or the class is not supported in the app container. Also can
/// indicate that the type of server you requested in the CLSCTX enumeration is not registered or the values for the server types in
/// the registry are corrupt.
/// </term>
/// </item>
/// <item>
/// <term>CLASS_E_NOAGGREGATION</term>
/// <term>This class cannot be created as part of an aggregate.</term>
/// </item>
/// <item>
/// <term>CO_S_NOTALLINTERFACES</term>
/// <term>
/// At least one, but not all of the interfaces requested in the pResults array were successfully retrieved. The hr member of each
/// of the MULTI_QI structures in pResults indicates with S_OK or E_NOINTERFACE whether the specific interface was returned.
/// </term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>None of the interfaces requested in the pResults array were successfully retrieved.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>CoCreateInstanceFromApp</c> function is the same as the CoCreateInstanceEx function, with the following differences.</para>
/// <list type="bullet">
/// <item>
/// <term>
/// The <c>CoCreateInstanceFromApp</c> function reads class registrations only from application contexts, and from the
/// HKLM\SOFTWARE\Classes\CLSID registry hive.
/// </term>
/// </item>
/// <item>
/// <term>
/// Only built-in classes that are supported in the app container are supplied. Attempts to activate unsupported classes, including
/// all classes installed by 3rd-party code as well as many Windows classes, result in error code <c>REGDB_E_CLASSNOTREG</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// The <c>CoCreateInstanceFromApp</c> function is available to Windows Store apps. Desktop applications can call this function, but
/// they have the same restrictions as Windows Store apps.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocreateinstancefromapp HRESULT
// CoCreateInstanceFromApp( REFCLSID Clsid, IUnknown *punkOuter, DWORD dwClsCtx, PVOID reserved, DWORD dwCount, MULTI_QI *pResults );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "1C773D78-5B33-44FE-A09B-AB8087F678A1")]
public static extern HRESULT CoCreateInstanceFromApp(in Guid Clsid, [MarshalAs(UnmanagedType.IUnknown)] object punkOuter, uint dwClsCtx, IntPtr reserved, uint dwCount, ref MULTI_QI pResults);
/// <summary>
/// Locates the implementation of a Component Object Model (COM) interface in a server process given an interface to a proxied object.
/// </summary>
/// <param name="dwClientPid">The process ID of the process that contains the proxy.</param>
/// <param name="ui64ProxyAddress">
/// The address of an interface on a proxy to the object. ui64ProxyAddress is considered a 64-bit value type, rather than a pointer
/// to a 64-bit value, and isn't a pointer to an object in the debugger process. Instead, this address is passed to the
/// ReadProcessMemory function.
/// </param>
/// <param name="pServerInformation">A structure that contains the process ID, the thread ID, and the address of the server.</param>
/// <returns>
/// <para>This function can return one of these values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The server information was successfully retrieved.</term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The caller is an app container, or the developer license is not installed.</term>
/// </item>
/// <item>
/// <term>RPC_E_INVALID_IPID</term>
/// <term>ui64ProxyAddress does not point to a proxy.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CoDecodeProxy</c> function is a COM API that enables native debuggers to locate the implementation of a COM interface in
/// a server process given an interface on a proxy to the object.
/// </para>
/// <para>
/// Also, the <c>CoDecodeProxy</c> function enables the debugger to monitor cross-apartment function calls and fail such calls when appropriate.
/// </para>
/// <para>
/// You can call the <c>CoDecodeProxy</c> function from a 32-bit or 64-bit process. ui64ProxyAddress can be a 32-bit or 64-bit
/// address. The <c>CoDecodeProxy</c> function returns a 32-bit or 64-bit address in the pServerInformation field. If it returns a
/// 64-bit address, you should pass the address to the ReadProcessMemory function only from a 64-bit process.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-codecodeproxy HRESULT CoDecodeProxy( DWORD
// dwClientPid, UINT64 ui64ProxyAddress, PServerInformation pServerInformation );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "C61C68B1-78CA-4052-9E24-629AB4083B86")]
public static extern HRESULT CoDecodeProxy(uint dwClientPid, ulong ui64ProxyAddress, IntPtr pServerInformation);
/// <summary>Releases the increment made by a previous call to the CoIncrementMTAUsage function.</summary>
/// <param name="Cookie">A <c>PVOID</c> variable that was set by a previous call to the CoIncrementMTAUsage function.</param>
/// <returns>If this function succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</returns>
/// <remarks>
/// <para>
/// Cookie must be a valid value returned by a successful previous call to the CoIncrementMTAUsage function. If the overall count of
/// MTA usage reaches 0, including both through this API and through the CoInitializeEx and CoUninitialize functions, the system
/// frees resources related to MTA support.
/// </para>
/// <para>
/// You can call CoIncrementMTAUsage from one thread and <c>CoDecrementMTAUsage</c> from another as long as a cookie previously
/// returned by <c>CoIncrementMTAUsage</c> is passed to <c>CoDecrementMTAUsage</c>.
/// </para>
/// <para>
/// Don't call <c>CoDecrementMTAUsage</c> during process shutdown or inside dllmain. You can call <c>CoDecrementMTAUsage</c> before
/// the call to start the shutdown process.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-codecrementmtausage HRESULT CoDecrementMTAUsage(
// CO_MTA_USAGE_COOKIE Cookie );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "66AA2783-7F24-41BB-911B-D452DF54C003")]
public static extern HRESULT CoDecrementMTAUsage(CO_MTA_USAGE_COOKIE Cookie);
/// <summary>
/// Undoes the action of a call to CoEnableCallCancellation. Disables cancellation of synchronous calls on the calling thread when
/// all calls to <c>CoEnableCallCancellation</c> are balanced by calls to <c>CoDisableCallCancellation</c>.
/// </summary>
/// <param name="pReserved">This parameter is reserved and must be <c>NULL</c>.</param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>Call cancellation was successfully disabled on the thread.</term>
/// </item>
/// <item>
/// <term>CO_E_CANCEL_DISABLED</term>
/// <term>
/// There have been more successful calls to CoEnableCallCancellation on the thread than there have been calls to
/// CoDisableCallCancellation. Cancellation is still enabled on the thread.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// When call cancellation is enabled on a thread, marshaled synchronous calls from that thread to objects on the same computer can
/// suffer serious performance degradation. By default, then, synchronous calls cannot be canceled, even if a cancel object is
/// available. To enable call cancellation, you must call CoEnableCallCancellation first.
/// </para>
/// <para>
/// When call cancellation is disabled, attempts to gain a pointer to a call object will fail. If the calling thread already has a
/// pointer to a call object, calls on that object will fail.
/// </para>
/// <para>
/// Unless you want to enable call cancellation on a thread at all times, you should pair calls to CoEnableCallCancellation with
/// calls to <c>CoDisableCallCancellation</c>. Call cancellation is disabled only if each successful call to
/// <c>CoEnableCallCancellation</c> is balanced by a successful call to <c>CoDisableCallCancellation</c>.
/// </para>
/// <para>
/// A call will be cancelable or not depending on the state of the thread at the time the call was made. Subsequently enabling or
/// disabling call cancellation has no effect on any calls that are pending on the thread.
/// </para>
/// <para>
/// If a thread is uninitialized and then reinitialized by calls to CoUninitialize and CoInitialize, call cancellation is disabled
/// on the thread, even if it was enabled when the thread was uninitialized.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-codisablecallcancellation HRESULT
// CoDisableCallCancellation( LPVOID pReserved );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "33d99eab-a0bf-4e4d-93a4-5c03c41cebbb")]
public static extern HRESULT CoDisableCallCancellation([Optional] IntPtr pReserved);
/// <summary>
/// <para>
/// Disconnects all proxy connections that are being maintained on behalf of all interface pointers that point to objects in the
/// current context.
/// </para>
/// <para>
/// This function blocks connections until all objects are successfully disconnected or the time-out expires. Only the context that
/// actually manages the objects should call <c>CoDisconnectContext</c>.
/// </para>
/// </summary>
/// <param name="dwTimeout">
/// The time in milliseconds after which <c>CoDisconnectContext</c> returns even if the proxy connections for all objects have not
/// been disconnected. INFINITE is an acceptable value for this parameter.
/// </param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_INVALIDARG, and E_OUTOFMEMORY, as well as the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The proxy connections for all objects were successfully disconnected.</term>
/// </item>
/// <item>
/// <term>RPC_E_TIMEOUT</term>
/// <term>Not all proxy connections were successfully deleted in the time specified in dwTimeout.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTSUPPORTED</term>
/// <term>The current context cannot be disconnected.</term>
/// </item>
/// <item>
/// <term>CONTEXT_E_WOULD_DEADLOCK</term>
/// <term>
/// An object tried to call CoDisconnectContext on the context it is residing in. This would cause the function to time-out and
/// deadlock if dwTimeout were set to INFINITE.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CoDisconnectContext</c> function is used to support unloading services in shared service hosts where you must unload your
/// service's binaries without affecting other COM servers that are running in the same process. If you control the process lifetime
/// and you do not unload until the process exits, the COM infrastructure will perform the necessary cleanup automatically and you
/// do not have to call this function.
/// </para>
/// <para>
/// The <c>CoDisconnectContext</c> function enables a server to correctly disconnect all external clients of all objects in the
/// current context. Default contexts cannot be disconnected. To use <c>CoDisconnectContext</c>, you must first create a context
/// that can be disconnected and register your class factories for objects from which you want to disconnect within that context.
/// You can do this with the IContextCallback interface.
/// </para>
/// <para>
/// If <c>CoDisconnectContext</c> returns RPC_E_TIMEOUT, this does not indicate that the function did not disconnect the objects,
/// but that not all disconnections could be completed in the time specified by dwTimeout because of outstanding calls on the
/// objects. All objects will be disconnected after all calls on them have been completed.
/// </para>
/// <para>
/// It is not safe to unload the DLL that hosts the service until <c>CoDisconnectContext</c> returns S_OK. If the function returns
/// RPC_E_TIMEOUT, the service may perform other clean-up. The service must call the function until it returns S_OK, and then it can
/// safely unload its DLL.
/// </para>
/// <para>The <c>CoDisconnectContext</c> function performs the following tasks:</para>
/// <list type="bullet">
/// <item>
/// <term>Calls CoDisconnectObject on all objects in the current context.</term>
/// </item>
/// <item>
/// <term>Blocks until all objects have been disconnected or the time-out has expired.</term>
/// </item>
/// </list>
/// <para>The <c>CoDisconnectContext</c> function has the following limitations:</para>
/// <list type="bullet">
/// <item>
/// <term>Asynchronous COM calls are not supported.</term>
/// </item>
/// <item>
/// <term>In-process objects must be registered and enabled using the CLSCTX_LOCAL_SERVER flag, or they will not be disconnected.</term>
/// </item>
/// <item>
/// <term>COM+ is not supported.</term>
/// </item>
/// <item>
/// <term>
/// COM interface pointers are context-sensitive. Therefore, any interface pointer created in the context to be disconnected can
/// only be used within that context.
/// </term>
/// </item>
/// </list>
/// <para>Examples</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-codisconnectcontext HRESULT CoDisconnectContext(
// DWORD dwTimeout );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "faacb583-285a-4ec6-9700-22320e87de6e")]
public static extern HRESULT CoDisconnectContext(uint dwTimeout);
/// <summary>
/// <para>
/// Disconnects all remote process connections being maintained on behalf of all the interface pointers that point to a specified object.
/// </para>
/// <para>Only the process that actually manages the object should call <c>CoDisconnectObject</c>.</para>
/// </summary>
/// <param name="pUnk">A pointer to any interface derived from IUnknown on the object to be disconnected.</param>
/// <param name="dwReserved">This parameter is reserved and must be 0.</param>
/// <returns>This function returns S_OK to indicate that all connections to remote processes were successfully deleted.</returns>
/// <remarks>
/// <para>
/// The <c>CoDisconnectObject</c> function enables a server to correctly disconnect all external clients to the object specified by pUnk.
/// </para>
/// <para>It performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>
/// Checks to see whether the object to be disconnected implements the IMarshal interface. If so, it gets the pointer to that
/// interface; if not, it gets a pointer to the standard marshaler's (i.e., COM's) <c>IMarshal</c> implementation.
/// </term>
/// </item>
/// <item>
/// <term>
/// Using whichever IMarshal interface pointer it has acquired, the function then calls IMarshal::DisconnectObject to disconnect all
/// out-of-process clients.
/// </term>
/// </item>
/// </list>
/// <para>
/// An object's client does not call <c>CoDisconnectObject</c> to disconnect itself from the server (clients should use
/// IUnknown::Release for this purpose). Rather, an OLE server calls <c>CoDisconnectObject</c> to forcibly disconnect an object's
/// clients, usually in response to a user closing the server application.
/// </para>
/// <para>
/// Similarly, an OLE container that supports external links to its embedded objects can call <c>CoDisconnectObject</c> to destroy
/// those links. Again, this call is normally made in response to a user closing the application. The container should first call
/// IOleObject::Close for all its OLE objects, each of which should send IAdviseSink::OnClose notifications to their various
/// clients. Then the container can call <c>CoDisconnectObject</c> to close any existing connections.
/// </para>
/// <para>
/// <c>CoDisconnectObject</c> does not necessarily disconnect out-of-process clients immediately. If any marshaled calls are pending
/// on the server object, <c>CoDisconnectObject</c> disconnects the object only when those calls have returned. In the meantime,
/// <c>CoDisconnectObject</c> sets a flag that causes any new marshaled calls to return CO_E_OBJNOTCONNECTED.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-codisconnectobject HRESULT CoDisconnectObject(
// LPUNKNOWN pUnk, DWORD dwReserved );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "4293316a-bafe-4fca-ad6a-68d8e99c8fba")]
public static extern HRESULT CoDisconnectObject([MarshalAs(UnmanagedType.IUnknown)] object pUnk, uint dwReserved = 0);
/// <summary>Enables cancellation of synchronous calls on the calling thread.</summary>
/// <param name="pReserved">This parameter is reserved and must be <c>NULL</c>.</param>
/// <returns>This function can return the standard return values S_OK, E_FAIL, E_INVALIDARG, and E_OUTOFMEMORY.</returns>
/// <remarks>
/// <para>
/// When call cancellation is enabled on a thread, marshaled synchronous calls from that thread to objects on the same computer can
/// suffer serious performance degradation. By default, synchronous calls cannot be canceled, even if a cancel object is available.
/// To enable call cancellation, you must call <c>CoEnableCallCancellation</c> first.
/// </para>
/// <para>
/// Unless you want to enable call cancellation on a thread at all times, you should pair calls to <c>CoEnableCallCancellation</c>
/// with calls to CoDisableCallCancellation. Call cancellation is disabled only if <c>CoDisableCallCancellation</c> has been called
/// once for each time <c>CoEnableCallCancellation</c> was called successfully.
/// </para>
/// <para>
/// A call will be cancelable or not depending on the state of the thread at the time the call was made. Subsequently enabling or
/// disabling call cancellation has no effect on any calls that are pending on the thread.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coenablecallcancellation HRESULT
// CoEnableCallCancellation( LPVOID pReserved );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "59b66f33-486e-49c3-9fb8-0eab93146ed9")]
public static extern HRESULT CoEnableCallCancellation(IntPtr pReserved = default);
/// <summary>
/// <para>Returns the current time as a FILETIME structure.</para>
/// <para><c>Note</c> This function is provided for compatibility with 16-bit Windows.</para>
/// </summary>
/// <param name="lpFileTime">A pointer to the FILETIME structure that receives the current time.</param>
/// <returns>This function returns S_OK to indicate success.</returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cofiletimenow HRESULT CoFileTimeNow( FILETIME
// *lpFileTime );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "00083429-1d61-4a0b-bb73-82158869466d")]
public static extern HRESULT CoFileTimeNow(out FILETIME lpFileTime);
/// <summary>
/// <para>Unloads any DLLs that are no longer in use, probably because the DLL no longer has any instantiated COM objects outstanding.</para>
/// <para><c>Note</c> This function is provided for compatibility with 16-bit Windows.</para>
/// </summary>
/// <remarks>
/// Applications can call <c>CoFreeUnusedLibraries</c> periodically to free resources. It is most efficient to call it either at the
/// top of a message loop or in some idle-time task. <c>CoFreeUnusedLibraries</c> internally calls DllCanUnloadNow for DLLs that
/// implement and export that function.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cofreeunusedlibraries void CoFreeUnusedLibraries( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "188e9a3b-39cc-454e-af65-4ac797e275d4")]
public static extern void CoFreeUnusedLibraries();
/// <summary>Unloads any DLLs that are no longer in use and whose unload delay has expired.</summary>
/// <param name="dwUnloadDelay">
/// The delay in milliseconds between the time that the DLL has stated it can be unloaded until it becomes a candidate to unload.
/// Setting this parameter to INFINITE uses the system default delay (10 minutes). Setting this parameter to 0 forces the unloading
/// of any DLLs without any delay.
/// </param>
/// <param name="dwReserved">This parameter is reserved and must be 0.</param>
/// <remarks>
/// <para>
/// COM supplies functions to reclaim memory held by DLLs containing components. The most commonly used function is
/// CoFreeUnusedLibraries. <c>CoFreeUnusedLibraries</c> does not immediately release DLLs that have no active object. There is a
/// 10-minute delay for multithreaded apartments (MTAs) and neutral apartments (NAs). For single-threaded apartments (STAs), there
/// is no delay.
/// </para>
/// <para>
/// The 10-minute delay for CoFreeUnusedLibraries is to avoid multithread race conditions caused by unloading a component DLL. This
/// default delay may be too long for many applications.
/// </para>
/// <para>
/// COM maintains a list of active DLLs that have had components loaded for the apartments that can be hosted on the thread where
/// this function is called. When <c>CoFreeUnusedLibrariesEx</c> is called, each DLL on that list has its DllCanUnloadNow function
/// called. If <c>DllCanUnloadNow</c> returns S_FALSE (or is not exported), this DLL is not ready to be unloaded. If
/// <c>DllCanUnloadNow</c> returns S_OK, this DLL is moved off the active list to a "candidate-for-unloading" list.
/// </para>
/// <para>
/// Adding the DLL to the candidate-for-unloading list time-stamps the DLL dwUnloadDelay milliseconds from when this move occurs.
/// When <c>CoFreeUnusedLibrariesEx</c> (or CoFreeUnusedLibraries) is called again, at least dwUnloadDelay milliseconds from the
/// call that moved the DLL to the candidate-for-unloading list, the DLL is actually freed from memory. If COM uses the component
/// DLL while the DLL is on the candidate-for-unloading list, it is moved back to the active list.
/// </para>
/// <para>
/// Setting dwUnloadDelay to 0 may have unexpected consequences. The component DLL may need some time for cleanup after it returns
/// from the DllCanUnloadNow function. For example, if the DLL had its own worker threads, using a value of 0 would most likely lead
/// to a problem because the code executing on these threads would be unmapped, caused by the unloading of the DLL before the worker
/// threads have a chance to exit. Also, using too brief of a value for dwUnloadDelay can lead to performance issues because there
/// is more overhead in reloading a DLL than letting it page out.
/// </para>
/// <para>
/// This behavior is triggered by the DLL supplying components with threading models set to Free, Neutral, or Both. For a threading
/// model set to Apartment (or if no threading model is specified), dwUnloadDelay is treated as 0 because these components are tied
/// to the single thread hosting the apartment.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cofreeunusedlibrariesex void
// CoFreeUnusedLibrariesEx( DWORD dwUnloadDelay, DWORD dwReserved );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "01660e9d-d8f2-40ef-a6d6-b80f0140ab5f")]
public static extern void CoFreeUnusedLibrariesEx(uint dwUnloadDelay, uint dwReserved = 0);
/// <summary>Returns the current apartment type and type qualifier.</summary>
/// <param name="pAptType">APTTYPE enumeration value that specifies the type of the current apartment.</param>
/// <param name="pAptQualifier">APTTYPEQUALIFIER enumeration value that specifies the type qualifier of the current apartment.</param>
/// <returns>
/// <para>Returns S_OK if the call succeeded. Otherwise, one of the following error codes is returned.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_FAIL</term>
/// <term>The call could not successfully query the current apartment type and type qualifier.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// An invalid parameter value was supplied to the function. Specifically, one or both of the parameters were set to NULL by the caller.
/// </term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>CoInitialize or CoInitializeEx was not called on this thread prior to calling CoGetApartmentType.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>On Windows platforms prior to Windows 7, the following actions must be taken on a thread to query the apartment type:</para>
/// <list type="bullet">
/// <item>
/// <term>Call CoGetContextToken to obtain the current context token.</term>
/// </item>
/// <item>
/// <term>Cast the context token to an IUnknown* pointer.</term>
/// </item>
/// <item>
/// <term>Call the QueryInterface method on that pointer to obtain the IComThreadingInfo interface.</term>
/// </item>
/// <item>
/// <term>Call the GetCurrentApartmentType method of the IComThreadingInfo interface to obtain the current apartment type.</term>
/// </item>
/// </list>
/// <para>
/// In multithreaded scenarios, there is a race condition which can potentially cause an Access Violation within the process when
/// executing the above sequence of operations. The <c>CoGetApartmentType</c> function is recommended as it does not potentially
/// incur the Access Violation.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetapartmenttype HRESULT CoGetApartmentType(
// APTTYPE *pAptType, APTTYPEQUALIFIER *pAptQualifier );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "ab0b6008-397f-4210-ba26-1a041b709722")]
public static extern HRESULT CoGetApartmentType(out APTTYPE pAptType, out APTTYPEQUALIFIER pAptQualifier);
/// <summary>Retrieves the context of the current call on the current thread.</summary>
/// <param name="riid">
/// Interface identifier (IID) of the call context that is being requested. If you are using the default call context supported by
/// standard marshaling, IID_IServerSecurity is available. For COM+ applications using role-based security, IID_ISecurityCallContext
/// is available.
/// </param>
/// <param name="ppInterface">
/// Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppInterface contains
/// the requested interface pointer.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The context was retrieved successfully.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>The call context does not support the interface specified by riid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <c>CoGetCallContext</c> retrieves the context of the current call on the current thread. The riid parameter specifies the
/// interface on the context to be retrieved. This is one of the functions provided to give the server access to any contextual
/// information of the caller.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetcallcontext HRESULT CoGetCallContext( REFIID
// riid, void **ppInterface );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "b82e32c0-840d-402e-90d5-ff678c51faf1")]
public static extern HRESULT CoGetCallContext(in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 0)] out object ppInterface);
/// <summary>Returns a pointer to a <c>DWORD</c> that contains the apartment ID of the caller's thread.</summary>
/// <param name="lpdwTID">
/// Receives the apartment ID of the caller's thread. For a single threaded apartment (STA), this is the current thread ID. For a
/// multithreaded apartment (MTA), the value is 0. For a neutral apartment (NA), the value is -1.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_TRUE</term>
/// <term>The caller's thread ID is set and the caller is in the same process.</term>
/// </item>
/// <item>
/// <term>S_FALSE</term>
/// <term>The caller's thread ID is set and the caller is in a different process.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>The caller's thread ID was not set.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If the caller is not running on the same computer, this function does not return the apartment ID and the return value is S_FALSE.
/// </para>
/// <para>
/// There is no guarantee that the information returned from this API is not tampered with, so do not use the ID that is returned to
/// make security decisions. The ID can only be used for logging and diagnostic purposes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetcallertid HRESULT CoGetCallerTID( LPDWORD
// lpdwTID );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "3a34001b-6286-4103-ae9f-700ea101dc17")]
public static extern HRESULT CoGetCallerTID(out uint lpdwTID);
/// <summary>
/// Obtains a pointer to a call control interface, normally ICancelMethodCalls, on the cancel object corresponding to an outbound
/// COM method call pending on the same or another client thread.
/// </summary>
/// <param name="dwThreadId">
/// The identifier of the thread on which the pending COM call is to be canceled. If this parameter is 0, the call is on the current thread.
/// </param>
/// <param name="iid">
/// The globally unique identifier of an interface on the cancel object for the call to be canceled. This argument is usually IID_ICancelMethodCalls.
/// </param>
/// <param name="ppUnk">Receives the address of a pointer to the interface specified by riid.</param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The call control object was retrieved successfully.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>The object on which the call is executing does not support the interface specified by riid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If two or more calls are pending on the same thread through nested calls, the thread ID may not be sufficient to identify the
/// call to be canceled. In this case, <c>CoGetCancelObject</c> returns a cancel interface corresponding to the innermost call that
/// is pending on the thread and has registered a cancel object.
/// </para>
/// <para>This function does not locate cancel objects for asynchronous calls.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetcancelobject HRESULT CoGetCancelObject( DWORD
// dwThreadId, REFIID iid, void **ppUnk );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "d38161af-d662-4430-99b7-6563efda6f4e")]
public static extern HRESULT CoGetCancelObject(uint dwThreadId, in Guid iid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object ppUnk);
/// <summary>
/// <para>
/// Provides a pointer to an interface on a class object associated with a specified CLSID. <c>CoGetClassObject</c> locates, and if
/// necessary, dynamically loads the executable code required to do this.
/// </para>
/// <para>
/// Call <c>CoGetClassObject</c> directly to create multiple objects through a class object for which there is a CLSID in the system
/// registry. You can also retrieve a class object from a specific remote computer. Most class objects implement the IClassFactory
/// interface. You would then call CreateInstance to create an uninitialized object. It is not always necessary to go through this
/// process however. To create a single object, call the CoCreateInstanceEx function, which allows you to create an instance on a
/// remote machine. This replaces the CoCreateInstance function, which can still be used to create an instance on a local computer.
/// Both functions encapsulate connecting to the class object, creating the instance, and releasing the class object. Two other
/// functions, CoGetInstanceFromFile and CoGetInstanceFromIStorage, provide both instance creation on a remote system and object
/// activation. There are numerous functions and interface methods whose purpose is to create objects of a single type and provide a
/// pointer to an interface on that object.
/// </para>
/// </summary>
/// <param name="rclsid">The CLSID associated with the data and code that you will use to create the objects.</param>
/// <param name="dwClsContext">
/// The context in which the executable code is to be run. To enable a remote activation, include CLSCTX_REMOTE_SERVER. For more
/// information on the context values and their use, see the CLSCTX enumeration.
/// </param>
/// <param name="pvReserved">
/// A pointer to computer on which to instantiate the class object. If this parameter is <c>NULL</c>, the class object is
/// instantiated on the current computer or at the computer specified under the class's RemoteServerName key, according to the
/// interpretation of the dwClsCtx parameter. See COSERVERINFO.
/// </param>
/// <param name="riid">
/// Reference to the identifier of the interface, which will be supplied in ppv on successful return. This interface will be used to
/// communicate with the class object. Typically this value is IID_IClassFactory, although other values – such as
/// IID_IClassFactory2 which supports a form of licensing – are allowed. All OLE-defined interface IIDs are defined in the OLE
/// header files as IID_interfacename, where interfacename is the name of the interface.
/// </param>
/// <param name="ppv">
/// The address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the
/// requested interface pointer.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>Location and connection to the specified class object was successful.</term>
/// </item>
/// <item>
/// <term>REGDB_E_CLASSNOTREG</term>
/// <term>
/// The CLSID is not properly registered. This error can also indicate that the value you specified in dwClsContext is not in the registry.
/// </term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>
/// Either the object pointed to by ppv does not support the interface identified by riid, or the QueryInterface operation on the
/// class object returned E_NOINTERFACE.
/// </term>
/// </item>
/// <item>
/// <term>REGDB_E_READREGDB</term>
/// <term>There was an error reading the registration database.</term>
/// </item>
/// <item>
/// <term>CO_E_DLLNOTFOUND</term>
/// <term>Either the in-process DLL or handler DLL was not found (depending on the context).</term>
/// </item>
/// <item>
/// <term>CO_E_APPNOTFOUND</term>
/// <term>The executable (.exe) was not found (CLSCTX_LOCAL_SERVER only).</term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>There was a general access failure on load.</term>
/// </item>
/// <item>
/// <term>CO_E_ERRORINDLL</term>
/// <term>There is an error in the executable image.</term>
/// </item>
/// <item>
/// <term>CO_E_APPDIDNTREG</term>
/// <term>The executable was launched, but it did not register the class object (and it may have shut down).</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// A class object in OLE is an intermediate object that supports an interface that permits operations common to a group of objects.
/// The objects in this group are instances derived from the same object definition represented by a single CLSID. Usually, the
/// interface implemented on a class object is IClassFactory, through which you can create object instances of a given definition (class).
/// </para>
/// <para>
/// A call to <c>CoGetClassObject</c> creates, initializes, and gives the caller access (through a pointer to an interface specified
/// with the riid parameter) to the class object. The class object is the one associated with the CLSID that you specify in the
/// rclsid parameter. The details of how the system locates the associated code and data within a computer are transparent to the
/// caller, as is the dynamic loading of any code that is not already loaded.
/// </para>
/// <para>
/// If the class context is CLSCTX_REMOTE_SERVER, indicating remote activation is required, the COSERVERINFO structure provided in
/// the pServerInfo parameter allows you to specify the computer on which the server is located. For information on the algorithm
/// used to locate a remote server when pServerInfo is <c>NULL</c>, refer to the CLSCTX enumeration.
/// </para>
/// <para>There are two places to find a CLSID for a class:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// The registry holds an association between CLSIDs and file suffixes, and between CLSIDs and file signatures for determining the
/// class of an object.
/// </term>
/// </item>
/// <item>
/// <term>When an object is saved to persistent storage, its CLSID is stored with its data.</term>
/// </item>
/// </list>
/// <para>
/// To create and initialize embedded or linked OLE document objects, it is not necessary to call <c>CoGetClassObject</c> directly.
/// Instead, call the OleCreate or <c>OleCreate</c> XXX function. These functions encapsulate the entire object instantiation and
/// initialization process, and call, among other functions, <c>CoGetClassObject</c>.
/// </para>
/// <para>
/// The riid parameter specifies the interface the client will use to communicate with the class object. In most cases, this
/// interface is IClassFactory. This provides access to the CreateInstance method, through which the caller can then create an
/// uninitialized object of the kind specified in its implementation. All classes registered in the system with a CLSID must
/// implement IClassFactory.
/// </para>
/// <para>
/// In rare cases, however, you may want to specify some other interface that defines operations common to a set of objects. For
/// example, in the way OLE implements monikers, the interface on the class object is IParseDisplayName, used to transform the
/// display name of an object into a moniker.
/// </para>
/// <para>
/// The dwClsContext parameter specifies the execution context, allowing one CLSID to be associated with different pieces of code in
/// different execution contexts. The CLSCTX enumeration specifies the available context flags. <c>CoGetClassObject</c> consults (as
/// appropriate for the context indicated) both the registry and the class objects that are currently registered by calling the
/// CoRegisterClassObject function.
/// </para>
/// <para>
/// To release a class object, use the class object's Release method. The function CoRevokeClassObject is to be used only to remove
/// a class object's CLSID from the system registry.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetclassobject HRESULT CoGetClassObject( REFCLSID
// rclsid, DWORD dwClsContext, LPVOID pvReserved, REFIID riid, LPVOID *ppv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "65e758ce-50a4-49e8-b3b2-0cd148d2781a")]
public static extern HRESULT CoGetClassObject(in Guid rclsid, CLSCTX dwClsContext, IntPtr pvReserved, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 3)] out object ppv);
/// <summary>Returns a pointer to an implementation of IObjContext for the current context.</summary>
/// <param name="pToken">A pointer to an implementation of IObjContext for the current context.</param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The token was retrieved successfully.</term>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <term>The caller did not pass a valid token pointer variable.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>The caller is not in an initialized apartment.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetcontexttoken HRESULT CoGetContextToken(
// ULONG_PTR *pToken );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "1218d928-ca3f-4bdc-9a00-ea4c214175a9")]
public static extern HRESULT CoGetContextToken([MarshalAs(UnmanagedType.IUnknown)] out IObjContext pToken);
/// <summary>Returns the logical thread identifier of the current physical thread.</summary>
/// <param name="pguid">A pointer to a GUID that contains the logical thread ID on return.</param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The logical thread ID was retrieved successfully.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>An invalid pointer was passed in for the pguid parameter.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>A memory allocation failed during the operation of the function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// This function retrieves the identifier of the current logical thread under which this physical thread is operating. The current
/// physical thread takes on the logical thread identifier of any client thread that makes a COM call into this application.
/// Similarly, the logical thread identifier of the current physical thread is used to denote the causality for outgoing COM calls
/// from this physical thread.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetcurrentlogicalthreadid HRESULT
// CoGetCurrentLogicalThreadId( GUID *pguid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "eced2f1e-9f2b-476c-bea8-945fb4804a89")]
public static extern HRESULT CoGetCurrentLogicalThreadId(out Guid pguid);
/// <summary>
/// Returns a value that is unique to the current thread. <c>CoGetCurrentProcess</c> can be used to avoid thread ID reuse problems.
/// </summary>
/// <returns>The function returns the unique identifier of the current thread.</returns>
/// <remarks>
/// <para>
/// Using the value returned from a call to <c>CoGetCurrentProcess</c> can help you in maintaining tables that are keyed by threads
/// or in uniquely identifying a thread to other threads or processes.
/// </para>
/// <para>
/// <c>CoGetCurrentProcess</c> returns a value that is effectively unique, because it is not used again until 2³² more threads have
/// been created on the current workstation or until the workstation is restarted.
/// </para>
/// <para>
/// The value returned by <c>CoGetCurrentProcess</c> will uniquely identify the same thread for the life of the caller. Because
/// thread IDs can be reused without notice as threads are created and destroyed, this value is more reliable than the value
/// returned by the GetCurrentThreadId function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetcurrentprocess DWORD CoGetCurrentProcess( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "46b0448f-f1c5-4da7-8489-bbd6d0fab79e")]
public static extern uint CoGetCurrentProcess();
/// <summary>Retrieves a reference to the default context of the specified apartment.</summary>
/// <param name="aptType">
/// <para>The apartment type of the default context that is being requested. This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>APTTYPE_CURRENT -1</term>
/// <term>The caller's apartment.</term>
/// </item>
/// <item>
/// <term>APTTYPE_MTA 1</term>
/// <term>The multithreaded apartment for the current process.</term>
/// </item>
/// <item>
/// <term>APTTYPE_NA 2</term>
/// <term>The neutral apartment for the current process.</term>
/// </item>
/// <item>
/// <term>APTTYPE_MAINSTA 3</term>
/// <term>The main single-threaded apartment for the current process.</term>
/// </item>
/// </list>
/// <para>
/// The APTTYPE value APTTYPE_STA (0) is not supported. A process can contain multiple single-threaded apartments, each with its own
/// context, so <c>CoGetDefaultContext</c> could not determine which STA is of interest. Therefore, this function returns
/// E_INVALIDARG if APTTYPE_STA is specified.
/// </para>
/// </param>
/// <param name="riid">
/// The interface identifier (IID) of the interface that is being requested on the default context. Typically, the caller requests
/// IID_IObjectContext. The default context does not support all of the normal object context interfaces.
/// </param>
/// <param name="ppv">
/// A reference to the interface specified by riid on the default context. If the object's component is non-configured, (that is,
/// the object's component has not been imported into a COM+ application), or if the <c>CoGetDefaultContext</c> function is called
/// from a constructor or an IUnknown method, this parameter is set to a <c>NULL</c> pointer.
/// </param>
/// <returns>
/// <para>This method can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The method completed successfully.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>One of the parameters is invalid.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>The caller is not in an initialized apartment.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>The object context does not support the interface specified by riid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Every COM apartment has a special context called the default context. A default context is different from all the other,
/// non-default contexts in an apartment because it does not provide runtime services. It does not support all of the normal object
/// context interfaces.
/// </para>
/// <para>
/// The default context is also used by instances of non-configured COM components, (that is, components that have not been part of
/// a COM+ application), when they are created from an apartment that does not support their threading model. In other words, if a
/// COM object creates an instance of a non-configured component and the new object cannot be added to its creator's context because
/// of its threading model, the new object is instead added to the default context of an apartment that supports its threading model.
/// </para>
/// <para>
/// An object should never pass an IObjectContext reference to another object. If you pass an <c>IObjectContext</c> reference to
/// another object, it is no longer a valid reference.
/// </para>
/// <para>
/// When an object obtains a reference to an IObjectContext, it must release the <c>IObjectContext</c> object when it is finished
/// with it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetdefaultcontext HRESULT CoGetDefaultContext(
// APTTYPE aptType, REFIID riid, void **ppv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "97a0e7da-e8bb-4bde-a8ba-35c90a1351d2")]
public static extern HRESULT CoGetDefaultContext(APTTYPE aptType, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object ppv);
/// <summary>
/// Unmarshals a buffer containing an interface pointer and releases the stream when an interface pointer has been marshaled from
/// another thread to the calling thread.
/// </summary>
/// <param name="pStm">A pointer to the IStream interface on the stream to be unmarshaled.</param>
/// <param name="iid">A reference to the identifier of the interface requested from the unmarshaled object.</param>
/// <param name="ppv">
/// The address of pointer variable that receives the interface pointer requested in <paramref name="iid"/>. Upon successful return,
/// <paramref name="ppv"/> contains the requested interface pointer to the unmarshaled interface.
/// </param>
/// <returns>
/// This function can return the standard return values S_OK and E_INVALIDARG, as well as any of the values returned by CoUnmarshalInterface.
/// </returns>
/// <remarks>
/// <para>
/// <c>Important</c> Security Note: Calling this method with untrusted data is a security risk. Call this method only with trusted
/// data. For more information, see Untrusted Data Security Risks.
/// </para>
/// <para>The <c>CoGetInterfaceAndReleaseStream</c> function performs the following tasks:</para>
/// <list type="bullet">
/// <item>
/// <term>Calls CoUnmarshalInterface to unmarshal an interface pointer previously passed in a call to CoMarshalInterThreadInterfaceInStream.</term>
/// </item>
/// <item>
/// <term>
/// Releases the stream pointer. Even if the unmarshaling fails, the stream is still released because there is no effective way to
/// recover from a failure of this kind.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetinterfaceandreleasestream HRESULT
// CoGetInterfaceAndReleaseStream( LPSTREAM pStm, REFIID iid, LPVOID *ppv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "b529f65f-3208-4594-a772-d1cad3727dc1")]
public static extern HRESULT CoGetInterfaceAndReleaseStream(IStream pStm, in Guid iid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
/// <summary>
/// Retrieves a pointer to the default OLE task memory allocator (which supports the system implementation of the IMalloc interface)
/// so applications can call its methods to manage memory.
/// </summary>
/// <param name="dwMemContext">This parameter must be 1.</param>
/// <param name="ppMalloc">
/// The address of an <c>IMalloc*</c> pointer variable that receives the interface pointer to the memory allocator.
/// </param>
/// <returns>This function can return the standard return values S_OK, E_INVALIDARG, and E_OUTOFMEMORY.</returns>
/// <remarks>
/// The pointer to the IMalloc interface pointer received through the ppMalloc parameter cannot be used from a remote process; each
/// process must have its own allocator.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetmalloc HRESULT CoGetMalloc( DWORD
// dwMemContext, LPMALLOC *ppMalloc );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "d1d09fbe-ca5c-4480-b807-3afcc043ccb9")]
public static extern HRESULT CoGetMalloc(uint dwMemContext, out IMalloc ppMalloc);
/// <summary>
/// Returns an upper bound on the number of bytes needed to marshal the specified interface pointer to the specified object.
/// </summary>
/// <param name="pulSize">
/// A pointer to the upper-bound value on the size, in bytes, of the data packet to be written to the marshaling stream. If this
/// parameter is 0, the size of the packet is unknown.
/// </param>
/// <param name="riid">
/// A reference to the identifier of the interface whose pointer is to be marshaled. This interface must be derived from the
/// IUnknown interface.
/// </param>
/// <param name="pUnk">A pointer to the interface to be marshaled. This interface must be derived from the IUnknown interface.</param>
/// <param name="dwDestContext">
/// The destination context where the specified interface is to be unmarshaled. Values for dwDestContext come from the enumeration MSHCTX.
/// </param>
/// <param name="pvDestContext">This parameter is reserved and must be <c>NULL</c>.</param>
/// <param name="mshlflags">
/// Indicates whether the data to be marshaled is to be transmitted back to the client processthe normal case or written to a global
/// table, where it can be retrieved by multiple clients. Values come from the enumeration MSHLFLAGS.
/// </param>
/// <returns>
/// <para>This function can return the standard return value E_UNEXPECTED, as well as the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The upper bound was returned successfully.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>Before this function can be called, either the CoInitialize or OleInitialize function must be called.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>This function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>
/// Queries the object for an IMarshal pointer or, if the object does not implement <c>IMarshal</c>, gets a pointer to COM's
/// standard marshaler.
/// </term>
/// </item>
/// <item>
/// <term>Using the pointer obtained in the preceding item, calls IMarshal::GetMarshalSizeMax.</term>
/// </item>
/// <item>
/// <term>
/// Adds to the value returned by the call to GetMarshalSizeMax the size of the marshaling data header and, possibly, that of the
/// proxy CLSID to obtain the maximum size in bytes of the amount of data to be written to the marshaling stream.
/// </term>
/// </item>
/// </list>
/// <para>
/// You do not explicitly call this function unless you are implementing IMarshal, in which case your marshaling stub should call
/// this function to get the correct size of the data packet to be marshaled.
/// </para>
/// <para>
/// The value returned by this method is guaranteed to be valid only as long as the internal state of the object being marshaled
/// does not change. Therefore, the actual marshaling should be done immediately after this function returns, or the stub runs the
/// risk that the object, because of some change in state, might require more memory to marshal than it originally indicated.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetmarshalsizemax HRESULT CoGetMarshalSizeMax(
// ULONG *pulSize, REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "c04c736c-8efe-438b-9d21-8b6ad53d36e7")]
public static extern HRESULT CoGetMarshalSizeMax(ref uint pulSize, in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] object pUnk,
MSHCTX dwDestContext, [Optional] IntPtr pvDestContext, MSHLFLAGS mshlflags);
/// <summary>Returns the context for the current object.</summary>
/// <param name="riid">
/// <para>A reference to the ID of an interface that is implemented on the context object.</para>
/// <para>For objects running within COM applications, IID_IComThreadingInfo, IID_IContext, and IID_IContextCallback are available.</para>
/// <para>
/// For objects running within COM+ applications, IID_IObjectContext, IID_IObjectContextActivity IID_IObjectContextInfo, and
/// IID_IContextState are available.
/// </para>
/// </param>
/// <param name="ppv">The address of a pointer to the interface specified by riid on the context object.</param>
/// <returns>
/// <para>This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The object context was successfully retrieved.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>The requested interface was not available.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>Before this function can be called, the CoInitializeEx function must be called on the current thread.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>CoGetObjectContext</c> retrieves the context for the object from which it is called, and returns a pointer to an interface
/// that can be used to manipulate context properties. Context properties are used to provide services to configured components
/// running within COM+ applications.
/// </para>
/// <para>
/// For components running within COM applications, the following interfaces are supported for accessing context properties:
/// IComThreadingInfo, IContext, and IContextCallback.
/// </para>
/// <para>
/// For components running within COM+ applications, the following interfaces are supported for accessing context properties:
/// IObjectContext, IObjectContextActivity, IObjectContextInfo, and IContextState.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetobjectcontext HRESULT CoGetObjectContext(
// REFIID riid, LPVOID *ppv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "97a0c6c3-a011-44dc-b428-aabdad7d4364")]
public static extern HRESULT CoGetObjectContext(in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 0)] out object ppv);
/// <summary>Returns the CLSID of the DLL that implements the proxy and stub for the specified interface.</summary>
/// <param name="riid">The interface whose proxy/stub CLSID is to be returned.</param>
/// <param name="pClsid">Specifies where to store the proxy/stub CLSID for the interface specified by riid.</param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The proxy/stub CLSID was successfully returned.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>One of the parameters is invalid.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>There is insufficient memory to complete this operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// The <c>CoGetPSClsid</c> function looks at the <c>HKEY_CLASSES_ROOT</c>&lt;b&gt;Interfaces&lt;i&gt;{string form of
/// riid}&lt;b&gt;ProxyStubClsid32 key in the registry to determine the CLSID of the DLL to load in order to create the proxy and
/// stub for the interface specified by riid. This function also returns the CLSID for any interface IID registered by
/// CoRegisterPSClsid within the current process.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetpsclsid HRESULT CoGetPSClsid( REFIID riid,
// CLSID *pClsid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "dfe6b514-a80a-4adb-bf43-d9a7d0e5f4a3")]
public static extern HRESULT CoGetPSClsid(in Guid riid, out Guid pClsid);
/// <summary>
/// Creates a default, or standard, marshaling object in either the client process or the server process, depending on the caller,
/// and returns a pointer to that object's IMarshal implementation.
/// </summary>
/// <param name="riid">
/// A reference to the identifier of the interface whose pointer is to be marshaled. This interface must be derived from the
/// IUnknown interface.
/// </param>
/// <param name="pUnk">A pointer to the interface to be marshaled.</param>
/// <param name="dwDestContext">
/// The destination context where the specified interface is to be unmarshaled. Values come from the enumeration MSHCTX.
/// Unmarshaling can occur either in another apartment of the current process (MSHCTX_INPROC) or in another process on the same
/// computer as the current process (MSHCTX_LOCAL).
/// </param>
/// <param name="pvDestContext">This parameter is reserved and must be <c>NULL</c>.</param>
/// <param name="mshlflags">
/// Indicates whether the data to be marshaled is to be transmitted back to the client process (the normal case) or written to a
/// global table where it can be retrieved by multiple clients. Values come from the MSHLFLAGS enumeration.
/// </param>
/// <param name="ppMarshal">
/// The address of <c>IMarshal*</c> pointer variable that receives the interface pointer to the standard marshaler.
/// </param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The IMarshal instance was returned successfully.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>Before this function can be called, the CoInitialize or OleInitialize function must be called on the current thread.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CoGetStandardMarshal</c> function creates a default, or standard, marshaling object in either the client process or the
/// server process, as may be necessary, and returns that object's IMarshal pointer to the caller. If you implement <c>IMarshal</c>,
/// you may want your implementation to call <c>CoGetStandardMarshal</c> as a way of delegating to COM's default implementation any
/// destination contexts that you do not fully understand or want to handle. Otherwise, you can ignore this function, which COM
/// calls as part of its internal marshaling procedures.
/// </para>
/// <para>
/// When the COM library in the client process receives a marshaled interface pointer, it looks for a CLSID to be used in creating a
/// proxy for the purposes of unmarshaling the packet. If the packet does not contain a CLSID for the proxy, COM calls
/// <c>CoGetStandardMarshal</c>, passing a <c>NULL</c> pUnk value. This function creates a standard proxy in the client process and
/// returns a pointer to that proxy's implementation of IMarshal. COM uses this pointer to call CoUnmarshalInterface to retrieve the
/// pointer to the requested interface.
/// </para>
/// <para>
/// If your OLE server application's implementation of IMarshal calls <c>CoGetStandardMarshal</c>, you should pass both the IID of
/// (riid), and a pointer to (pUnk), the interface being requested.
/// </para>
/// <para>This function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>Determines whether pUnk is <c>NULL</c>.</term>
/// </item>
/// <item>
/// <term>
/// If pUnk is <c>NULL</c>, creates a standard interface proxy in the client process for the specified riid and returns the proxy's
/// IMarshal pointer.
/// </term>
/// </item>
/// <item>
/// <term>
/// If pUnk is not <c>NULL</c>, checks to see if a marshaler for the object already exists, creates a new one if necessary, and
/// returns the marshaler's IMarshal pointer.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetstandardmarshal HRESULT CoGetStandardMarshal(
// REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags, LPMARSHAL *ppMarshal );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "0cb74adc-e192-4ae5-9267-02c79e301681")]
public static extern HRESULT CoGetStandardMarshal(in Guid riid, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnk,
MSHCTX dwDestContext, [Optional] IntPtr pvDestContext, MSHLFLAGS mshlflags, out IMarshal ppMarshal);
/// <summary>Creates an aggregated standard marshaler for use with lightweight client-side handlers.</summary>
/// <param name="pUnkOuter">A pointer to the controlling IUnknown.</param>
/// <param name="smexflags">
/// <para>
/// One of two values indicating whether the aggregated standard marshaler is on the client side or the server side. These flags are
/// defined in the <c>STDMSHLFLAGS</c> enumeration.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SMEXF_SERVER 0x01</term>
/// <term>Indicates a server-side aggregated standard marshaler.</term>
/// </item>
/// <item>
/// <term>SMEXF_HANDLER 0x0</term>
/// <term>Indicates a client-side (handler) aggregated standard marshaler.</term>
/// </item>
/// </list>
/// </param>
/// <param name="ppUnkInner">
/// On successful return, address of pointer to the IUnknown interface on the newly-created aggregated standard marshaler. If an
/// error occurs, this value is <c>NULL</c>.
/// </param>
/// <returns>This function returns S_OK.</returns>
/// <remarks>
/// The server calls <c>CoGetStdMarshalEx</c> passing in the flag SMEXF_SERVER. This creates a server side standard marshaler (known
/// as a stub manager). The handler calls <c>CoGetStdMarshalEx</c> passing in the flag SMEXF_HANDLER. This creates a client side
/// standard marshaler (known as a proxy manager). Note that when calling this function, the handler must pass the original
/// controlling unknown that was passed to the handler when the handler was created. This will be the system implemented controlling
/// unknown. Failure to pass the correct IUnknown results in an error returned. On success, the ppUnkInner returned is the
/// controlling unknown of the inner object. The server and handler must keep this pointer, and may use it to call
/// IUnknown::QueryInterface for the IMarshal interface.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetstdmarshalex HRESULT CoGetStdMarshalEx(
// LPUNKNOWN pUnkOuter, DWORD smexflags, LPUNKNOWN *ppUnkInner );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "405c5ff3-8702-48b3-9be9-df4a9461696e")]
public static extern HRESULT CoGetStdMarshalEx([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, STDMSHLFLAGS smexflags,
[MarshalAs(UnmanagedType.IUnknown)] out object ppUnkInner);
/// <summary>Returns the CLSID of an object that can emulate the specified object.</summary>
/// <param name="clsidOld">The CLSID of the object that can be emulated (treated as) an object with a different CLSID.</param>
/// <param name="pClsidNew">
/// A pointer to where the CLSID that can emulate clsidOld objects is retrieved. This parameter cannot be <c>NULL</c>. If there is
/// no emulation information for clsidOld objects, the clsidOld parameter is supplied.
/// </param>
/// <returns>
/// <para>This function can return the following values, as well as any error values returned by the CLSIDFromString function.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>A new CLSID was successfully returned.</term>
/// </item>
/// <item>
/// <term>S_FALSE</term>
/// <term>There is no emulation information for the clsidOld parameter, so the pClsidNew parameter is set to clsidOld.</term>
/// </item>
/// <item>
/// <term>REGDB_E_READREGDB</term>
/// <term>There was an error reading the registry.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <c>CoGetTreatAsClass</c> returns the TreatAs entry in the registry for the specified object. The <c>TreatAs</c> entry, if set,
/// is the CLSID of a registered object (an application) that can emulate the object in question. The <c>TreatAs</c> entry is set
/// through a call to the CoTreatAsClass function. Emulation allows an application to open and edit an object of a different format,
/// while retaining the original format of the object. Objects of the original CLSID are activated and treated as objects of the
/// second CLSID. When the object is saved, this may result in loss of edits not supported by the original format. If there is no
/// <c>TreatAs</c> entry for the specified object, this function returns the CLSID of the original object (clsidOld).
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogettreatasclass HRESULT CoGetTreatAsClass(
// REFCLSID clsidOld, LPCLSID pClsidNew );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "f95fefe6-dc37-45f4-93be-87c996990ab9")]
public static extern HRESULT CoGetTreatAsClass(in Guid clsidOld, out Guid pClsidNew);
/// <summary>Enables the server to impersonate the client of the current call for the duration of the call.</summary>
/// <returns>This function supports the standard return values, including S_OK.</returns>
/// <remarks>
/// <para>
/// This method allows the server to impersonate the client of the current call for the duration of the call. If you do not call
/// CoRevertToSelf, COM reverts automatically for you. This function will fail unless the object is being called with
/// RPC_C_AUTHN_LEVEL_CONNECT or higher authentication in effect (which is any authentication level except RPC_C_AUTHN_LEVEL_NONE).
/// This function encapsulates the following sequence of common calls (error handling excluded):
/// </para>
/// <para>
/// <c>CoImpersonateClient</c> encapsulates the process of getting a pointer to an instance of IServerSecurity that contains data
/// about the current call, calling its ImpersonateClient method, and then releasing the pointer. One call to CoRevertToSelf (or
/// IServerSecurity::RevertToSelf) will undo any number of calls to impersonate the client.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coimpersonateclient HRESULT CoImpersonateClient( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "a3cbfbbc-fc6f-4d1b-8460-1e3351cd32d7")]
public static extern HRESULT CoImpersonateClient();
/// <summary>Keeps MTA support active when no MTA threads are running.</summary>
/// <param name="pCookie">
/// Address of a <c>PVOID</c> variable that receives the cookie for the CoDecrementMTAUsage function, or <c>NULL</c> if the call fails.
/// </param>
/// <returns>If this function succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</returns>
/// <remarks>
/// <para>
/// The <c>CoIncrementMTAUsage</c> function enables clients to create MTA workers and wait on them for completion before exiting the process.
/// </para>
/// <para>
/// The <c>CoIncrementMTAUsage</c> function ensures that the system doesn't free resources related to MTA support., even if the MTA
/// thread count goes to 0.
/// </para>
/// <para>On success, call the CoDecrementMTAUsage once only. On failure, don't call the <c>CoDecrementMTAUsage</c> function.</para>
/// <para>
/// Don't call <c>CoIncrementMTAUsage</c> during process shutdown or inside dllmain. You can call <c>CoIncrementMTAUsage</c> before
/// the call to start the shutdown process.
/// </para>
/// <para>
/// You can call <c>CoIncrementMTAUsage</c> from one thread and CoDecrementMTAUsage from another as long as a cookie previously
/// returned by <c>CoIncrementMTAUsage</c> is passed to <c>CoDecrementMTAUsage</c>.
/// </para>
/// <para>
/// <c>CoIncrementMTAUsage</c> creates the MTA, if the MTA does not already exist. <c>CoIncrementMTAUsage</c> puts the current
/// thread into the MTA, if the current thread is not already in an apartment
/// </para>
/// <para>You can use <c>CoIncrementMTAUsage</c> when:</para>
/// <list type="bullet">
/// <item>
/// <term>You want a server to keep the MTA alive even when all worker threads are idle.</term>
/// </item>
/// <item>
/// <term>
/// Your API implementation requires COM to be initialized, but has no information about whether the current thread is already in an
/// apartment, and does not need the current thread to go into a particular apartment.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coincrementmtausage HRESULT CoIncrementMTAUsage(
// CO_MTA_USAGE_COOKIE *pCookie );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "EFE6E66A-96A3-4B51-92DD-1CE84B1F0185")]
public static extern HRESULT CoIncrementMTAUsage(out CO_MTA_USAGE_COOKIE pCookie);
/// <summary>
/// <para>Tells the service control manager to flush any cached RPC binding handles for the specified computer.</para>
/// <para>Only administrators may call this function.</para>
/// </summary>
/// <param name="pszMachineName">
/// The computer name for which binding handles should be flushed, or an empty string to signify that all handles in the cache
/// should be flushed.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>Indicates success.</term>
/// </item>
/// <item>
/// <term>CO_S_MACHINENAMENOTFOUND</term>
/// <term>
/// Indicates that the specified computer name was not found or that the binding handle cache was empty, indicating that an empty
/// string was passed instead of a specific computer name.
/// </term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>Indicates the caller was not an administrator for this computer.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>Indicates that a NULL value was passed for pszMachineName.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The OLE Service Control Manager is used by COM to send component activation requests to other machines. To do this, the OLE
/// Service Control Manager maintains a cache of RPC binding handles to send activation requests to computer, keyed by computer
/// name. Under normal circumstances, this works well, but in some scenarios, such as Web farms and load-balancing situations, the
/// ability to purge this cache of specific handles might be needed in order to facilitate rebinding to a different physical server
/// by the same name. <c>CoInvalidateRemoteMachineBindings</c> is used for this purpose.
/// </para>
/// <para>
/// The OLE Service Control Manager will flush unused binding handles over time. It is not necessary to call
/// <c>CoInvalidateRemoteMachineBindings</c> to do this.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coinvalidateremotemachinebindings HRESULT
// CoInvalidateRemoteMachineBindings( LPOLESTR pszMachineName );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "6d0fa512-a9e9-44ff-929d-00b9c826da99")]
public static extern HRESULT CoInvalidateRemoteMachineBindings([In, MarshalAs(UnmanagedType.LPWStr)] string pszMachineName);
/// <summary>Determines whether a remote object is connected to the corresponding in-process object.</summary>
/// <param name="pUnk">A pointer to the controlling IUnknown interface on the remote object.</param>
/// <returns>
/// If the object is not remote or if it is remote and still connected, the return value is <c>TRUE</c>; otherwise, it is <c>FALSE</c>.
/// </returns>
/// <remarks>
/// The <c>CoIsHandlerConnected</c> function determines the status of a remote object. You can use it to determine when to release a
/// remote object. You specify the remote object by giving the function a pointer to its controlling IUnknown interface (the pUnk
/// parameter). A value of <c>TRUE</c> returned from the function indicates either that the specified object is not remote, or that
/// it is remote and is still connected to its remote handler. A value of <c>FALSE</c> returned from the function indicates that the
/// object is remote but is no longer connected to its remote handler; in this case, the caller should respond by releasing the object.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coishandlerconnected BOOL CoIsHandlerConnected(
// LPUNKNOWN pUnk );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "f58bdec6-3709-439d-9867-0022a069c53d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CoIsHandlerConnected([In, MarshalAs(UnmanagedType.IUnknown)] object pUnk);
/// <summary>Called either to lock an object to ensure that it stays in memory, or to release such a lock.</summary>
/// <param name="pUnk">A pointer to the IUnknown interface on the object to be locked or unlocked.</param>
/// <param name="fLock">
/// Indicates whether the object is to be locked or released. If this parameter is <c>TRUE</c>, the object is kept in memory,
/// independent of <c>AddRef</c>/ <c>Release</c> operations, registrations, or revocations. If this parameter is <c>FALSE</c>, the
/// lock previously set with a call to this function is released.
/// </param>
/// <param name="fLastUnlockReleases">
/// <para>
/// If the lock is the last reference that is supposed to keep an object alive, specify <c>TRUE</c> to release all pointers to the
/// object (there may be other references that are not supposed to keep it alive). Otherwise, specify <c>FALSE</c>.
/// </para>
/// <para>If fLock is <c>TRUE</c>, this parameter is ignored.</para>
/// </param>
/// <returns>This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, and S_OK.</returns>
/// <remarks>
/// <para>
/// The <c>CoLockObjectExternal</c> function must be called in the process in which the object actually resides (the EXE process,
/// not the process in which handlers may be loaded).
/// </para>
/// <para>
/// The <c>CoLockObjectExternal</c> function prevents the reference count of an object from going to zero, thereby "locking" it into
/// existence until the lock is released. The same function (with different parameters) releases the lock. The lock is implemented
/// by having the system call IUnknown::AddRef on the object. The system then waits to call IUnknown::Release on the object until a
/// later call to <c>CoLockObjectExternal</c> with fLock set to <c>FALSE</c>. This function can be used to maintain a reference
/// count on the object on behalf of the end user, because it acts outside of the object, as does the user.
/// </para>
/// <para>
/// The end user has explicit control over the lifetime of an application, even if there are external locks on it. That is, if a
/// user decides to close the application, it must shut down. In the presence of external locks (such as the lock set by
/// <c>CoLockObjectExternal</c>), the application can call the CoDisconnectObject function to force these connections to close prior
/// to shutdown.
/// </para>
/// <para>
/// Calling <c>CoLockObjectExternal</c> sets a strong lock on an object. A strong lock keeps an object in memory, while a weak lock
/// does not. Strong locks are required, for example, during a silent update to an OLE embedding. The embedded object's container
/// must remain in memory until the update process is complete. There must also be a strong lock on an application object to ensure
/// that the application stays alive until it has finished providing services to its clients. All external references place a strong
/// reference lock on an object.
/// </para>
/// <para>The <c>CoLockObjectExternal</c> function is typically called in the following situations:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// Object servers should call <c>CoLockObjectExternal</c> with both fLock and fLastLockReleases set to <c>TRUE</c> when they become
/// visible. This call creates a strong lock on behalf of the user. When the application is closing, free the lock with a call to
/// <c>CoLockObjectExternal</c>, setting fLock to <c>FALSE</c> and fLastLockReleases to <c>TRUE</c>.
/// </term>
/// </item>
/// <item>
/// <term>A call to <c>CoLockObjectExternal</c> on the server can also be used in the implementation of IOleContainer::LockContainer.</term>
/// </item>
/// </list>
/// <para>
/// There are several things to be aware of when you use <c>CoLockObjectExternal</c> in the implementation of LockContainer. An
/// embedded object would call <c>LockContainer</c> on its container to keep it running (to lock it) in the absence of other reasons
/// to keep it running. When the embedded object becomes visible, the container must weaken its connection to the embedded object
/// with a call to the OleSetContainedObject function, so other connections can affect the object.
/// </para>
/// <para>
/// Unless an application manages all aspects of its application and document shutdown completely with calls to
/// <c>CoLockObjectExternal</c>, the container must keep a private lock count in LockContainer so that it exits when the lock count
/// reaches zero and the container is invisible. Maintaining all aspects of shutdown, and thereby avoiding keeping a private lock
/// count, means that <c>CoLockObjectExternal</c> should be called whenever one of the following conditions occur:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>A document is created and destroyed or made visible or invisible.</term>
/// </item>
/// <item>
/// <term>An application is started and shut down by the user.</term>
/// </item>
/// <item>
/// <term>A pseudo-object is created and destroyed.</term>
/// </item>
/// </list>
/// <para>For debugging purposes, it may be useful to keep a count of the number of external locks (and unlocks) set on the application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-colockobjectexternal HRESULT CoLockObjectExternal(
// LPUNKNOWN pUnk, BOOL fLock, BOOL fLastUnlockReleases );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "36eb55f1-06de-49ad-8a8d-91693ca92e99")]
public static extern HRESULT CoLockObjectExternal([In, MarshalAs(UnmanagedType.IUnknown)] object pUnk,
[MarshalAs(UnmanagedType.Bool)] bool fLock, [MarshalAs(UnmanagedType.Bool)] bool fLastUnlockReleases);
/// <summary>
/// <para>Marshals an <c>HRESULT</c> to the specified stream, from which it can be unmarshaled using the CoUnmarshalHresult function.</para>
/// </summary>
/// <param name="pstm">
/// <para>A pointer to the marshaling stream. See IStream.</para>
/// </param>
/// <param name="hresult">
/// <para>The <c>HRESULT</c> in the originating process.</para>
/// </param>
/// <returns>
/// <para>This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The HRESULT was marshaled successfully.</term>
/// </item>
/// <item>
/// <term>STG_E_INVALIDPOINTER</term>
/// <term>A bad pointer was specified for pstm.</term>
/// </item>
/// <item>
/// <term>STG_E_MEDIUMFULL</term>
/// <term>The medium is full.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// An <c>HRESULT</c> is process-specific, so an <c>HRESULT</c> that is valid in one process might not be valid in another. If you
/// are writing your own implementation of IMarshal and need to marshal an <c>HRESULT</c> from one process to another, either as a
/// parameter or a return code, you must call this function. In other circumstances, you will have no need to call this function.
/// </para>
/// <para>This function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>Writes an <c>HRESULT</c> to a stream.</term>
/// </item>
/// <item>
/// <term>Returns an IStream pointer to that stream.</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-comarshalhresult HRESULT CoMarshalHresult( LPSTREAM
// pstm, HRESULT hresult );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "37aaf404-49ca-4881-a369-44c5288abf1d")]
public static extern HRESULT CoMarshalHresult(IStream pstm, HRESULT hresult);
/// <summary>Writes into a stream the data required to initialize a proxy object in some client process.</summary>
/// <param name="pStm">A pointer to the stream to be used during marshaling. See IStream.</param>
/// <param name="riid">
/// A reference to the identifier of the interface to be marshaled. This interface must be derived from the IUnknown interface.
/// </param>
/// <param name="pUnk">A pointer to the interface to be marshaled. This interface must be derived from the IUnknown interface.</param>
/// <param name="dwDestContext">
/// The destination context where the specified interface is to be unmarshaled. The possible values come from the enumeration
/// MSHCTX. Currently, unmarshaling can occur in another apartment of the current process (MSHCTX_INPROC), in another process on the
/// same computer as the current process (MSHCTX_LOCAL), or in a process on a different computer (MSHCTX_DIFFERENTMACHINE).
/// </param>
/// <param name="pvDestContext">This parameter is reserved and must be <c>NULL</c>.</param>
/// <param name="mshlflags">
/// The flags that specify whether the data to be marshaled is to be transmitted back to the client process (the typical case) or
/// written to a global table, where it can be retrieved by multiple clients. The possibles values come from the MSHLFLAGS enumeration.
/// </param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_OUTOFMEMORY, and E_UNEXPECTED, the stream-access error values
/// returned by IStream, as well as the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The HRESULT was marshaled successfully.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>The CoInitialize or OleInitialize function was not called on the current thread before this function was called.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CoMarshalInterface</c> function marshals the interface referred to by riid on the object whose IUnknown implementation is
/// pointed to by pUnk. To do so, the <c>CoMarshalInterface</c> function performs the following tasks:
/// </para>
/// <list type="number">
/// <item>
/// <term>
/// Queries the object for a pointer to the IMarshal interface. If the object does not implement <c>IMarshal</c>, meaning that it
/// relies on COM to provide marshaling support, <c>CoMarshalInterface</c> gets a pointer to COM's default implementation of <c>IMarshal</c>.
/// </term>
/// </item>
/// <item>
/// <term>
/// Gets the CLSID of the object's proxy by calling IMarshal::GetUnmarshalClass, using whichever IMarshal interface pointer has been returned.
/// </term>
/// </item>
/// <item>
/// <term>Writes the CLSID of the proxy to the stream to be used for marshaling.</term>
/// </item>
/// <item>
/// <term>Marshals the interface pointer by calling IMarshal::MarshalInterface.</term>
/// </item>
/// </list>
/// <para>
/// The COM library in the client process calls the CoUnmarshalInterface function to extract the data and initialize the proxy.
/// Before calling <c>CoUnmarshalInterface</c>, seek back to the original position in the stream.
/// </para>
/// <para>
/// If you are implementing existing COM interfaces or defining your own interfaces using the Microsoft Interface Definition
/// Language (MIDL), the MIDL-generated proxies and stubs call <c>CoMarshalInterface</c> for you. If you are writing your own
/// proxies and stubs, your proxy code and stub code should each call <c>CoMarshalInterface</c> to correctly marshal interface
/// pointers. Calling IMarshal directly from your proxy and stub code is not recommended.
/// </para>
/// <para>
/// If you are writing your own implementation of IMarshal, and your proxy needs access to a private object, you can include an
/// interface pointer to that object as part of the data you write to the stream. In such situations, if you want to use COM's
/// default marshaling implementation when passing the interface pointer, you can call <c>CoMarshalInterface</c> on the object to do so.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-comarshalinterface HRESULT CoMarshalInterface(
// LPSTREAM pStm, REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "04ca1217-eac1-43e2-b736-8d7522ce8592")]
public static extern HRESULT CoMarshalInterface(IStream pStm, in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] object pUnk, MSHCTX dwDestContext, [Optional] IntPtr pvDestContext, MSHLFLAGS mshlflags);
/// <summary>Marshals an interface pointer from one thread to another thread in the same process.</summary>
/// <param name="riid">A reference to the identifier of the interface to be marshaled.</param>
/// <param name="pUnk">A pointer to the interface to be marshaled, which must be derived from IUnknown. This parameter can be <c>NULL</c>.</param>
/// <param name="ppStm">
/// The address of the IStream* pointer variable that receives the interface pointer to the stream that contains the marshaled interface.
/// </param>
/// <returns>This function can return the standard return values E_OUTOFMEMORY and S_OK.</returns>
/// <remarks>
/// <para>
/// The <c>CoMarshalInterThreadInterfaceInStream</c> function enables an object to easily and reliably marshal an interface pointer
/// to another thread in the same process. The stream returned in the ppStm parameter is guaranteed to behave correctly when a
/// client running in the receiving thread attempts to unmarshal the pointer. The client can then call the
/// CoGetInterfaceAndReleaseStream to unmarshal the interface pointer and release the stream object.
/// </para>
/// <para>The <c>CoMarshalInterThreadInterfaceInStream</c> function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>Creates a stream object.</term>
/// </item>
/// <item>
/// <term>Passes the stream object's IStream pointer to CoMarshalInterface.</term>
/// </item>
/// <item>
/// <term>Returns the IStream pointer to the caller.</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-comarshalinterthreadinterfaceinstream HRESULT
// CoMarshalInterThreadInterfaceInStream( REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "c9ab8713-8604-4f0b-a11b-bdfb7d595d95")]
public static extern HRESULT CoMarshalInterThreadInterfaceInStream(in Guid riid, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnk, out IStream ppStm);
/// <summary>Retrieves a list of the authentication services registered when the process called CoInitializeSecurity.</summary>
/// <param name="pcAuthSvc">A pointer to a variable that receives the number of entries returned in the asAuthSvc array.</param>
/// <param name="asAuthSvc">
/// A pointer to an array of SOLE_AUTHENTICATION_SERVICE structures. The list is allocated through a call to the CoTaskMemAlloc
/// function. The caller must free the list when finished with it by calling the CoTaskMemFree function.
/// </param>
/// <returns>This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK.</returns>
/// <remarks>
/// <para>
/// <c>CoQueryAuthenticationServices</c> retrieves a list of the authentication services currently registered. If the process calls
/// CoInitializeSecurity, these are the services registered through that call. If the application does not call it,
/// <c>CoInitializeSecurity</c> is called automatically by COM, registering the default security package, the first time an
/// interface is marshaled or unmarshaled.
/// </para>
/// <para>
/// This function returns only the authentication services registered with CoInitializeSecurity. It does not return all of the
/// authentication services installed on the computer, but EnumerateSecurityPackages does. <c>CoQueryAuthenticationServices</c> is
/// primarily useful for custom marshalers, to determine which principal names an application can use.
/// </para>
/// <para>
/// Different authentication services support different levels of security. For example, NTLMSSP does not support delegation or
/// mutual authentication while Kerberos does. The application is responsible only for registering authentication services that
/// provide the features the application needs. This function provides a way to find out which services have been registered with CoInitializeSecurity.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coqueryauthenticationservices HRESULT
// CoQueryAuthenticationServices( DWORD *pcAuthSvc, SOLE_AUTHENTICATION_SERVICE **asAuthSvc );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "e9e7c5a3-70ec-4a68-ac21-1ab6774d140f")]
public static extern HRESULT CoQueryAuthenticationServices(out uint pcAuthSvc, out SafeCoTaskMemHandle asAuthSvc);
/// <summary>Retrieves a list of the authentication services registered when the process called CoInitializeSecurity.</summary>
/// <returns>An array of SOLE_AUTHENTICATION_SERVICE structures.</returns>
/// <remarks>
/// <para>
/// <c>CoQueryAuthenticationServices</c> retrieves a list of the authentication services currently registered. If the process calls
/// CoInitializeSecurity, these are the services registered through that call. If the application does not call it,
/// <c>CoInitializeSecurity</c> is called automatically by COM, registering the default security package, the first time an
/// interface is marshaled or unmarshaled.
/// </para>
/// <para>
/// This function returns only the authentication services registered with CoInitializeSecurity. It does not return all of the
/// authentication services installed on the computer, but EnumerateSecurityPackages does. <c>CoQueryAuthenticationServices</c> is
/// primarily useful for custom marshalers, to determine which principal names an application can use.
/// </para>
/// <para>
/// Different authentication services support different levels of security. For example, NTLMSSP does not support delegation or
/// mutual authentication while Kerberos does. The application is responsible only for registering authentication services that
/// provide the features the application needs. This function provides a way to find out which services have been registered with CoInitializeSecurity.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coqueryauthenticationservices HRESULT
[PInvokeData("combaseapi.h", MSDNShortId = "e9e7c5a3-70ec-4a68-ac21-1ab6774d140f")]
public static SOLE_AUTHENTICATION_SERVICE[] CoQueryAuthenticationServices() { CoQueryAuthenticationServices(out var c, out var a).ThrowIfFailed(); return a.ToArray<SOLE_AUTHENTICATION_SERVICE>((int)c); }
/// <summary>
/// Called by the server to find out about the client that invoked the method executing on the current thread. This is a helper
/// function for IServerSecurity::QueryBlanket.
/// </summary>
/// <param name="pAuthnSvc">
/// A pointer to a variable that receives the current authentication service. This will be a single value taken from the
/// authentication service constants. If the caller specifies <c>NULL</c>, the current authentication service is not retrieved.
/// </param>
/// <param name="pAuthzSvc">
/// A pointer to a variable that receives the current authorization service. This will be a single value taken from the
/// authorization constants. If the caller specifies <c>NULL</c>, the current authorization service is not retrieved.
/// </param>
/// <param name="pServerPrincName">The string builder.</param>
/// <param name="pAuthnLevel">
/// A pointer to a variable that receives the current authentication level. This will be a single value taken from the
/// authentication level constants. If the caller specifies <c>NULL</c>, the current authentication level is not retrieved.
/// </param>
/// <param name="pImpLevel">This parameter must be <c>NULL</c>.</param>
/// <param name="pPrivs">
/// A pointer to a handle that receives the privilege information for the client application. The format of the structure that the
/// handle refers to depends on the authentication service. The application should not write or free the memory. The information is
/// valid only for the duration of the current call. For NTLMSSP and Kerberos, this is a string identifying the client principal.
/// For Schannel, this is a CERT_CONTEXT structure that represents the client's certificate. If the client has no certificate,
/// <c>NULL</c> is returned. If the caller specifies <c>NULL</c>, the current privilege information is not retrieved. See RPC_AUTHZ_HANDLE.
/// </param>
/// <param name="pCapabilities">
/// A pointer to return flags indicating capabilities of the call. To request that the principal name be returned in fullsic form if
/// Schannel is the authentication service, the caller can set the EOAC_MAKE_FULLSIC flag in this parameter. If the caller specifies
/// <c>NULL</c>, the current capabilities are not retrieved.
/// </param>
/// <returns>This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK.</returns>
/// <remarks>
/// <para>
/// <c>CoQueryClientBlanket</c> is called by the server to get security information about the client that invoked the method
/// executing on the current thread. This function encapsulates the following sequence of common calls (error handling excluded):
/// </para>
/// <para>
/// This sequence calls CoGetCallContext to get a pointer to IServerSecurity and, with the resulting pointer, calls
/// IServerSecurity::QueryBlanket and then releases the pointer.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coqueryclientblanket HRESULT CoQueryClientBlanket(
// DWORD *pAuthnSvc, DWORD *pAuthzSvc, LPOLESTR *pServerPrincName, DWORD *pAuthnLevel, DWORD *pImpLevel, RPC_AUTHZ_HANDLE *pPrivs,
// DWORD *pCapabilities );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "58a2c121-c324-4c33-aaca-490b5a09738c")]
public static extern HRESULT CoQueryClientBlanket(out RPC_C_AUTHN pAuthnSvc, out RPC_C_AUTHZ pAuthzSvc, [MarshalAs(UnmanagedType.LPWStr)] out string pServerPrincName,
out RPC_C_AUTHN_LEVEL pAuthnLevel, out RPC_C_IMP_LEVEL pImpLevel, out RPC_AUTHZ_HANDLE pPrivs, ref EOLE_AUTHENTICATION_CAPABILITIES pCapabilities);
/// <summary>
/// Retrieves the authentication information the client uses to make calls on the specified proxy. This is a helper function for IClientSecurity::QueryBlanket.
/// </summary>
/// <param name="pProxy">
/// A pointer indicating the proxy to query. This parameter cannot be <c>NULL</c>. For more information, see the Remarks section.
/// </param>
/// <param name="pwAuthnSvc">
/// A pointer to a variable that receives the current authentication level. This will be a single value taken from the
/// authentication level constants. If the caller specifies <c>NULL</c>, the current authentication level is not retrieved.
/// </param>
/// <param name="pAuthzSvc">
/// A pointer to a variable that receives the current authorization service. This will be a single value taken from the
/// authorization constants. If the caller specifies <c>NULL</c>, the current authorization service is not retrieved.
/// </param>
/// <param name="pServerPrincName">
/// The current principal name. The string will be allocated by the callee using CoTaskMemAlloc, and must be freed by the caller
/// using CoTaskMemFree. The EOAC_MAKE_FULLSIC flag is not accepted in the pCapabilities parameter. For more information about the
/// msstd and fullsic forms, see Principal Names. If the caller specifies <c>NULL</c>, the current principal name is not retrieved.
/// </param>
/// <param name="pAuthnLevel">
/// A pointer to a variable that receives the current authentication level. This will be a single value taken from the
/// authentication level constants. If the caller specifies <c>NULL</c>, the current authentication level is not retrieved.
/// </param>
/// <param name="pImpLevel">
/// A pointer to a variable that receives the current impersonation level. This will be a single value taken from the impersonation
/// level constants. If the caller specifies <c>NULL</c>, the current impersonation level is not retrieved.
/// </param>
/// <param name="pAuthInfo">
/// A pointer to a handle that receives the identity of the client that was passed to the last IClientSecurity::SetBlanket call (or
/// the default value). Default values are only valid until the proxy is released. If the caller specifies <c>NULL</c>, the client
/// identity is not retrieved. The format of the structure that the handle refers to depends on the authentication service. The
/// application should not write or free the memory. For NTLMSSP and Kerberos, if the client specified a structure in the pAuthInfo
/// parameter to CoInitializeSecurity, that value is returned. For Schannel, if a certificate for the client could be retrieved from
/// the certificate manager, that value is returned here. Otherwise, <c>NULL</c> is returned. See RPC_AUTH_IDENTITY_HANDLE.
/// </param>
/// <param name="pCapabilites">
/// A pointer to a variable that receives the capabilities of the proxy. If the caller specifies <c>NULL</c>, the current capability
/// flags are not retrieved.
/// </param>
/// <returns>This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK.</returns>
/// <remarks>
/// <para>
/// <c>CoQueryProxyBlanket</c> is called by the client to retrieve the authentication information COM will use on calls made from
/// the specified proxy. This function encapsulates the following sequence of common calls (error handling excluded):
/// </para>
/// <para>
/// This sequence calls QueryInterface on the proxy to get a pointer to IClientSecurity, and with the resulting pointer, calls
/// IClientSecurity::QueryBlanket and then releases the pointer.
/// </para>
/// <para>
/// In pProxy, you can pass any proxy, such as a proxy you get through a call to CoCreateInstance or CoUnmarshalInterface, or you
/// can pass an interface pointer. It can be any interface. You cannot pass a pointer to something that is not a proxy. Therefore,
/// you can't pass a pointer to an interface that has the local keyword in its interface definition because no proxy is created for
/// such an interface. IUnknown is the exception to this rule.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coqueryproxyblanket HRESULT CoQueryProxyBlanket(
// IUnknown *pProxy, DWORD *pwAuthnSvc, DWORD *pAuthzSvc, LPOLESTR *pServerPrincName, DWORD *pAuthnLevel, DWORD *pImpLevel,
// RPC_AUTH_IDENTITY_HANDLE *pAuthInfo, DWORD *pCapabilites );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "e613e06a-0900-413e-bde2-39ce1612fed1")]
public static extern HRESULT CoQueryProxyBlanket([In, MarshalAs(UnmanagedType.IUnknown)] object pProxy, out RPC_C_AUTHN pAuthnLevel,
out RPC_C_AUTHZ pAuthzSvc, SafeCoTaskMemString pServerPrincName, out RPC_C_AUTHN_LEVEL pwAuthnSvc, out RPC_C_IMP_LEVEL pImpLevel,
out RPC_AUTH_IDENTITY_HANDLE pAuthInfo, ref EOLE_AUTHENTICATION_CAPABILITIES pCapabilites);
/// <summary>Registers a process-wide filter to process activation requests.</summary>
/// <param name="pActivationFilter">Pointer to the filter to register.</param>
/// <returns>If this function succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</returns>
/// <remarks>This registers one and only one process-wide filter.</remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coregisteractivationfilter HRESULT
// CoRegisterActivationFilter( IActivationFilter *pActivationFilter );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "4189633F-9B14-4EAD-84BD-F74355376164")]
public static extern HRESULT CoRegisterActivationFilter([In] IActivationFilter pActivationFilter);
/// <summary>Registers an EXE class object with OLE so other applications can connect to it.</summary>
/// <param name="rclsid">The CLSID to be registered.</param>
/// <param name="pUnk">A pointer to the IUnknown interface on the class object whose availability is being published.</param>
/// <param name="dwClsContext">
/// The context in which the executable code is to be run. For information on these context values, see the CLSCTX enumeration.
/// </param>
/// <param name="flags">
/// Indicates how connections are made to the class object. For information on these flags, see the REGCLS enumeration.
/// </param>
/// <param name="lpdwRegister">
/// A pointer to a value that identifies the class object registered; later used by the CoRevokeClassObject function to revoke the registration.
/// </param>
/// <returns>
/// <para>
/// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The class object was registered successfully.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// EXE object applications should call <c>CoRegisterClassObject</c> on startup. It can also be used to register internal objects
/// for use by the same EXE or other code (such as DLLs) that the EXE uses. Only EXE object applications call
/// <c>CoRegisterClassObject</c>. Object handlers or DLL object applications do not call this function — instead, they must
/// implement and export the DllGetClassObject function.
/// </para>
/// <para>
/// At startup, a multiple-use EXE object application must create a class object (with the IClassFactory interface on it), and call
/// <c>CoRegisterClassObject</c> to register the class object. Object applications that support several different classes (such as
/// multiple types of embeddable objects) must allocate and register a different class object for each.
/// </para>
/// <para>
/// Multiple registrations of the same class object are independent and do not produce an error. Each subsequent registration yields
/// a unique key in lpdwRegister.
/// </para>
/// <para>
/// Multiple document interface (MDI) applications must register their class objects. Single document interface (SDI) applications
/// must register their class objects only if they can be started by means of the <c>/Embedding</c> switch.
/// </para>
/// <para>
/// The server for a class object should call CoRevokeClassObject to revoke the class object (remove its registration) when all of
/// the following are true:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>There are no existing instances of the object definition.</term>
/// </item>
/// <item>
/// <term>There are no locks on the class object.</term>
/// </item>
/// <item>
/// <term>The application providing services to the class object is not under user control (not visible to the user on the display).</term>
/// </item>
/// </list>
/// <para>
/// After the class object is revoked, when its reference count reaches zero, the class object can be released, allowing the
/// application to exit. Note that <c>CoRegisterClassObject</c> calls IUnknown::AddRef and CoRevokeClassObject calls
/// IUnknown::Release, so the two functions form an <c>AddRef</c>/ <c>Release</c> pair.
/// </para>
/// <para>
/// As of Windows Server 2003, if a COM object application is registered as a service, COM verifies the registration. COM makes sure
/// the process ID of the service, in the service control manager (SCM), matches the process ID of the registering process. If not,
/// COM fails the registration. If the COM object application runs in the system account with no registry key, COM treats the
/// objects application identity as Launching User.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coregisterclassobject HRESULT
// CoRegisterClassObject( REFCLSID rclsid, LPUNKNOWN pUnk, DWORD dwClsContext, DWORD flags, LPDWORD lpdwRegister );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "d27bfa6c-194a-41f1-8fcf-76c4dff14a8a")]
public static extern HRESULT CoRegisterClassObject(in Guid rclsid, [MarshalAs(UnmanagedType.IUnknown)] object pUnk, CLSCTX dwClsContext, REGCLS flags, out uint lpdwRegister);
/// <summary>
/// Enables a downloaded DLL to register its custom interfaces within its running process so that the marshaling code will be able
/// to marshal those interfaces.
/// </summary>
/// <param name="riid">A pointer to the IID of the interface to be registered.</param>
/// <param name="rclsid">
/// A pointer to the CLSID of the DLL that contains the proxy/stub code for the custom interface specified by riid.
/// </param>
/// <returns>This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK.</returns>
/// <remarks>
/// <para>
/// Typically, the code responsible for marshaling an interface pointer into the current running process reads the
/// <c>HKEY_CLASSES_ROOT\Interfaces</c> section of the registry to obtain the CLSID of the DLL containing the ProxyStub code to be
/// loaded. To obtain the ProxyStub CLSIDs for an existing interface, the code calls the CoGetPSClsid function.
/// </para>
/// <para>
/// In some cases, however, it may be desirable or necessary for an in-process handler or in-process server to make its custom
/// interfaces available without writing to the registry. A DLL downloaded across a network may not even have permission to access
/// the local registry, and because the code originated on another computer, the user, for security purposes, may want to run it in
/// a restricted environment. Or a DLL may have custom interfaces that it uses to talk to a remote server and may also include the
/// ProxyStub code for those interfaces. In such cases, a DLL needs an alternative way to register its interfaces.
/// <c>CoRegisterPSClsid</c>, used in conjunction with CoRegisterClassObject, provides that alternative.
/// </para>
/// <para>Examples</para>
/// <para>A DLL would typically call <c>CoRegisterPSClsid</c> as shown in the following code fragment.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coregisterpsclsid HRESULT CoRegisterPSClsid( REFIID
// riid, REFCLSID rclsid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "a73dbd6d-d3f2-48d7-b053-b62f2f18f2d6")]
public static extern HRESULT CoRegisterPSClsid(in Guid riid, in Guid rclsid);
/// <summary>Registers the surrogate process through its ISurrogate interface pointer.</summary>
/// <param name="pSurrogate">A pointer to the ISurrogate interface on the surrogate process to be registered.</param>
/// <returns>This function returns S_OK to indicate that the surrogate process was registered successfully.</returns>
/// <remarks>
/// <para>
/// The <c>CoRegisterSurrogate</c> function sets a global interface pointer to the ISurrogate interface implemented on the surrogate
/// process. This pointer is set in the ole32 DLL loaded in the surrogate process. COM uses this global pointer in ole32 to call the
/// methods of <c>ISurrogate</c>. This function is usually called by the surrogate implementation when it is launched.
/// </para>
/// <para>
/// As of Windows Server 2003, if a COM object application is registered as a service, COM verifies the registration. COM makes sure
/// the process ID of the service, in the service control manager (SCM), matches the process ID of the registering process. If not,
/// COM fails the registration.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coregistersurrogate HRESULT CoRegisterSurrogate(
// LPSURROGATE pSurrogate );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "4d1c6ca6-ab21-429c-9433-7c95d9e757b5")]
public static extern HRESULT CoRegisterSurrogate(ISurrogate pSurrogate);
/// <summary>Destroys a previously marshaled data packet.</summary>
/// <param name="pStm">A pointer to the stream that contains the data packet to be destroyed. See IStream.</param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The data packet was successfully destroyed.</term>
/// </item>
/// <item>
/// <term>STG_E_INVALIDPOINTER</term>
/// <term>An error related to the pStm parameter.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>The CoInitialize or OleInitialize function was not called on the current thread before this function was called.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>Important</c> Security Note: Calling this method with untrusted data is a security risk. Call this method only with trusted
/// data. For more information, see Untrusted Data Security Risks.
/// </para>
/// <para>The <c>CoReleaseMarshalData</c> function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>The function reads a CLSID from the stream.</term>
/// </item>
/// <item>
/// <term>
/// If COM's default marshaling implementation is being used, the function gets an IMarshal pointer to an instance of the standard
/// unmarshaler. If custom marshaling is being used, the function creates a proxy by calling the CoCreateInstance function, passing
/// the CLSID it read from the stream, and requests an <c>IMarshal</c> interface pointer to the newly created proxy.
/// </term>
/// </item>
/// <item>
/// <term>Using whichever IMarshal interface pointer it has acquired, the function calls IMarshal::ReleaseMarshalData.</term>
/// </item>
/// </list>
/// <para>
/// You typically do not call this function. The only situation in which you might need to call this function is if you use custom
/// marshaling (write and use your own implementation of IMarshal). Examples of when <c>CoReleaseMarshalData</c> should be called
/// include the following situations:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>An attempt was made to unmarshal the data packet, but it failed.</term>
/// </item>
/// <item>
/// <term>A marshaled data packet was removed from a global table.</term>
/// </item>
/// </list>
/// <para>
/// As an analogy, the data packet can be thought of as a reference to the original object, just as if it were another interface
/// pointer being held on the object. Like a real interface pointer, that data packet must be released at some point. The use of
/// IMarshal::ReleaseMarshalData to release data packets is analogous to the use of IUnknown::Release to release interface pointers.
/// </para>
/// <para>
/// Note that you do not need to call <c>CoReleaseMarshalData</c> after a successful call of the CoUnmarshalInterface function; that
/// function releases the marshal data as part of the processing that it does.
/// </para>
/// <para>
/// <c>Important</c> You must call the <c>CoReleaseMarshalData</c> function in the same apartment that called CoMarshalInterface to
/// marshal the object into the stream. Failure to do this may cause the object reference held by the marshaled packet in the stream
/// to be leaked.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coreleasemarshaldata HRESULT CoReleaseMarshalData(
// LPSTREAM pStm );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "a642a20f-3a3c-46bc-b833-e424dab3a16d")]
public static extern HRESULT CoReleaseMarshalData(IStream pStm);
/// <summary>Decrements the global per-process reference count.</summary>
/// <returns>
/// If the server application should initiate its cleanup, the function returns 0; otherwise, the function returns a nonzero value.
/// </returns>
/// <remarks>
/// <para>
/// Servers can call <c>CoReleaseServerProcess</c> to decrement a global per-process reference count incremented through a call to CoAddRefServerProcess.
/// </para>
/// <para>
/// When that count reaches zero, OLE automatically calls CoSuspendClassObjects, which prevents new activation requests from coming
/// in. This permits the server to deregister its class objects from its various threads without worry that another activation
/// request may come in. New activation requests result in launching a new instance of the local server process.
/// </para>
/// <para>
/// The simplest way for a local server application to make use of these functions is to call CoAddRefServerProcess in the
/// constructor for each of its instance objects, and in each of its IClassFactory::LockServer methods when the fLock parameter is
/// <c>TRUE</c>. The server application should also call <c>CoReleaseServerProcess</c> in the destructor of each of its instance
/// objects, and in each of its <c>IClassFactory::LockServer</c> methods when the fLock parameter is <c>FALSE</c>. Finally, the
/// server application must check the return code from <c>CoReleaseServerProcess</c>; if it returns 0, the server application should
/// initiate its cleanup. This typically means that a server with multiple threads should signal its various threads to exit their
/// message loops and call CoRevokeClassObject and CoUninitialize.
/// </para>
/// <para>
/// If these APIs are used at all, they must be called in both the object instances and the LockServer method, otherwise the server
/// application may be shutdown prematurely. In-process Servers typically should not call CoAddRefServerProcess or <c>CoReleaseServerProcess</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coreleaseserverprocess ULONG
// CoReleaseServerProcess( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "b28d41e2-4144-413d-9963-14f2d4dc8876")]
public static extern uint CoReleaseServerProcess();
/// <summary>
/// Called by a server that can register multiple class objects to inform the SCM about all registered classes, and permits
/// activation requests for those class objects.
/// </summary>
/// <returns>This function returns S_OK to indicate that the CLSID was retrieved successfully.</returns>
/// <remarks>
/// <para>
/// Servers that can register multiple class objects call <c>CoResumeClassObjects</c> once, after having first called
/// CoRegisterClassObject, specifying REGCLS_LOCAL_SERVER | REGCLS_SUSPENDED for each CLSID the server supports. This function
/// causes OLE to inform the SCM about all the registered classes, and begins letting activation requests into the server process.
/// </para>
/// <para>
/// This reduces the overall registration time, and thus the server application startup time, by making a single call to the SCM, no
/// matter how many CLSIDs are registered for the server. Another advantage is that if the server has multiple apartments with
/// different CLSIDs registered in different apartments, or is a free-threaded server, no activation requests will come in until the
/// server calls <c>CoResumeClassObjects</c>. This gives the server a chance to register all of its CLSIDs and get properly set up
/// before having to deal with activation requests, and possibly shutdown requests.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coresumeclassobjects HRESULT CoResumeClassObjects( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "c2b6e8d8-99a1-4af3-9881-bfe6932e4a76")]
public static extern HRESULT CoResumeClassObjects();
/// <summary>Restores the authentication information on a thread of execution.</summary>
/// <returns>This function supports the standard return values, including S_OK to indicate success.</returns>
/// <remarks>
/// <para>
/// <c>CoRevertToSelf</c>, which is a helper function that calls IServerSecurity::RevertToSelf, restores the authentication
/// information on a thread to the authentication information on the thread before impersonation began.
/// </para>
/// <para><c>CoRevertToSelf</c> encapsulates the following common sequence of calls (error handling excluded):</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coreverttoself HRESULT CoRevertToSelf( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "8061ddbe-ed21-47f7-9ac4-b3ec910ff89d")]
public static extern HRESULT CoRevertToSelf();
/// <summary>
/// Informs OLE that a class object, previously registered with the CoRegisterClassObject function, is no longer available for use.
/// </summary>
/// <param name="dwRegister">A token previously returned from the CoRegisterClassObject function.</param>
/// <returns>
/// <para>
/// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The class object was revoked successfully.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// A successful call to <c>CoRevokeClassObject</c> means that the class object has been removed from the global class object table
/// (although it does not release the class object). If other clients still have pointers to the class object and have caused the
/// reference count to be incremented by calls to IUnknown::AddRef, the reference count will not be zero. When this occurs,
/// applications may benefit if subsequent calls (with the obvious exceptions of <c>AddRef</c> and IUnknown::Release) to the class
/// object fail. Note that CoRegisterClassObject calls <c>AddRef</c> and <c>CoRevokeClassObject</c> calls <c>Release</c>, so the two
/// functions form an <c>AddRef</c>/ <c>Release</c> pair.
/// </para>
/// <para>
/// An object application must call <c>CoRevokeClassObject</c> to revoke registered class objects before exiting the program. Class
/// object implementers should call <c>CoRevokeClassObject</c> as part of the release sequence. You must specifically revoke the
/// class object even when you have specified the flags value REGCLS_SINGLEUSE in a call to CoRegisterClassObject, indicating that
/// only one application can connect to the class object.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-corevokeclassobject HRESULT CoRevokeClassObject(
// DWORD dwRegister );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "90b9b9ca-b5b2-48f5-8c2a-b478b6daa7ec")]
public static extern HRESULT CoRevokeClassObject(uint dwRegister);
/// <summary>
/// Sets (registers) or resets (unregisters) a cancel object for use during subsequent cancel operations on the current thread.
/// </summary>
/// <param name="pUnk">
/// Pointer to the IUnknown interface on the cancel object to be set or reset on the current thread. If this parameter is
/// <c>NULL</c>, the topmost cancel object is reset.
/// </param>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The cancel object was successfully set or reset.</term>
/// </item>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>The cancel object cannot be set or reset at this time because of a block on cancel operations.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// For objects that support standard marshaling, the proxy object begins marshaling a method call by calling
/// <c>CoSetCancelObject</c> to register a cancel object for the current thread.
/// </para>
/// <para>
/// <c>CoSetCancelObject</c> calls QueryInterface for ICancelMethodCalls on the cancel object. If the cancel object does not
/// implement <c>ICancelMethodCalls</c>, <c>CoSetCancelObject</c> fails with E_NOINTERFACE. To disable cancel operations on a
/// custom-marshaled interface, the implementation of ICancelMethodCalls::Cancel should do nothing but return E_NOTIMPL, E_FAIL, or
/// some other appropriate value.
/// </para>
/// <para><c>CoSetCancelObject</c> calls AddRef on objects that it registers and Release on objects that it unregisters.</para>
/// <para><c>CoSetCancelObject</c> does not set or reset cancel objects for asynchronous methods.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cosetcancelobject HRESULT CoSetCancelObject(
// IUnknown *pUnk );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "0978e252-2206-4597-abf2-fe0dac32efc4")]
public static extern HRESULT CoSetCancelObject([In, MarshalAs(UnmanagedType.IUnknown)] object pUnk);
/// <summary>
/// Sets the authentication information that will be used to make calls on the specified proxy. This is a helper function for IClientSecurity::SetBlanket.
/// </summary>
/// <param name="pProxy">The proxy to be set.</param>
/// <param name="dwAuthnSvc">
/// The authentication service to be used. For a list of possible values, see Authentication Service Constants. Use RPC_C_AUTHN_NONE
/// if no authentication is required. If RPC_C_AUTHN_DEFAULT is specified, DCOM will pick an authentication service following its
/// normal security blanket negotiation algorithm.
/// </param>
/// <param name="dwAuthzSvc">
/// The authorization service to be used. For a list of possible values, see Authorization Constants. If RPC_C_AUTHZ_DEFAULT is
/// specified, DCOM will pick an authorization service following its normal security blanket negotiation algorithm. RPC_C_AUTHZ_NONE
/// should be used as the authorization service if NTLMSSP, Kerberos, or Schannel is used as the authentication service.
/// </param>
/// <param name="pServerPrincName">
/// <para>
/// The server principal name to be used with the authentication service. If COLE_DEFAULT_PRINCIPAL is specified, DCOM will pick a
/// principal name using its security blanket negotiation algorithm. If Kerberos is used as the authentication service, this value
/// must not be <c>NULL</c>. It must be the correct principal name of the server or the call will fail.
/// </para>
/// <para>
/// If Schannel is used as the authentication service, this value must be one of the msstd or fullsic forms described in Principal
/// Names, or <c>NULL</c> if you do not want mutual authentication.
/// </para>
/// <para>
/// Generally, specifying <c>NULL</c> will not reset the server principal name on the proxy; rather, the previous setting will be
/// retained. You must be careful when using <c>NULL</c> as pServerPrincName when selecting a different authentication service for
/// the proxy, because there is no guarantee that the previously set principal name would be valid for the newly selected
/// authentication service.
/// </para>
/// </param>
/// <param name="dwAuthnLevel">
/// The authentication level to be used. For a list of possible values, see Authentication Level Constants. If
/// RPC_C_AUTHN_LEVEL_DEFAULT is specified, DCOM will pick an authentication level following its normal security blanket negotiation
/// algorithm. If this value is none, the authentication service must also be none.
/// </param>
/// <param name="dwImpLevel">
/// The impersonation level to be used. For a list of possible values, see Impersonation Level Constants. If RPC_C_IMP_LEVEL_DEFAULT
/// is specified, DCOM will pick an impersonation level following its normal security blanket negotiation algorithm. If NTLMSSP is
/// the authentication service, this value must be RPC_C_IMP_LEVEL_IMPERSONATE or RPC_C_IMP_LEVEL_IDENTIFY. NTLMSSP also supports
/// delegate-level impersonation (RPC_C_IMP_LEVEL_DELEGATE) on the same computer. If Schannel is the authentication service, this
/// parameter must be RPC_C_IMP_LEVEL_IMPERSONATE.
/// </param>
/// <param name="pAuthInfo">
/// <para>
/// A pointer to an <c>RPC_AUTH_IDENTITY_HANDLE</c> value that establishes the identity of the client. The format of the structure
/// referred to by the handle depends on the provider of the authentication service.
/// </para>
/// <para>
/// For calls on the same computer, RPC logs on the user with the supplied credentials and uses the resulting token for the method call.
/// </para>
/// <para>
/// For NTLMSSP or Kerberos, the structure is a SEC_WINNT_AUTH_IDENTITY or SEC_WINNT_AUTH_IDENTITY_EX structure. The client can
/// discard pAuthInfo after calling the API. RPC does not keep a copy of the pAuthInfo pointer, and the client cannot retrieve it
/// later in the CoQueryProxyBlanket method.
/// </para>
/// <para>
/// If this parameter is <c>NULL</c>, DCOM uses the current proxy identity (which is either the process token or the impersonation
/// token). If the handle refers to a structure, that identity is used.
/// </para>
/// <para>
/// For Schannel, this parameter must be either a pointer to a CERT_CONTEXT structure that contains the client's X.509 certificate
/// or is <c>NULL</c> if the client wishes to make an anonymous connection to the server. If a certificate is specified, the caller
/// must not free it as long as any proxy to the object exists in the current apartment.
/// </para>
/// <para>
/// For Snego, this member is either <c>NULL</c>, points to a SEC_WINNT_AUTH_IDENTITY structure, or points to a
/// SEC_WINNT_AUTH_IDENTITY_EX structure. If it is <c>NULL</c>, Snego will pick a list of authentication services based on those
/// available on the client computer. If it points to a <c>SEC_WINNT_AUTH_IDENTITY_EX</c> structure, the structure's
/// <c>PackageList</c> member must point to a string containing a comma-separated list of authentication service names and the
/// <c>PackageListLength</c> member must give the number of bytes in the <c>PackageList</c> string. If <c>PackageList</c> is
/// <c>NULL</c>, all calls using Snego will fail.
/// </para>
/// <para>
/// If COLE_DEFAULT_AUTHINFO is specified for this parameter, DCOM will pick the authentication information following its normal
/// security blanket negotiation algorithm.
/// </para>
/// <para><c>CoSetProxyBlanket</c> will fail if pAuthInfo is set and one of the cloaking flags is set in the dwCapabilities parameter.</para>
/// </param>
/// <param name="dwCapabilities">
/// The capabilities of this proxy. For a list of possible values, see the EOLE_AUTHENTICATION_CAPABILITIES enumeration. The only
/// flags that can be set through this function are EOAC_MUTUAL_AUTH, EOAC_STATIC_CLOAKING, EOAC_DYNAMIC_CLOAKING,
/// EOAC_ANY_AUTHORITY (this flag is deprecated), EOAC_MAKE_FULLSIC, and EOAC_DEFAULT. Either EOAC_STATIC_CLOAKING or
/// EOAC_DYNAMIC_CLOAKING can be set if pAuthInfo is not set and Schannel is not the authentication service. (See Cloaking for more
/// information.) If any capability flags other than those mentioned here are set, <c>CoSetProxyBlanket</c> will fail.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>One or more arguments is invalid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>CoSetProxyBlanket</c> sets the authentication information that will be used to make calls on the specified proxy. This
/// function encapsulates the following sequence of common calls (error handling excluded).
/// </para>
/// <para>
/// This sequence calls QueryInterface on the proxy to get a pointer to IClientSecurity, and with the resulting pointer, calls
/// IClientSecurity::SetBlanket and then releases the pointer.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cosetproxyblanket HRESULT CoSetProxyBlanket(
// IUnknown *pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, OLECHAR *pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,
// RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("combaseapi.h", MSDNShortId = "c2e5e681-8fa5-4b02-b59d-ba796eb0dccf")]
public static extern HRESULT CoSetProxyBlanket([In, MarshalAs(UnmanagedType.IUnknown)] object pProxy, RPC_C_AUTHN dwAuthnSvc,
RPC_C_AUTHZ dwAuthzSvc, string pServerPrincName, RPC_C_AUTHN_LEVEL dwAuthnLevel, RPC_C_IMP_LEVEL dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, EOLE_AUTHENTICATION_CAPABILITIES dwCapabilities);
/// <summary>Prevents any new activation requests from the SCM on all class objects registered within the process.</summary>
/// <returns>This function returns S_OK to indicate that the activation of class objects was successfully suspended.</returns>
/// <remarks>
/// <c>CoSuspendClassObjects</c> prevents any new activation requests from the SCM on all class objects registered within the
/// process. Even though a process may call this function, the process still must call the CoRevokeClassObject function for each
/// CLSID it has registered, in the apartment it registered in. Applications typically do not need to call this function, which is
/// generally only called internally by OLE when used in conjunction with the CoReleaseServerProcess function.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cosuspendclassobjects HRESULT
// CoSuspendClassObjects( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "a9e526f8-b7c1-47ec-a6ab-91690d93119e")]
public static extern HRESULT CoSuspendClassObjects();
/// <summary>Switches the call context object used by CoGetCallContext.</summary>
/// <param name="pNewObject">
/// A pointer to an interface on the new call context object. COM stores this pointer without adding a reference to the pointer
/// until <c>CoSwitchCallContext</c> is called with another object. This parameter may be <c>NULL</c> if you are calling
/// <c>CoSwitchCallContext</c> to switch back to the original call context but there was no original call context.
/// </param>
/// <param name="ppOldObject">
/// The address of pointer variable that receives a pointer to the call context object of the call currently in progress. This value
/// is returned so that the original call context can be restored by the custom marshaller. The returned pointer will be <c>NULL</c>
/// if there was no call in progress.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>E_OUT_OF_MEMORY</term>
/// <term>Out of memory.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Custom marshallers call <c>CoSwitchCallContext</c> to change the call context object used by the CoGetCallContext function.
/// Before dispatching an arriving call, custom marshallers call <c>CoSwitchCallContext</c>, specifying the new context object.
/// After sending a reply, they must restore the original call context by calling <c>CoSwitchCallContext</c> again, this time
/// passing a pointer to the original context object.
/// </para>
/// <para>
/// <c>CoSwitchCallContext</c> does not add a reference to the new context object. Custom marshallers must ensure that the lifetime
/// of their context object continues throughout their call and until the call to restore the original context. Custom marshallers
/// should not release the value that they placed into the ppOldObject parameter when they set their context.
/// </para>
/// <para>Call context objects provided by custom marshallers should support the IServerSecurity interface.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-coswitchcallcontext HRESULT CoSwitchCallContext(
// IUnknown *pNewObject, IUnknown **ppOldObject );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "146855a2-97ec-4e71-88dc-316eaa1a24a0")]
public static extern HRESULT CoSwitchCallContext([In, MarshalAs(UnmanagedType.IUnknown)] object pNewObject,
[MarshalAs(UnmanagedType.IUnknown)] out object ppOldObject);
/// <summary>Allocates a block of task memory in the same way that IMalloc::Alloc does.</summary>
/// <param name="cb">The size of the memory block to be allocated, in bytes.</param>
/// <returns>If the function succeeds, it returns the allocated memory block. Otherwise, it returns <c>NULL</c>.</returns>
/// <remarks>
/// <para>
/// <c>CoTaskMemAlloc</c> uses the default allocator to allocate a memory block in the same way that IMalloc::Alloc does. It is not
/// necessary to call the CoGetMalloc function before calling <c>CoTaskMemAlloc</c>.
/// </para>
/// <para>
/// The initial contents of the returned memory block are undefined there is no guarantee that the block has been initialized. The
/// allocated block may be larger than cb bytes because of the space required for alignment and for maintenance information.
/// </para>
/// <para>
/// If cb is 0, <c>CoTaskMemAlloc</c> allocates a zero-length item and returns a valid pointer to that item. If there is
/// insufficient memory available, <c>CoTaskMemAlloc</c> returns <c>NULL</c>. Applications should always check the return value from
/// this function, even when requesting small amounts of memory, because there is no guarantee that the memory will be allocated.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cotaskmemalloc LPVOID CoTaskMemAlloc( SIZE_T cb );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "c4cb588d-9482-4f90-a92e-75b604540d5c")]
public static extern IntPtr CoTaskMemAlloc(SizeT cb);
/// <summary>Frees a block of task memory previously allocated through a call to the CoTaskMemAlloc or CoTaskMemRealloc function.</summary>
/// <param name="pv">A pointer to the memory block to be freed. If this parameter is <c>NULL</c>, the function has no effect.</param>
/// <returns>This function does not return a value.</returns>
/// <remarks>
/// <para>The <c>CoTaskMemFree</c> function uses the default OLE allocator.</para>
/// <para>
/// The number of bytes freed equals the number of bytes that were originally allocated or reallocated. After the call, the memory
/// block pointed to by pv is invalid and can no longer be used.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cotaskmemfree void CoTaskMemFree( _Frees_ptr_opt_
// LPVOID pv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "3d0af12e-fc74-4ef7-b2dd-e9da5d0483c7")]
public static extern void CoTaskMemFree(IntPtr pv);
/// <summary>Changes the size of a previously allocated block of task memory.</summary>
/// <param name="pv">A pointer to the memory block to be reallocated. This parameter can be <c>NULL</c>, as discussed in Remarks.</param>
/// <param name="cb">The size of the memory block to be reallocated, in bytes. This parameter can be 0, as discussed in Remarks.</param>
/// <returns>If the function succeeds, it returns the reallocated memory block. Otherwise, it returns <c>NULL</c>.</returns>
/// <remarks>
/// <para>
/// This function changes the size of a previously allocated memory block in the same way that IMalloc::Realloc does. It is not
/// necessary to call the CoGetMalloc function to get a pointer to the OLE allocator before calling <c>CoTaskMemRealloc</c>.
/// </para>
/// <para>
/// The pv parameter points to the beginning of the memory block. If pv is <c>NULL</c>, <c>CoTaskMemRealloc</c> allocates a new
/// memory block in the same way as the CoTaskMemAlloc function. If pv is not <c>NULL</c>, it should be a pointer returned by a
/// prior call to <c>CoTaskMemAlloc</c>.
/// </para>
/// <para>
/// The cb parameter specifies the size of the new block. The contents of the block are unchanged up to the shorter of the new and
/// old sizes, although the new block can be in a different location. Because the new block can be in a different memory location,
/// the pointer returned by <c>CoTaskMemRealloc</c> is not guaranteed to be the pointer passed through the pv argument. If pv is not
/// <c>NULL</c> and cb is 0, then the memory pointed to by pv is freed.
/// </para>
/// <para>
/// <c>CoTaskMemRealloc</c> returns a void pointer to the reallocated (and possibly moved) memory block. The return value is
/// <c>NULL</c> if the size is 0 and the buffer argument is not <c>NULL</c>, or if there is not enough memory available to expand
/// the block to the specified size. In the first case, the original block is freed; in the second case, the original block is unchanged.
/// </para>
/// <para>
/// The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. To get
/// a pointer to a type other than <c>void</c>, use a type cast on the return value.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cotaskmemrealloc LPVOID CoTaskMemRealloc( LPVOID pv,
// SIZE_T cb );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "83014a3e-198d-4b4b-91aa-0c0804c8e1bf")]
public static extern IntPtr CoTaskMemRealloc(IntPtr pv, SizeT cb);
/// <summary>
/// <para>Determines whether the call being executed on the server has been canceled by the client.</para>
/// </summary>
/// <returns>
/// <para>
/// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>RPC_S_CALLPENDING</term>
/// <term>The call is still pending and has not yet been canceled by the client.</term>
/// </item>
/// <item>
/// <term>RPC_E_CALL_CANCELED</term>
/// <term>The call has been canceled by the client.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Server objects should call <c>CoTestCancel</c> at least once before returning to detect client cancellation requests. Doing so
/// can save the server unnecessary work if the client has issued a cancellation request, and it can reduce the client's wait time
/// if it has set the cancel timeout as RPC_C_CANCEL_INFINITE_TIMEOUT. Furthermore, if the server object detects a cancellation
/// request before returning from a pending call, it can clean up any memory, marshaled interfaces, or handles it has created or obtained.
/// </para>
/// <para>
/// <c>CoTestCancel</c> calls CoGetCallContext to obtain the ICancelMethodCalls interface on the current cancel object and then
/// calls ICancelMethodCalls::TestCancel. Objects that implement custom marshaling should first call CoSwitchCallContext to install
/// the appropriate call context object.
/// </para>
/// <para>This function does not test cancellation for asynchronous calls.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cotestcancel HRESULT CoTestCancel( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "9432621a-be31-4b8b-83b6-069539ba06b4")]
public static extern HRESULT CoTestCancel();
/// <summary>Unmarshals an <c>HRESULT</c> type from the specified stream.</summary>
/// <param name="pstm">A pointer to the stream from which the <c>HRESULT</c> is to be unmarshaled.</param>
/// <param name="phresult">A pointer to the unmarshaled <c>HRESULT</c>.</param>
/// <returns>
/// <para>This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The HRESULT was unmarshaled successfully.</term>
/// </item>
/// <item>
/// <term>STG_E_INVALIDPOINTER</term>
/// <term>pStm is an invalid pointer.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You do not explicitly call this function unless you are performing custom marshaling (that is, writing your own implementation
/// of IMarshal), and your implementation needs to unmarshal an <c>HRESULT</c>.
/// </para>
/// <para>
/// You must use <c>CoUnmarshalHresult</c> to unmarshal <c>HRESULT</c> values previously marshaled by a call to the CoMarshalHresult function.
/// </para>
/// <para>This function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>an <c>HRESULT</c> from a stream.</term>
/// </item>
/// <item>
/// <term>Returns the <c>HRESULT</c>.</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-counmarshalhresult HRESULT CoUnmarshalHresult(
// LPSTREAM pstm, HRESULT *phresult );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "a45ef72c-d385-4012-9683-7d2cc6d68b6d")]
public static extern HRESULT CoUnmarshalHresult(IStream pstm, out HRESULT phresult);
/// <summary>
/// Initializes a newly created proxy using data written into the stream by a previous call to the CoMarshalInterface function, and
/// returns an interface pointer to that proxy.
/// </summary>
/// <param name="pStm">A pointer to the stream from which the interface is to be unmarshaled.</param>
/// <param name="riid">
/// A reference to the identifier of the interface to be unmarshaled. For <c>IID_NULL</c>, the returned interface is the one defined
/// by the stream, objref.iid.
/// </param>
/// <param name="ppv">
/// The address of pointer variable that receives the interface pointer requested in <paramref name="riid"/>. Upon successful
/// return, <paramref name="ppv"/> contains the requested interface pointer for the unmarshaled interface.
/// </param>
/// <returns>
/// <para>This function can return the standard return value E_FAIL, errors returned by CoCreateInstance, and the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The interface pointer was unmarshaled successfully.</term>
/// </item>
/// <item>
/// <term>STG_E_INVALIDPOINTER</term>
/// <term>pStm is an invalid pointer.</term>
/// </item>
/// <item>
/// <term>CO_E_NOTINITIALIZED</term>
/// <term>The CoInitialize or OleInitialize function was not called on the current thread before this function was called.</term>
/// </item>
/// <item>
/// <term>CO_E_OBJNOTCONNECTED</term>
/// <term>
/// The object application has been disconnected from the remoting system (for example, as a result of a call to the
/// CoDisconnectObject function).
/// </term>
/// </item>
/// <item>
/// <term>REGDB_E_CLASSNOTREG</term>
/// <term>An error occurred reading the registration database.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>The final QueryInterface of this function for the requested interface returned E_NOINTERFACE.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>Important</c> Security Note: Calling this method with untrusted data is a security risk. Call this method only with trusted
/// data. For more information, see Untrusted Data Security Risks.
/// </para>
/// <para>The <c>CoUnmarshalInterface</c> function performs the following tasks:</para>
/// <list type="number">
/// <item>
/// <term>Reads from the stream the CLSID to be used to create an instance of the proxy.</term>
/// </item>
/// <item>
/// <term>
/// Gets an IMarshal pointer to the proxy that is to do the unmarshaling. If the object uses COM's default marshaling
/// implementation, the pointer thus obtained is to an instance of the generic proxy object. If the marshaling is occurring between
/// two threads in the same process, the pointer is to an instance of the in-process free threaded marshaler. If the object provides
/// its own marshaling code, <c>CoUnmarshalInterface</c> calls the CoCreateInstance function, passing the CLSID it read from the
/// marshaling stream. <c>CoCreateInstance</c> creates an instance of the object's proxy and returns an <c>IMarshal</c> interface
/// pointer to the proxy.
/// </term>
/// </item>
/// <item>
/// <term>
/// Using whichever IMarshal interface pointer it has acquired, the function then calls IMarshal::UnmarshalInterface and, if
/// appropriate, IMarshal::ReleaseMarshalData.
/// </term>
/// </item>
/// </list>
/// <para>
/// The primary caller of this function is COM itself, from within interface proxies or stubs that unmarshal an interface pointer.
/// There are, however, some situations in which you might call <c>CoUnmarshalInterface</c>. For example, if you are implementing a
/// stub, your implementation would call <c>CoUnmarshalInterface</c> when the stub receives an interface pointer as a parameter in a
/// method call.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-counmarshalinterface HRESULT CoUnmarshalInterface(
// LPSTREAM pStm, REFIID riid, LPVOID *ppv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "d0eac0da-2f41-40c4-b756-31bc22752c17")]
public static extern HRESULT CoUnmarshalInterface(IStream pStm, in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
/// <summary>Waits for specified handles to be signaled or for a specified timeout period to elapse.</summary>
/// <param name="dwFlags">The wait options. Possible values are taken from the COWAIT_FLAGS enumeration.</param>
/// <param name="dwTimeout">The timeout period, in milliseconds.</param>
/// <param name="cHandles">The number of elements in the pHandles array.</param>
/// <param name="pHandles">An array of handles.</param>
/// <param name="lpdwindex">
/// <para>
/// A pointer to a variable that, when the returned status is S_OK, receives a value indicating the event that caused the function
/// to return. This value is usually the index into pHandles for the handle that was signaled.
/// </para>
/// <para>
/// If pHandles includes one or more handles to mutex objects, a value between WAIT_ABANDONED_0 and (WAIT_ABANDONED_0 + nCount– 1)
/// indicates the index into pHandles for the mutex that was abandoned.
/// </para>
/// <para>
/// If the COWAIT_ALERTABLE flag is set in dwFlags, a value of WAIT_IO_COMPLETION indicates the wait was ended by one or more
/// user-mode asynchronous procedure calls (APC) queued to the thread.
/// </para>
/// <para>See WaitForMultipleObjectsEx for more information.</para>
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <para>
/// <c>Note</c> The return value of <c>CoWaitForMultipleHandles</c> can be nondeterministic if the COWAIT_ALERTABLE flag is set in
/// dwFlags, or if pHandles includes one or more handles to mutex objects. The recommended workaround is to call
/// SetLastError(ERROR_SUCCESS) before <c>CoWaitForMultipleHandles</c>.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The required handle or handles were signaled.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>pHandles was NULL, lpdwindex was NULL, or dwFlags was not a value from the COWAIT_FLAGS enumeration.</term>
/// </item>
/// <item>
/// <term>RPC_E_NO_SYNC</term>
/// <term>The value of pHandles was 0.</term>
/// </item>
/// <item>
/// <term>RPC_S_CALLPENDING</term>
/// <term>The timeout period elapsed before the required handle or handles were signaled.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Depending on which flags are set in the dwFlags parameter, <c>CoWaitForMultipleHandles</c> blocks the calling thread until one
/// of the following events occurs:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// One or all of the handles is signaled. In the case of mutex objects, this condition is also satisfied by a mutex being abandoned.
/// </term>
/// </item>
/// <item>
/// <term>An asynchronous procedure call (APC) has been queued to the calling thread with a call to the QueueUserAPC function.</term>
/// </item>
/// <item>
/// <term>The timeout period expires.</term>
/// </item>
/// </list>
/// <para>
/// If the caller resides in a single-thread apartment, <c>CoWaitForMultipleHandles</c> enters the COM modal loop, and the thread's
/// message loop will continue to dispatch messages using the thread's message filter. If no message filter is registered for the
/// thread, the default COM message processing is used.
/// </para>
/// <para>
/// If the calling thread resides in a multithread apartment (MTA), <c>CoWaitForMultipleHandles</c> calls the
/// WaitForMultipleObjectsEx function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cowaitformultiplehandles HRESULT
// CoWaitForMultipleHandles( DWORD dwFlags, DWORD dwTimeout, ULONG cHandles, LPHANDLE pHandles, LPDWORD lpdwindex );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "3eeecd34-aa94-4a48-8b41-167a71b52860")]
public static extern HRESULT CoWaitForMultipleHandles(COWAIT_FLAGS dwFlags, uint dwTimeout, uint cHandles, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IntPtr[] pHandles, out uint lpdwindex);
/// <summary>
/// A replacement for CoWaitForMultipleHandles. This replacement API hides the options for <c>CoWaitForMultipleHandles</c> that are
/// not supported in ASTA.
/// </summary>
/// <param name="dwFlags">
/// CWMO_FLAGS flag controlling whether call/window message reentrancy is enabled from this wait. By default, neither COM calls nor
/// window messages are dispatched from <c>CoWaitForMultipleObjects</c> in ASTA.
/// </param>
/// <param name="dwTimeout">The timeout in milliseconds of the wait.</param>
/// <param name="cHandles">The length of the pHandles array. Must be &lt;= 56.</param>
/// <param name="pHandles">An array of handles to waitable kernel objects.</param>
/// <param name="lpdwindex">Receives the index of the handle that satisfied the wait.</param>
/// <returns>
/// Same return values as CoWaitForMultipleHandles, except the ASTA-specific CO_E_NOTSUPPORTED cases instead return E_INVALIDARG
/// from all apartment types.
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cowaitformultipleobjects HRESULT
// CoWaitForMultipleObjects( DWORD dwFlags, DWORD dwTimeout, ULONG cHandles, const HANDLE *pHandles, LPDWORD lpdwindex );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "7A14E4F4-20F0-43FF-8D64-9AAC34B8D56F")]
public static extern HRESULT CoWaitForMultipleObjects(CWMO_FLAGS dwFlags, uint dwTimeout, uint cHandles, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IntPtr[] pHandles, out uint lpdwindex);
/// <summary>
/// <para>
/// The <c>CreateStreamOnHGlobal</c> function creates a stream object that uses an HGLOBAL memory handle to store the stream
/// contents. This object is the OLE-provided implementation of the IStream interface.
/// </para>
/// <para>
/// The returned stream object supports both reading and writing, is not transacted, and does not support region locking. The object
/// calls the GlobalReAlloc function to grow the memory block as required.
/// </para>
/// <para>
/// <c>Tip</c> Consider using the SHCreateMemStream function, which produces better performance, or for Windows Store apps, consider
/// using InMemoryRandomAccessStream.
/// </para>
/// </summary>
/// <param name="hGlobal">
/// A memory handle allocated by the GlobalAlloc function, or if <c>NULL</c> a new handle is to be allocated instead. The handle
/// must be allocated as moveable and nondiscardable.
/// </param>
/// <param name="fDeleteOnRelease">
/// A value that indicates whether the underlying handle for this stream object should be automatically freed when the stream object
/// is released. If set to <c>FALSE</c>, the caller must free the hGlobal after the final release. If set to <c>TRUE</c>, the final
/// release will automatically free the hGlobal parameter.
/// </param>
/// <param name="ppstm">
/// The address of IStream* pointer variable that receives the interface pointer to the new stream object. Its value cannot be <c>NULL</c>.
/// </param>
/// <returns>This function supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following.</returns>
/// <remarks>
/// <para>If hGlobal is <c>NULL</c>, the function allocates a new memory handle and the stream is initially empty.</para>
/// <para>
/// If hGlobal is not <c>NULL</c>, the initial contents of the stream are the current contents of the memory block. Thus,
/// <c>CreateStreamOnHGlobal</c> can be used to open an existing stream in memory. The memory handle and its contents are
/// undisturbed by the creation of the new stream object.
/// </para>
/// <para>
/// The initial size of the stream is the size of hGlobal as returned by the GlobalSize function. Because of rounding, this is not
/// necessarily the same size that was originally allocated for the handle. If the logical size of the stream is important, follow
/// the call to this function with a call to the IStream::SetSize method.
/// </para>
/// <para>The new stream objects initial seek position is the beginning of the stream.</para>
/// <para>
/// After creating the stream object with <c>CreateStreamOnHGlobal</c>, call GetHGlobalFromStream to retrieve the memory handle
/// associated with the stream object.
/// </para>
/// <para>
/// If a memory handle is passed to <c>CreateStreamOnHGlobal</c> or if GetHGlobalFromStream is called, the memory handle of this
/// function can be directly accessed by the caller while it is still in use by the stream object. Appropriate caution should be
/// exercised in the use of this capability and its implications:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// Do not free the hGlobal memory handle during the lifetime of the stream object. IStream::Release must be called before freeing
/// the memory handle.
/// </term>
/// </item>
/// <item>
/// <term>
/// Do not call GlobalReAlloc to change the size of the memory handle during the lifetime of the stream object or its clones. This
/// may cause application crashes or memory corruption. Avoid creating multiple stream objects separately on the same memory handle,
/// because the IStream::Write and IStream::SetSize methods may internally call <c>GlobalReAlloc</c>. The IStream::Clone method can
/// be used to create a new stream object based on the same memory handle that will properly coordinate its access with the original
/// stream object.
/// </term>
/// </item>
/// <item>
/// <term>
/// If possible, avoid accessing the memory block during the lifetime of the stream object, because the object may internally call
/// GlobalReAlloc and do not make assumptions about its size and location. If the memory block must be accessed, the memory access
/// calls should be surrounded by calls to GlobalLock and GlobalUnLock.
/// </term>
/// </item>
/// <item>
/// <term>
/// Avoid calling the objects methods while you have the memory handle locked with GlobalLock. This can cause method calls to fail unpredictably.
/// </term>
/// </item>
/// </list>
/// <para>
/// If the caller sets the fDeleteOnRelease parameter to <c>FALSE</c>, then the caller must also free the hGlobal after the final
/// release. If the caller sets the fDeleteOnRelease parameter to <c>TRUE</c>, the final release will automatically free the hGlobal.
/// </para>
/// <para>
/// The memory handle passed as the hGlobal parameter must be allocated as movable and nondiscardable, as shown in the following example:
/// </para>
/// <para>
/// <c>CreateStreamOnHGlobal</c> will accept a memory handle allocated with GMEM_FIXED, but this usage is not recommended. HGLOBALs
/// allocated with <c>GMEM_FIXED</c> are not really handles and their value can change when they are reallocated. If the memory
/// handle was allocated with <c>GMEM_FIXED</c> and fDeleteOnRelease is <c>FALSE</c>, the caller must call GetHGlobalFromStream to
/// get the correct handle in order to free it.
/// </para>
/// <para>
/// Prior to Windows 7 and Windows Server 2008 R2, this implementation did not zero memory when calling GlobalReAlloc to grow the
/// memory block. Increasing the size of the stream with IStream::SetSize or by writing to a location past the current end of the
/// stream may leave portions of the newly allocated memory uninitialized.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-createstreamonhglobal HRESULT
// CreateStreamOnHGlobal( HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "413c107b-a943-4c02-9c00-aea708e876d7")]
public static extern HRESULT CreateStreamOnHGlobal(IntPtr hGlobal, [MarshalAs(UnmanagedType.Bool)] bool fDeleteOnRelease, out IStream ppstm);
/// <summary>
/// <para>Determines whether the DLL that implements this function is in use. If not, the caller can unload the DLL from memory.</para>
/// <para>
/// OLE does not provide this function. DLLs that support the OLE Component Object Model (COM) should implement and export <c>DllCanUnloadNow</c>.
/// </para>
/// </summary>
/// <returns>If the function succeeds, the return value is S_OK. Otherwise, it is S_FALSE.</returns>
/// <remarks>
/// <para>
/// A call to <c>DllCanUnloadNow</c> determines whether the DLL from which it is exported is still in use. A DLL is no longer in use
/// when it is not managing any existing objects (the reference count on all of its objects is 0).
/// </para>
/// <para>Notes to Callers</para>
/// <para>
/// You should not have to call <c>DllCanUnloadNow</c> directly. OLE calls it only through a call to the CoFreeUnusedLibraries
/// function. When it returns S_OK, <c>CoFreeUnusedLibraries</c> frees the DLL.
/// </para>
/// <para>Notes to Implementers</para>
/// <para>
/// You must implement <c>DllCanUnloadNow</c> in, and export it from, DLLs that are to be dynamically loaded through a call to the
/// CoGetClassObject function. (You also need to implement and export the DllGetClassObject function in the same DLL).
/// </para>
/// <para>
/// If a DLL loaded through a call to CoGetClassObject fails to export <c>DllCanUnloadNow</c>, the DLL will not be unloaded until
/// the application calls the CoUninitialize function to release the OLE libraries.
/// </para>
/// <para><c>DllCanUnloadNow</c> should return S_FALSE if there are any existing references to objects that the DLL manages.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-dllcanunloadnow HRESULT DllCanUnloadNow( );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "a47df9eb-97cb-4875-a121-1dabe7bc9db6")]
public static extern HRESULT DllCanUnloadNow();
/// <summary>
/// <para>Retrieves the class object from a DLL object handler or object application.</para>
/// <para>
/// OLE does not provide this function. DLLs that support the OLE Component Object Model (COM) must implement
/// <c>DllGetClassObject</c> in OLE object handlers or DLL applications.
/// </para>
/// </summary>
/// <param name="rclsid">The CLSID that will associate the correct data and code.</param>
/// <param name="riid">
/// A reference to the identifier of the interface that the caller is to use to communicate with the class object. Usually, this is
/// IID_IClassFactory (defined in the OLE headers as the interface identifier for IClassFactory).
/// </param>
/// <param name="ppv">
/// The address of a pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains
/// the requested interface pointer. If an error occurs, the interface pointer is <c>NULL</c>.
/// </param>
/// <returns>
/// <para>
/// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The object was retrieved successfully.</term>
/// </item>
/// <item>
/// <term>CLASS_E_CLASSNOTAVAILABLE</term>
/// <term>The DLL does not support the class (object definition).</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If a call to the CoGetClassObject function finds the class object that is to be loaded in a DLL, <c>CoGetClassObject</c> uses
/// the DLL's exported <c>DllGetClassObject</c> function.
/// </para>
/// <para>Notes to Callers</para>
/// <para>
/// You should not call <c>DllGetClassObject</c> directly. When an object is defined in a DLL, CoGetClassObject calls the
/// CoLoadLibrary function to load the DLL, which, in turn, calls <c>DllGetClassObject</c>.
/// </para>
/// <para>Notes to Implementers</para>
/// <para>You need to implement <c>DllGetClassObject</c> in (and export it from) DLLs that support COM.</para>
/// <para>Examples</para>
/// <para>
/// The following is an example (in C++) of an implementation of <c>DllGetClassObject</c>. In this example, <c>DllGetClassObject</c>
/// creates a class object and calls its QueryInterface method to retrieve a pointer to the interface requested in riid. The
/// implementation releases the reference it holds to the IClassFactory interface because it returns a reference-counted pointer to
/// <c>IClassFactory</c> to the caller.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-dllgetclassobject HRESULT DllGetClassObject(
// REFCLSID rclsid, REFIID riid, LPVOID *ppv );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "42c08149-c251-47f7-a81f-383975d7081c")]
public static extern HRESULT DllGetClassObject(in Guid rclsid, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object ppv);
/// <summary>
/// The <c>FreePropVariantArray</c> function calls PropVariantClear on each of the PROPVARIANT structures in the rgvars array to
/// make the value zero for each of the members of the array.
/// </summary>
/// <param name="cVariants">Count of elements in the PROPVARIANT array (rgvars).</param>
/// <param name="rgvars">
/// Pointer to an initialized array of PROPVARIANT structures for which any deallocatable elements are to be freed. On exit, all
/// zeroes are written to the <c>PROPVARIANT</c> structure (thus tagging them as VT_EMPTY).
/// </param>
/// <returns>This function returns HRESULT.</returns>
/// <remarks>
/// <para>
/// <c>FreePropVariantArray</c> calls PropVariantClear on an array of PROPVARIANT structures to clear all the valid members. All
/// valid <c>PROPVARIANT</c> structures are freed. If any of the <c>PROPVARIANT</c> structures contain illegal VT types, valid
/// members are freed and the function returns STG_E_INVALIDPARAMETER.
/// </para>
/// <para>Passing <c>NULL</c> for rgvars is legal, and produces a return code of S_OK.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-freepropvariantarray?redirectedfrom=MSDN HRESULT
// FreePropVariantArray( ULONG cVariants, PROPVARIANT *rgvars );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "2eefb57e-9311-46e1-9eed-e25aa3b5afaa")]
public static extern HRESULT FreePropVariantArray(uint cVariants, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] PROPVARIANT[] rgvars);
/// <summary>
/// The <c>GetHGlobalFromStream</c> function retrieves the global memory handle to a stream that was created through a call to the
/// CreateStreamOnHGlobal function.
/// </summary>
/// <param name="pstm">IStream pointer to the stream object previously created by a call to the CreateStreamOnHGlobal function.</param>
/// <param name="phglobal">Pointer to the current memory handle used by the specified stream object.</param>
/// <returns>This function returns HRESULT.</returns>
/// <remarks>
/// <para>
/// The handle <c>GetHGlobalFromStream</c> returns may be different from the original handle due to intervening GlobalReAlloc calls.
/// </para>
/// <para>This function can be called only from within the same process from which the byte array was created.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-gethglobalfromstream HRESULT GetHGlobalFromStream(
// LPSTREAM pstm, HGLOBAL *phglobal );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "79e39345-7a20-4b0f-bceb-f62de13d3260")]
public static extern HRESULT GetHGlobalFromStream(IStream pstm, out IntPtr phglobal);
/// <summary>Converts a string generated by the StringFromIID function back into the original interface identifier (IID).</summary>
/// <param name="lpsz">A pointer to the string representation of the IID.</param>
/// <param name="lpiid">A pointer to the requested IID on return.</param>
/// <returns>This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK.</returns>
/// <remarks>
/// The function converts the interface identifier in a way that guarantees different interface identifiers will always be converted
/// to different strings.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-iidfromstring HRESULT IIDFromString( LPCOLESTR lpsz,
// LPIID lpiid );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "7fa72a65-68f8-438e-8a0c-6e0e0208420d")]
public static extern HRESULT IIDFromString([MarshalAs(UnmanagedType.LPWStr)] string lpsz, out Guid lpiid);
/// <summary>Retrieves the ProgID for a given CLSID.</summary>
/// <param name="clsid">The CLSID for which the ProgID is to be requested.</param>
/// <param name="lplpszProgID">
/// The address of a pointer variable that receives the ProgID string. The string that represents clsid includes enclosing braces.
/// </param>
/// <returns>
/// <para>This function can return the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The ProgID was returned successfully.</term>
/// </item>
/// <item>
/// <term>REGDB_E_CLASSNOTREG</term>
/// <term>Class not registered in the registry.</term>
/// </item>
/// <item>
/// <term>REGDB_E_READREGDB</term>
/// <term>There was an error reading from the registry.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Every OLE object class listed in the <c>Insert Object</c> dialog box must have a programmatic identifier (ProgID), a string that
/// uniquely identifies a given class, stored in the registry. In addition to determining the eligibility for the <c>Insert
/// Object</c> dialog box, the ProgID can be used as an identifier in a macro programming language to identify a class. Finally, the
/// ProgID is also the class name used for an object of an OLE class that is placed in an OLE 1 container.
/// </para>
/// <para>
/// <c>ProgIDFromCLSID</c> uses entries in the registry to do the conversion. OLE application authors are responsible for ensuring
/// that the registry is configured correctly in the application's setup program.
/// </para>
/// <para>
/// The ProgID string must be different than the class name of any OLE 1 application, including the OLE 1 version of the same
/// application, if there is one. In addition, a ProgID string must not contain more than 39 characters, start with a digit, or,
/// except for a single period, contain any punctuation (including underscores).
/// </para>
/// <para>
/// The ProgID must never be shown to the user in the user interface. If you need a short displayable string for an object, call IOleObject::GetUserType.
/// </para>
/// <para>
/// Call the CLSIDFromProgID function to find the CLSID associated with a given ProgID. Be sure to free the returned ProgID when you
/// are finished with it by calling the CoTaskMemFree function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-progidfromclsid HRESULT ProgIDFromCLSID( REFCLSID
// clsid, LPOLESTR *lplpszProgID );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("combaseapi.h", MSDNShortId = "a863cbc2-f8ab-468a-8254-b273077a6a2b")]
public static extern HRESULT ProgIDFromCLSID(in Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID);
/// <summary>Creates an agile reference for an object specified by the given interface.</summary>
/// <param name="options">The options.</param>
/// <param name="riid">The interface ID of the object for which an agile reference is being obtained.</param>
/// <param name="pUnk">
/// Pointer to the interface to be encapsulated in an agile reference. It must be the same type as riid. It may be a pointer to an
/// in-process object or a pointer to a proxy of an object.
/// </param>
/// <param name="ppAgileReference">
/// The agile reference for the object. Call the Resolve method to localize the object into the apartment in which <c>Resolve</c> is called.
/// </param>
/// <returns>
/// <para>This function can return one of these values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The function completed successfully.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The options parameter in invalid.</term>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <term>The agile reference couldn't be constructed due to an out-of-memory condition.</term>
/// </item>
/// <item>
/// <term>E_NOINTERFACE</term>
/// <term>The pUnk parameter doesn't support the interface ID specified by the riid parameter.</term>
/// </item>
/// <item>
/// <term>CO_E_NOT_SUPPORTED</term>
/// <term>The object implements the INoMarshal interface.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Call the <c>RoGetAgileReference</c> function on an existing object to request an agile reference to the object. The object may
/// or may not be agile, but the returned IAgileReference is agile. The agile reference can be passed to another apartment within
/// the same process, where the original object is retrieved by using the <c>IAgileReference</c> interface.
/// </para>
/// <para>
/// This is conceptually similar to the existing Global Interface Table (GIT). Rather than interacting with the GIT, an
/// IAgileReference is obtained and used to retrieve the object directly. Just as the GIT is per-process only, agile references are
/// per-process and can't be marshaled.
/// </para>
/// <para>
/// The agile reference feature provides a performance improvement over the GIT. The agile reference performs eager marshaling by
/// default, which saves a cross-apartment call in cases where the object is retrieved from the agile reference in an apartment
/// that's different from where the agile reference was created. For additional performance improvement, users of the
/// <c>RoGetAgileReference</c> function can use the same interface to create an IAgileReference and resolve the original object.
/// This saves an additional QueryInterface call to obtain the desired interface from the resolved object.
/// </para>
/// <para>
/// For example, you have a non-agile object named CDemoExample, which implements the IDemo and IExample interfaces. Call the
/// <c>RoGetAgileReference</c> function and pass the object, with IID_IDemo. You get back an IAgileReference interface pointer,
/// which is agile, so you can pass it to a different apartment. In the other apartment, call the Resolve method, with IID_IExample.
/// You get back an IExample pointer that you can use within this apartment. This IExample pointer is an IExample proxy that's
/// connected to the original CDemoExample object. The agile reference handles the complexity of operations like manually marshaling
/// to a stream and unmarshaling on the other side of the apartment boundary.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-rogetagilereference HRESULT RoGetAgileReference(
// AgileReferenceOptions options , REFIID riid, IUnknown *pUnk, IAgileReference **ppAgileReference );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "D16224C7-1BB7-46F5-B66C-54D0B9679006")]
public static extern HRESULT RoGetAgileReference(AgileReferenceOptions options, in Guid riid, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnk, out IAgileReference ppAgileReference);
/// <summary>Converts a CLSID into a string of printable characters. Different CLSIDs always convert to different strings.</summary>
/// <param name="rclsid">The CLSID to be converted.</param>
/// <param name="lplpsz">
/// The address of a pointer variable that receives a pointer to the resulting string. The string that represents rclsid includes
/// enclosing braces.
/// </param>
/// <returns>This function can return the standard return values E_OUTOFMEMORY and S_OK.</returns>
/// <remarks>
/// <para>
/// <c>StringFromCLSID</c> calls the StringFromGUID2 function to convert a globally unique identifier (GUID) into a string of
/// printable characters.
/// </para>
/// <para>The caller is responsible for freeing the memory allocated for the string by calling the CoTaskMemFree function.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-stringfromclsid HRESULT StringFromCLSID( REFCLSID
// rclsid, LPOLESTR *lplpsz );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "61210ebd-cbf3-4e78-b077-53d2779053eb")]
public static extern HRESULT StringFromCLSID(in Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpsz);
/// <summary>Converts a globally unique identifier (GUID) into a string of printable characters.</summary>
/// <param name="rguid">The GUID to be converted.</param>
/// <param name="lpsz">
/// A pointer to a caller-allocated string variable to receive the resulting string. The string that represents rguid includes
/// enclosing braces.
/// </param>
/// <param name="cchMax">The number of characters available in the lpsz buffer.</param>
/// <returns>
/// If the function succeeds, the return value is the number of characters in the returned string, including the null terminator. If
/// the buffer is too small to contain the string, the return value is 0.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-stringfromguid2 int StringFromGUID2( REFGUID rguid,
// LPOLESTR lpsz, int cchMax );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "5f437658-b749-416b-805a-2afdac682660")]
public static extern int StringFromGUID2(in Guid rguid, [MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder lpsz, int cchMax);
/// <summary>Converts an interface identifier into a string of printable characters.</summary>
/// <param name="rclsid">The interface identifier to be converted.</param>
/// <param name="lplpsz">
/// The address of a pointer variable that receives a pointer to the resulting string. The string that represents rclsid includes
/// enclosing braces.
/// </param>
/// <returns>This function can return the standard return values E_OUTOFMEMORY and S_OK.</returns>
/// <remarks>The caller is responsible for freeing the memory allocated for the string by calling the CoTaskMemFree function.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-stringfromiid HRESULT StringFromIID( REFIID rclsid,
// LPOLESTR *lplpsz );
[DllImport(Lib.Ole32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("combaseapi.h", MSDNShortId = "92e59631-0675-4bca-bcd4-a1f83ab6ec8a")]
public static extern HRESULT StringFromIID(in Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpsz);
}
}