diff --git a/PInvoke/Ole/Ole32/ComBaseApi.cs b/PInvoke/Ole/Ole32/ComBaseApi.cs index f4b7e593..9bdc85bf 100644 --- a/PInvoke/Ole/Ole32/ComBaseApi.cs +++ b/PInvoke/Ole/Ole32/ComBaseApi.cs @@ -5,4251 +5,4255 @@ using Vanara.InteropServices; using static Vanara.PInvoke.Rpc; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +public static partial class Ole32 { - public static partial class Ole32 + /// If COLE_DEFAULT_PRINCIPAL is specified, DCOM will pick a principal name using its security blanket negotiation algorithm. + public const string COLE_DEFAULT_PRINCIPAL = null; + + /// Specifies options for the RoGetAgileReference function. + // 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 { - /// Specifies options for the RoGetAgileReference function. - // 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 - { - /// - /// Use the default marshaling behavior, which is to marshal interfaces when an agile reference to the interface is obtained. - /// - AGILEREFERENCE_DEFAULT, - - /// - /// 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. - /// - AGILEREFERENCE_DELAYEDMARSHAL - } + /// + /// Use the default marshaling behavior, which is to marshal interfaces when an agile reference to the interface is obtained. + /// + AGILEREFERENCE_DEFAULT, /// - /// Specifies the behavior of the CoWaitForMultipleHandles function. + /// 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. /// - // 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 - { - /// Dispatch calls needed for marshaling without dispatching arbitrary calls. - COWAIT_DEFAULT = 0, + AGILEREFERENCE_DELAYEDMARSHAL + } - /// - /// 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. - /// - COWAIT_WAITALL = 1, - - /// - /// 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. - /// - COWAIT_ALERTABLE = 2, - - /// - /// 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. - /// - COWAIT_INPUTAVAILABLE = 4, - - /// - /// Dispatch calls from CoWaitForMultipleHandles in an ASTA. Default is no call dispatch. This value has no meaning in other - /// apartment types and is ignored. - /// - COWAIT_DISPATCH_CALLS = 8, - - /// - /// 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. - /// - COWAIT_DISPATCH_WINDOW_MESSAGES = 0x10, - } - - /// Provides flags for the CoWaitForMultipleObjects function. - // 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 - { - /// No call dispatch. - CWMO_DEFAULT = 0, - - /// Dispatch calls from CoWaitForMultipleObjects (default is no call dispatch). - CWMO_DISPATCH_CALLS = 1, - - /// - CWMO_DISPATCH_WINDOW_MESSAGES = 2, - } + /// + /// Specifies the behavior of the CoWaitForMultipleHandles function. + /// + // 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 + { + /// Dispatch calls needed for marshaling without dispatching arbitrary calls. + COWAIT_DEFAULT = 0, /// - /// Controls the type of connections to a class object. + /// 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. /// - /// - /// - /// In CoRegisterClassObject, members of both the REGCLS and the CLSCTX enumerations, taken together, determine how the class - /// object is registered. - /// - /// - /// An EXE surrogate (in which DLL servers are run) calls CoRegisterClassObject to register a class factory using a new - /// REGCLS value, REGCLS_SURROGATE. - /// - /// - /// 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. - /// - /// - /// The following table summarizes the allowable REGCLS value combinations and the object registrations affected by the combinations. - /// - /// - /// - /// - /// REGCLS_SINGLEUSE - /// REGCLS_MULTIPLEUSE - /// REGCLS_MULTI_SEPARATE - /// Other - /// - /// - /// CLSCTX_INPROC_SERVER - /// Error - /// In-process - /// In-process - /// Error - /// - /// - /// CLSCTX_LOCAL_SERVER - /// Local - /// In-process/local - /// Local - /// Error - /// - /// - /// Both of the above - /// Error - /// In-process/local - /// In-process/local - /// Error - /// - /// - /// Other - /// Error - /// Error - /// Error - /// Error - /// - /// - /// - // 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 - { - /// - /// 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. - /// - REGCLS_SINGLEUSE = 0, - - /// - /// 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. - /// - REGCLS_MULTIPLEUSE = 1, - - /// - /// 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. - /// - REGCLS_MULTI_SEPARATE = 2, - - /// - /// 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. - /// - REGCLS_SUSPENDED = 4, - - /// - /// 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. - /// - REGCLS_SURROGATE = 8, - - /// - /// 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. - /// - REGCLS_AGILE = 0x10, - } - - /// Flags used by CoGetStdMarshalEx. - [PInvokeData("combaseapi.h", MSDNShortId = "405c5ff3-8702-48b3-9be9-df4a9461696e")] - public enum STDMSHLFLAGS - { - /// Indicates a client-side (handler) aggregated standard marshaler. - SMEXF_HANDLER = 0x0, - - /// Indicates a server-side aggregated standard marshaler. - SMEXF_SERVER = 0x01, - } - - /// Looks up a CLSID in the registry, given a ProgID. - /// A pointer to the ProgID whose CLSID is requested. - /// Receives a pointer to the retrieved CLSID on return. - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The CLSID was retrieved successfully. - /// - /// - /// CO_E_CLASSSTRING - /// The registered CLSID for the ProgID is invalid. - /// - /// - /// REGDB_E_WRITEREGDB - /// An error occurred writing the CLSID to the registry. See Remarks below. - /// - /// - /// - /// - /// Given a ProgID, CLSIDFromProgID looks up its associated CLSID in the registry. If the ProgID cannot be found in the - /// registry, CLSIDFromProgID 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, CLSIDFromProgID and CLSIDFromString are the only two functions that can be - /// used to generate a CLSID for an OLE 1 object. - /// - // 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); + COWAIT_WAITALL = 1, /// - /// Triggers automatic installation if the COMClassStore policy is enabled. - /// - /// This is analogous to the behavior of CoCreateInstance when neither CLSCTX_ENABLE_CODE_DOWNLOAD nor CLSCTX_NO_CODE_DOWNLOAD are specified. - /// + /// 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. /// - /// A pointer to the ProgID whose CLSID is requested. - /// Receives a pointer to the retrieved CLSID on return. - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The CLSID was retrieved successfully. - /// - /// - /// CO_E_CLASSSTRING - /// The registered CLSID for the ProgID is invalid. - /// - /// - /// REGDB_E_WRITEREGDB - /// An error occurred writing the CLSID to the registry. See Remarks below. - /// - /// - /// - /// - /// - /// 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). - /// - /// - /// If the COMClassStore Policy enables automatic installation, CLSCTX_NO_CODE_DOWNLOAD can be used to explicitly disallow download - /// for an activation. - /// - /// If either of the following registry values are enabled (meaning set to 1), automatic download of missing classes is enabled: - /// - /// - /// HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\App Management\ COMClassStore - /// - /// - /// HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\App Management\ COMClassStore - /// - /// - /// - // 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); - - /// Converts a string generated by the StringFromCLSID function back into the original CLSID. - /// The string representation of the CLSID. - /// A pointer to the CLSID. - /// - /// This function can return the standard return value E_INVALIDARG, as well as the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// NOERROR - /// The CLSID was obtained successfully. - /// - /// - /// CO_E_CLASSSTRING - /// The class string was improperly formatted. - /// - /// - /// REGDB_E_CLASSNOTREG - /// The CLSID corresponding to the class string was not found in the registry. - /// - /// - /// REGDB_E_READREGDB - /// The registry could not be opened for reading. - /// - /// - /// - // 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); - - /// Increments a global per-process reference count. - /// The current reference count. - /// - /// - /// Servers can call CoAddRefServerProcess 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 CoAddRefServerProcess - /// increments a global per-process reference count, and calling CoReleaseServerProcess decrements that count. - /// - /// - /// 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. - /// - /// - /// 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 - /// TRUE. The server application should also call CoReleaseServerProcess in the destruction of each of its instance objects, - /// and in each of its LockServer methods when the fLock parameter is FALSE. Finally, the server application should - /// pay attention to the return code from CoReleaseServerProcess 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. - /// - /// - /// 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 CoAddRefServerProcess or CoReleaseServerProcess. - /// - /// - // 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(); - - /// Adds an unmarshaler CLSID to the allowed list for the calling process only. - /// The CLSID of the unmarshaler to be added to the per-process allowed list. - /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. - /// - /// - /// Don't call the CoAllowUnmarshalerCLSID function until after CoInitializeSecurity has been called in the current process. - /// - /// - /// The CoAllowUnmarshalerCLSID 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 CoAllowUnmarshalerCLSID function is to - /// make the policy comparatively weaker. For this reason, only call CoAllowUnmarshalerCLSID 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. - /// - /// - /// For example, it's appropriate to call the CoAllowUnmarshalerCLSID function when an unmarshaler is known or believed to - /// have a vulnerability but is required by an app. Also, it's appropriate to call CoAllowUnmarshalerCLSID if the unmarshaler - /// is used in multiple processes, but only as part of an uncommon feature. Don't use the CoAllowUnmarshalerCLSID function as - /// a replacement for hardening the unmarshaler. - /// - /// - // 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); - - /// Requests cancellation of an outbound DCOM method call pending on a specified thread. - /// - /// 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. - /// - /// - /// The number of seconds CoCancelCall waits for the server to complete the outbound call after the client requests cancellation. - /// - /// - /// - /// This function can return the standard return values E_FAIL, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The cancellation request was made. - /// - /// - /// E_NOINTERFACE - /// There is no cancel object corresponding to the specified thread. - /// - /// - /// CO_E_CANCEL_DISABLED - /// Call cancellation is not enabled on the specified thread. - /// - /// - /// RPC_E_CALL_COMPLETE - /// The call was completed during the timeout interval. - /// - /// - /// RPC_E_CALL_CANCELED - /// The call was already canceled. - /// - /// - /// - /// - /// - /// CoCancelCall calls CoGetCancelObject and then ICancelMethodCalls::Cancel on the cancel object for the call being executed. - /// - /// This function does not locate cancel objects for asynchronous calls. - /// - /// 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. - /// - /// - // 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); - - /// Makes a private copy of the specified proxy. - /// A pointer to the IUnknown interface on the proxy to be copied. This parameter cannot be NULL. - /// - /// Address of the pointer variable that receives the interface pointer to the copy of the proxy. This parameter cannot be NULL. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// Indicates success. - /// - /// - /// E_INVALIDARG - /// One or more arguments are invalid. - /// - /// - /// - /// - /// - /// CoCopyProxy 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. CoSetProxyBlanket affects all the users of an instance of a proxy, so - /// creating a private copy of the proxy through a call to CoCopyProxy and then calling CoSetProxyBlanket (or - /// IClientSecurity::SetBlanket) using the copy eliminates the problem. - /// - /// This helper function encapsulates the following sequence of common calls (error handling excluded): - /// Local interfaces may not be copied. IUnknown and IClientSecurity are examples of existing local interfaces. - /// - /// 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 QueryInterface 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. - /// - /// - // 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); - - /// Creates an aggregatable object capable of context-dependent marshaling. - /// A pointer to the aggregating object's controlling IUnknown. - /// Address of the pointer variable that receives the interface pointer to the aggregatable marshaler. - /// - /// This function can return the standard return value E_OUTOFMEMORY, as well as the following value. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The marshaler was created. - /// - /// - /// - /// - /// - /// The CoCreateFreeThreadedMarshaler 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. - /// - /// The CoCreateFreeThreadedMarshaler function performs the following tasks: - /// - /// - /// Creates a free-threaded marshaler object. - /// - /// - /// - /// Aggregates this marshaler to the object specified by the punkOuter parameter. This object is normally the one whose interface - /// pointers are to be marshaled. - /// - /// - /// - /// - /// 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: - /// - /// - /// - /// Checks the destination context specified by the CoMarshalInterface function's dwDestContext parameter. - /// - /// - /// If the destination context is MSHCTX_INPROC, copies the interface pointer into the marshaling stream. - /// - /// - /// - /// If the destination context is any other value, finds or creates an instance of COM's default (standard) marshaler and delegates - /// marshaling to it. - /// - /// - /// - /// - /// 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 - /// CoCreateFreeThreadedMarshaler delegates the marshaling job to COM's default implementation. - /// - /// - /// Great care should be exercised in using the CoCreateFreeThreadedMarshaler 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: - /// - /// - /// - /// - /// 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. - /// - /// - /// - /// - /// 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. - /// - /// - /// - /// - // 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); - - /// Creates a GUID, a unique 128-bit integer used for CLSIDs and interface identifiers. - /// A pointer to the requested GUID. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The GUID was successfully created. - /// - /// - /// Errors returned by UuidCreate are wrapped as an HRESULT. - /// - /// - /// The CoCreateGuid function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use - /// CoCreateGuid 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. - /// - // 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); + COWAIT_ALERTABLE = 2, /// - /// Creates a single uninitialized object of the class associated with a specified CLSID. - /// - /// Call CoCreateInstance 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. - /// + /// 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. /// - /// The CLSID associated with the data and code that will be used to create the object. - /// - /// If NULL, indicates that the object is not being created as part of an aggregate. If non- NULL, pointer to the - /// aggregate object's IUnknown interface (the controlling IUnknown). - /// - /// - /// Context in which the code that manages the newly created object will run. The values are taken from the enumeration CLSCTX. - /// - /// A reference to the identifier of the interface to be used to communicate with the object. - /// - /// 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 NULL. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// An instance of the specified object class was successfully created. - /// - /// - /// REGDB_E_CLASSNOTREG - /// - /// 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. - /// - /// - /// - /// CLASS_E_NOAGGREGATION - /// This class cannot be created as part of an aggregate. - /// - /// - /// E_NOINTERFACE - /// - /// The specified class does not implement the requested interface, or the controlling IUnknown does not expose the requested interface. - /// - /// - /// - /// E_POINTER - /// The ppv parameter is NULL. - /// - /// - /// - /// - /// - /// The CoCreateInstance 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: - /// - /// - /// It is convenient to use CoCreateInstance 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. - /// - /// - /// 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. - /// - /// - // 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); + COWAIT_INPUTAVAILABLE = 4, /// - /// Creates an instance of a specific class on a specific computer. + /// Dispatch calls from CoWaitForMultipleHandles in an ASTA. Default is no call dispatch. This value has no meaning in other + /// apartment types and is ignored. /// - /// - /// The CLSID of the object to be created. - /// - /// - /// - /// If this parameter non- NULL, 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- NULL. - /// - /// - /// - /// A value from the CLSCTX enumeration. - /// - /// - /// - /// Information about the computer on which to instantiate the object. See COSERVERINFO. This parameter can be NULL, 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. - /// - /// - /// - /// The number of structures in pResults. This value must be greater than 0. - /// - /// - /// - /// An array of MULTI_QI structures. Each structure has three members: the identifier for a requested interface ( pIID), the - /// location to return the interface pointer ( pItf) and the return value of the call to QueryInterface ( hr). - /// - /// - /// - /// This function can return the standard return value E_INVALIDARG, as well as the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// Indicates success. - /// - /// - /// REGDB_E_CLASSNOTREG - /// - /// 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. - /// - /// - /// - /// CLASS_E_NOAGGREGATION - /// This class cannot be created as part of an aggregate. - /// - /// - /// CO_S_NOTALLINTERFACES - /// - /// 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. - /// - /// - /// - /// E_NOINTERFACE - /// None of the interfaces requested in the pResults array were successfully retrieved. - /// - /// - /// - /// - /// - /// CoCreateInstanceEx 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, CoCreateInstanceEx 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. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - // 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); - - /// Creates an instance of a specific class on a specific computer from within an app container. - /// The CLSID of the object to be created. - /// - /// If this parameter non- NULL, 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- NULL. - /// - /// A value from the CLSCTX enumeration. - /// Reserved for future use. - /// The number of structures in pResults. This value must be greater than 0. - /// - /// An array of MULTI_QI structures. Each structure has three members: the identifier for a requested interface ( pIID), the - /// location to return the interface pointer ( pItf) and the return value of the call to QueryInterface ( hr). - /// - /// - /// This function can return the standard return value E_INVALIDARG, as well as the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// Indicates success. - /// - /// - /// REGDB_E_CLASSNOTREG - /// - /// 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. - /// - /// - /// - /// CLASS_E_NOAGGREGATION - /// This class cannot be created as part of an aggregate. - /// - /// - /// CO_S_NOTALLINTERFACES - /// - /// 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. - /// - /// - /// - /// E_NOINTERFACE - /// None of the interfaces requested in the pResults array were successfully retrieved. - /// - /// - /// - /// - /// The CoCreateInstanceFromApp function is the same as the CoCreateInstanceEx function, with the following differences. - /// - /// - /// - /// The CoCreateInstanceFromApp function reads class registrations only from application contexts, and from the - /// HKLM\SOFTWARE\Classes\CLSID registry hive. - /// - /// - /// - /// - /// 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 REGDB_E_CLASSNOTREG. - /// - /// - /// - /// - /// The CoCreateInstanceFromApp function is available to Windows Store apps. Desktop applications can call this function, but - /// they have the same restrictions as Windows Store apps. - /// - /// - /// - /// - // 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); + COWAIT_DISPATCH_CALLS = 8, /// - /// Locates the implementation of a Component Object Model (COM) interface in a server process given an interface to a proxied object. + /// 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. /// - /// The process ID of the process that contains the proxy. - /// - /// 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. - /// - /// A structure that contains the process ID, the thread ID, and the address of the server. - /// - /// This function can return one of these values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The server information was successfully retrieved. - /// - /// - /// E_ACCESSDENIED - /// The caller is an app container, or the developer license is not installed. - /// - /// - /// RPC_E_INVALID_IPID - /// ui64ProxyAddress does not point to a proxy. - /// - /// - /// - /// - /// - /// The CoDecodeProxy 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. - /// - /// - /// Also, the CoDecodeProxy function enables the debugger to monitor cross-apartment function calls and fail such calls when appropriate. - /// - /// - /// You can call the CoDecodeProxy function from a 32-bit or 64-bit process. ui64ProxyAddress can be a 32-bit or 64-bit - /// address. The CoDecodeProxy 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. - /// - /// - // 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, out ServerInformation pServerInformation); + COWAIT_DISPATCH_WINDOW_MESSAGES = 0x10, + } - /// Releases the increment made by a previous call to the CoIncrementMTAUsage function. - /// A PVOID variable that was set by a previous call to the CoIncrementMTAUsage function. - /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. - /// - /// - /// 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. - /// - /// - /// You can call CoIncrementMTAUsage from one thread and CoDecrementMTAUsage from another as long as a cookie previously - /// returned by CoIncrementMTAUsage is passed to CoDecrementMTAUsage. - /// - /// - /// Don't call CoDecrementMTAUsage during process shutdown or inside dllmain. You can call CoDecrementMTAUsage before - /// the call to start the shutdown process. - /// - /// - // 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); + /// Provides flags for the CoWaitForMultipleObjects function. + // 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 + { + /// No call dispatch. + CWMO_DEFAULT = 0, + + /// Dispatch calls from CoWaitForMultipleObjects (default is no call dispatch). + CWMO_DISPATCH_CALLS = 1, + + /// + CWMO_DISPATCH_WINDOW_MESSAGES = 2, + } + + /// + /// Controls the type of connections to a class object. + /// + /// + /// + /// In CoRegisterClassObject, members of both the REGCLS and the CLSCTX enumerations, taken together, determine how the class + /// object is registered. + /// + /// + /// An EXE surrogate (in which DLL servers are run) calls CoRegisterClassObject to register a class factory using a new + /// REGCLS value, REGCLS_SURROGATE. + /// + /// + /// 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. + /// + /// + /// The following table summarizes the allowable REGCLS value combinations and the object registrations affected by the combinations. + /// + /// + /// + /// + /// REGCLS_SINGLEUSE + /// REGCLS_MULTIPLEUSE + /// REGCLS_MULTI_SEPARATE + /// Other + /// + /// + /// CLSCTX_INPROC_SERVER + /// Error + /// In-process + /// In-process + /// Error + /// + /// + /// CLSCTX_LOCAL_SERVER + /// Local + /// In-process/local + /// Local + /// Error + /// + /// + /// Both of the above + /// Error + /// In-process/local + /// In-process/local + /// Error + /// + /// + /// Other + /// Error + /// Error + /// Error + /// Error + /// + /// + /// + // 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 + { + /// + /// 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. + /// + REGCLS_SINGLEUSE = 0, /// - /// Undoes the action of a call to CoEnableCallCancellation. Disables cancellation of synchronous calls on the calling thread when - /// all calls to CoEnableCallCancellation are balanced by calls to CoDisableCallCancellation. + /// 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. /// - /// This parameter is reserved and must be NULL. - /// - /// - /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the - /// following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// Call cancellation was successfully disabled on the thread. - /// - /// - /// CO_E_CANCEL_DISABLED - /// - /// 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. - /// - /// - /// - /// - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// Unless you want to enable call cancellation on a thread at all times, you should pair calls to CoEnableCallCancellation with - /// calls to CoDisableCallCancellation. Call cancellation is disabled only if each successful call to - /// CoEnableCallCancellation is balanced by a successful call to CoDisableCallCancellation. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - // 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); + REGCLS_MULTIPLEUSE = 1, /// - /// - /// Disconnects all proxy connections that are being maintained on behalf of all interface pointers that point to objects in the - /// current context. - /// - /// - /// 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 CoDisconnectContext. - /// + /// 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. /// - /// - /// The time in milliseconds after which CoDisconnectContext returns even if the proxy connections for all objects have not - /// been disconnected. INFINITE is an acceptable value for this parameter. - /// - /// - /// - /// This function can return the standard return values E_FAIL, E_INVALIDARG, and E_OUTOFMEMORY, as well as the following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The proxy connections for all objects were successfully disconnected. - /// - /// - /// RPC_E_TIMEOUT - /// Not all proxy connections were successfully deleted in the time specified in dwTimeout. - /// - /// - /// CO_E_NOTSUPPORTED - /// The current context cannot be disconnected. - /// - /// - /// CONTEXT_E_WOULD_DEADLOCK - /// - /// 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. - /// - /// - /// - /// - /// - /// - /// The CoDisconnectContext 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. - /// - /// - /// The CoDisconnectContext function enables a server to correctly disconnect all external clients of all objects in the - /// current context. Default contexts cannot be disconnected. To use CoDisconnectContext, 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. - /// - /// - /// If CoDisconnectContext 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. - /// - /// - /// It is not safe to unload the DLL that hosts the service until CoDisconnectContext 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. - /// - /// The CoDisconnectContext function performs the following tasks: - /// - /// - /// Calls CoDisconnectObject on all objects in the current context. - /// - /// - /// Blocks until all objects have been disconnected or the time-out has expired. - /// - /// - /// The CoDisconnectContext function has the following limitations: - /// - /// - /// Asynchronous COM calls are not supported. - /// - /// - /// In-process objects must be registered and enabled using the CLSCTX_LOCAL_SERVER flag, or they will not be disconnected. - /// - /// - /// COM+ is not supported. - /// - /// - /// - /// COM interface pointers are context-sensitive. Therefore, any interface pointer created in the context to be disconnected can - /// only be used within that context. - /// - /// - /// - /// Examples - /// - // 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); + REGCLS_MULTI_SEPARATE = 2, /// - /// - /// Disconnects all remote process connections being maintained on behalf of all the interface pointers that point to a specified object. - /// - /// Only the process that actually manages the object should call CoDisconnectObject. + /// 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. /// - /// A pointer to any interface derived from IUnknown on the object to be disconnected. - /// This parameter is reserved and must be 0. - /// This function returns S_OK to indicate that all connections to remote processes were successfully deleted. - /// - /// - /// The CoDisconnectObject function enables a server to correctly disconnect all external clients to the object specified by pUnk. - /// - /// It performs the following tasks: - /// - /// - /// - /// 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) IMarshal implementation. - /// - /// - /// - /// - /// Using whichever IMarshal interface pointer it has acquired, the function then calls IMarshal::DisconnectObject to disconnect all - /// out-of-process clients. - /// - /// - /// - /// - /// An object's client does not call CoDisconnectObject to disconnect itself from the server (clients should use - /// IUnknown::Release for this purpose). Rather, an OLE server calls CoDisconnectObject to forcibly disconnect an object's - /// clients, usually in response to a user closing the server application. - /// - /// - /// Similarly, an OLE container that supports external links to its embedded objects can call CoDisconnectObject 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 CoDisconnectObject to close any existing connections. - /// - /// - /// CoDisconnectObject does not necessarily disconnect out-of-process clients immediately. If any marshaled calls are pending - /// on the server object, CoDisconnectObject disconnects the object only when those calls have returned. In the meantime, - /// CoDisconnectObject sets a flag that causes any new marshaled calls to return CO_E_OBJNOTCONNECTED. - /// - /// - // 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); - - /// Enables cancellation of synchronous calls on the calling thread. - /// This parameter is reserved and must be NULL. - /// This function can return the standard return values S_OK, E_FAIL, E_INVALIDARG, and E_OUTOFMEMORY. - /// - /// - /// 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 CoEnableCallCancellation first. - /// - /// - /// Unless you want to enable call cancellation on a thread at all times, you should pair calls to CoEnableCallCancellation - /// with calls to CoDisableCallCancellation. Call cancellation is disabled only if CoDisableCallCancellation has been called - /// once for each time CoEnableCallCancellation was called successfully. - /// - /// - /// 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. - /// - /// - // 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); + REGCLS_SUSPENDED = 4, /// - /// Returns the current time as a FILETIME structure. - /// Note This function is provided for compatibility with 16-bit Windows. + /// 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. /// - /// A pointer to the FILETIME structure that receives the current time. - /// This function returns S_OK to indicate success. - // 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); + REGCLS_SURROGATE = 8, /// - /// Unloads any DLLs that are no longer in use, probably because the DLL no longer has any instantiated COM objects outstanding. - /// Note This function is provided for compatibility with 16-bit Windows. + /// 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. /// - /// - /// Applications can call CoFreeUnusedLibraries 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. CoFreeUnusedLibraries internally calls DllCanUnloadNow for DLLs that - /// implement and export that function. - /// - // 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(); + REGCLS_AGILE = 0x10, + } - /// Unloads any DLLs that are no longer in use and whose unload delay has expired. - /// - /// 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. - /// - /// This parameter is reserved and must be 0. - /// - /// - /// COM supplies functions to reclaim memory held by DLLs containing components. The most commonly used function is - /// CoFreeUnusedLibraries. CoFreeUnusedLibraries 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. - /// - /// - /// 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. - /// - /// - /// 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 CoFreeUnusedLibrariesEx is called, each DLL on that list has its DllCanUnloadNow function - /// called. If DllCanUnloadNow returns S_FALSE (or is not exported), this DLL is not ready to be unloaded. If - /// DllCanUnloadNow returns S_OK, this DLL is moved off the active list to a "candidate-for-unloading" list. - /// - /// - /// Adding the DLL to the candidate-for-unloading list time-stamps the DLL dwUnloadDelay milliseconds from when this move occurs. - /// When CoFreeUnusedLibrariesEx (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. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - // 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); + /// Flags used by CoGetStdMarshalEx. + [PInvokeData("combaseapi.h", MSDNShortId = "405c5ff3-8702-48b3-9be9-df4a9461696e")] + public enum STDMSHLFLAGS + { + /// Indicates a client-side (handler) aggregated standard marshaler. + SMEXF_HANDLER = 0x0, - /// Returns the current apartment type and type qualifier. - /// APTTYPE enumeration value that specifies the type of the current apartment. - /// APTTYPEQUALIFIER enumeration value that specifies the type qualifier of the current apartment. - /// - /// Returns S_OK if the call succeeded. Otherwise, one of the following error codes is returned. - /// - /// - /// Return code - /// Description - /// - /// - /// E_FAIL - /// The call could not successfully query the current apartment type and type qualifier. - /// - /// - /// E_INVALIDARG - /// - /// An invalid parameter value was supplied to the function. Specifically, one or both of the parameters were set to NULL by the caller. - /// - /// - /// - /// CO_E_NOTINITIALIZED - /// CoInitialize or CoInitializeEx was not called on this thread prior to calling CoGetApartmentType. - /// - /// - /// - /// - /// On Windows platforms prior to Windows 7, the following actions must be taken on a thread to query the apartment type: - /// - /// - /// Call CoGetContextToken to obtain the current context token. - /// - /// - /// Cast the context token to an IUnknown* pointer. - /// - /// - /// Call the QueryInterface method on that pointer to obtain the IComThreadingInfo interface. - /// - /// - /// Call the GetCurrentApartmentType method of the IComThreadingInfo interface to obtain the current apartment type. - /// - /// - /// - /// 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 CoGetApartmentType function is recommended as it does not potentially - /// incur the Access Violation. - /// - /// - // 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); + /// Indicates a server-side aggregated standard marshaler. + SMEXF_SERVER = 0x01, + } - /// Retrieves the context of the current call on the current thread. - /// - /// 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. - /// - /// - /// Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppInterface contains - /// the requested interface pointer. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The context was retrieved successfully. - /// - /// - /// E_NOINTERFACE - /// The call context does not support the interface specified by riid. - /// - /// - /// - /// - /// CoGetCallContext 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. - /// - // 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); + /// Looks up a CLSID in the registry, given a ProgID. + /// A pointer to the ProgID whose CLSID is requested. + /// Receives a pointer to the retrieved CLSID on return. + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The CLSID was retrieved successfully. + /// + /// + /// CO_E_CLASSSTRING + /// The registered CLSID for the ProgID is invalid. + /// + /// + /// REGDB_E_WRITEREGDB + /// An error occurred writing the CLSID to the registry. See Remarks below. + /// + /// + /// + /// + /// Given a ProgID, CLSIDFromProgID looks up its associated CLSID in the registry. If the ProgID cannot be found in the + /// registry, CLSIDFromProgID 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, CLSIDFromProgID and CLSIDFromString are the only two functions that can be + /// used to generate a CLSID for an OLE 1 object. + /// + // 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); - /// Returns a pointer to a DWORD that contains the apartment ID of the caller's thread. - /// - /// 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. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_TRUE - /// The caller's thread ID is set and the caller is in the same process. - /// - /// - /// S_FALSE - /// The caller's thread ID is set and the caller is in a different process. - /// - /// - /// E_OUTOFMEMORY - /// The caller's thread ID was not set. - /// - /// - /// - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - // 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); + /// + /// Triggers automatic installation if the COMClassStore policy is enabled. + /// + /// This is analogous to the behavior of CoCreateInstance when neither CLSCTX_ENABLE_CODE_DOWNLOAD nor CLSCTX_NO_CODE_DOWNLOAD are specified. + /// + /// + /// A pointer to the ProgID whose CLSID is requested. + /// Receives a pointer to the retrieved CLSID on return. + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The CLSID was retrieved successfully. + /// + /// + /// CO_E_CLASSSTRING + /// The registered CLSID for the ProgID is invalid. + /// + /// + /// REGDB_E_WRITEREGDB + /// An error occurred writing the CLSID to the registry. See Remarks below. + /// + /// + /// + /// + /// + /// 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). + /// + /// + /// If the COMClassStore Policy enables automatic installation, CLSCTX_NO_CODE_DOWNLOAD can be used to explicitly disallow download + /// for an activation. + /// + /// If either of the following registry values are enabled (meaning set to 1), automatic download of missing classes is enabled: + /// + /// + /// HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\App Management\ COMClassStore + /// + /// + /// HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\App Management\ COMClassStore + /// + /// + /// + // 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); + + /// Converts a string generated by the StringFromCLSID function back into the original CLSID. + /// The string representation of the CLSID. + /// A pointer to the CLSID. + /// + /// This function can return the standard return value E_INVALIDARG, as well as the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// NOERROR + /// The CLSID was obtained successfully. + /// + /// + /// CO_E_CLASSSTRING + /// The class string was improperly formatted. + /// + /// + /// REGDB_E_CLASSNOTREG + /// The CLSID corresponding to the class string was not found in the registry. + /// + /// + /// REGDB_E_READREGDB + /// The registry could not be opened for reading. + /// + /// + /// + // 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); + + /// Increments a global per-process reference count. + /// The current reference count. + /// + /// + /// Servers can call CoAddRefServerProcess 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 CoAddRefServerProcess + /// increments a global per-process reference count, and calling CoReleaseServerProcess decrements that count. + /// + /// + /// 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. + /// + /// + /// 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 + /// TRUE. The server application should also call CoReleaseServerProcess in the destruction of each of its instance objects, + /// and in each of its LockServer methods when the fLock parameter is FALSE. Finally, the server application should + /// pay attention to the return code from CoReleaseServerProcess 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. + /// + /// + /// 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 CoAddRefServerProcess or CoReleaseServerProcess. + /// + /// + // 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(); + + /// Adds an unmarshaler CLSID to the allowed list for the calling process only. + /// The CLSID of the unmarshaler to be added to the per-process allowed list. + /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// + /// + /// Don't call the CoAllowUnmarshalerCLSID function until after CoInitializeSecurity has been called in the current process. + /// + /// + /// The CoAllowUnmarshalerCLSID 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 CoAllowUnmarshalerCLSID function is to + /// make the policy comparatively weaker. For this reason, only call CoAllowUnmarshalerCLSID 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. + /// + /// + /// For example, it's appropriate to call the CoAllowUnmarshalerCLSID function when an unmarshaler is known or believed to + /// have a vulnerability but is required by an app. Also, it's appropriate to call CoAllowUnmarshalerCLSID if the unmarshaler + /// is used in multiple processes, but only as part of an uncommon feature. Don't use the CoAllowUnmarshalerCLSID function as + /// a replacement for hardening the unmarshaler. + /// + /// + // 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); + + /// Requests cancellation of an outbound DCOM method call pending on a specified thread. + /// + /// 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. + /// + /// + /// The number of seconds CoCancelCall waits for the server to complete the outbound call after the client requests cancellation. + /// + /// + /// + /// This function can return the standard return values E_FAIL, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The cancellation request was made. + /// + /// + /// E_NOINTERFACE + /// There is no cancel object corresponding to the specified thread. + /// + /// + /// CO_E_CANCEL_DISABLED + /// Call cancellation is not enabled on the specified thread. + /// + /// + /// RPC_E_CALL_COMPLETE + /// The call was completed during the timeout interval. + /// + /// + /// RPC_E_CALL_CANCELED + /// The call was already canceled. + /// + /// + /// + /// + /// + /// CoCancelCall calls CoGetCancelObject and then ICancelMethodCalls::Cancel on the cancel object for the call being executed. + /// + /// This function does not locate cancel objects for asynchronous calls. + /// + /// 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. + /// + /// + // 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); + + /// Makes a private copy of the specified proxy. + /// A pointer to the IUnknown interface on the proxy to be copied. This parameter cannot be NULL. + /// + /// Address of the pointer variable that receives the interface pointer to the copy of the proxy. This parameter cannot be NULL. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// Indicates success. + /// + /// + /// E_INVALIDARG + /// One or more arguments are invalid. + /// + /// + /// + /// + /// + /// CoCopyProxy 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. CoSetProxyBlanket affects all the users of an instance of a proxy, so + /// creating a private copy of the proxy through a call to CoCopyProxy and then calling CoSetProxyBlanket (or + /// IClientSecurity::SetBlanket) using the copy eliminates the problem. + /// + /// This helper function encapsulates the following sequence of common calls (error handling excluded): + /// Local interfaces may not be copied. IUnknown and IClientSecurity are examples of existing local interfaces. + /// + /// 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 QueryInterface 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. + /// + /// + // 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); + + /// Creates an aggregatable object capable of context-dependent marshaling. + /// A pointer to the aggregating object's controlling IUnknown. + /// Address of the pointer variable that receives the interface pointer to the aggregatable marshaler. + /// + /// This function can return the standard return value E_OUTOFMEMORY, as well as the following value. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The marshaler was created. + /// + /// + /// + /// + /// + /// The CoCreateFreeThreadedMarshaler 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. + /// + /// The CoCreateFreeThreadedMarshaler function performs the following tasks: + /// + /// + /// Creates a free-threaded marshaler object. + /// + /// + /// + /// Aggregates this marshaler to the object specified by the punkOuter parameter. This object is normally the one whose interface + /// pointers are to be marshaled. + /// + /// + /// + /// + /// 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: + /// + /// + /// + /// Checks the destination context specified by the CoMarshalInterface function's dwDestContext parameter. + /// + /// + /// If the destination context is MSHCTX_INPROC, copies the interface pointer into the marshaling stream. + /// + /// + /// + /// If the destination context is any other value, finds or creates an instance of COM's default (standard) marshaler and delegates + /// marshaling to it. + /// + /// + /// + /// + /// 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 + /// CoCreateFreeThreadedMarshaler delegates the marshaling job to COM's default implementation. + /// + /// + /// Great care should be exercised in using the CoCreateFreeThreadedMarshaler 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: + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + // 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); + + /// Creates a GUID, a unique 128-bit integer used for CLSIDs and interface identifiers. + /// A pointer to the requested GUID. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The GUID was successfully created. + /// + /// + /// Errors returned by UuidCreate are wrapped as an HRESULT. + /// + /// + /// The CoCreateGuid function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use + /// CoCreateGuid 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. + /// + // 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); + + /// + /// Creates a single uninitialized object of the class associated with a specified CLSID. + /// + /// Call CoCreateInstance 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. + /// + /// + /// The CLSID associated with the data and code that will be used to create the object. + /// + /// If NULL, indicates that the object is not being created as part of an aggregate. If non- NULL, pointer to the + /// aggregate object's IUnknown interface (the controlling IUnknown). + /// + /// + /// Context in which the code that manages the newly created object will run. The values are taken from the enumeration CLSCTX. + /// + /// A reference to the identifier of the interface to be used to communicate with the object. + /// + /// 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 NULL. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// An instance of the specified object class was successfully created. + /// + /// + /// REGDB_E_CLASSNOTREG + /// + /// 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. + /// + /// + /// + /// CLASS_E_NOAGGREGATION + /// This class cannot be created as part of an aggregate. + /// + /// + /// E_NOINTERFACE + /// + /// The specified class does not implement the requested interface, or the controlling IUnknown does not expose the requested interface. + /// + /// + /// + /// E_POINTER + /// The ppv parameter is NULL. + /// + /// + /// + /// + /// + /// The CoCreateInstance 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: + /// + /// + /// It is convenient to use CoCreateInstance 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// Creates an instance of a specific class on a specific computer. + /// + /// + /// The CLSID of the object to be created. + /// + /// + /// + /// If this parameter non- NULL, 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- NULL. + /// + /// + /// + /// A value from the CLSCTX enumeration. + /// + /// + /// + /// Information about the computer on which to instantiate the object. See COSERVERINFO. This parameter can be NULL, 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. + /// + /// + /// + /// The number of structures in pResults. This value must be greater than 0. + /// + /// + /// + /// An array of MULTI_QI structures. Each structure has three members: the identifier for a requested interface ( pIID), the + /// location to return the interface pointer ( pItf) and the return value of the call to QueryInterface ( hr). + /// + /// + /// + /// This function can return the standard return value E_INVALIDARG, as well as the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// Indicates success. + /// + /// + /// REGDB_E_CLASSNOTREG + /// + /// 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. + /// + /// + /// + /// CLASS_E_NOAGGREGATION + /// This class cannot be created as part of an aggregate. + /// + /// + /// CO_S_NOTALLINTERFACES + /// + /// 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. + /// + /// + /// + /// E_NOINTERFACE + /// None of the interfaces requested in the pResults array were successfully retrieved. + /// + /// + /// + /// + /// + /// CoCreateInstanceEx 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, CoCreateInstanceEx 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. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// Creates an instance of a specific class on a specific computer from within an app container. + /// The CLSID of the object to be created. + /// + /// If this parameter non- NULL, 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- NULL. + /// + /// A value from the CLSCTX enumeration. + /// Reserved for future use. + /// The number of structures in pResults. This value must be greater than 0. + /// + /// An array of MULTI_QI structures. Each structure has three members: the identifier for a requested interface ( pIID), the + /// location to return the interface pointer ( pItf) and the return value of the call to QueryInterface ( hr). + /// + /// + /// This function can return the standard return value E_INVALIDARG, as well as the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// Indicates success. + /// + /// + /// REGDB_E_CLASSNOTREG + /// + /// 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. + /// + /// + /// + /// CLASS_E_NOAGGREGATION + /// This class cannot be created as part of an aggregate. + /// + /// + /// CO_S_NOTALLINTERFACES + /// + /// 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. + /// + /// + /// + /// E_NOINTERFACE + /// None of the interfaces requested in the pResults array were successfully retrieved. + /// + /// + /// + /// + /// The CoCreateInstanceFromApp function is the same as the CoCreateInstanceEx function, with the following differences. + /// + /// + /// + /// The CoCreateInstanceFromApp function reads class registrations only from application contexts, and from the + /// HKLM\SOFTWARE\Classes\CLSID registry hive. + /// + /// + /// + /// + /// 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 REGDB_E_CLASSNOTREG. + /// + /// + /// + /// + /// The CoCreateInstanceFromApp function is available to Windows Store apps. Desktop applications can call this function, but + /// they have the same restrictions as Windows Store apps. + /// + /// + /// + /// + // 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); + + /// + /// Locates the implementation of a Component Object Model (COM) interface in a server process given an interface to a proxied object. + /// + /// The process ID of the process that contains the proxy. + /// + /// 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. + /// + /// A structure that contains the process ID, the thread ID, and the address of the server. + /// + /// This function can return one of these values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The server information was successfully retrieved. + /// + /// + /// E_ACCESSDENIED + /// The caller is an app container, or the developer license is not installed. + /// + /// + /// RPC_E_INVALID_IPID + /// ui64ProxyAddress does not point to a proxy. + /// + /// + /// + /// + /// + /// The CoDecodeProxy 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. + /// + /// + /// Also, the CoDecodeProxy function enables the debugger to monitor cross-apartment function calls and fail such calls when appropriate. + /// + /// + /// You can call the CoDecodeProxy function from a 32-bit or 64-bit process. ui64ProxyAddress can be a 32-bit or 64-bit + /// address. The CoDecodeProxy 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. + /// + /// + // 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, out ServerInformation pServerInformation); + + /// Releases the increment made by a previous call to the CoIncrementMTAUsage function. + /// A PVOID variable that was set by a previous call to the CoIncrementMTAUsage function. + /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// + /// + /// 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. + /// + /// + /// You can call CoIncrementMTAUsage from one thread and CoDecrementMTAUsage from another as long as a cookie previously + /// returned by CoIncrementMTAUsage is passed to CoDecrementMTAUsage. + /// + /// + /// Don't call CoDecrementMTAUsage during process shutdown or inside dllmain. You can call CoDecrementMTAUsage before + /// the call to start the shutdown process. + /// + /// + // 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); + + /// + /// Undoes the action of a call to CoEnableCallCancellation. Disables cancellation of synchronous calls on the calling thread when + /// all calls to CoEnableCallCancellation are balanced by calls to CoDisableCallCancellation. + /// + /// This parameter is reserved and must be NULL. + /// + /// + /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the + /// following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// Call cancellation was successfully disabled on the thread. + /// + /// + /// CO_E_CANCEL_DISABLED + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// Unless you want to enable call cancellation on a thread at all times, you should pair calls to CoEnableCallCancellation with + /// calls to CoDisableCallCancellation. Call cancellation is disabled only if each successful call to + /// CoEnableCallCancellation is balanced by a successful call to CoDisableCallCancellation. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// + /// Disconnects all proxy connections that are being maintained on behalf of all interface pointers that point to objects in the + /// current context. + /// + /// + /// 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 CoDisconnectContext. + /// + /// + /// + /// The time in milliseconds after which CoDisconnectContext returns even if the proxy connections for all objects have not + /// been disconnected. INFINITE is an acceptable value for this parameter. + /// + /// + /// + /// This function can return the standard return values E_FAIL, E_INVALIDARG, and E_OUTOFMEMORY, as well as the following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The proxy connections for all objects were successfully disconnected. + /// + /// + /// RPC_E_TIMEOUT + /// Not all proxy connections were successfully deleted in the time specified in dwTimeout. + /// + /// + /// CO_E_NOTSUPPORTED + /// The current context cannot be disconnected. + /// + /// + /// CONTEXT_E_WOULD_DEADLOCK + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// The CoDisconnectContext 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. + /// + /// + /// The CoDisconnectContext function enables a server to correctly disconnect all external clients of all objects in the + /// current context. Default contexts cannot be disconnected. To use CoDisconnectContext, 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. + /// + /// + /// If CoDisconnectContext 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. + /// + /// + /// It is not safe to unload the DLL that hosts the service until CoDisconnectContext 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. + /// + /// The CoDisconnectContext function performs the following tasks: + /// + /// + /// Calls CoDisconnectObject on all objects in the current context. + /// + /// + /// Blocks until all objects have been disconnected or the time-out has expired. + /// + /// + /// The CoDisconnectContext function has the following limitations: + /// + /// + /// Asynchronous COM calls are not supported. + /// + /// + /// In-process objects must be registered and enabled using the CLSCTX_LOCAL_SERVER flag, or they will not be disconnected. + /// + /// + /// COM+ is not supported. + /// + /// + /// + /// COM interface pointers are context-sensitive. Therefore, any interface pointer created in the context to be disconnected can + /// only be used within that context. + /// + /// + /// + /// Examples + /// + // 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); + + /// + /// + /// Disconnects all remote process connections being maintained on behalf of all the interface pointers that point to a specified object. + /// + /// Only the process that actually manages the object should call CoDisconnectObject. + /// + /// A pointer to any interface derived from IUnknown on the object to be disconnected. + /// This parameter is reserved and must be 0. + /// This function returns S_OK to indicate that all connections to remote processes were successfully deleted. + /// + /// + /// The CoDisconnectObject function enables a server to correctly disconnect all external clients to the object specified by pUnk. + /// + /// It performs the following tasks: + /// + /// + /// + /// 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) IMarshal implementation. + /// + /// + /// + /// + /// Using whichever IMarshal interface pointer it has acquired, the function then calls IMarshal::DisconnectObject to disconnect all + /// out-of-process clients. + /// + /// + /// + /// + /// An object's client does not call CoDisconnectObject to disconnect itself from the server (clients should use + /// IUnknown::Release for this purpose). Rather, an OLE server calls CoDisconnectObject to forcibly disconnect an object's + /// clients, usually in response to a user closing the server application. + /// + /// + /// Similarly, an OLE container that supports external links to its embedded objects can call CoDisconnectObject 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 CoDisconnectObject to close any existing connections. + /// + /// + /// CoDisconnectObject does not necessarily disconnect out-of-process clients immediately. If any marshaled calls are pending + /// on the server object, CoDisconnectObject disconnects the object only when those calls have returned. In the meantime, + /// CoDisconnectObject sets a flag that causes any new marshaled calls to return CO_E_OBJNOTCONNECTED. + /// + /// + // 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); + + /// Enables cancellation of synchronous calls on the calling thread. + /// This parameter is reserved and must be NULL. + /// This function can return the standard return values S_OK, E_FAIL, E_INVALIDARG, and E_OUTOFMEMORY. + /// + /// + /// 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 CoEnableCallCancellation first. + /// + /// + /// Unless you want to enable call cancellation on a thread at all times, you should pair calls to CoEnableCallCancellation + /// with calls to CoDisableCallCancellation. Call cancellation is disabled only if CoDisableCallCancellation has been called + /// once for each time CoEnableCallCancellation was called successfully. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// Returns the current time as a FILETIME structure. + /// Note This function is provided for compatibility with 16-bit Windows. + /// + /// A pointer to the FILETIME structure that receives the current time. + /// This function returns S_OK to indicate success. + // 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); + + /// + /// Unloads any DLLs that are no longer in use, probably because the DLL no longer has any instantiated COM objects outstanding. + /// Note This function is provided for compatibility with 16-bit Windows. + /// + /// + /// Applications can call CoFreeUnusedLibraries 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. CoFreeUnusedLibraries internally calls DllCanUnloadNow for DLLs that + /// implement and export that function. + /// + // 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(); + + /// Unloads any DLLs that are no longer in use and whose unload delay has expired. + /// + /// 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. + /// + /// This parameter is reserved and must be 0. + /// + /// + /// COM supplies functions to reclaim memory held by DLLs containing components. The most commonly used function is + /// CoFreeUnusedLibraries. CoFreeUnusedLibraries 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. + /// + /// + /// 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. + /// + /// + /// 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 CoFreeUnusedLibrariesEx is called, each DLL on that list has its DllCanUnloadNow function + /// called. If DllCanUnloadNow returns S_FALSE (or is not exported), this DLL is not ready to be unloaded. If + /// DllCanUnloadNow returns S_OK, this DLL is moved off the active list to a "candidate-for-unloading" list. + /// + /// + /// Adding the DLL to the candidate-for-unloading list time-stamps the DLL dwUnloadDelay milliseconds from when this move occurs. + /// When CoFreeUnusedLibrariesEx (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. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// Returns the current apartment type and type qualifier. + /// APTTYPE enumeration value that specifies the type of the current apartment. + /// APTTYPEQUALIFIER enumeration value that specifies the type qualifier of the current apartment. + /// + /// Returns S_OK if the call succeeded. Otherwise, one of the following error codes is returned. + /// + /// + /// Return code + /// Description + /// + /// + /// E_FAIL + /// The call could not successfully query the current apartment type and type qualifier. + /// + /// + /// E_INVALIDARG + /// + /// An invalid parameter value was supplied to the function. Specifically, one or both of the parameters were set to NULL by the caller. + /// + /// + /// + /// CO_E_NOTINITIALIZED + /// CoInitialize or CoInitializeEx was not called on this thread prior to calling CoGetApartmentType. + /// + /// + /// + /// + /// On Windows platforms prior to Windows 7, the following actions must be taken on a thread to query the apartment type: + /// + /// + /// Call CoGetContextToken to obtain the current context token. + /// + /// + /// Cast the context token to an IUnknown* pointer. + /// + /// + /// Call the QueryInterface method on that pointer to obtain the IComThreadingInfo interface. + /// + /// + /// Call the GetCurrentApartmentType method of the IComThreadingInfo interface to obtain the current apartment type. + /// + /// + /// + /// 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 CoGetApartmentType function is recommended as it does not potentially + /// incur the Access Violation. + /// + /// + // 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); + + /// Retrieves the context of the current call on the current thread. + /// + /// 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. + /// + /// + /// Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppInterface contains + /// the requested interface pointer. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The context was retrieved successfully. + /// + /// + /// E_NOINTERFACE + /// The call context does not support the interface specified by riid. + /// + /// + /// + /// + /// CoGetCallContext 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. + /// + // 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); + + /// Returns a pointer to a DWORD that contains the apartment ID of the caller's thread. + /// + /// 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. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_TRUE + /// The caller's thread ID is set and the caller is in the same process. + /// + /// + /// S_FALSE + /// The caller's thread ID is set and the caller is in a different process. + /// + /// + /// E_OUTOFMEMORY + /// The caller's thread ID was not set. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// The globally unique identifier of an interface on the cancel object for the call to be canceled. This argument is usually IID_ICancelMethodCalls. + /// + /// Receives the address of a pointer to the interface specified by riid. + /// + /// + /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the + /// following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The call control object was retrieved successfully. + /// + /// + /// E_NOINTERFACE + /// The object on which the call is executing does not support the interface specified by riid. + /// + /// + /// + /// + /// + /// 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, CoGetCancelObject returns a cancel interface corresponding to the innermost call that + /// is pending on the thread and has registered a cancel object. + /// + /// This function does not locate cancel objects for asynchronous calls. + /// + // 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); + + /// + /// + /// Provides a pointer to an interface on a class object associated with a specified CLSID. CoGetClassObject locates, and if + /// necessary, dynamically loads the executable code required to do this. + /// + /// + /// Call CoGetClassObject 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. + /// + /// + /// The CLSID associated with the data and code that you will use to create the objects. + /// + /// 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. + /// + /// + /// A pointer to computer on which to instantiate the class object. If this parameter is NULL, 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. + /// + /// + /// 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. + /// + /// + /// The address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the + /// requested interface pointer. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// Location and connection to the specified class object was successful. + /// + /// + /// REGDB_E_CLASSNOTREG + /// + /// The CLSID is not properly registered. This error can also indicate that the value you specified in dwClsContext is not in the registry. + /// + /// + /// + /// E_NOINTERFACE + /// + /// 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. + /// + /// + /// + /// REGDB_E_READREGDB + /// There was an error reading the registration database. + /// + /// + /// CO_E_DLLNOTFOUND + /// Either the in-process DLL or handler DLL was not found (depending on the context). + /// + /// + /// CO_E_APPNOTFOUND + /// The executable (.exe) was not found (CLSCTX_LOCAL_SERVER only). + /// + /// + /// E_ACCESSDENIED + /// There was a general access failure on load. + /// + /// + /// CO_E_ERRORINDLL + /// There is an error in the executable image. + /// + /// + /// CO_E_APPDIDNTREG + /// The executable was launched, but it did not register the class object (and it may have shut down). + /// + /// + /// + /// + /// + /// 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). + /// + /// + /// A call to CoGetClassObject 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. + /// + /// + /// 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 NULL, refer to the CLSCTX enumeration. + /// + /// There are two places to find a CLSID for a class: + /// + /// + /// + /// The registry holds an association between CLSIDs and file suffixes, and between CLSIDs and file signatures for determining the + /// class of an object. + /// + /// + /// + /// When an object is saved to persistent storage, its CLSID is stored with its data. + /// + /// + /// + /// To create and initialize embedded or linked OLE document objects, it is not necessary to call CoGetClassObject directly. + /// Instead, call the OleCreate or OleCreate XXX function. These functions encapsulate the entire object instantiation and + /// initialization process, and call, among other functions, CoGetClassObject. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// 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. CoGetClassObject consults (as + /// appropriate for the context indicated) both the registry and the class objects that are currently registered by calling the + /// CoRegisterClassObject function. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// + /// Provides a pointer to an interface on a class object associated with a specified CLSID. CoGetClassObject locates, and if + /// necessary, dynamically loads the executable code required to do this. + /// + /// + /// Call CoGetClassObject 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. + /// + /// + /// The CLSID associated with the data and code that you will use to create the objects. + /// + /// 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. + /// + /// + /// A pointer to computer on which to instantiate the class object. If this parameter is NULL, 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. + /// + /// + /// 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. + /// + /// + /// The address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the + /// requested interface pointer. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// Location and connection to the specified class object was successful. + /// + /// + /// REGDB_E_CLASSNOTREG + /// + /// The CLSID is not properly registered. This error can also indicate that the value you specified in dwClsContext is not in the registry. + /// + /// + /// + /// E_NOINTERFACE + /// + /// 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. + /// + /// + /// + /// REGDB_E_READREGDB + /// There was an error reading the registration database. + /// + /// + /// CO_E_DLLNOTFOUND + /// Either the in-process DLL or handler DLL was not found (depending on the context). + /// + /// + /// CO_E_APPNOTFOUND + /// The executable (.exe) was not found (CLSCTX_LOCAL_SERVER only). + /// + /// + /// E_ACCESSDENIED + /// There was a general access failure on load. + /// + /// + /// CO_E_ERRORINDLL + /// There is an error in the executable image. + /// + /// + /// CO_E_APPDIDNTREG + /// The executable was launched, but it did not register the class object (and it may have shut down). + /// + /// + /// + /// + /// + /// 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). + /// + /// + /// A call to CoGetClassObject 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. + /// + /// + /// 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 NULL, refer to the CLSCTX enumeration. + /// + /// There are two places to find a CLSID for a class: + /// + /// + /// + /// The registry holds an association between CLSIDs and file suffixes, and between CLSIDs and file signatures for determining the + /// class of an object. + /// + /// + /// + /// When an object is saved to persistent storage, its CLSID is stored with its data. + /// + /// + /// + /// To create and initialize embedded or linked OLE document objects, it is not necessary to call CoGetClassObject directly. + /// Instead, call the OleCreate or OleCreate XXX function. These functions encapsulate the entire object instantiation and + /// initialization process, and call, among other functions, CoGetClassObject. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// 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. CoGetClassObject consults (as + /// appropriate for the context indicated) both the registry and the class objects that are currently registered by calling the + /// CoRegisterClassObject function. + /// + /// + /// 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. + /// + /// + // 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, [In, Optional] COSERVERINFO pvReserved, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 3)] out object ppv); + + /// Returns a pointer to an implementation of IObjContext for the current context. + /// A pointer to an implementation of IObjContext for the current context. + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The token was retrieved successfully. + /// + /// + /// E_POINTER + /// The caller did not pass a valid token pointer variable. + /// + /// + /// CO_E_NOTINITIALIZED + /// The caller is not in an initialized apartment. + /// + /// + /// + // 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); + + /// Returns the logical thread identifier of the current physical thread. + /// A pointer to a GUID that contains the logical thread ID on return. + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The logical thread ID was retrieved successfully. + /// + /// + /// E_INVALIDARG + /// An invalid pointer was passed in for the pguid parameter. + /// + /// + /// E_OUTOFMEMORY + /// A memory allocation failed during the operation of the function. + /// + /// + /// + /// + /// 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. + /// + // 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); + + /// + /// Returns a value that is unique to the current thread. CoGetCurrentProcess can be used to avoid thread ID reuse problems. + /// + /// The function returns the unique identifier of the current thread. + /// + /// + /// Using the value returned from a call to CoGetCurrentProcess can help you in maintaining tables that are keyed by threads + /// or in uniquely identifying a thread to other threads or processes. + /// + /// + /// CoGetCurrentProcess 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. + /// + /// + /// The value returned by CoGetCurrentProcess 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. + /// + /// + // 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(); + + /// Retrieves a reference to the default context of the specified apartment. + /// + /// The apartment type of the default context that is being requested. This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// APTTYPE_CURRENT -1 + /// The caller's apartment. + /// + /// + /// APTTYPE_MTA 1 + /// The multithreaded apartment for the current process. + /// + /// + /// APTTYPE_NA 2 + /// The neutral apartment for the current process. + /// + /// + /// APTTYPE_MAINSTA 3 + /// The main single-threaded apartment for the current process. + /// + /// + /// + /// The APTTYPE value APTTYPE_STA (0) is not supported. A process can contain multiple single-threaded apartments, each with its own + /// context, so CoGetDefaultContext could not determine which STA is of interest. Therefore, this function returns + /// E_INVALIDARG if APTTYPE_STA is specified. + /// + /// + /// + /// 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. + /// + /// + /// 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 CoGetDefaultContext function is called + /// from a constructor or an IUnknown method, this parameter is set to a NULL pointer. + /// + /// + /// This method can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The method completed successfully. + /// + /// + /// E_INVALIDARG + /// One of the parameters is invalid. + /// + /// + /// CO_E_NOTINITIALIZED + /// The caller is not in an initialized apartment. + /// + /// + /// E_NOINTERFACE + /// The object context does not support the interface specified by riid. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// An object should never pass an IObjectContext reference to another object. If you pass an IObjectContext reference to + /// another object, it is no longer a valid reference. + /// + /// + /// When an object obtains a reference to an IObjectContext, it must release the IObjectContext object when it is finished + /// with it. + /// + /// + // 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); + + /// + /// 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. + /// + /// A pointer to the IStream interface on the stream to be unmarshaled. + /// A reference to the identifier of the interface requested from the unmarshaled object. + /// + /// The address of pointer variable that receives the interface pointer requested in . Upon successful return, + /// contains the requested interface pointer to the unmarshaled interface. + /// + /// + /// This function can return the standard return values S_OK and E_INVALIDARG, as well as any of the values returned by CoUnmarshalInterface. + /// + /// + /// + /// Important 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. + /// + /// The CoGetInterfaceAndReleaseStream function performs the following tasks: + /// + /// + /// Calls CoUnmarshalInterface to unmarshal an interface pointer previously passed in a call to CoMarshalInterThreadInterfaceInStream. + /// + /// + /// + /// 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. + /// + /// + /// + /// + // 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); + + /// + /// 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. + /// + /// This parameter must be 1. + /// + /// The address of an IMalloc* pointer variable that receives the interface pointer to the memory allocator. + /// + /// This function can return the standard return values S_OK, E_INVALIDARG, and E_OUTOFMEMORY. + /// + /// 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. + /// + // 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); + + /// + /// Returns an upper bound on the number of bytes needed to marshal the specified interface pointer to the specified object. + /// + /// + /// 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. + /// + /// + /// A reference to the identifier of the interface whose pointer is to be marshaled. This interface must be derived from the + /// IUnknown interface. + /// + /// A pointer to the interface to be marshaled. This interface must be derived from the IUnknown interface. + /// + /// The destination context where the specified interface is to be unmarshaled. Values for dwDestContext come from the enumeration MSHCTX. + /// + /// This parameter is reserved and must be NULL. + /// + /// 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. + /// + /// + /// This function can return the standard return value E_UNEXPECTED, as well as the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The upper bound was returned successfully. + /// + /// + /// CO_E_NOTINITIALIZED + /// Before this function can be called, either the CoInitialize or OleInitialize function must be called. + /// + /// + /// + /// + /// This function performs the following tasks: + /// + /// + /// + /// Queries the object for an IMarshal pointer or, if the object does not implement IMarshal, gets a pointer to COM's + /// standard marshaler. + /// + /// + /// + /// Using the pointer obtained in the preceding item, calls IMarshal::GetMarshalSizeMax. + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// Returns the context for the current object. + /// + /// A reference to the ID of an interface that is implemented on the context object. + /// For objects running within COM applications, IID_IComThreadingInfo, IID_IContext, and IID_IContextCallback are available. + /// + /// For objects running within COM+ applications, IID_IObjectContext, IID_IObjectContextActivity IID_IObjectContextInfo, and + /// IID_IContextState are available. + /// + /// + /// The address of a pointer to the interface specified by riid on the context object. + /// + /// This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The object context was successfully retrieved. + /// + /// + /// E_NOINTERFACE + /// The requested interface was not available. + /// + /// + /// CO_E_NOTINITIALIZED + /// Before this function can be called, the CoInitializeEx function must be called on the current thread. + /// + /// + /// + /// + /// + /// CoGetObjectContext 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. + /// + /// + /// For components running within COM applications, the following interfaces are supported for accessing context properties: + /// IComThreadingInfo, IContext, and IContextCallback. + /// + /// + /// For components running within COM+ applications, the following interfaces are supported for accessing context properties: + /// IObjectContext, IObjectContextActivity, IObjectContextInfo, and IContextState. + /// + /// + // 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); + + /// Returns the CLSID of the DLL that implements the proxy and stub for the specified interface. + /// The interface whose proxy/stub CLSID is to be returned. + /// Specifies where to store the proxy/stub CLSID for the interface specified by riid. + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The proxy/stub CLSID was successfully returned. + /// + /// + /// E_INVALIDARG + /// One of the parameters is invalid. + /// + /// + /// E_OUTOFMEMORY + /// There is insufficient memory to complete this operation. + /// + /// + /// + /// + /// The CoGetPSClsid function looks at the HKEY_CLASSES_ROOT<b>Interfaces<i>{string form of + /// riid}<b>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. + /// + // 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); + + /// + /// 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. + /// + /// + /// A reference to the identifier of the interface whose pointer is to be marshaled. This interface must be derived from the + /// IUnknown interface. + /// + /// A pointer to the interface to be marshaled. + /// + /// 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). + /// + /// This parameter is reserved and must be NULL. + /// + /// 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. + /// + /// + /// The address of IMarshal* pointer variable that receives the interface pointer to the standard marshaler. + /// + /// + /// + /// This function can return the standard return values E_FAIL, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The IMarshal instance was returned successfully. + /// + /// + /// CO_E_NOTINITIALIZED + /// Before this function can be called, the CoInitialize or OleInitialize function must be called on the current thread. + /// + /// + /// + /// + /// + /// The CoGetStandardMarshal 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 IMarshal, + /// you may want your implementation to call CoGetStandardMarshal 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. + /// + /// + /// 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 + /// CoGetStandardMarshal, passing a NULL 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. + /// + /// + /// If your OLE server application's implementation of IMarshal calls CoGetStandardMarshal, you should pass both the IID of + /// (riid), and a pointer to (pUnk), the interface being requested. + /// + /// This function performs the following tasks: + /// + /// + /// Determines whether pUnk is NULL. + /// + /// + /// + /// If pUnk is NULL, creates a standard interface proxy in the client process for the specified riid and returns the proxy's + /// IMarshal pointer. + /// + /// + /// + /// + /// If pUnk is not NULL, checks to see if a marshaler for the object already exists, creates a new one if necessary, and + /// returns the marshaler's IMarshal pointer. + /// + /// + /// + /// + // 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); + + /// Creates an aggregated standard marshaler for use with lightweight client-side handlers. + /// A pointer to the controlling IUnknown. + /// + /// + /// 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 STDMSHLFLAGS enumeration. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SMEXF_SERVER 0x01 + /// Indicates a server-side aggregated standard marshaler. + /// + /// + /// SMEXF_HANDLER 0x0 + /// Indicates a client-side (handler) aggregated standard marshaler. + /// + /// + /// + /// + /// On successful return, address of pointer to the IUnknown interface on the newly-created aggregated standard marshaler. If an + /// error occurs, this value is NULL. + /// + /// This function returns S_OK. + /// + /// The server calls CoGetStdMarshalEx passing in the flag SMEXF_SERVER. This creates a server side standard marshaler (known + /// as a stub manager). The handler calls CoGetStdMarshalEx 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. + /// + // 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); + + /// Returns the CLSID of an object that can emulate the specified object. + /// The CLSID of the object that can be emulated (treated as) an object with a different CLSID. + /// + /// A pointer to where the CLSID that can emulate clsidOld objects is retrieved. This parameter cannot be NULL. If there is + /// no emulation information for clsidOld objects, the clsidOld parameter is supplied. + /// + /// + /// This function can return the following values, as well as any error values returned by the CLSIDFromString function. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// A new CLSID was successfully returned. + /// + /// + /// S_FALSE + /// There is no emulation information for the clsidOld parameter, so the pClsidNew parameter is set to clsidOld. + /// + /// + /// REGDB_E_READREGDB + /// There was an error reading the registry. + /// + /// + /// + /// + /// CoGetTreatAsClass returns the TreatAs entry in the registry for the specified object. The TreatAs entry, if set, + /// is the CLSID of a registered object (an application) that can emulate the object in question. The TreatAs 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 + /// TreatAs entry for the specified object, this function returns the CLSID of the original object (clsidOld). + /// + // 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); + + /// Enables the server to impersonate the client of the current call for the duration of the call. + /// This function supports the standard return values, including S_OK. + /// + /// + /// 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): + /// + /// + /// CoImpersonateClient 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. + /// + /// + // 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(); + + /// Keeps MTA support active when no MTA threads are running. + /// + /// Address of a PVOID variable that receives the cookie for the CoDecrementMTAUsage function, or NULL if the call fails. + /// + /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// + /// + /// The CoIncrementMTAUsage function enables clients to create MTA workers and wait on them for completion before exiting the process. + /// + /// + /// The CoIncrementMTAUsage function ensures that the system doesn't free resources related to MTA support., even if the MTA + /// thread count goes to 0. + /// + /// On success, call the CoDecrementMTAUsage once only. On failure, don't call the CoDecrementMTAUsage function. + /// + /// Don't call CoIncrementMTAUsage during process shutdown or inside dllmain. You can call CoIncrementMTAUsage before + /// the call to start the shutdown process. + /// + /// + /// You can call CoIncrementMTAUsage from one thread and CoDecrementMTAUsage from another as long as a cookie previously + /// returned by CoIncrementMTAUsage is passed to CoDecrementMTAUsage. + /// + /// + /// CoIncrementMTAUsage creates the MTA, if the MTA does not already exist. CoIncrementMTAUsage puts the current + /// thread into the MTA, if the current thread is not already in an apartment + /// + /// You can use CoIncrementMTAUsage when: + /// + /// + /// You want a server to keep the MTA alive even when all worker threads are idle. + /// + /// + /// + /// 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. + /// + /// + /// + /// + // 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); + + /// + /// Tells the service control manager to flush any cached RPC binding handles for the specified computer. + /// Only administrators may call this function. + /// + /// + /// 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. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// Indicates success. + /// + /// + /// CO_S_MACHINENAMENOTFOUND + /// + /// 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. + /// + /// + /// + /// E_ACCESSDENIED + /// Indicates the caller was not an administrator for this computer. + /// + /// + /// E_INVALIDARG + /// Indicates that a NULL value was passed for pszMachineName. + /// + /// + /// + /// + /// + /// 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. CoInvalidateRemoteMachineBindings is used for this purpose. + /// + /// + /// The OLE Service Control Manager will flush unused binding handles over time. It is not necessary to call + /// CoInvalidateRemoteMachineBindings to do this. + /// + /// + // 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); + + /// Determines whether a remote object is connected to the corresponding in-process object. + /// A pointer to the controlling IUnknown interface on the remote object. + /// + /// If the object is not remote or if it is remote and still connected, the return value is TRUE; otherwise, it is FALSE. + /// + /// + /// The CoIsHandlerConnected 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 TRUE 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 FALSE 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. + /// + // 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); + + /// Called either to lock an object to ensure that it stays in memory, or to release such a lock. + /// A pointer to the IUnknown interface on the object to be locked or unlocked. + /// + /// Indicates whether the object is to be locked or released. If this parameter is TRUE, the object is kept in memory, + /// independent of AddRef/ Release operations, registrations, or revocations. If this parameter is FALSE, the + /// lock previously set with a call to this function is released. + /// + /// + /// + /// If the lock is the last reference that is supposed to keep an object alive, specify TRUE to release all pointers to the + /// object (there may be other references that are not supposed to keep it alive). Otherwise, specify FALSE. + /// + /// If fLock is TRUE, this parameter is ignored. + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, and S_OK. + /// + /// + /// The CoLockObjectExternal 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). + /// + /// + /// The CoLockObjectExternal 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 CoLockObjectExternal with fLock set to FALSE. 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. + /// + /// + /// 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 + /// CoLockObjectExternal), the application can call the CoDisconnectObject function to force these connections to close prior + /// to shutdown. + /// + /// + /// Calling CoLockObjectExternal 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. + /// + /// The CoLockObjectExternal function is typically called in the following situations: + /// + /// + /// + /// Object servers should call CoLockObjectExternal with both fLock and fLastLockReleases set to TRUE 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 + /// CoLockObjectExternal, setting fLock to FALSE and fLastLockReleases to TRUE. + /// + /// + /// + /// A call to CoLockObjectExternal on the server can also be used in the implementation of IOleContainer::LockContainer. + /// + /// + /// + /// There are several things to be aware of when you use CoLockObjectExternal in the implementation of LockContainer. An + /// embedded object would call LockContainer 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. + /// + /// + /// Unless an application manages all aspects of its application and document shutdown completely with calls to + /// CoLockObjectExternal, 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 CoLockObjectExternal should be called whenever one of the following conditions occur: + /// + /// + /// + /// A document is created and destroyed or made visible or invisible. + /// + /// + /// An application is started and shut down by the user. + /// + /// + /// A pseudo-object is created and destroyed. + /// + /// + /// For debugging purposes, it may be useful to keep a count of the number of external locks (and unlocks) set on the application. + /// + // 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); + + /// + /// Marshals an HRESULT to the specified stream, from which it can be unmarshaled using the CoUnmarshalHresult function. + /// + /// + /// A pointer to the marshaling stream. See IStream. + /// + /// + /// The HRESULT in the originating process. + /// + /// + /// This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The HRESULT was marshaled successfully. + /// + /// + /// STG_E_INVALIDPOINTER + /// A bad pointer was specified for pstm. + /// + /// + /// STG_E_MEDIUMFULL + /// The medium is full. + /// + /// + /// + /// + /// + /// An HRESULT is process-specific, so an HRESULT 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 HRESULT 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. + /// + /// This function performs the following tasks: + /// + /// + /// Writes an HRESULT to a stream. + /// + /// + /// Returns an IStream pointer to that stream. + /// + /// + /// + // 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); + + /// Writes into a stream the data required to initialize a proxy object in some client process. + /// A pointer to the stream to be used during marshaling. See IStream. + /// + /// A reference to the identifier of the interface to be marshaled. This interface must be derived from the IUnknown interface. + /// + /// A pointer to the interface to be marshaled. This interface must be derived from the IUnknown interface. + /// + /// 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). + /// + /// This parameter is reserved and must be NULL. + /// + /// 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. + /// + /// + /// + /// 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. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The HRESULT was marshaled successfully. + /// + /// + /// CO_E_NOTINITIALIZED + /// The CoInitialize or OleInitialize function was not called on the current thread before this function was called. + /// + /// + /// + /// + /// + /// The CoMarshalInterface function marshals the interface referred to by riid on the object whose IUnknown implementation is + /// pointed to by pUnk. To do so, the CoMarshalInterface function performs the following tasks: + /// + /// + /// + /// + /// Queries the object for a pointer to the IMarshal interface. If the object does not implement IMarshal, meaning that it + /// relies on COM to provide marshaling support, CoMarshalInterface gets a pointer to COM's default implementation of IMarshal. + /// + /// + /// + /// + /// Gets the CLSID of the object's proxy by calling IMarshal::GetUnmarshalClass, using whichever IMarshal interface pointer has been returned. + /// + /// + /// + /// Writes the CLSID of the proxy to the stream to be used for marshaling. + /// + /// + /// Marshals the interface pointer by calling IMarshal::MarshalInterface. + /// + /// + /// + /// The COM library in the client process calls the CoUnmarshalInterface function to extract the data and initialize the proxy. + /// Before calling CoUnmarshalInterface, seek back to the original position in the stream. + /// + /// + /// 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 CoMarshalInterface for you. If you are writing your own + /// proxies and stubs, your proxy code and stub code should each call CoMarshalInterface to correctly marshal interface + /// pointers. Calling IMarshal directly from your proxy and stub code is not recommended. + /// + /// + /// 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 CoMarshalInterface on the object to do so. + /// + /// + // 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); + + /// Marshals an interface pointer from one thread to another thread in the same process. + /// A reference to the identifier of the interface to be marshaled. + /// A pointer to the interface to be marshaled, which must be derived from IUnknown. This parameter can be NULL. + /// + /// The address of the IStream* pointer variable that receives the interface pointer to the stream that contains the marshaled interface. + /// + /// This function can return the standard return values E_OUTOFMEMORY and S_OK. + /// + /// + /// The CoMarshalInterThreadInterfaceInStream 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. + /// + /// The CoMarshalInterThreadInterfaceInStream function performs the following tasks: + /// + /// + /// Creates a stream object. + /// + /// + /// Passes the stream object's IStream pointer to CoMarshalInterface. + /// + /// + /// Returns the IStream pointer to the caller. + /// + /// + /// + // 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); + + /// Retrieves a list of the authentication services registered when the process called CoInitializeSecurity. + /// A pointer to a variable that receives the number of entries returned in the asAuthSvc array. + /// + /// 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. + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. + /// + /// + /// CoQueryAuthenticationServices 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, + /// CoInitializeSecurity is called automatically by COM, registering the default security package, the first time an + /// interface is marshaled or unmarshaled. + /// + /// + /// 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. CoQueryAuthenticationServices is + /// primarily useful for custom marshalers, to determine which principal names an application can use. + /// + /// + /// 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. + /// + /// + // 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); + + /// Retrieves a list of the authentication services registered when the process called CoInitializeSecurity. + /// An array of SOLE_AUTHENTICATION_SERVICE structures. + /// + /// + /// CoQueryAuthenticationServices 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, + /// CoInitializeSecurity is called automatically by COM, registering the default security package, the first time an + /// interface is marshaled or unmarshaled. + /// + /// + /// 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. CoQueryAuthenticationServices is + /// primarily useful for custom marshalers, to determine which principal names an application can use. + /// + /// + /// 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. + /// + /// + // 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((int)c); } + + /// + /// 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. + /// + /// + /// 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 NULL, the current authentication service is not retrieved. + /// + /// + /// 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 NULL, the current authorization service is not retrieved. + /// + /// The string builder. + /// + /// 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 NULL, the current authentication level is not retrieved. + /// + /// This parameter must be NULL. + /// + /// 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, + /// NULL is returned. If the caller specifies NULL, the current privilege information is not retrieved. See RPC_AUTHZ_HANDLE. + /// + /// + /// 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 + /// NULL, the current capabilities are not retrieved. + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. + /// + /// + /// CoQueryClientBlanket 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): + /// + /// + /// This sequence calls CoGetCallContext to get a pointer to IServerSecurity and, with the resulting pointer, calls + /// IServerSecurity::QueryBlanket and then releases the pointer. + /// + /// + // 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); + + /// + /// Retrieves the authentication information the client uses to make calls on the specified proxy. This is a helper function for IClientSecurity::QueryBlanket. + /// + /// + /// A pointer indicating the proxy to query. This parameter cannot be NULL. For more information, see the Remarks section. + /// + /// + /// 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 NULL, the current authentication level is not retrieved. + /// + /// + /// 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 NULL, the current authorization service is not retrieved. + /// + /// + /// 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 NULL, the current principal name is not retrieved. + /// + /// + /// 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 NULL, the current authentication level is not retrieved. + /// + /// + /// 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 NULL, the current impersonation level is not retrieved. + /// + /// + /// 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 NULL, 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, NULL is returned. See RPC_AUTH_IDENTITY_HANDLE. + /// + /// + /// A pointer to a variable that receives the capabilities of the proxy. If the caller specifies NULL, the current capability + /// flags are not retrieved. + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. + /// + /// + /// CoQueryProxyBlanket 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): + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// Registers a process-wide filter to process activation requests. + /// Pointer to the filter to register. + /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + /// This registers one and only one process-wide filter. + // 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); + + /// Registers an EXE class object with OLE so other applications can connect to it. + /// The CLSID to be registered. + /// A pointer to the IUnknown interface on the class object whose availability is being published. + /// + /// The context in which the executable code is to be run. For information on these context values, see the CLSCTX enumeration. + /// + /// + /// Indicates how connections are made to the class object. For information on these flags, see the REGCLS enumeration. + /// + /// + /// A pointer to a value that identifies the class object registered; later used by the CoRevokeClassObject function to revoke the registration. + /// + /// + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The class object was registered successfully. + /// + /// + /// + /// + /// + /// EXE object applications should call CoRegisterClassObject 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 + /// CoRegisterClassObject. Object handlers or DLL object applications do not call this function — instead, they must + /// implement and export the DllGetClassObject function. + /// + /// + /// At startup, a multiple-use EXE object application must create a class object (with the IClassFactory interface on it), and call + /// CoRegisterClassObject 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. + /// + /// + /// Multiple registrations of the same class object are independent and do not produce an error. Each subsequent registration yields + /// a unique key in lpdwRegister. + /// + /// + /// 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 /Embedding switch. + /// + /// + /// The server for a class object should call CoRevokeClassObject to revoke the class object (remove its registration) when all of + /// the following are true: + /// + /// + /// + /// There are no existing instances of the object definition. + /// + /// + /// There are no locks on the class object. + /// + /// + /// The application providing services to the class object is not under user control (not visible to the user on the display). + /// + /// + /// + /// 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 CoRegisterClassObject calls IUnknown::AddRef and CoRevokeClassObject calls + /// IUnknown::Release, so the two functions form an AddRef/ Release pair. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// 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. + /// + /// A pointer to the IID of the interface to be registered. + /// + /// A pointer to the CLSID of the DLL that contains the proxy/stub code for the custom interface specified by riid. + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. + /// + /// + /// Typically, the code responsible for marshaling an interface pointer into the current running process reads the + /// HKEY_CLASSES_ROOT\Interfaces 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. + /// + /// + /// 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. + /// CoRegisterPSClsid, used in conjunction with CoRegisterClassObject, provides that alternative. + /// + /// Examples + /// A DLL would typically call CoRegisterPSClsid as shown in the following code fragment. + /// + // 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); + + /// Registers the surrogate process through its ISurrogate interface pointer. + /// A pointer to the ISurrogate interface on the surrogate process to be registered. + /// This function returns S_OK to indicate that the surrogate process was registered successfully. + /// + /// + /// The CoRegisterSurrogate 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 ISurrogate. This function is usually called by the surrogate implementation when it is launched. + /// + /// + /// 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. + /// + /// + // 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); + + /// Destroys a previously marshaled data packet. + /// A pointer to the stream that contains the data packet to be destroyed. See IStream. + /// + /// + /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the + /// following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The data packet was successfully destroyed. + /// + /// + /// STG_E_INVALIDPOINTER + /// An error related to the pStm parameter. + /// + /// + /// CO_E_NOTINITIALIZED + /// The CoInitialize or OleInitialize function was not called on the current thread before this function was called. + /// + /// + /// + /// + /// + /// Important 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. + /// + /// The CoReleaseMarshalData function performs the following tasks: + /// + /// + /// The function reads a CLSID from the stream. + /// + /// + /// + /// 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 IMarshal interface pointer to the newly created proxy. + /// + /// + /// + /// Using whichever IMarshal interface pointer it has acquired, the function calls IMarshal::ReleaseMarshalData. + /// + /// + /// + /// 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 CoReleaseMarshalData should be called + /// include the following situations: + /// + /// + /// + /// An attempt was made to unmarshal the data packet, but it failed. + /// + /// + /// A marshaled data packet was removed from a global table. + /// + /// + /// + /// 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. + /// + /// + /// Note that you do not need to call CoReleaseMarshalData after a successful call of the CoUnmarshalInterface function; that + /// function releases the marshal data as part of the processing that it does. + /// + /// + /// Important You must call the CoReleaseMarshalData 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. + /// + /// + // 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); + + /// Decrements the global per-process reference count. + /// + /// If the server application should initiate its cleanup, the function returns 0; otherwise, the function returns a nonzero value. + /// + /// + /// + /// Servers can call CoReleaseServerProcess to decrement a global per-process reference count incremented through a call to CoAddRefServerProcess. + /// + /// + /// 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. + /// + /// + /// 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 + /// TRUE. The server application should also call CoReleaseServerProcess in the destructor of each of its instance + /// objects, and in each of its IClassFactory::LockServer methods when the fLock parameter is FALSE. Finally, the + /// server application must check the return code from CoReleaseServerProcess; 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. + /// + /// + /// 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 CoReleaseServerProcess. + /// + /// + // 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(); + + /// + /// 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. + /// + /// This function returns S_OK to indicate that the CLSID was retrieved successfully. + /// + /// + /// Servers that can register multiple class objects call CoResumeClassObjects 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. + /// + /// + /// 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 CoResumeClassObjects. 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. + /// + /// + // 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(); + + /// Restores the authentication information on a thread of execution. + /// This function supports the standard return values, including S_OK to indicate success. + /// + /// + /// CoRevertToSelf, 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. + /// + /// CoRevertToSelf encapsulates the following common sequence of calls (error handling excluded): + /// + // 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(); + + /// + /// Informs OLE that a class object, previously registered with the CoRegisterClassObject function, is no longer available for use. + /// + /// A token previously returned from the CoRegisterClassObject function. + /// + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The class object was revoked successfully. + /// + /// + /// + /// + /// + /// A successful call to CoRevokeClassObject 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 AddRef and IUnknown::Release) to the class + /// object fail. Note that CoRegisterClassObject calls AddRef and CoRevokeClassObject calls Release, so the two + /// functions form an AddRef/ Release pair. + /// + /// + /// An object application must call CoRevokeClassObject to revoke registered class objects before exiting the program. Class + /// object implementers should call CoRevokeClassObject 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. + /// + /// + // 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); + + /// + /// Sets (registers) or resets (unregisters) a cancel object for use during subsequent cancel operations on the current thread. + /// + /// + /// Pointer to the IUnknown interface on the cancel object to be set or reset on the current thread. If this parameter is + /// NULL, the topmost cancel object is reset. + /// + /// + /// + /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the + /// following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The cancel object was successfully set or reset. + /// + /// + /// E_ACCESSDENIED + /// The cancel object cannot be set or reset at this time because of a block on cancel operations. + /// + /// + /// + /// + /// + /// For objects that support standard marshaling, the proxy object begins marshaling a method call by calling + /// CoSetCancelObject to register a cancel object for the current thread. + /// + /// + /// CoSetCancelObject calls QueryInterface for ICancelMethodCalls on the cancel object. If the cancel object does not + /// implement ICancelMethodCalls, CoSetCancelObject 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. + /// + /// CoSetCancelObject calls AddRef on objects that it registers and Release on objects that it unregisters. + /// CoSetCancelObject does not set or reset cancel objects for asynchronous methods. + /// + // 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); + + /// + /// Sets the authentication information that will be used to make calls on the specified proxy. This is a helper function for IClientSecurity::SetBlanket. + /// + /// The proxy to be set. + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// + /// 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 NULL. It must be the correct principal name of the server or the call will fail. + /// + /// + /// If Schannel is used as the authentication service, this value must be one of the msstd or fullsic forms described in Principal + /// Names, or NULL if you do not want mutual authentication. + /// + /// + /// Generally, specifying NULL will not reset the server principal name on the proxy; rather, the previous setting will be + /// retained. You must be careful when using NULL 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. + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// + /// A pointer to an RPC_AUTH_IDENTITY_HANDLE 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. + /// + /// + /// For calls on the same computer, RPC logs on the user with the supplied credentials and uses the resulting token for the method call. + /// + /// + /// 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. + /// + /// + /// If this parameter is NULL, 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. + /// + /// + /// For Schannel, this parameter must be either a pointer to a CERT_CONTEXT structure that contains the client's X.509 certificate + /// or is NULL 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. + /// + /// + /// For Snego, this member is either NULL, points to a SEC_WINNT_AUTH_IDENTITY structure, or points to a + /// SEC_WINNT_AUTH_IDENTITY_EX structure. If it is NULL, Snego will pick a list of authentication services based on those + /// available on the client computer. If it points to a SEC_WINNT_AUTH_IDENTITY_EX structure, the structure's + /// PackageList member must point to a string containing a comma-separated list of authentication service names and the + /// PackageListLength member must give the number of bytes in the PackageList string. If PackageList is + /// NULL, all calls using Snego will fail. + /// + /// + /// If COLE_DEFAULT_AUTHINFO is specified for this parameter, DCOM will pick the authentication information following its normal + /// security blanket negotiation algorithm. + /// + /// CoSetProxyBlanket will fail if pAuthInfo is set and one of the cloaking flags is set in the dwCapabilities parameter. + /// + /// + /// 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, CoSetProxyBlanket will fail. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The function was successful. + /// + /// + /// E_INVALIDARG + /// One or more arguments is invalid. + /// + /// + /// + /// + /// + /// CoSetProxyBlanket 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). + /// + /// + /// 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. + /// + /// + // 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_AUTHN.RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ dwAuthzSvc = RPC_C_AUTHZ.RPC_C_AUTHZ_DEFAULT, + string pServerPrincName = COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL dwAuthnLevel = RPC_C_AUTHN_LEVEL.RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL dwImpLevel = RPC_C_IMP_LEVEL.RPC_C_IMP_LEVEL_DEFAULT, RPC_AUTH_IDENTITY_HANDLE pAuthInfo = default, + EOLE_AUTHENTICATION_CAPABILITIES dwCapabilities = EOLE_AUTHENTICATION_CAPABILITIES.EOAC_DEFAULT); + + /// Prevents any new activation requests from the SCM on all class objects registered within the process. + /// This function returns S_OK to indicate that the activation of class objects was successfully suspended. + /// + /// CoSuspendClassObjects 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. + /// + // 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(); + + /// Switches the call context object used by CoGetCallContext. + /// + /// A pointer to an interface on the new call context object. COM stores this pointer without adding a reference to the pointer + /// until CoSwitchCallContext is called with another object. This parameter may be NULL if you are calling + /// CoSwitchCallContext to switch back to the original call context but there was no original call context. + /// + /// + /// 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 NULL + /// if there was no call in progress. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The function was successful. + /// + /// + /// E_OUT_OF_MEMORY + /// Out of memory. + /// + /// + /// + /// + /// + /// Custom marshallers call CoSwitchCallContext to change the call context object used by the CoGetCallContext function. + /// Before dispatching an arriving call, custom marshallers call CoSwitchCallContext, specifying the new context object. + /// After sending a reply, they must restore the original call context by calling CoSwitchCallContext again, this time + /// passing a pointer to the original context object. + /// + /// + /// CoSwitchCallContext 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. + /// + /// Call context objects provided by custom marshallers should support the IServerSecurity interface. + /// + // 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); + + /// Allocates a block of task memory in the same way that IMalloc::Alloc does. + /// The size of the memory block to be allocated, in bytes. + /// If the function succeeds, it returns the allocated memory block. Otherwise, it returns NULL. + /// + /// + /// CoTaskMemAlloc 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 CoTaskMemAlloc. + /// + /// + /// 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. + /// + /// + /// If cb is 0, CoTaskMemAlloc allocates a zero-length item and returns a valid pointer to that item. If there is + /// insufficient memory available, CoTaskMemAlloc returns NULL. 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. + /// + /// + // 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); + + /// Frees a block of task memory previously allocated through a call to the CoTaskMemAlloc or CoTaskMemRealloc function. + /// A pointer to the memory block to be freed. If this parameter is NULL, the function has no effect. + /// This function does not return a value. + /// + /// The CoTaskMemFree function uses the default OLE allocator. + /// + /// 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. + /// + /// + // 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); + + /// Changes the size of a previously allocated block of task memory. + /// A pointer to the memory block to be reallocated. This parameter can be NULL, as discussed in Remarks. + /// The size of the memory block to be reallocated, in bytes. This parameter can be 0, as discussed in Remarks. + /// If the function succeeds, it returns the reallocated memory block. Otherwise, it returns NULL. + /// + /// + /// 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 CoTaskMemRealloc. + /// + /// + /// The pv parameter points to the beginning of the memory block. If pv is NULL, CoTaskMemRealloc allocates a new + /// memory block in the same way as the CoTaskMemAlloc function. If pv is not NULL, it should be a pointer returned by a + /// prior call to CoTaskMemAlloc. + /// + /// + /// 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 CoTaskMemRealloc is not guaranteed to be the pointer passed through the pv argument. If pv is not + /// NULL and cb is 0, then the memory pointed to by pv is freed. + /// + /// + /// CoTaskMemRealloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is + /// NULL if the size is 0 and the buffer argument is not NULL, 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. + /// + /// + /// 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 void, use a type cast on the return value. + /// + /// + // 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); + + /// + /// Determines whether the call being executed on the server has been canceled by the client. + /// + /// + /// + /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the + /// following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// RPC_S_CALLPENDING + /// The call is still pending and has not yet been canceled by the client. + /// + /// + /// RPC_E_CALL_CANCELED + /// The call has been canceled by the client. + /// + /// + /// + /// + /// + /// Server objects should call CoTestCancel 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. + /// + /// + /// CoTestCancel 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. + /// + /// This function does not test cancellation for asynchronous calls. + /// + // 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(); + + /// Unmarshals an HRESULT type from the specified stream. + /// A pointer to the stream from which the HRESULT is to be unmarshaled. + /// A pointer to the unmarshaled HRESULT. + /// + /// This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The HRESULT was unmarshaled successfully. + /// + /// + /// STG_E_INVALIDPOINTER + /// pStm is an invalid pointer. + /// + /// + /// + /// + /// + /// 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 HRESULT. + /// + /// + /// You must use CoUnmarshalHresult to unmarshal HRESULT values previously marshaled by a call to the CoMarshalHresult function. + /// + /// This function performs the following tasks: + /// + /// + /// an HRESULT from a stream. + /// + /// + /// Returns the HRESULT. + /// + /// + /// + // 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); + + /// + /// 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. + /// + /// A pointer to the stream from which the interface is to be unmarshaled. + /// + /// A reference to the identifier of the interface to be unmarshaled. For IID_NULL, the returned interface is the one defined + /// by the stream, objref.iid. + /// + /// + /// The address of pointer variable that receives the interface pointer requested in . Upon successful + /// return, contains the requested interface pointer for the unmarshaled interface. + /// + /// + /// This function can return the standard return value E_FAIL, errors returned by CoCreateInstance, and the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The interface pointer was unmarshaled successfully. + /// + /// + /// STG_E_INVALIDPOINTER + /// pStm is an invalid pointer. + /// + /// + /// CO_E_NOTINITIALIZED + /// The CoInitialize or OleInitialize function was not called on the current thread before this function was called. + /// + /// + /// CO_E_OBJNOTCONNECTED + /// + /// The object application has been disconnected from the remoting system (for example, as a result of a call to the + /// CoDisconnectObject function). + /// + /// + /// + /// REGDB_E_CLASSNOTREG + /// An error occurred reading the registration database. + /// + /// + /// E_NOINTERFACE + /// The final QueryInterface of this function for the requested interface returned E_NOINTERFACE. + /// + /// + /// + /// + /// + /// Important 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. + /// + /// The CoUnmarshalInterface function performs the following tasks: + /// + /// + /// Reads from the stream the CLSID to be used to create an instance of the proxy. + /// + /// + /// + /// 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, CoUnmarshalInterface calls the CoCreateInstance function, passing the CLSID it read from the + /// marshaling stream. CoCreateInstance creates an instance of the object's proxy and returns an IMarshal interface + /// pointer to the proxy. + /// + /// + /// + /// + /// Using whichever IMarshal interface pointer it has acquired, the function then calls IMarshal::UnmarshalInterface and, if + /// appropriate, IMarshal::ReleaseMarshalData. + /// + /// + /// + /// + /// 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 CoUnmarshalInterface. For example, if you are implementing a + /// stub, your implementation would call CoUnmarshalInterface when the stub receives an interface pointer as a parameter in a + /// method call. + /// + /// + // 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); + + /// Waits for specified handles to be signaled or for a specified timeout period to elapse. + /// The wait options. Possible values are taken from the COWAIT_FLAGS enumeration. + /// The timeout period, in milliseconds. + /// The number of elements in the pHandles array. + /// An array of handles. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// See WaitForMultipleObjectsEx for more information. + /// + /// + /// This function can return the following values. + /// + /// Note The return value of CoWaitForMultipleHandles 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 CoWaitForMultipleHandles. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The required handle or handles were signaled. + /// + /// + /// E_INVALIDARG + /// pHandles was NULL, lpdwindex was NULL, or dwFlags was not a value from the COWAIT_FLAGS enumeration. + /// + /// + /// RPC_E_NO_SYNC + /// The value of pHandles was 0. + /// + /// + /// RPC_S_CALLPENDING + /// The timeout period elapsed before the required handle or handles were signaled. + /// + /// + /// + /// + /// + /// Depending on which flags are set in the dwFlags parameter, CoWaitForMultipleHandles blocks the calling thread until one + /// of the following events occurs: + /// + /// + /// + /// + /// One or all of the handles is signaled. In the case of mutex objects, this condition is also satisfied by a mutex being abandoned. + /// + /// + /// + /// An asynchronous procedure call (APC) has been queued to the calling thread with a call to the QueueUserAPC function. + /// + /// + /// The timeout period expires. + /// + /// + /// + /// If the caller resides in a single-thread apartment, CoWaitForMultipleHandles 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. + /// + /// + /// If the calling thread resides in a multithread apartment (MTA), CoWaitForMultipleHandles calls the + /// WaitForMultipleObjectsEx function. + /// + /// + // 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); + + /// + /// A replacement for CoWaitForMultipleHandles. This replacement API hides the options for CoWaitForMultipleHandles that are + /// not supported in ASTA. + /// + /// + /// 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 CoWaitForMultipleObjects in ASTA. + /// + /// The timeout in milliseconds of the wait. + /// The length of the pHandles array. Must be <= 56. + /// An array of handles to waitable kernel objects. + /// Receives the index of the handle that satisfied the wait. + /// + /// Same return values as CoWaitForMultipleHandles, except the ASTA-specific CO_E_NOTSUPPORTED cases instead return E_INVALIDARG + /// from all apartment types. + /// + // 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); + + /// + /// + /// The CreateStreamOnHGlobal 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. + /// + /// + /// 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. + /// + /// + /// Tip Consider using the SHCreateMemStream function, which produces better performance, or for Windows Store apps, consider + /// using InMemoryRandomAccessStream. + /// + /// + /// + /// A memory handle allocated by the GlobalAlloc function, or if NULL a new handle is to be allocated instead. The handle + /// must be allocated as moveable and nondiscardable. + /// + /// + /// 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 FALSE, the caller must free the hGlobal after the final release. If set to TRUE, the final + /// release will automatically free the hGlobal parameter. + /// + /// + /// The address of IStream* pointer variable that receives the interface pointer to the new stream object. Its value cannot be NULL. + /// + /// This function supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following. + /// + /// If hGlobal is NULL, the function allocates a new memory handle and the stream is initially empty. + /// + /// If hGlobal is not NULL, the initial contents of the stream are the current contents of the memory block. Thus, + /// CreateStreamOnHGlobal 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. + /// + /// + /// 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. + /// + /// The new stream object’s initial seek position is the beginning of the stream. + /// + /// After creating the stream object with CreateStreamOnHGlobal, call GetHGlobalFromStream to retrieve the memory handle + /// associated with the stream object. + /// + /// + /// If a memory handle is passed to CreateStreamOnHGlobal 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: + /// + /// + /// + /// + /// Do not free the hGlobal memory handle during the lifetime of the stream object. IStream::Release must be called before freeing + /// the memory handle. + /// + /// + /// + /// + /// 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 GlobalReAlloc. 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// Avoid calling the object’s methods while you have the memory handle locked with GlobalLock. This can cause method calls to fail unpredictably. + /// + /// + /// + /// + /// If the caller sets the fDeleteOnRelease parameter to FALSE, then the caller must also free the hGlobal after the final + /// release. If the caller sets the fDeleteOnRelease parameter to TRUE, the final release will automatically free the hGlobal. + /// + /// + /// The memory handle passed as the hGlobal parameter must be allocated as movable and nondiscardable, as shown in the following example: + /// + /// + /// CreateStreamOnHGlobal will accept a memory handle allocated with GMEM_FIXED, but this usage is not recommended. HGLOBALs + /// allocated with GMEM_FIXED are not really handles and their value can change when they are reallocated. If the memory + /// handle was allocated with GMEM_FIXED and fDeleteOnRelease is FALSE, the caller must call GetHGlobalFromStream to + /// get the correct handle in order to free it. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// Determines whether the DLL that implements this function is in use. If not, the caller can unload the DLL from memory. + /// + /// OLE does not provide this function. DLLs that support the OLE Component Object Model (COM) should implement and export DllCanUnloadNow. + /// + /// + /// If the function succeeds, the return value is S_OK. Otherwise, it is S_FALSE. + /// + /// + /// A call to DllCanUnloadNow 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). + /// + /// Notes to Callers + /// + /// You should not have to call DllCanUnloadNow directly. OLE calls it only through a call to the CoFreeUnusedLibraries + /// function. When it returns S_OK, CoFreeUnusedLibraries frees the DLL. + /// + /// Notes to Implementers + /// + /// You must implement DllCanUnloadNow 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). + /// + /// + /// If a DLL loaded through a call to CoGetClassObject fails to export DllCanUnloadNow, the DLL will not be unloaded until + /// the application calls the CoUninitialize function to release the OLE libraries. + /// + /// DllCanUnloadNow should return S_FALSE if there are any existing references to objects that the DLL manages. + /// + // 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(); + + /// + /// Retrieves the class object from a DLL object handler or object application. + /// + /// OLE does not provide this function. DLLs that support the OLE Component Object Model (COM) must implement + /// DllGetClassObject in OLE object handlers or DLL applications. + /// + /// + /// The CLSID that will associate the correct data and code. + /// + /// 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). + /// + /// + /// 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 NULL. + /// + /// + /// + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The object was retrieved successfully. + /// + /// + /// CLASS_E_CLASSNOTAVAILABLE + /// The DLL does not support the class (object definition). + /// + /// + /// + /// + /// + /// If a call to the CoGetClassObject function finds the class object that is to be loaded in a DLL, CoGetClassObject uses + /// the DLL's exported DllGetClassObject function. + /// + /// Notes to Callers + /// + /// You should not call DllGetClassObject directly. When an object is defined in a DLL, CoGetClassObject calls the + /// CoLoadLibrary function to load the DLL, which, in turn, calls DllGetClassObject. + /// + /// Notes to Implementers + /// You need to implement DllGetClassObject in (and export it from) DLLs that support COM. + /// Examples + /// + /// The following is an example (in C++) of an implementation of DllGetClassObject. In this example, DllGetClassObject + /// 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 + /// IClassFactory to the caller. + /// + /// + // 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); + + /// + /// The FreePropVariantArray 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. + /// + /// Count of elements in the PROPVARIANT array (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 PROPVARIANT structure (thus tagging them as VT_EMPTY). + /// + /// This function returns HRESULT. + /// + /// + /// FreePropVariantArray calls PropVariantClear on an array of PROPVARIANT structures to clear all the valid members. All + /// valid PROPVARIANT structures are freed. If any of the PROPVARIANT structures contain illegal VT types, valid + /// members are freed and the function returns STG_E_INVALIDPARAMETER. + /// + /// Passing NULL for rgvars is legal, and produces a return code of S_OK. + /// + // 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); + + /// + /// The GetHGlobalFromStream function retrieves the global memory handle to a stream that was created through a call to the + /// CreateStreamOnHGlobal function. + /// + /// IStream pointer to the stream object previously created by a call to the CreateStreamOnHGlobal function. + /// Pointer to the current memory handle used by the specified stream object. + /// This function returns HRESULT. + /// + /// + /// The handle GetHGlobalFromStream returns may be different from the original handle due to intervening GlobalReAlloc calls. + /// + /// This function can be called only from within the same process from which the byte array was created. + /// + // 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); + + /// Converts a string generated by the StringFromIID function back into the original interface identifier (IID). + /// A pointer to the string representation of the IID. + /// A pointer to the requested IID on return. + /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. + /// + /// The function converts the interface identifier in a way that guarantees different interface identifiers will always be converted + /// to different strings. + /// + // 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); + + /// Retrieves the ProgID for a given CLSID. + /// The CLSID for which the ProgID is to be requested. + /// + /// The address of a pointer variable that receives the ProgID string. The string that represents clsid includes enclosing braces. + /// + /// + /// This function can return the following values. + /// + /// + /// Return code + /// Description + /// + /// + /// S_OK + /// The ProgID was returned successfully. + /// + /// + /// REGDB_E_CLASSNOTREG + /// Class not registered in the registry. + /// + /// + /// REGDB_E_READREGDB + /// There was an error reading from the registry. + /// + /// + /// + /// + /// + /// Every OLE object class listed in the Insert Object 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 Insert + /// Object 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. + /// + /// + /// ProgIDFromCLSID 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. + /// + /// + /// 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). + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// Creates an agile reference for an object specified by the given interface. + /// The options. + /// The interface ID of the object for which an agile reference is being obtained. + /// + /// 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. + /// + /// + /// The agile reference for the object. Call the Resolve method to localize the object into the apartment in which Resolve is called. + /// + /// + /// This function can return one of these values. + /// + /// + /// Return value + /// Description + /// + /// + /// S_OK + /// The function completed successfully. + /// + /// + /// E_INVALIDARG + /// The options parameter in invalid. + /// + /// + /// E_OUTOFMEMORY + /// The agile reference couldn't be constructed due to an out-of-memory condition. + /// + /// + /// E_NOINTERFACE + /// The pUnk parameter doesn't support the interface ID specified by the riid parameter. + /// + /// + /// CO_E_NOT_SUPPORTED + /// The object implements the INoMarshal interface. + /// + /// + /// + /// + /// + /// Call the RoGetAgileReference 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 IAgileReference interface. + /// + /// + /// 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. + /// + /// + /// 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 + /// RoGetAgileReference 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. + /// + /// + /// For example, you have a non-agile object named CDemoExample, which implements the IDemo and IExample interfaces. Call the + /// RoGetAgileReference 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. + /// + /// + // 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); + + /// Converts a CLSID into a string of printable characters. Different CLSIDs always convert to different strings. + /// The CLSID to be converted. + /// + /// The address of a pointer variable that receives a pointer to the resulting string. The string that represents rclsid includes + /// enclosing braces. + /// + /// This function can return the standard return values E_OUTOFMEMORY and S_OK. + /// + /// + /// StringFromCLSID calls the StringFromGUID2 function to convert a globally unique identifier (GUID) into a string of + /// printable characters. + /// + /// The caller is responsible for freeing the memory allocated for the string by calling the CoTaskMemFree function. + /// + // 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); + + /// Converts a globally unique identifier (GUID) into a string of printable characters. + /// The GUID to be converted. + /// + /// A pointer to a caller-allocated string variable to receive the resulting string. The string that represents rguid includes + /// enclosing braces. + /// + /// The number of characters available in the lpsz buffer. + /// + /// 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. + /// + // 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); + + /// Converts an interface identifier into a string of printable characters. + /// The interface identifier to be converted. + /// + /// The address of a pointer variable that receives a pointer to the resulting string. The string that represents rclsid includes + /// enclosing braces. + /// + /// This function can return the standard return values E_OUTOFMEMORY and S_OK. + /// The caller is responsible for freeing the memory allocated for the string by calling the CoTaskMemFree function. + // 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); + + /// Represents the implementation of a Component Object Model (COM) interface in a server process. + /// + /// The ServerInformation structure is used by the CoDecodeProxy function to enable native debuggers to locate the + /// implementation of a COM interface in a server process, given a Windows Runtime interface on a proxy to the Windows Runtime object. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/ns-combaseapi-serverinformation typedef struct tagServerInformation + // { DWORD dwServerPid; DWORD dwServerTid; UINT64 ui64ServerAddress; } ServerInformation, *PServerInformation; + [PInvokeData("combaseapi.h", MSDNShortId = "NS:combaseapi.tagServerInformation")] + [StructLayout(LayoutKind.Sequential)] + public struct ServerInformation + { + /// The process ID of the server. + public uint dwServerPid; /// - /// 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. + /// The thread ID of the server object if it's in the STA, 0 if it's in the MTA, and 0x0000FFFF if it's in the NA. /// - /// - /// 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. - /// - /// - /// The globally unique identifier of an interface on the cancel object for the call to be canceled. This argument is usually IID_ICancelMethodCalls. - /// - /// Receives the address of a pointer to the interface specified by riid. - /// - /// - /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the - /// following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The call control object was retrieved successfully. - /// - /// - /// E_NOINTERFACE - /// The object on which the call is executing does not support the interface specified by riid. - /// - /// - /// - /// - /// - /// 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, CoGetCancelObject returns a cancel interface corresponding to the innermost call that - /// is pending on the thread and has registered a cancel object. - /// - /// This function does not locate cancel objects for asynchronous calls. - /// - // 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); + public uint dwServerTid; /// - /// - /// Provides a pointer to an interface on a class object associated with a specified CLSID. CoGetClassObject locates, and if - /// necessary, dynamically loads the executable code required to do this. - /// - /// - /// Call CoGetClassObject 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. - /// + /// ui64ServerAddress 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. /// - /// The CLSID associated with the data and code that you will use to create the objects. - /// - /// 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. - /// - /// - /// A pointer to computer on which to instantiate the class object. If this parameter is NULL, 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. - /// - /// - /// 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. - /// - /// - /// The address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the - /// requested interface pointer. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// Location and connection to the specified class object was successful. - /// - /// - /// REGDB_E_CLASSNOTREG - /// - /// The CLSID is not properly registered. This error can also indicate that the value you specified in dwClsContext is not in the registry. - /// - /// - /// - /// E_NOINTERFACE - /// - /// 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. - /// - /// - /// - /// REGDB_E_READREGDB - /// There was an error reading the registration database. - /// - /// - /// CO_E_DLLNOTFOUND - /// Either the in-process DLL or handler DLL was not found (depending on the context). - /// - /// - /// CO_E_APPNOTFOUND - /// The executable (.exe) was not found (CLSCTX_LOCAL_SERVER only). - /// - /// - /// E_ACCESSDENIED - /// There was a general access failure on load. - /// - /// - /// CO_E_ERRORINDLL - /// There is an error in the executable image. - /// - /// - /// CO_E_APPDIDNTREG - /// The executable was launched, but it did not register the class object (and it may have shut down). - /// - /// - /// - /// - /// - /// 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). - /// - /// - /// A call to CoGetClassObject 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. - /// - /// - /// 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 NULL, refer to the CLSCTX enumeration. - /// - /// There are two places to find a CLSID for a class: - /// - /// - /// - /// The registry holds an association between CLSIDs and file suffixes, and between CLSIDs and file signatures for determining the - /// class of an object. - /// - /// - /// - /// When an object is saved to persistent storage, its CLSID is stored with its data. - /// - /// - /// - /// To create and initialize embedded or linked OLE document objects, it is not necessary to call CoGetClassObject directly. - /// Instead, call the OleCreate or OleCreate XXX function. These functions encapsulate the entire object instantiation and - /// initialization process, and call, among other functions, CoGetClassObject. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// 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. CoGetClassObject consults (as - /// appropriate for the context indicated) both the registry and the class objects that are currently registered by calling the - /// CoRegisterClassObject function. - /// - /// - /// 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. - /// - /// - // 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); - - /// - /// - /// Provides a pointer to an interface on a class object associated with a specified CLSID. CoGetClassObject locates, and if - /// necessary, dynamically loads the executable code required to do this. - /// - /// - /// Call CoGetClassObject 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. - /// - /// - /// The CLSID associated with the data and code that you will use to create the objects. - /// - /// 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. - /// - /// - /// A pointer to computer on which to instantiate the class object. If this parameter is NULL, 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. - /// - /// - /// 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. - /// - /// - /// The address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the - /// requested interface pointer. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// Location and connection to the specified class object was successful. - /// - /// - /// REGDB_E_CLASSNOTREG - /// - /// The CLSID is not properly registered. This error can also indicate that the value you specified in dwClsContext is not in the registry. - /// - /// - /// - /// E_NOINTERFACE - /// - /// 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. - /// - /// - /// - /// REGDB_E_READREGDB - /// There was an error reading the registration database. - /// - /// - /// CO_E_DLLNOTFOUND - /// Either the in-process DLL or handler DLL was not found (depending on the context). - /// - /// - /// CO_E_APPNOTFOUND - /// The executable (.exe) was not found (CLSCTX_LOCAL_SERVER only). - /// - /// - /// E_ACCESSDENIED - /// There was a general access failure on load. - /// - /// - /// CO_E_ERRORINDLL - /// There is an error in the executable image. - /// - /// - /// CO_E_APPDIDNTREG - /// The executable was launched, but it did not register the class object (and it may have shut down). - /// - /// - /// - /// - /// - /// 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). - /// - /// - /// A call to CoGetClassObject 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. - /// - /// - /// 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 NULL, refer to the CLSCTX enumeration. - /// - /// There are two places to find a CLSID for a class: - /// - /// - /// - /// The registry holds an association between CLSIDs and file suffixes, and between CLSIDs and file signatures for determining the - /// class of an object. - /// - /// - /// - /// When an object is saved to persistent storage, its CLSID is stored with its data. - /// - /// - /// - /// To create and initialize embedded or linked OLE document objects, it is not necessary to call CoGetClassObject directly. - /// Instead, call the OleCreate or OleCreate XXX function. These functions encapsulate the entire object instantiation and - /// initialization process, and call, among other functions, CoGetClassObject. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// 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. CoGetClassObject consults (as - /// appropriate for the context indicated) both the registry and the class objects that are currently registered by calling the - /// CoRegisterClassObject function. - /// - /// - /// 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. - /// - /// - // 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, [In, Optional] COSERVERINFO pvReserved, in Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 3)] out object ppv); - - /// Returns a pointer to an implementation of IObjContext for the current context. - /// A pointer to an implementation of IObjContext for the current context. - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The token was retrieved successfully. - /// - /// - /// E_POINTER - /// The caller did not pass a valid token pointer variable. - /// - /// - /// CO_E_NOTINITIALIZED - /// The caller is not in an initialized apartment. - /// - /// - /// - // 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); - - /// Returns the logical thread identifier of the current physical thread. - /// A pointer to a GUID that contains the logical thread ID on return. - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The logical thread ID was retrieved successfully. - /// - /// - /// E_INVALIDARG - /// An invalid pointer was passed in for the pguid parameter. - /// - /// - /// E_OUTOFMEMORY - /// A memory allocation failed during the operation of the function. - /// - /// - /// - /// - /// 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. - /// - // 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); - - /// - /// Returns a value that is unique to the current thread. CoGetCurrentProcess can be used to avoid thread ID reuse problems. - /// - /// The function returns the unique identifier of the current thread. - /// - /// - /// Using the value returned from a call to CoGetCurrentProcess can help you in maintaining tables that are keyed by threads - /// or in uniquely identifying a thread to other threads or processes. - /// - /// - /// CoGetCurrentProcess 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. - /// - /// - /// The value returned by CoGetCurrentProcess 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. - /// - /// - // 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(); - - /// Retrieves a reference to the default context of the specified apartment. - /// - /// The apartment type of the default context that is being requested. This parameter can be one of the following values. - /// - /// - /// Value - /// Meaning - /// - /// - /// APTTYPE_CURRENT -1 - /// The caller's apartment. - /// - /// - /// APTTYPE_MTA 1 - /// The multithreaded apartment for the current process. - /// - /// - /// APTTYPE_NA 2 - /// The neutral apartment for the current process. - /// - /// - /// APTTYPE_MAINSTA 3 - /// The main single-threaded apartment for the current process. - /// - /// - /// - /// The APTTYPE value APTTYPE_STA (0) is not supported. A process can contain multiple single-threaded apartments, each with its own - /// context, so CoGetDefaultContext could not determine which STA is of interest. Therefore, this function returns - /// E_INVALIDARG if APTTYPE_STA is specified. - /// - /// - /// - /// 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. - /// - /// - /// 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 CoGetDefaultContext function is called - /// from a constructor or an IUnknown method, this parameter is set to a NULL pointer. - /// - /// - /// This method can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The method completed successfully. - /// - /// - /// E_INVALIDARG - /// One of the parameters is invalid. - /// - /// - /// CO_E_NOTINITIALIZED - /// The caller is not in an initialized apartment. - /// - /// - /// E_NOINTERFACE - /// The object context does not support the interface specified by riid. - /// - /// - /// - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// An object should never pass an IObjectContext reference to another object. If you pass an IObjectContext reference to - /// another object, it is no longer a valid reference. - /// - /// - /// When an object obtains a reference to an IObjectContext, it must release the IObjectContext object when it is finished - /// with it. - /// - /// - // 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); - - /// - /// 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. - /// - /// A pointer to the IStream interface on the stream to be unmarshaled. - /// A reference to the identifier of the interface requested from the unmarshaled object. - /// - /// The address of pointer variable that receives the interface pointer requested in . Upon successful return, - /// contains the requested interface pointer to the unmarshaled interface. - /// - /// - /// This function can return the standard return values S_OK and E_INVALIDARG, as well as any of the values returned by CoUnmarshalInterface. - /// - /// - /// - /// Important 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. - /// - /// The CoGetInterfaceAndReleaseStream function performs the following tasks: - /// - /// - /// Calls CoUnmarshalInterface to unmarshal an interface pointer previously passed in a call to CoMarshalInterThreadInterfaceInStream. - /// - /// - /// - /// 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. - /// - /// - /// - /// - // 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); - - /// - /// 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. - /// - /// This parameter must be 1. - /// - /// The address of an IMalloc* pointer variable that receives the interface pointer to the memory allocator. - /// - /// This function can return the standard return values S_OK, E_INVALIDARG, and E_OUTOFMEMORY. - /// - /// 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. - /// - // 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); - - /// - /// Returns an upper bound on the number of bytes needed to marshal the specified interface pointer to the specified object. - /// - /// - /// 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. - /// - /// - /// A reference to the identifier of the interface whose pointer is to be marshaled. This interface must be derived from the - /// IUnknown interface. - /// - /// A pointer to the interface to be marshaled. This interface must be derived from the IUnknown interface. - /// - /// The destination context where the specified interface is to be unmarshaled. Values for dwDestContext come from the enumeration MSHCTX. - /// - /// This parameter is reserved and must be NULL. - /// - /// 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. - /// - /// - /// This function can return the standard return value E_UNEXPECTED, as well as the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The upper bound was returned successfully. - /// - /// - /// CO_E_NOTINITIALIZED - /// Before this function can be called, either the CoInitialize or OleInitialize function must be called. - /// - /// - /// - /// - /// This function performs the following tasks: - /// - /// - /// - /// Queries the object for an IMarshal pointer or, if the object does not implement IMarshal, gets a pointer to COM's - /// standard marshaler. - /// - /// - /// - /// Using the pointer obtained in the preceding item, calls IMarshal::GetMarshalSizeMax. - /// - /// - /// - /// 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. - /// - /// - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - // 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); - - /// Returns the context for the current object. - /// - /// A reference to the ID of an interface that is implemented on the context object. - /// For objects running within COM applications, IID_IComThreadingInfo, IID_IContext, and IID_IContextCallback are available. - /// - /// For objects running within COM+ applications, IID_IObjectContext, IID_IObjectContextActivity IID_IObjectContextInfo, and - /// IID_IContextState are available. - /// - /// - /// The address of a pointer to the interface specified by riid on the context object. - /// - /// This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The object context was successfully retrieved. - /// - /// - /// E_NOINTERFACE - /// The requested interface was not available. - /// - /// - /// CO_E_NOTINITIALIZED - /// Before this function can be called, the CoInitializeEx function must be called on the current thread. - /// - /// - /// - /// - /// - /// CoGetObjectContext 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. - /// - /// - /// For components running within COM applications, the following interfaces are supported for accessing context properties: - /// IComThreadingInfo, IContext, and IContextCallback. - /// - /// - /// For components running within COM+ applications, the following interfaces are supported for accessing context properties: - /// IObjectContext, IObjectContextActivity, IObjectContextInfo, and IContextState. - /// - /// - // 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); - - /// Returns the CLSID of the DLL that implements the proxy and stub for the specified interface. - /// The interface whose proxy/stub CLSID is to be returned. - /// Specifies where to store the proxy/stub CLSID for the interface specified by riid. - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The proxy/stub CLSID was successfully returned. - /// - /// - /// E_INVALIDARG - /// One of the parameters is invalid. - /// - /// - /// E_OUTOFMEMORY - /// There is insufficient memory to complete this operation. - /// - /// - /// - /// - /// The CoGetPSClsid function looks at the HKEY_CLASSES_ROOT<b>Interfaces<i>{string form of - /// riid}<b>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. - /// - // 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); - - /// - /// 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. - /// - /// - /// A reference to the identifier of the interface whose pointer is to be marshaled. This interface must be derived from the - /// IUnknown interface. - /// - /// A pointer to the interface to be marshaled. - /// - /// 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). - /// - /// This parameter is reserved and must be NULL. - /// - /// 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. - /// - /// - /// The address of IMarshal* pointer variable that receives the interface pointer to the standard marshaler. - /// - /// - /// - /// This function can return the standard return values E_FAIL, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The IMarshal instance was returned successfully. - /// - /// - /// CO_E_NOTINITIALIZED - /// Before this function can be called, the CoInitialize or OleInitialize function must be called on the current thread. - /// - /// - /// - /// - /// - /// The CoGetStandardMarshal 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 IMarshal, - /// you may want your implementation to call CoGetStandardMarshal 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. - /// - /// - /// 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 - /// CoGetStandardMarshal, passing a NULL 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. - /// - /// - /// If your OLE server application's implementation of IMarshal calls CoGetStandardMarshal, you should pass both the IID of - /// (riid), and a pointer to (pUnk), the interface being requested. - /// - /// This function performs the following tasks: - /// - /// - /// Determines whether pUnk is NULL. - /// - /// - /// - /// If pUnk is NULL, creates a standard interface proxy in the client process for the specified riid and returns the proxy's - /// IMarshal pointer. - /// - /// - /// - /// - /// If pUnk is not NULL, checks to see if a marshaler for the object already exists, creates a new one if necessary, and - /// returns the marshaler's IMarshal pointer. - /// - /// - /// - /// - // 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); - - /// Creates an aggregated standard marshaler for use with lightweight client-side handlers. - /// A pointer to the controlling IUnknown. - /// - /// - /// 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 STDMSHLFLAGS enumeration. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// SMEXF_SERVER 0x01 - /// Indicates a server-side aggregated standard marshaler. - /// - /// - /// SMEXF_HANDLER 0x0 - /// Indicates a client-side (handler) aggregated standard marshaler. - /// - /// - /// - /// - /// On successful return, address of pointer to the IUnknown interface on the newly-created aggregated standard marshaler. If an - /// error occurs, this value is NULL. - /// - /// This function returns S_OK. - /// - /// The server calls CoGetStdMarshalEx passing in the flag SMEXF_SERVER. This creates a server side standard marshaler (known - /// as a stub manager). The handler calls CoGetStdMarshalEx 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. - /// - // 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); - - /// Returns the CLSID of an object that can emulate the specified object. - /// The CLSID of the object that can be emulated (treated as) an object with a different CLSID. - /// - /// A pointer to where the CLSID that can emulate clsidOld objects is retrieved. This parameter cannot be NULL. If there is - /// no emulation information for clsidOld objects, the clsidOld parameter is supplied. - /// - /// - /// This function can return the following values, as well as any error values returned by the CLSIDFromString function. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// A new CLSID was successfully returned. - /// - /// - /// S_FALSE - /// There is no emulation information for the clsidOld parameter, so the pClsidNew parameter is set to clsidOld. - /// - /// - /// REGDB_E_READREGDB - /// There was an error reading the registry. - /// - /// - /// - /// - /// CoGetTreatAsClass returns the TreatAs entry in the registry for the specified object. The TreatAs entry, if set, - /// is the CLSID of a registered object (an application) that can emulate the object in question. The TreatAs 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 - /// TreatAs entry for the specified object, this function returns the CLSID of the original object (clsidOld). - /// - // 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); - - /// Enables the server to impersonate the client of the current call for the duration of the call. - /// This function supports the standard return values, including S_OK. - /// - /// - /// 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): - /// - /// - /// CoImpersonateClient 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. - /// - /// - // 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(); - - /// Keeps MTA support active when no MTA threads are running. - /// - /// Address of a PVOID variable that receives the cookie for the CoDecrementMTAUsage function, or NULL if the call fails. - /// - /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. - /// - /// - /// The CoIncrementMTAUsage function enables clients to create MTA workers and wait on them for completion before exiting the process. - /// - /// - /// The CoIncrementMTAUsage function ensures that the system doesn't free resources related to MTA support., even if the MTA - /// thread count goes to 0. - /// - /// On success, call the CoDecrementMTAUsage once only. On failure, don't call the CoDecrementMTAUsage function. - /// - /// Don't call CoIncrementMTAUsage during process shutdown or inside dllmain. You can call CoIncrementMTAUsage before - /// the call to start the shutdown process. - /// - /// - /// You can call CoIncrementMTAUsage from one thread and CoDecrementMTAUsage from another as long as a cookie previously - /// returned by CoIncrementMTAUsage is passed to CoDecrementMTAUsage. - /// - /// - /// CoIncrementMTAUsage creates the MTA, if the MTA does not already exist. CoIncrementMTAUsage puts the current - /// thread into the MTA, if the current thread is not already in an apartment - /// - /// You can use CoIncrementMTAUsage when: - /// - /// - /// You want a server to keep the MTA alive even when all worker threads are idle. - /// - /// - /// - /// 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. - /// - /// - /// - /// - // 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); - - /// - /// Tells the service control manager to flush any cached RPC binding handles for the specified computer. - /// Only administrators may call this function. - /// - /// - /// 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. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// Indicates success. - /// - /// - /// CO_S_MACHINENAMENOTFOUND - /// - /// 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. - /// - /// - /// - /// E_ACCESSDENIED - /// Indicates the caller was not an administrator for this computer. - /// - /// - /// E_INVALIDARG - /// Indicates that a NULL value was passed for pszMachineName. - /// - /// - /// - /// - /// - /// 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. CoInvalidateRemoteMachineBindings is used for this purpose. - /// - /// - /// The OLE Service Control Manager will flush unused binding handles over time. It is not necessary to call - /// CoInvalidateRemoteMachineBindings to do this. - /// - /// - // 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); - - /// Determines whether a remote object is connected to the corresponding in-process object. - /// A pointer to the controlling IUnknown interface on the remote object. - /// - /// If the object is not remote or if it is remote and still connected, the return value is TRUE; otherwise, it is FALSE. - /// - /// - /// The CoIsHandlerConnected 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 TRUE 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 FALSE 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. - /// - // 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); - - /// Called either to lock an object to ensure that it stays in memory, or to release such a lock. - /// A pointer to the IUnknown interface on the object to be locked or unlocked. - /// - /// Indicates whether the object is to be locked or released. If this parameter is TRUE, the object is kept in memory, - /// independent of AddRef/ Release operations, registrations, or revocations. If this parameter is FALSE, the - /// lock previously set with a call to this function is released. - /// - /// - /// - /// If the lock is the last reference that is supposed to keep an object alive, specify TRUE to release all pointers to the - /// object (there may be other references that are not supposed to keep it alive). Otherwise, specify FALSE. - /// - /// If fLock is TRUE, this parameter is ignored. - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, and S_OK. - /// - /// - /// The CoLockObjectExternal 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). - /// - /// - /// The CoLockObjectExternal 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 CoLockObjectExternal with fLock set to FALSE. 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. - /// - /// - /// 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 - /// CoLockObjectExternal), the application can call the CoDisconnectObject function to force these connections to close prior - /// to shutdown. - /// - /// - /// Calling CoLockObjectExternal 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. - /// - /// The CoLockObjectExternal function is typically called in the following situations: - /// - /// - /// - /// Object servers should call CoLockObjectExternal with both fLock and fLastLockReleases set to TRUE 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 - /// CoLockObjectExternal, setting fLock to FALSE and fLastLockReleases to TRUE. - /// - /// - /// - /// A call to CoLockObjectExternal on the server can also be used in the implementation of IOleContainer::LockContainer. - /// - /// - /// - /// There are several things to be aware of when you use CoLockObjectExternal in the implementation of LockContainer. An - /// embedded object would call LockContainer 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. - /// - /// - /// Unless an application manages all aspects of its application and document shutdown completely with calls to - /// CoLockObjectExternal, 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 CoLockObjectExternal should be called whenever one of the following conditions occur: - /// - /// - /// - /// A document is created and destroyed or made visible or invisible. - /// - /// - /// An application is started and shut down by the user. - /// - /// - /// A pseudo-object is created and destroyed. - /// - /// - /// For debugging purposes, it may be useful to keep a count of the number of external locks (and unlocks) set on the application. - /// - // 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); - - /// - /// Marshals an HRESULT to the specified stream, from which it can be unmarshaled using the CoUnmarshalHresult function. - /// - /// - /// A pointer to the marshaling stream. See IStream. - /// - /// - /// The HRESULT in the originating process. - /// - /// - /// This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The HRESULT was marshaled successfully. - /// - /// - /// STG_E_INVALIDPOINTER - /// A bad pointer was specified for pstm. - /// - /// - /// STG_E_MEDIUMFULL - /// The medium is full. - /// - /// - /// - /// - /// - /// An HRESULT is process-specific, so an HRESULT 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 HRESULT 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. - /// - /// This function performs the following tasks: - /// - /// - /// Writes an HRESULT to a stream. - /// - /// - /// Returns an IStream pointer to that stream. - /// - /// - /// - // 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); - - /// Writes into a stream the data required to initialize a proxy object in some client process. - /// A pointer to the stream to be used during marshaling. See IStream. - /// - /// A reference to the identifier of the interface to be marshaled. This interface must be derived from the IUnknown interface. - /// - /// A pointer to the interface to be marshaled. This interface must be derived from the IUnknown interface. - /// - /// 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). - /// - /// This parameter is reserved and must be NULL. - /// - /// 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. - /// - /// - /// - /// 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. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The HRESULT was marshaled successfully. - /// - /// - /// CO_E_NOTINITIALIZED - /// The CoInitialize or OleInitialize function was not called on the current thread before this function was called. - /// - /// - /// - /// - /// - /// The CoMarshalInterface function marshals the interface referred to by riid on the object whose IUnknown implementation is - /// pointed to by pUnk. To do so, the CoMarshalInterface function performs the following tasks: - /// - /// - /// - /// - /// Queries the object for a pointer to the IMarshal interface. If the object does not implement IMarshal, meaning that it - /// relies on COM to provide marshaling support, CoMarshalInterface gets a pointer to COM's default implementation of IMarshal. - /// - /// - /// - /// - /// Gets the CLSID of the object's proxy by calling IMarshal::GetUnmarshalClass, using whichever IMarshal interface pointer has been returned. - /// - /// - /// - /// Writes the CLSID of the proxy to the stream to be used for marshaling. - /// - /// - /// Marshals the interface pointer by calling IMarshal::MarshalInterface. - /// - /// - /// - /// The COM library in the client process calls the CoUnmarshalInterface function to extract the data and initialize the proxy. - /// Before calling CoUnmarshalInterface, seek back to the original position in the stream. - /// - /// - /// 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 CoMarshalInterface for you. If you are writing your own - /// proxies and stubs, your proxy code and stub code should each call CoMarshalInterface to correctly marshal interface - /// pointers. Calling IMarshal directly from your proxy and stub code is not recommended. - /// - /// - /// 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 CoMarshalInterface on the object to do so. - /// - /// - // 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); - - /// Marshals an interface pointer from one thread to another thread in the same process. - /// A reference to the identifier of the interface to be marshaled. - /// A pointer to the interface to be marshaled, which must be derived from IUnknown. This parameter can be NULL. - /// - /// The address of the IStream* pointer variable that receives the interface pointer to the stream that contains the marshaled interface. - /// - /// This function can return the standard return values E_OUTOFMEMORY and S_OK. - /// - /// - /// The CoMarshalInterThreadInterfaceInStream 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. - /// - /// The CoMarshalInterThreadInterfaceInStream function performs the following tasks: - /// - /// - /// Creates a stream object. - /// - /// - /// Passes the stream object's IStream pointer to CoMarshalInterface. - /// - /// - /// Returns the IStream pointer to the caller. - /// - /// - /// - // 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); - - /// Retrieves a list of the authentication services registered when the process called CoInitializeSecurity. - /// A pointer to a variable that receives the number of entries returned in the asAuthSvc array. - /// - /// 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. - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. - /// - /// - /// CoQueryAuthenticationServices 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, - /// CoInitializeSecurity is called automatically by COM, registering the default security package, the first time an - /// interface is marshaled or unmarshaled. - /// - /// - /// 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. CoQueryAuthenticationServices is - /// primarily useful for custom marshalers, to determine which principal names an application can use. - /// - /// - /// 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. - /// - /// - // 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); - - /// Retrieves a list of the authentication services registered when the process called CoInitializeSecurity. - /// An array of SOLE_AUTHENTICATION_SERVICE structures. - /// - /// - /// CoQueryAuthenticationServices 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, - /// CoInitializeSecurity is called automatically by COM, registering the default security package, the first time an - /// interface is marshaled or unmarshaled. - /// - /// - /// 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. CoQueryAuthenticationServices is - /// primarily useful for custom marshalers, to determine which principal names an application can use. - /// - /// - /// 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. - /// - /// - // 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((int)c); } - - /// - /// 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. - /// - /// - /// 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 NULL, the current authentication service is not retrieved. - /// - /// - /// 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 NULL, the current authorization service is not retrieved. - /// - /// The string builder. - /// - /// 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 NULL, the current authentication level is not retrieved. - /// - /// This parameter must be NULL. - /// - /// 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, - /// NULL is returned. If the caller specifies NULL, the current privilege information is not retrieved. See RPC_AUTHZ_HANDLE. - /// - /// - /// 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 - /// NULL, the current capabilities are not retrieved. - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. - /// - /// - /// CoQueryClientBlanket 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): - /// - /// - /// This sequence calls CoGetCallContext to get a pointer to IServerSecurity and, with the resulting pointer, calls - /// IServerSecurity::QueryBlanket and then releases the pointer. - /// - /// - // 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); - - /// - /// Retrieves the authentication information the client uses to make calls on the specified proxy. This is a helper function for IClientSecurity::QueryBlanket. - /// - /// - /// A pointer indicating the proxy to query. This parameter cannot be NULL. For more information, see the Remarks section. - /// - /// - /// 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 NULL, the current authentication level is not retrieved. - /// - /// - /// 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 NULL, the current authorization service is not retrieved. - /// - /// - /// 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 NULL, the current principal name is not retrieved. - /// - /// - /// 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 NULL, the current authentication level is not retrieved. - /// - /// - /// 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 NULL, the current impersonation level is not retrieved. - /// - /// - /// 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 NULL, 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, NULL is returned. See RPC_AUTH_IDENTITY_HANDLE. - /// - /// - /// A pointer to a variable that receives the capabilities of the proxy. If the caller specifies NULL, the current capability - /// flags are not retrieved. - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. - /// - /// - /// CoQueryProxyBlanket 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): - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - // 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); - - /// Registers a process-wide filter to process activation requests. - /// Pointer to the filter to register. - /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. - /// This registers one and only one process-wide filter. - // 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); - - /// Registers an EXE class object with OLE so other applications can connect to it. - /// The CLSID to be registered. - /// A pointer to the IUnknown interface on the class object whose availability is being published. - /// - /// The context in which the executable code is to be run. For information on these context values, see the CLSCTX enumeration. - /// - /// - /// Indicates how connections are made to the class object. For information on these flags, see the REGCLS enumeration. - /// - /// - /// A pointer to a value that identifies the class object registered; later used by the CoRevokeClassObject function to revoke the registration. - /// - /// - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The class object was registered successfully. - /// - /// - /// - /// - /// - /// EXE object applications should call CoRegisterClassObject 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 - /// CoRegisterClassObject. Object handlers or DLL object applications do not call this function — instead, they must - /// implement and export the DllGetClassObject function. - /// - /// - /// At startup, a multiple-use EXE object application must create a class object (with the IClassFactory interface on it), and call - /// CoRegisterClassObject 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. - /// - /// - /// Multiple registrations of the same class object are independent and do not produce an error. Each subsequent registration yields - /// a unique key in lpdwRegister. - /// - /// - /// 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 /Embedding switch. - /// - /// - /// The server for a class object should call CoRevokeClassObject to revoke the class object (remove its registration) when all of - /// the following are true: - /// - /// - /// - /// There are no existing instances of the object definition. - /// - /// - /// There are no locks on the class object. - /// - /// - /// The application providing services to the class object is not under user control (not visible to the user on the display). - /// - /// - /// - /// 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 CoRegisterClassObject calls IUnknown::AddRef and CoRevokeClassObject calls - /// IUnknown::Release, so the two functions form an AddRef/ Release pair. - /// - /// - /// 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. - /// - /// - // 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); - - /// - /// 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. - /// - /// A pointer to the IID of the interface to be registered. - /// - /// A pointer to the CLSID of the DLL that contains the proxy/stub code for the custom interface specified by riid. - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. - /// - /// - /// Typically, the code responsible for marshaling an interface pointer into the current running process reads the - /// HKEY_CLASSES_ROOT\Interfaces 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. - /// - /// - /// 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. - /// CoRegisterPSClsid, used in conjunction with CoRegisterClassObject, provides that alternative. - /// - /// Examples - /// A DLL would typically call CoRegisterPSClsid as shown in the following code fragment. - /// - // 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); - - /// Registers the surrogate process through its ISurrogate interface pointer. - /// A pointer to the ISurrogate interface on the surrogate process to be registered. - /// This function returns S_OK to indicate that the surrogate process was registered successfully. - /// - /// - /// The CoRegisterSurrogate 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 ISurrogate. This function is usually called by the surrogate implementation when it is launched. - /// - /// - /// 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. - /// - /// - // 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); - - /// Destroys a previously marshaled data packet. - /// A pointer to the stream that contains the data packet to be destroyed. See IStream. - /// - /// - /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the - /// following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The data packet was successfully destroyed. - /// - /// - /// STG_E_INVALIDPOINTER - /// An error related to the pStm parameter. - /// - /// - /// CO_E_NOTINITIALIZED - /// The CoInitialize or OleInitialize function was not called on the current thread before this function was called. - /// - /// - /// - /// - /// - /// Important 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. - /// - /// The CoReleaseMarshalData function performs the following tasks: - /// - /// - /// The function reads a CLSID from the stream. - /// - /// - /// - /// 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 IMarshal interface pointer to the newly created proxy. - /// - /// - /// - /// Using whichever IMarshal interface pointer it has acquired, the function calls IMarshal::ReleaseMarshalData. - /// - /// - /// - /// 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 CoReleaseMarshalData should be called - /// include the following situations: - /// - /// - /// - /// An attempt was made to unmarshal the data packet, but it failed. - /// - /// - /// A marshaled data packet was removed from a global table. - /// - /// - /// - /// 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. - /// - /// - /// Note that you do not need to call CoReleaseMarshalData after a successful call of the CoUnmarshalInterface function; that - /// function releases the marshal data as part of the processing that it does. - /// - /// - /// Important You must call the CoReleaseMarshalData 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. - /// - /// - // 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); - - /// Decrements the global per-process reference count. - /// - /// If the server application should initiate its cleanup, the function returns 0; otherwise, the function returns a nonzero value. - /// - /// - /// - /// Servers can call CoReleaseServerProcess to decrement a global per-process reference count incremented through a call to CoAddRefServerProcess. - /// - /// - /// 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. - /// - /// - /// 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 - /// TRUE. The server application should also call CoReleaseServerProcess in the destructor of each of its instance - /// objects, and in each of its IClassFactory::LockServer methods when the fLock parameter is FALSE. Finally, the - /// server application must check the return code from CoReleaseServerProcess; 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. - /// - /// - /// 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 CoReleaseServerProcess. - /// - /// - // 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(); - - /// - /// 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. - /// - /// This function returns S_OK to indicate that the CLSID was retrieved successfully. - /// - /// - /// Servers that can register multiple class objects call CoResumeClassObjects 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. - /// - /// - /// 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 CoResumeClassObjects. 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. - /// - /// - // 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(); - - /// Restores the authentication information on a thread of execution. - /// This function supports the standard return values, including S_OK to indicate success. - /// - /// - /// CoRevertToSelf, 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. - /// - /// CoRevertToSelf encapsulates the following common sequence of calls (error handling excluded): - /// - // 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(); - - /// - /// Informs OLE that a class object, previously registered with the CoRegisterClassObject function, is no longer available for use. - /// - /// A token previously returned from the CoRegisterClassObject function. - /// - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The class object was revoked successfully. - /// - /// - /// - /// - /// - /// A successful call to CoRevokeClassObject 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 AddRef and IUnknown::Release) to the class - /// object fail. Note that CoRegisterClassObject calls AddRef and CoRevokeClassObject calls Release, so the two - /// functions form an AddRef/ Release pair. - /// - /// - /// An object application must call CoRevokeClassObject to revoke registered class objects before exiting the program. Class - /// object implementers should call CoRevokeClassObject 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. - /// - /// - // 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); - - /// - /// Sets (registers) or resets (unregisters) a cancel object for use during subsequent cancel operations on the current thread. - /// - /// - /// Pointer to the IUnknown interface on the cancel object to be set or reset on the current thread. If this parameter is - /// NULL, the topmost cancel object is reset. - /// - /// - /// - /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the - /// following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The cancel object was successfully set or reset. - /// - /// - /// E_ACCESSDENIED - /// The cancel object cannot be set or reset at this time because of a block on cancel operations. - /// - /// - /// - /// - /// - /// For objects that support standard marshaling, the proxy object begins marshaling a method call by calling - /// CoSetCancelObject to register a cancel object for the current thread. - /// - /// - /// CoSetCancelObject calls QueryInterface for ICancelMethodCalls on the cancel object. If the cancel object does not - /// implement ICancelMethodCalls, CoSetCancelObject 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. - /// - /// CoSetCancelObject calls AddRef on objects that it registers and Release on objects that it unregisters. - /// CoSetCancelObject does not set or reset cancel objects for asynchronous methods. - /// - // 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); - - /// - /// Sets the authentication information that will be used to make calls on the specified proxy. This is a helper function for IClientSecurity::SetBlanket. - /// - /// The proxy to be set. - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// - /// 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 NULL. It must be the correct principal name of the server or the call will fail. - /// - /// - /// If Schannel is used as the authentication service, this value must be one of the msstd or fullsic forms described in Principal - /// Names, or NULL if you do not want mutual authentication. - /// - /// - /// Generally, specifying NULL will not reset the server principal name on the proxy; rather, the previous setting will be - /// retained. You must be careful when using NULL 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. - /// - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// - /// A pointer to an RPC_AUTH_IDENTITY_HANDLE 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. - /// - /// - /// For calls on the same computer, RPC logs on the user with the supplied credentials and uses the resulting token for the method call. - /// - /// - /// 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. - /// - /// - /// If this parameter is NULL, 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. - /// - /// - /// For Schannel, this parameter must be either a pointer to a CERT_CONTEXT structure that contains the client's X.509 certificate - /// or is NULL 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. - /// - /// - /// For Snego, this member is either NULL, points to a SEC_WINNT_AUTH_IDENTITY structure, or points to a - /// SEC_WINNT_AUTH_IDENTITY_EX structure. If it is NULL, Snego will pick a list of authentication services based on those - /// available on the client computer. If it points to a SEC_WINNT_AUTH_IDENTITY_EX structure, the structure's - /// PackageList member must point to a string containing a comma-separated list of authentication service names and the - /// PackageListLength member must give the number of bytes in the PackageList string. If PackageList is - /// NULL, all calls using Snego will fail. - /// - /// - /// If COLE_DEFAULT_AUTHINFO is specified for this parameter, DCOM will pick the authentication information following its normal - /// security blanket negotiation algorithm. - /// - /// CoSetProxyBlanket will fail if pAuthInfo is set and one of the cloaking flags is set in the dwCapabilities parameter. - /// - /// - /// 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, CoSetProxyBlanket will fail. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The function was successful. - /// - /// - /// E_INVALIDARG - /// One or more arguments is invalid. - /// - /// - /// - /// - /// - /// CoSetProxyBlanket 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). - /// - /// - /// 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. - /// - /// - // 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); - - /// Prevents any new activation requests from the SCM on all class objects registered within the process. - /// This function returns S_OK to indicate that the activation of class objects was successfully suspended. - /// - /// CoSuspendClassObjects 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. - /// - // 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(); - - /// Switches the call context object used by CoGetCallContext. - /// - /// A pointer to an interface on the new call context object. COM stores this pointer without adding a reference to the pointer - /// until CoSwitchCallContext is called with another object. This parameter may be NULL if you are calling - /// CoSwitchCallContext to switch back to the original call context but there was no original call context. - /// - /// - /// 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 NULL - /// if there was no call in progress. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The function was successful. - /// - /// - /// E_OUT_OF_MEMORY - /// Out of memory. - /// - /// - /// - /// - /// - /// Custom marshallers call CoSwitchCallContext to change the call context object used by the CoGetCallContext function. - /// Before dispatching an arriving call, custom marshallers call CoSwitchCallContext, specifying the new context object. - /// After sending a reply, they must restore the original call context by calling CoSwitchCallContext again, this time - /// passing a pointer to the original context object. - /// - /// - /// CoSwitchCallContext 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. - /// - /// Call context objects provided by custom marshallers should support the IServerSecurity interface. - /// - // 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); - - /// Allocates a block of task memory in the same way that IMalloc::Alloc does. - /// The size of the memory block to be allocated, in bytes. - /// If the function succeeds, it returns the allocated memory block. Otherwise, it returns NULL. - /// - /// - /// CoTaskMemAlloc 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 CoTaskMemAlloc. - /// - /// - /// 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. - /// - /// - /// If cb is 0, CoTaskMemAlloc allocates a zero-length item and returns a valid pointer to that item. If there is - /// insufficient memory available, CoTaskMemAlloc returns NULL. 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. - /// - /// - // 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); - - /// Frees a block of task memory previously allocated through a call to the CoTaskMemAlloc or CoTaskMemRealloc function. - /// A pointer to the memory block to be freed. If this parameter is NULL, the function has no effect. - /// This function does not return a value. - /// - /// The CoTaskMemFree function uses the default OLE allocator. - /// - /// 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. - /// - /// - // 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); - - /// Changes the size of a previously allocated block of task memory. - /// A pointer to the memory block to be reallocated. This parameter can be NULL, as discussed in Remarks. - /// The size of the memory block to be reallocated, in bytes. This parameter can be 0, as discussed in Remarks. - /// If the function succeeds, it returns the reallocated memory block. Otherwise, it returns NULL. - /// - /// - /// 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 CoTaskMemRealloc. - /// - /// - /// The pv parameter points to the beginning of the memory block. If pv is NULL, CoTaskMemRealloc allocates a new - /// memory block in the same way as the CoTaskMemAlloc function. If pv is not NULL, it should be a pointer returned by a - /// prior call to CoTaskMemAlloc. - /// - /// - /// 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 CoTaskMemRealloc is not guaranteed to be the pointer passed through the pv argument. If pv is not - /// NULL and cb is 0, then the memory pointed to by pv is freed. - /// - /// - /// CoTaskMemRealloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is - /// NULL if the size is 0 and the buffer argument is not NULL, 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. - /// - /// - /// 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 void, use a type cast on the return value. - /// - /// - // 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); - - /// - /// Determines whether the call being executed on the server has been canceled by the client. - /// - /// - /// - /// This function can return the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the - /// following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// RPC_S_CALLPENDING - /// The call is still pending and has not yet been canceled by the client. - /// - /// - /// RPC_E_CALL_CANCELED - /// The call has been canceled by the client. - /// - /// - /// - /// - /// - /// Server objects should call CoTestCancel 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. - /// - /// - /// CoTestCancel 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. - /// - /// This function does not test cancellation for asynchronous calls. - /// - // 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(); - - /// Unmarshals an HRESULT type from the specified stream. - /// A pointer to the stream from which the HRESULT is to be unmarshaled. - /// A pointer to the unmarshaled HRESULT. - /// - /// This function can return the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The HRESULT was unmarshaled successfully. - /// - /// - /// STG_E_INVALIDPOINTER - /// pStm is an invalid pointer. - /// - /// - /// - /// - /// - /// 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 HRESULT. - /// - /// - /// You must use CoUnmarshalHresult to unmarshal HRESULT values previously marshaled by a call to the CoMarshalHresult function. - /// - /// This function performs the following tasks: - /// - /// - /// an HRESULT from a stream. - /// - /// - /// Returns the HRESULT. - /// - /// - /// - // 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); - - /// - /// 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. - /// - /// A pointer to the stream from which the interface is to be unmarshaled. - /// - /// A reference to the identifier of the interface to be unmarshaled. For IID_NULL, the returned interface is the one defined - /// by the stream, objref.iid. - /// - /// - /// The address of pointer variable that receives the interface pointer requested in . Upon successful - /// return, contains the requested interface pointer for the unmarshaled interface. - /// - /// - /// This function can return the standard return value E_FAIL, errors returned by CoCreateInstance, and the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The interface pointer was unmarshaled successfully. - /// - /// - /// STG_E_INVALIDPOINTER - /// pStm is an invalid pointer. - /// - /// - /// CO_E_NOTINITIALIZED - /// The CoInitialize or OleInitialize function was not called on the current thread before this function was called. - /// - /// - /// CO_E_OBJNOTCONNECTED - /// - /// The object application has been disconnected from the remoting system (for example, as a result of a call to the - /// CoDisconnectObject function). - /// - /// - /// - /// REGDB_E_CLASSNOTREG - /// An error occurred reading the registration database. - /// - /// - /// E_NOINTERFACE - /// The final QueryInterface of this function for the requested interface returned E_NOINTERFACE. - /// - /// - /// - /// - /// - /// Important 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. - /// - /// The CoUnmarshalInterface function performs the following tasks: - /// - /// - /// Reads from the stream the CLSID to be used to create an instance of the proxy. - /// - /// - /// - /// 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, CoUnmarshalInterface calls the CoCreateInstance function, passing the CLSID it read from the - /// marshaling stream. CoCreateInstance creates an instance of the object's proxy and returns an IMarshal interface - /// pointer to the proxy. - /// - /// - /// - /// - /// Using whichever IMarshal interface pointer it has acquired, the function then calls IMarshal::UnmarshalInterface and, if - /// appropriate, IMarshal::ReleaseMarshalData. - /// - /// - /// - /// - /// 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 CoUnmarshalInterface. For example, if you are implementing a - /// stub, your implementation would call CoUnmarshalInterface when the stub receives an interface pointer as a parameter in a - /// method call. - /// - /// - // 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); - - /// Waits for specified handles to be signaled or for a specified timeout period to elapse. - /// The wait options. Possible values are taken from the COWAIT_FLAGS enumeration. - /// The timeout period, in milliseconds. - /// The number of elements in the pHandles array. - /// An array of handles. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// See WaitForMultipleObjectsEx for more information. - /// - /// - /// This function can return the following values. - /// - /// Note The return value of CoWaitForMultipleHandles 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 CoWaitForMultipleHandles. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The required handle or handles were signaled. - /// - /// - /// E_INVALIDARG - /// pHandles was NULL, lpdwindex was NULL, or dwFlags was not a value from the COWAIT_FLAGS enumeration. - /// - /// - /// RPC_E_NO_SYNC - /// The value of pHandles was 0. - /// - /// - /// RPC_S_CALLPENDING - /// The timeout period elapsed before the required handle or handles were signaled. - /// - /// - /// - /// - /// - /// Depending on which flags are set in the dwFlags parameter, CoWaitForMultipleHandles blocks the calling thread until one - /// of the following events occurs: - /// - /// - /// - /// - /// One or all of the handles is signaled. In the case of mutex objects, this condition is also satisfied by a mutex being abandoned. - /// - /// - /// - /// An asynchronous procedure call (APC) has been queued to the calling thread with a call to the QueueUserAPC function. - /// - /// - /// The timeout period expires. - /// - /// - /// - /// If the caller resides in a single-thread apartment, CoWaitForMultipleHandles 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. - /// - /// - /// If the calling thread resides in a multithread apartment (MTA), CoWaitForMultipleHandles calls the - /// WaitForMultipleObjectsEx function. - /// - /// - // 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); - - /// - /// A replacement for CoWaitForMultipleHandles. This replacement API hides the options for CoWaitForMultipleHandles that are - /// not supported in ASTA. - /// - /// - /// 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 CoWaitForMultipleObjects in ASTA. - /// - /// The timeout in milliseconds of the wait. - /// The length of the pHandles array. Must be <= 56. - /// An array of handles to waitable kernel objects. - /// Receives the index of the handle that satisfied the wait. - /// - /// Same return values as CoWaitForMultipleHandles, except the ASTA-specific CO_E_NOTSUPPORTED cases instead return E_INVALIDARG - /// from all apartment types. - /// - // 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); - - /// - /// - /// The CreateStreamOnHGlobal 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. - /// - /// - /// 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. - /// - /// - /// Tip Consider using the SHCreateMemStream function, which produces better performance, or for Windows Store apps, consider - /// using InMemoryRandomAccessStream. - /// - /// - /// - /// A memory handle allocated by the GlobalAlloc function, or if NULL a new handle is to be allocated instead. The handle - /// must be allocated as moveable and nondiscardable. - /// - /// - /// 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 FALSE, the caller must free the hGlobal after the final release. If set to TRUE, the final - /// release will automatically free the hGlobal parameter. - /// - /// - /// The address of IStream* pointer variable that receives the interface pointer to the new stream object. Its value cannot be NULL. - /// - /// This function supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following. - /// - /// If hGlobal is NULL, the function allocates a new memory handle and the stream is initially empty. - /// - /// If hGlobal is not NULL, the initial contents of the stream are the current contents of the memory block. Thus, - /// CreateStreamOnHGlobal 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. - /// - /// - /// 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. - /// - /// The new stream object’s initial seek position is the beginning of the stream. - /// - /// After creating the stream object with CreateStreamOnHGlobal, call GetHGlobalFromStream to retrieve the memory handle - /// associated with the stream object. - /// - /// - /// If a memory handle is passed to CreateStreamOnHGlobal 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: - /// - /// - /// - /// - /// Do not free the hGlobal memory handle during the lifetime of the stream object. IStream::Release must be called before freeing - /// the memory handle. - /// - /// - /// - /// - /// 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 GlobalReAlloc. 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. - /// - /// - /// - /// - /// 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. - /// - /// - /// - /// - /// Avoid calling the object’s methods while you have the memory handle locked with GlobalLock. This can cause method calls to fail unpredictably. - /// - /// - /// - /// - /// If the caller sets the fDeleteOnRelease parameter to FALSE, then the caller must also free the hGlobal after the final - /// release. If the caller sets the fDeleteOnRelease parameter to TRUE, the final release will automatically free the hGlobal. - /// - /// - /// The memory handle passed as the hGlobal parameter must be allocated as movable and nondiscardable, as shown in the following example: - /// - /// - /// CreateStreamOnHGlobal will accept a memory handle allocated with GMEM_FIXED, but this usage is not recommended. HGLOBALs - /// allocated with GMEM_FIXED are not really handles and their value can change when they are reallocated. If the memory - /// handle was allocated with GMEM_FIXED and fDeleteOnRelease is FALSE, the caller must call GetHGlobalFromStream to - /// get the correct handle in order to free it. - /// - /// - /// 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. - /// - /// - // 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); - - /// - /// Determines whether the DLL that implements this function is in use. If not, the caller can unload the DLL from memory. - /// - /// OLE does not provide this function. DLLs that support the OLE Component Object Model (COM) should implement and export DllCanUnloadNow. - /// - /// - /// If the function succeeds, the return value is S_OK. Otherwise, it is S_FALSE. - /// - /// - /// A call to DllCanUnloadNow 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). - /// - /// Notes to Callers - /// - /// You should not have to call DllCanUnloadNow directly. OLE calls it only through a call to the CoFreeUnusedLibraries - /// function. When it returns S_OK, CoFreeUnusedLibraries frees the DLL. - /// - /// Notes to Implementers - /// - /// You must implement DllCanUnloadNow 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). - /// - /// - /// If a DLL loaded through a call to CoGetClassObject fails to export DllCanUnloadNow, the DLL will not be unloaded until - /// the application calls the CoUninitialize function to release the OLE libraries. - /// - /// DllCanUnloadNow should return S_FALSE if there are any existing references to objects that the DLL manages. - /// - // 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(); - - /// - /// Retrieves the class object from a DLL object handler or object application. - /// - /// OLE does not provide this function. DLLs that support the OLE Component Object Model (COM) must implement - /// DllGetClassObject in OLE object handlers or DLL applications. - /// - /// - /// The CLSID that will associate the correct data and code. - /// - /// 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). - /// - /// - /// 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 NULL. - /// - /// - /// - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following values. - /// - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The object was retrieved successfully. - /// - /// - /// CLASS_E_CLASSNOTAVAILABLE - /// The DLL does not support the class (object definition). - /// - /// - /// - /// - /// - /// If a call to the CoGetClassObject function finds the class object that is to be loaded in a DLL, CoGetClassObject uses - /// the DLL's exported DllGetClassObject function. - /// - /// Notes to Callers - /// - /// You should not call DllGetClassObject directly. When an object is defined in a DLL, CoGetClassObject calls the - /// CoLoadLibrary function to load the DLL, which, in turn, calls DllGetClassObject. - /// - /// Notes to Implementers - /// You need to implement DllGetClassObject in (and export it from) DLLs that support COM. - /// Examples - /// - /// The following is an example (in C++) of an implementation of DllGetClassObject. In this example, DllGetClassObject - /// 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 - /// IClassFactory to the caller. - /// - /// - // 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); - - /// - /// The FreePropVariantArray 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. - /// - /// Count of elements in the PROPVARIANT array (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 PROPVARIANT structure (thus tagging them as VT_EMPTY). - /// - /// This function returns HRESULT. - /// - /// - /// FreePropVariantArray calls PropVariantClear on an array of PROPVARIANT structures to clear all the valid members. All - /// valid PROPVARIANT structures are freed. If any of the PROPVARIANT structures contain illegal VT types, valid - /// members are freed and the function returns STG_E_INVALIDPARAMETER. - /// - /// Passing NULL for rgvars is legal, and produces a return code of S_OK. - /// - // 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); - - /// - /// The GetHGlobalFromStream function retrieves the global memory handle to a stream that was created through a call to the - /// CreateStreamOnHGlobal function. - /// - /// IStream pointer to the stream object previously created by a call to the CreateStreamOnHGlobal function. - /// Pointer to the current memory handle used by the specified stream object. - /// This function returns HRESULT. - /// - /// - /// The handle GetHGlobalFromStream returns may be different from the original handle due to intervening GlobalReAlloc calls. - /// - /// This function can be called only from within the same process from which the byte array was created. - /// - // 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); - - /// Converts a string generated by the StringFromIID function back into the original interface identifier (IID). - /// A pointer to the string representation of the IID. - /// A pointer to the requested IID on return. - /// This function can return the standard return values E_INVALIDARG, E_OUTOFMEMORY, and S_OK. - /// - /// The function converts the interface identifier in a way that guarantees different interface identifiers will always be converted - /// to different strings. - /// - // 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); - - /// Retrieves the ProgID for a given CLSID. - /// The CLSID for which the ProgID is to be requested. - /// - /// The address of a pointer variable that receives the ProgID string. The string that represents clsid includes enclosing braces. - /// - /// - /// This function can return the following values. - /// - /// - /// Return code - /// Description - /// - /// - /// S_OK - /// The ProgID was returned successfully. - /// - /// - /// REGDB_E_CLASSNOTREG - /// Class not registered in the registry. - /// - /// - /// REGDB_E_READREGDB - /// There was an error reading from the registry. - /// - /// - /// - /// - /// - /// Every OLE object class listed in the Insert Object 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 Insert - /// Object 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. - /// - /// - /// ProgIDFromCLSID 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. - /// - /// - /// 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). - /// - /// - /// 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. - /// - /// - /// 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. - /// - /// - // 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); - - /// Creates an agile reference for an object specified by the given interface. - /// The options. - /// The interface ID of the object for which an agile reference is being obtained. - /// - /// 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. - /// - /// - /// The agile reference for the object. Call the Resolve method to localize the object into the apartment in which Resolve is called. - /// - /// - /// This function can return one of these values. - /// - /// - /// Return value - /// Description - /// - /// - /// S_OK - /// The function completed successfully. - /// - /// - /// E_INVALIDARG - /// The options parameter in invalid. - /// - /// - /// E_OUTOFMEMORY - /// The agile reference couldn't be constructed due to an out-of-memory condition. - /// - /// - /// E_NOINTERFACE - /// The pUnk parameter doesn't support the interface ID specified by the riid parameter. - /// - /// - /// CO_E_NOT_SUPPORTED - /// The object implements the INoMarshal interface. - /// - /// - /// - /// - /// - /// Call the RoGetAgileReference 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 IAgileReference interface. - /// - /// - /// 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. - /// - /// - /// 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 - /// RoGetAgileReference 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. - /// - /// - /// For example, you have a non-agile object named CDemoExample, which implements the IDemo and IExample interfaces. Call the - /// RoGetAgileReference 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. - /// - /// - // 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); - - /// Converts a CLSID into a string of printable characters. Different CLSIDs always convert to different strings. - /// The CLSID to be converted. - /// - /// The address of a pointer variable that receives a pointer to the resulting string. The string that represents rclsid includes - /// enclosing braces. - /// - /// This function can return the standard return values E_OUTOFMEMORY and S_OK. - /// - /// - /// StringFromCLSID calls the StringFromGUID2 function to convert a globally unique identifier (GUID) into a string of - /// printable characters. - /// - /// The caller is responsible for freeing the memory allocated for the string by calling the CoTaskMemFree function. - /// - // 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); - - /// Converts a globally unique identifier (GUID) into a string of printable characters. - /// The GUID to be converted. - /// - /// A pointer to a caller-allocated string variable to receive the resulting string. The string that represents rguid includes - /// enclosing braces. - /// - /// The number of characters available in the lpsz buffer. - /// - /// 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. - /// - // 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); - - /// Converts an interface identifier into a string of printable characters. - /// The interface identifier to be converted. - /// - /// The address of a pointer variable that receives a pointer to the resulting string. The string that represents rclsid includes - /// enclosing braces. - /// - /// This function can return the standard return values E_OUTOFMEMORY and S_OK. - /// The caller is responsible for freeing the memory allocated for the string by calling the CoTaskMemFree function. - // 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); - - /// Represents the implementation of a Component Object Model (COM) interface in a server process. - /// - /// The ServerInformation structure is used by the CoDecodeProxy function to enable native debuggers to locate the - /// implementation of a COM interface in a server process, given a Windows Runtime interface on a proxy to the Windows Runtime object. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/ns-combaseapi-serverinformation typedef struct tagServerInformation - // { DWORD dwServerPid; DWORD dwServerTid; UINT64 ui64ServerAddress; } ServerInformation, *PServerInformation; - [PInvokeData("combaseapi.h", MSDNShortId = "NS:combaseapi.tagServerInformation")] - [StructLayout(LayoutKind.Sequential)] - public struct ServerInformation - { - /// The process ID of the server. - public uint dwServerPid; - - /// - /// The thread ID of the server object if it's in the STA, 0 if it's in the MTA, and 0x0000FFFF if it's in the NA. - /// - public uint dwServerTid; - - /// - /// ui64ServerAddress 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. - /// - public ulong ui64ServerAddress; - } + public ulong ui64ServerAddress; } } \ No newline at end of file