using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using Vanara.Extensions; using Vanara.InteropServices; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; using STATSTG = System.Runtime.InteropServices.ComTypes.STATSTG; namespace Vanara.PInvoke { public static partial class Ole32 { /// /// Specifies various capabilities in CoInitializeSecurity and IClientSecurity::SetBlanket (or its helper function CoSetProxyBlanket). /// /// /// /// When the EOAC_APPID flag is set, CoInitializeSecurity looks for the authentication level under the AppID. If the authentication /// level is not found, it looks for the default authentication level. If the default authentication level is not found, it generates /// a default authentication level of connect. If the authentication level is not RPC_C_AUTHN_LEVEL_NONE, CoInitializeSecurity /// looks for the access permission value under the AppID. If not found, it looks for the default access permission value. If not /// found, it generates a default access permission. All the other security settings are determined the same way as for a legacy application. /// /// /// If the AppID is NULL, CoInitializeSecurity looks up the application .exe name in the registry and uses the AppID stored /// there. If the AppID does not exist, the machine defaults are used. /// /// /// The IClientSecurity::SetBlanket method and CoSetProxyBlanket function return an error if any of the following flags are set in /// the capabilities parameter: EOAC_SECURE_REFS, EOAC_ACCESS_CONTROL, EOAC_APPID, EOAC_DYNAMIC, EOAC_REQUIRE_FULLSIC, /// EOAC_DISABLE_AAA, or EOAC_NO_CUSTOM_MARSHAL. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/objidlbase/ne-objidlbase-tageole_authentication_capabilities typedef enum // tagEOLE_AUTHENTICATION_CAPABILITIES { EOAC_NONE , EOAC_MUTUAL_AUTH , EOAC_STATIC_CLOAKING , EOAC_DYNAMIC_CLOAKING , // EOAC_ANY_AUTHORITY , EOAC_MAKE_FULLSIC , EOAC_DEFAULT , EOAC_SECURE_REFS , EOAC_ACCESS_CONTROL , EOAC_APPID , EOAC_DYNAMIC , // EOAC_REQUIRE_FULLSIC , EOAC_AUTO_IMPERSONATE , EOAC_DISABLE_AAA , EOAC_NO_CUSTOM_MARSHAL , EOAC_RESERVED1 } EOLE_AUTHENTICATION_CAPABILITIES; [PInvokeData("objidlbase.h", MSDNShortId = "cf3396d0-6674-4f12-bd4a-227a8d32bc92")] [Flags] public enum EOLE_AUTHENTICATION_CAPABILITIES : uint { /// Indicates that no capability flags are set. EOAC_NONE = 0x0000, /// /// If this flag is specified, it will be ignored. Support for mutual authentication is automatically provided by some /// authentication services. See COM and Security Packages for more information. /// EOAC_MUTUAL_AUTH = 0x0001, /// /// Sets static cloaking. When this flag is set, DCOM uses the thread token (if present) when determining the client's identity. /// However, the client's identity is determined on the first call on each proxy (if SetBlanket is not called) and each time /// CoSetProxyBlanket is called on the proxy. For more information about static cloaking, see Cloaking. CoInitializeSecurity and /// IClientSecurity::SetBlanket return errors if both cloaking flags are set or if either flag is set when Schannel is the /// authentication service. /// EOAC_STATIC_CLOAKING = 0x0020, /// /// Sets dynamic cloaking. When this flag is set, DCOM uses the thread token (if present) when determining the client's identity. /// On each call to a proxy, the current thread token is examined to determine whether the client's identity has changed /// (incurring an additional performance cost) and the client is authenticated again only if necessary. Dynamic cloaking can be /// set by clients only. For more information about dynamic cloaking, see Cloaking. CoInitializeSecurity and /// IClientSecurity::SetBlanket return errors if both cloaking flags are set or if either flag is set when Schannel is the /// authentication service. /// EOAC_DYNAMIC_CLOAKING = 0x0040, /// This flag is obsolete. EOAC_ANY_AUTHORITY = 0x0080, /// /// Causes DCOM to send Schannel server principal names in fullsic format to clients as part of the default security negotiation. /// The name is extracted from the server certificate. For more information about the fullsic form, see Principal Names. /// EOAC_MAKE_FULLSIC = 0x0100, /// /// Tells DCOM to use the valid capabilities from the call to CoInitializeSecurity. If CoInitializeSecurity was not called, /// EOAC_NONE will be used for the capabilities flag. This flag can be set only by clients in a call to /// IClientSecurity::SetBlanket or CoSetProxyBlanket. /// EOAC_DEFAULT = 0x0800, /// /// Authenticates distributed reference count calls to prevent malicious users from releasing objects that are still being used. /// If this flag is set, which can be done only in a call to CoInitializeSecurity by the client, the authentication level (in /// dwAuthnLevel) cannot be set to none. The server always authenticates Release calls. Setting this flag prevents an /// authenticated client from releasing the objects of another authenticated client. It is recommended that clients always set /// this flag, although performance is affected because of the overhead associated with the extra security. /// EOAC_SECURE_REFS = 0x0002, /// /// Indicates that the pSecDesc parameter to CoInitializeSecurity is a pointer to a GUID that is an AppID. The /// CoInitializeSecurity function looks up the AppID in the registry and reads the security settings from there. If this flag is /// set, all other parameters to CoInitializeSecurity are ignored and must be zero. Only the server can set this flag. For more /// information about this capability flag, see the Remarks section below. CoInitializeSecurity returns an error if both the /// EOAC_APPID and EOAC_ACCESS_CONTROL flags are set. /// EOAC_APPID = 0x0008, /// /// Specifying this flag helps protect server security when using DCOM or COM+. It reduces the chances of executing arbitrary /// DLLs because it allows the marshaling of only CLSIDs that are implemented in Ole32.dll, ComAdmin.dll, ComSvcs.dll, or Es.dll, /// or that implement the CATID_MARSHALER category ID. Any service that is critical to system operation should set this flag. /// EOAC_NO_CUSTOM_MARSHAL = 0x2000, /// EOAC_RESERVED1 = 0x4000, /// /// Indicates that the pSecDesc parameter to CoInitializeSecurity is a pointer to an IAccessControl interface on an access /// control object. When DCOM makes security checks, it calls IAccessControl::IsAccessAllowed. This flag is set only by the /// server. CoInitializeSecurity returns an error if both the EOAC_APPID and EOAC_ACCESS_CONTROL flags are set. /// EOAC_ACCESS_CONTROL = 0x0004, /// Reserved. EOAC_DYNAMIC = 0x0010, /// /// Causes DCOM to fail CoSetProxyBlanket calls where an Schannel principal name is specified in any format other than fullsic. /// This flag is currently for clients only. For more information about the fullsic form, see Principal Names. /// EOAC_REQUIRE_FULLSIC = 0x0200, /// Reserved. EOAC_AUTO_IMPERSONATE = 0x0400, /// /// Causes any activation where a server process would be launched under the caller's identity (activate-as-activator) to fail /// with E_ACCESSDENIED. This value, which can be specified only in a call to CoInitializeSecurity by the client, allows an /// application that runs under a privileged account (such as LocalSystem) to help prevent its identity from being used to launch /// untrusted components. An activation call that uses CLSCTX_ENABLE_AAA of the CLSCTX enumeration will allow /// activate-as-activator activations for that call. /// EOAC_DISABLE_AAA = 0x1000, } /// /// The IEnumSTATSTG interface enumerates an array of STATSTG structures. These structures contain statistical data about open /// storage, stream, or byte array objects. /// [ComImport, Guid("0000000D-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [PInvokeData("Objidl.h", MSDNShortId = "aa379217")] public interface IEnumSTATSTG { /// /// The Next method retrieves a specified number of STATSTG structures, that follow in the enumeration sequence. If there are /// fewer than the requested number of STATSTG structures that remain in the enumeration sequence, it retrieves the remaining /// STATSTG structures. /// /// The number of STATSTG structures requested. /// An array of STATSTG structures returned. /// The number of STATSTG structures retrieved in the rgelt parameter. /// /// This method supports the following return values: S_OK = The number of STATSTG structures returned is equal to the number /// specified in the celt parameter. S_FALSE = The number of STATSTG structures returned is less than the number specified in the /// celt parameter. /// [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] HRESULT Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] STATSTG[] rgelt, out uint pceltFetched); /// Skips a specified number of STATSTG structures in the enumeration sequence. /// The number of STATSTG structures to skip. /// /// This method supports the following return values: S_OK = The specified number of STATSTG structures that were successfully /// skipped. S_FALSE = The number of STATSTG structures skipped is less than the celt parameter. /// [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] HRESULT Skip([In] uint celt); /// Resets the enumeration sequence to the beginning of the STATSTG structure array. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void Reset(); /// Creates a new enumerator that contains the same enumeration state as the current STATSTG structure enumerator. /// An IEnumSTATSTG interface pointer. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.Interface)] IEnumSTATSTG Clone(); } /// /// The IStorage interface supports the creation and management of structured storage objects. Structured storage allows hierarchical /// storage of information within a single file, and is often referred to as "a file system within a file". Elements of a structured /// storage object are storages and streams. Storages are analogous to directories, and streams are analogous to files. Within a /// structured storage there will be a primary storage object that may contain substorages, possibly nested, and streams. Storages /// provide the structure of the object, and streams contain the data, which is manipulated through the IStream interface. /// /// The IStorage interface provides methods for creating and managing the root storage object, child storage objects, and stream /// objects. These methods can create, open, enumerate, move, copy, rename, or delete the elements in the storage object. /// /// /// An application must release its IStorage pointers when it is done with the storage object to deallocate memory used. There are /// also methods for changing the date and time of an element. /// /// /// There are a number of different modes in which a storage object and its elements can be opened, determined by setting values from /// STGM Constants. One aspect of this is how changes are committed. You can set direct mode, in which changes to an object are /// immediately written to it, or transacted mode, in which changes are written to a buffer until explicitly committed. The IStorage /// interface provides methods for committing changes and reverting to the last-committed version. For example, a stream can be /// opened in read-only mode or read/write mode. For more information, see STGM Constants. /// /// Other methods provide access to information about a storage object and its elements through the STATSTG structure. /// [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComConversionLoss, Guid("0000000B-0000-0000-C000-000000000046")] [PInvokeData("Objidl.h", MSDNShortId = "aa380015")] public interface IStorage { /// /// The CreateStream method creates and opens a stream object with the specified name contained in this storage object. All /// elements within a storage objects, both streams and other storage objects, are kept in the same name space. /// /// /// A string that contains the name of the newly created stream. The name can be used later to open or reopen the stream. The /// name must not exceed 31 characters in length, not including the string terminator. The 000 through 01f characters, serving as /// the first character of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a /// structured storage restriction. /// /// /// Specifies the access mode to use when opening the newly created stream. For more information and descriptions of the possible /// values, see STGM Constants. /// /// Reserved for future use; must be zero. /// Reserved for future use; must be zero. /// On return, the new IStream interface pointer. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.Interface)] IStream CreateStream([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In] STGM grfMode, [In, Optional] uint reserved1, [In, Optional] uint reserved2); /// The OpenStream method opens an existing stream object within this storage object in the specified access mode. /// /// A string that contains the name of the stream to open. The 000 through 01f characters, serving as the first character of the /// stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a structured storage restriction. /// /// Reserved for future use; must be NULL. /// /// Specifies the access mode to be assigned to the open stream. For more information and descriptions of possible values, see /// STGM Constants. Other modes you choose must at least specify STGM_SHARE_EXCLUSIVE when calling this method in the compound /// file implementation. /// /// Reserved for future use; must be zero. /// A IStream interface pointer to the newly opened stream object. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.Interface)] IStream OpenStream([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In, Optional] IntPtr reserved1, [In] STGM grfMode, [In, Optional] uint reserved2); /// /// The CreateStorage method creates and opens a new storage object nested within this storage object with the specified name in /// the specified access mode. /// /// /// A string that contains the name of the newly created storage object. The name can be used later to reopen the storage object. /// The name must not exceed 31 characters in length, not including the string terminator. The 000 through 01f characters, /// serving as the first character of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, /// not a structured storage restriction. /// /// /// A value that specifies the access mode to use when opening the newly created storage object. For more information and a /// description of possible values, see STGM Constants. /// /// Reserved for future use; must be zero. /// Reserved for future use; must be zero. /// On return, the new IStorage interface pointer. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.Interface)] IStorage CreateStorage([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In] STGM grfMode, [In, Optional] uint reserved1, [In, Optional] uint reserved2); /// The OpenStorage method opens an existing storage object with the specified name in the specified access mode. /// /// A string that contains the name of the storage object to open. The 000 through 01f characters, serving as the first character /// of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a structured storage /// restriction. It is ignored if pstgPriority is non-NULL. /// /// Must be NULL. A non-NULL value will return STG_E_INVALIDPARAMETER. /// /// Specifies the access mode to use when opening the storage object. For descriptions of the possible values, see STGM /// Constants. Other modes you choose must at least specify STGM_SHARE_EXCLUSIVE when calling this method. /// /// Must be NULL. A non-NULL value will return STG_E_INVALIDPARAMETER. /// Reserved for future use; must be zero. /// On return, the IStorage interface pointer to the opened storage. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.Interface)] IStorage OpenStorage([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In, MarshalAs(UnmanagedType.Interface)] IStorage pstgPriority, [In] STGM grfMode, [In] SNB snbExclude, [In, Optional] uint reserved); /// The CopyTo method copies the entire contents of an open storage object to another storage object. /// /// The number of elements in the array pointed to by rgiidExclude. If rgiidExclude is NULL, then ciidExclude is ignored. /// /// /// An array of interface identifiers (IIDs) that either the caller knows about and does not want copied or that the storage /// object does not support, but whose state the caller will later explicitly copy. The array can include IStorage, indicating /// that only stream objects are to be copied, and IStream, indicating that only storage objects are to be copied. An array /// length of zero indicates that only the state exposed by the IStorage object is to be copied; all other interfaces on the /// object are to be ignored. Passing NULL indicates that all interfaces on the object are to be copied. /// /// /// A string name block (refer to SNB) that specifies a block of storage or stream objects that are not to be copied to the /// destination. These elements are not created at the destination. If IID_IStorage is in the rgiidExclude array, this parameter /// is ignored. This parameter may be NULL. /// /// /// A pointer to the open storage object into which this storage object is to be copied. The destination storage object can be a /// different implementation of the IStorage interface from the source storage object. Thus, IStorage::CopyTo can use only /// publicly available methods of the destination storage object. If pstgDest is open in transacted mode, it can be reverted by /// calling its IStorage::Revert method. /// [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void CopyTo([In] uint ciidExclude, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] Guid[] rgiidExclude, [In] SNB snbExclude, [In, MarshalAs(UnmanagedType.Interface)] IStorage pstgDest); /// /// The MoveElementTo method copies or moves a substorage or stream from this storage object to another storage object. /// /// A string that contains the name of the element in this storage object to be moved or copied. /// IStorage pointer to the destination storage object. /// A string that contains the new name for the element in its new storage object. /// /// Specifies whether the operation should be a move (STGMOVE_MOVE) or a copy (STGMOVE_COPY). See the STGMOVE enumeration. /// [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void MoveElementTo([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In, MarshalAs(UnmanagedType.Interface)] IStorage pstgDest, [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName, [In] STGMOVE grfFlags); /// /// The Commit method ensures that any changes made to a storage object open in transacted mode are reflected in the parent /// storage. For nonroot storage objects in direct mode, this method has no effect. For a root storage, it reflects the changes /// in the actual device; for example, a file on disk. For a root storage object opened in direct mode, always call the /// IStorage::Commit method prior to Release. IStorage::Commit flushes all memory buffers to the disk for a root storage in /// direct mode and will return an error code upon failure. Although Release also flushes memory buffers to disk, it has no /// capacity to return any error codes upon failure. Therefore, calling Release without first calling Commit causes indeterminate results. /// /// /// Controls how the changes are committed to the storage object. See the STGC enumeration for a definition of these values. /// [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void Commit([In] STGC grfCommitFlags); /// The Revert method discards all changes that have been made to the storage object since the last commit operation. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void Revert(); /// /// The EnumElements method retrieves a pointer to an enumerator object that can be used to enumerate the storage and stream /// objects contained within this storage object. /// /// Reserved for future use; must be zero. /// Reserved for future use; must be NULL. /// Reserved for future use; must be zero. /// The interface pointer to the new enumerator object. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.Interface)] IEnumSTATSTG EnumElements([In] uint reserved1, [In, Optional] IntPtr reserved2, [In, Optional] uint reserved3); /// The DestroyElement method removes the specified storage or stream from this storage object. /// A string that contains the name of the storage or stream to be removed. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void DestroyElement([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName); /// The RenameElement method renames the specified substorage or stream in this storage object. /// A string that contains the name of the substorage or stream to be changed. /// A string that contains the new name for the specified substorage or stream. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void RenameElement([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsOldName, [In, MarshalAs(UnmanagedType.LPWStr)] string pwcsNewName); /// /// The SetElementTimes method sets the modification, access, and creation times of the specified storage element, if the /// underlying file system supports this method. /// /// /// The name of the storage object element whose times are to be modified. If NULL, the time is set on the root storage rather /// than one of its elements. /// /// /// Either the new creation time as the first element of the array for the element or NULL if the creation time is not to be modified. /// /// /// Either the new access time as the first element of the array for the element or NULL if the access time is not to be modified. /// /// /// Either the new modification time as the first element of the array for the element or NULL if the modification time is not to /// be modified. /// [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void SetElementTimes([In, MarshalAs(UnmanagedType.LPWStr)] string pwcsName, [In, MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] FILETIME[] pctime, [In, MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] FILETIME[] patime, [In, MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] FILETIME[] pmtime); /// The SetClass method assigns the specified class identifier (CLSID) to this storage object. /// The CLSID that is to be associated with the storage object. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void SetClass(in Guid clsid); /// /// The SetStateBits method stores up to 32 bits of state information in this storage object. This method is reserved for future use. /// /// /// Specifies the new values of the bits to set. No legal values are defined for these bits; they are all reserved for future use /// and must not be used by applications. /// /// A binary mask indicating which bits in grfStateBits are significant in this call. [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void SetStateBits([In] uint grfStateBits, [In] uint grfMask); /// The Stat method retrieves the STATSTG structure for this open storage object. /// /// On return, pointer to a STATSTG structure where this method places information about the open storage object. This parameter /// is NULL if an error occurs. /// /// /// Specifies that some of the members in the STATSTG structure are not returned, thus saving a memory allocation operation. /// Values are taken from the STATFLAG enumeration. /// [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void Stat(out STATSTG pstatstg, [In] STATFLAG grfStatFlag); } /// /// Identifies an authentication service, authorization service, and the authentication information for the specified authentication service. /// // https://docs.microsoft.com/en-us/windows/desktop/api/objidl/ns-objidl-tagsole_authentication_info typedef struct // tagSOLE_AUTHENTICATION_INFO { DWORD dwAuthnSvc; DWORD dwAuthzSvc; void *pAuthInfo; } SOLE_AUTHENTICATION_INFO, *PSOLE_AUTHENTICATION_INFO; [PInvokeData("objidl.h", MSDNShortId = "23beb1b1-e4b7-4282-9868-5caf40a69a61")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct SOLE_AUTHENTICATION_INFO { /// /// The authentication service. This member can be a single value from the Authentication Service Constants. /// public RPC_C_AUTHN_LEVEL dwAuthnSvc; /// /// The authorization service. This member can be a single value from the Authorization Constants. /// public RPC_C_AUTHZ dwAuthzSvc; /// /// A pointer to the authentication information, whose type is specific to the authentication service identified by dwAuthnSvc. /// /// For Schannel (RPC_C_AUTHN_GSS_SCHANNEL), this member either points to a CERT_CONTEXT structure that contains the client's /// X.509 certificate or is NULL if the client has no certificate or wishes to remain anonymous to the server. /// /// /// For NTLMSSP (RPC_C_AUTHN_WINNT) and Kerberos (RPC_C_AUTHN_GSS_KERBEROS), this member points to a SEC_WINNT_AUTH_IDENTITY or /// SEC_WINNT_AUTH_IDENTITY_EX structure that contains the user name and password. /// /// /// For Snego (RPC_C_AUTHN_GSS_NEGOTIATE), 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. /// /// /// For authentication services not registered with DCOM, pAuthInfo must be set to NULL and DCOM will use the /// process identity to represent the client. For more information, see COM and Security Packages. /// /// public IntPtr pAuthInfo; } /// /// Indicates the default authentication information to use with each authentication service. When DCOM negotiates the default /// authentication service for a proxy, it picks the default authentication information from this list. /// // https://docs.microsoft.com/en-us/windows/desktop/api/objidl/ns-objidl-tagsole_authentication_list typedef struct // tagSOLE_AUTHENTICATION_LIST { DWORD cAuthInfo; SOLE_AUTHENTICATION_INFO *aAuthInfo; } SOLE_AUTHENTICATION_LIST, *PSOLE_AUTHENTICATION_LIST; [PInvokeData("objidl.h", MSDNShortId = "21f7aef3-b6be-41cc-a6ed-16d3778e3cee")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct SOLE_AUTHENTICATION_LIST { /// /// The count of pointers in the array pointed to by aAuthInfo. /// public uint cAuthInfo; /// /// An array of SOLE_AUTHENTICATION_INFO structures. Each of these structures contains an identifier for an authentication /// service, an identifier for the authorization service, and a pointer to authentication information to use with the specified /// authentication service. /// public IntPtr aAuthInfo; } /// /// Identifies an authentication service that a server is willing to use to communicate to a client. /// // https://docs.microsoft.com/en-us/windows/desktop/api/objidl/ns-objidl-tagsole_authentication_service typedef struct // tagSOLE_AUTHENTICATION_SERVICE { DWORD dwAuthnSvc; DWORD dwAuthzSvc; OLECHAR *pPrincipalName; HRESULT hr; } SOLE_AUTHENTICATION_SERVICE; [PInvokeData("objidl.h", MSDNShortId = "77fd15d7-54d4-4812-93d3-13a671e7afff")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct SOLE_AUTHENTICATION_SERVICE { /// /// The authentication service. This member can be a single value from the Authentication Service Constants. /// public RPC_C_AUTHN_LEVEL dwAuthnSvc; /// /// The authorization service. This member can be a single value from the Authorization Constants. /// public RPC_C_AUTHZ dwAuthzSvc; /// /// The principal name to be used with the authentication service. If the principal name is NULL, the current user /// identifier is assumed. A NULL principal name is allowed for NTLMSSP, Kerberos, and Snego authentication services but /// may not work for other authentication services. For Schannel, this member must point to a CERT_CONTEXT structure that /// contains the server's certificate; if it NULL and if a certificate for the current user does not exist, /// RPC_E_NO_GOOD_SECURITY_PACKAGES is returned. /// [MarshalAs(UnmanagedType.LPWStr)] public string pPrincipalName; /// /// When used in CoInitializeSecurity, set on return to indicate the status of the call to register the authentication services. /// public HRESULT hr; } /// /// A string name block (SNB) is a pointer to an array of pointers to strings, that ends in a NULL pointer. String name blocks are /// used by the IStorage interface and by function calls that open storage objects. The strings point to contained storage objects or /// streams that are to be excluded in the open calls. /// /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public class SNB : IDisposable { private SafeCoTaskMemHandle ptr; /// Initializes a new instance of the class. /// The list of names to associate with this instance. public SNB(IEnumerable names) => ptr = names == null ? SafeCoTaskMemHandle.Null : SafeCoTaskMemHandle.CreateFromStringList(names, StringListPackMethod.Packed, CharSet.Unicode); /// Prevents a default instance of the class from being created. private SNB() { } /// Initializes a new instance of the class. /// The native pointer. private SNB(IntPtr p) => ptr = new SafeCoTaskMemHandle(p, 0, true); /// Gets the names. /// The names. public IEnumerable Names => ptr.ToStringEnum(Count, CharSet.Unicode); private int Count => ptr.DangerousGetHandle().GetNulledPtrArrayLength(); /// Performs an implicit conversion from to . /// The native pointer to take ownership of. /// The result of the conversion. public static implicit operator SNB(IntPtr p) => new SNB(p); /// Performs an implicit conversion from to . /// The names. /// The result of the conversion. public static implicit operator SNB(string[] names) => new SNB(names); /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. void IDisposable.Dispose() => ptr?.Dispose(); } } }