using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.Ole32;
namespace Vanara.PInvoke
{
public static partial class OleAut32
{
/// SafeArray advanced features.
[Flags]
[PInvokeData("OAIdl.h", MSDNShortId = "cc237824")]
public enum ADVFEATUREFLAGS : ushort
{
/// An array that is allocated on the stack.
FADF_AUTO = 0x0001,
/// An array that is statically allocated.
FADF_STATIC = 0x0002,
/// An array that is embedded in a structure.
FADF_EMBEDDED = 0x0004,
/// An array that may not be resized or reallocated.
FADF_FIXEDSIZE = 0x0010,
///
/// An array that contains records. When set, there will be a pointer to the IRecordInfo interface at negative offset 4 in the
/// array descriptor.
///
FADF_RECORD = 0x0020,
///
/// An array that has an IID identifying interface. When set, there will be a GUID at negative offset 16 in the safe array
/// descriptor. Flag is set only when FADF_DISPATCH or FADF_UNKNOWN is also set.
///
FADF_HAVEIID = 0x0040,
/// An array that has a variant type. The variant type can be retrieved with SafeArrayGetVartype.
FADF_HAVEVARTYPE = 0x0080,
/// An array of BSTRs.
FADF_BSTR = 0x0100,
/// An array of IUnknown*.
FADF_UNKNOWN = 0x0200,
/// An array of IDispatch*.
FADF_DISPATCH = 0x0400,
/// An array of VARIANTs.
FADF_VARIANT = 0x0800
}
///
/// Increments the lock count of an array, and retrieves a pointer to the array data.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The array data.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is not valid.
///
/// -
/// E_UNEXPECTED
/// The array could not be locked.
///
///
///
///
/// After calling SafeArrayAccessData, you must call the SafeArrayUnaccessData function to unlock the array.
/// Examples
///
/// The following example sorts a safe array of one dimension that contains BSTRs by accessing the array elements directly. This
/// approach is faster than using SafeArrayGetElement and SafeArrayPutElement.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayaccessdata HRESULT SafeArrayAccessData( SAFEARRAY
// *psa, void HUGEP **ppvData );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "ded2112e-f6cd-4982-bacb-b95370e80187")]
public static extern HRESULT SafeArrayAccessData(SafeSAFEARRAY psa, out IntPtr ppvData);
///
///
/// The safe array for which the pinning reference count of the descriptor should increase. While that count remains greater than 0,
/// the memory for the descriptor is prevented from being freed by calls to the SafeArrayDestroy or SafeArrayDestroyDescriptor functions.
///
///
/// Returns the safe array data for which a pinning reference was added, if SafeArrayAddRef also added a pinning reference for
/// the safe array data. This parameter is NULL if SafeArrayAddRef did not add a pinning reference for the safe array data.
/// SafeArrayAddRef does not add a pinning reference for the safe array data if that safe array data was not dynamically allocated.
///
///
///
///
/// The safe array for which the pinning reference count of the descriptor should increase. While that count remains greater than 0,
/// the memory for the descriptor is prevented from being freed by calls to the SafeArrayDestroy or SafeArrayDestroyDescriptor functions.
///
///
///
///
/// Returns the safe array data for which a pinning reference was added, if SafeArrayAddRef also added a pinning reference for
/// the safe array data. This parameter is NULL if SafeArrayAddRef did not add a pinning reference for the safe array data.
/// SafeArrayAddRef does not add a pinning reference for the safe array data if that safe array data was not dynamically allocated.
///
///
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
///
/// Safe arrays have not traditionally had a reference count. All existing usage of safe arrays will continue to work with no
/// changes. The SafeArrayAddRef, SafeArrayReleaseData, SafeArrayReleaseDescriptor functions add the ability to use reference
/// counting to pin the safe array into memory before calling from an untrusted script into an IDispatch method that may not expect
/// the script to free that memory before the method returns, so that the script cannot force the code for that method into accessing
/// memory that has been freed. After such a method safely returns, the pinning references should be released. You can release the
/// pinning references by calling the following functions:
///
///
/// -
/// SafeArrayReleaseData, for the data that the ppDataToRelease parameter points to, if it is not null.
///
/// -
/// SafeArrayReleaseDescriptor, for the descriptor that the psa parameter specifies.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayaddref HRESULT SafeArrayAddRef( SAFEARRAY *psa,
// PVOID *ppDataToRelease );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "0745D2E7-447E-4688-ADCF-1F889BC55BFB")]
public static extern HRESULT SafeArrayAddRef(SafeSAFEARRAY psa, out IntPtr ppDataToRelease);
///
/// Allocates memory for a safe array, based on a descriptor created with SafeArrayAllocDescriptor.
///
///
/// A safe array descriptor created by SafeArrayAllocDescriptor.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is not valid.
///
/// -
/// E_UNEXPECTED
/// The array could not be locked.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayallocdata HRESULT SafeArrayAllocData( SAFEARRAY
// *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "a1f984cd-9638-415d-8582-25b1bdfbd694")]
public static extern HRESULT SafeArrayAllocData(SafeSAFEARRAY psa);
///
/// Allocates memory for a safe array descriptor.
///
///
/// The number of dimensions of the array.
///
///
/// The safe array descriptor.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa was not valid.
///
/// -
/// E_UNEXPECTED
/// The array could not be locked.
///
///
///
///
///
/// This function allows the creation of safe arrays that contain elements with data types other than those provided by
/// SafeArrayCreate. After creating an array descriptor using SafeArrayAllocDescriptor, set the element size in the array
/// descriptor, an call SafeArrayAllocData to allocate memory for the array elements.
///
/// Examples
/// The following example creates a safe array using the SafeArrayAllocDescriptor and SafeArrayAllocData functions.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayallocdescriptor HRESULT SafeArrayAllocDescriptor(
// UINT cDims, SAFEARRAY **ppsaOut );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "8fe5c802-cdc0-4e7a-9410-ba65f9a5140e")]
public static extern HRESULT SafeArrayAllocDescriptor(uint cDims, out SafeDescriptorSAFEARRAY ppsaOut);
///
///
/// Creates a safe array descriptor for an array of any valid variant type, including VT_RECORD, without allocating the array data.
///
///
///
/// The variant type.
///
///
/// The number of dimensions in the array.
///
///
/// The safe array descriptor.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa was not valid.
///
///
///
///
///
/// Because SafeArrayAllocDescriptor does not take a VARTYPE, it is not possible to use it to create the safe array descriptor for an
/// array of records. The SafeArrayAllocDescriptorEx is used to allocate a safe array descriptor for an array of records of
/// the given dimensions.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayallocdescriptorex HRESULT
// SafeArrayAllocDescriptorEx( VARTYPE vt, UINT cDims, SAFEARRAY **ppsaOut );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "c368d278-ef62-4cf3-a7f8-c48549207c09")]
public static extern HRESULT SafeArrayAllocDescriptorEx(VARTYPE vt, uint cDims, out SafeDescriptorSAFEARRAY ppsaOut);
///
/// Creates a copy of an existing safe array.
///
///
/// A safe array descriptor created by SafeArrayCreate.
///
///
/// The safe array descriptor.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa was not valid.
///
/// -
/// E_OUTOFMEMORY
/// Insufficient memory to complete the operation.
///
///
///
///
///
/// SafeArrayCopy calls the string or variant manipulation functions if the array to copy contains either of these data types.
/// If the array being copied contains object references, the reference counts for the objects are incremented.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycopy HRESULT SafeArrayCopy( SAFEARRAY *psa,
// SAFEARRAY **ppsaOut );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "8f84d4f6-1852-4ad8-b174-f3fa37e5bbd6")]
public static extern HRESULT SafeArrayCopy(SafeSAFEARRAY psa, out SafeSAFEARRAY ppsaOut);
///
///
/// Copies the source array to the specified target array after releasing any resources in the target array. This is similar to
/// SafeArrayCopy, except that the target array has to be set up by the caller. The target is not allocated or reallocated.
///
///
///
/// The safe array to copy.
///
///
/// The target safe array.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa was not valid.
///
/// -
/// E_OUTOFMEMORY
/// Insufficient memory to complete the operation.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycopydata HRESULT SafeArrayCopyData( SAFEARRAY
// *psaSource, SAFEARRAY *psaTarget );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "32c1fc4f-3fe0-490f-b5af-640514a8cecc")]
public static extern HRESULT SafeArrayCopyData(SafeSAFEARRAY psaSource, SafeSAFEARRAY psaTarget);
///
///
/// Creates a new array descriptor, allocates and initializes the data for the array, and returns a pointer to the new array descriptor.
///
///
///
///
/// The base type of the array (the VARTYPE of each element of the array). The VARTYPE is restricted to a subset of the variant
/// types. Neither the VT_ARRAY nor the VT_BYREF flag can be set. VT_EMPTY and VT_NULL are not valid base types for the array. All
/// other types are legal.
///
///
///
/// The number of dimensions in the array. The number cannot be changed after the array is created.
///
///
/// A vector of bounds (one for each dimension) to allocate for the array.
///
///
/// A safe array descriptor, or null if the array could not be created.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreate SAFEARRAY * SafeArrayCreate( VARTYPE vt,
// UINT cDims, SAFEARRAYBOUND *rgsabound );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "5b94f1a2-a558-473f-85dd-9545c0464cc7")]
public static extern SafeSAFEARRAY SafeArrayCreate(VARTYPE vt, uint cDims, in SAFEARRAYBOUND rgsabound);
///
/// Creates and returns a safe array descriptor from the specified VARTYPE, number of dimensions and bounds.
///
///
///
/// The base type or the VARTYPE of each element of the array. The FADF_RECORD flag can be set for a variant type VT_RECORD, The
/// FADF_HAVEIID flag can be set for VT_DISPATCH or VT_UNKNOWN, and FADF_HAVEVARTYPE can be set for all other VARTYPEs.
///
///
///
/// The number of dimensions in the array.
///
///
/// A vector of bounds (one for each dimension) to allocate for the array.
///
///
///
/// the type information of the user-defined type, if you are creating a safe array of user-defined types. If the vt parameter is
/// VT_RECORD, then pvExtra will be a pointer to an IRecordInfo describing the record. If the vt parameter is VT_DISPATCH or
/// VT_UNKNOWN, then pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
///
///
///
/// A safe array descriptor, or null if the array could not be created.
///
///
///
/// If the VARTYPE is VT_RECORD then SafeArraySetRecordInfo is called. If the VARTYPE is VT_DISPATCH or VT_UNKNOWN then the elements
/// of the array must contain interfaces of the same type. Part of the process of marshaling this array to other processes does
/// include generating the proxy/stub code of the IID pointed to by the pvExtra parameter. To actually pass heterogeneous interfaces
/// one will need to specify either IID_IUnknown or IID_IDispatch in pvExtra and provide some other means for the caller to identify
/// how to query for the actual interface.
///
/// Examples
/// The following example describes how a safe array of user-defined types is stored into a variant of type VT_RECORD.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreateex SAFEARRAY * SafeArrayCreateEx( VARTYPE
// vt, UINT cDims, SAFEARRAYBOUND *rgsabound, PVOID pvExtra );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "63117428-6676-4fb5-a0ae-7e3b22546d77")]
// public static extern SAFEARRAY * SafeArrayCreateEx(VARTYPE vt, uint cDims, ref SAFEARRAYBOUND rgsabound, IntPtr pvExtra);
public static extern SafeSAFEARRAY SafeArrayCreateEx(VARTYPE vt, uint cDims, in SAFEARRAYBOUND rgsabound, IntPtr pvExtra);
///
/// Creates and returns a safe array descriptor from the specified VARTYPE, number of dimensions and bounds.
///
///
///
/// The base type or the VARTYPE of each element of the array. The FADF_RECORD flag can be set for a variant type VT_RECORD, The
/// FADF_HAVEIID flag can be set for VT_DISPATCH or VT_UNKNOWN, and FADF_HAVEVARTYPE can be set for all other VARTYPEs.
///
///
///
/// The number of dimensions in the array.
///
///
/// A vector of bounds (one for each dimension) to allocate for the array.
///
///
///
/// the type information of the user-defined type, if you are creating a safe array of user-defined types. If the vt parameter is
/// VT_RECORD, then pvExtra will be a pointer to an IRecordInfo describing the record. If the vt parameter is VT_DISPATCH or
/// VT_UNKNOWN, then pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
///
///
///
/// A safe array descriptor, or null if the array could not be created.
///
///
///
/// If the VARTYPE is VT_RECORD then SafeArraySetRecordInfo is called. If the VARTYPE is VT_DISPATCH or VT_UNKNOWN then the elements
/// of the array must contain interfaces of the same type. Part of the process of marshaling this array to other processes does
/// include generating the proxy/stub code of the IID pointed to by the pvExtra parameter. To actually pass heterogeneous interfaces
/// one will need to specify either IID_IUnknown or IID_IDispatch in pvExtra and provide some other means for the caller to identify
/// how to query for the actual interface.
///
/// Examples
/// The following example describes how a safe array of user-defined types is stored into a variant of type VT_RECORD.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreateex SAFEARRAY * SafeArrayCreateEx( VARTYPE
// vt, UINT cDims, SAFEARRAYBOUND *rgsabound, PVOID pvExtra );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "63117428-6676-4fb5-a0ae-7e3b22546d77")]
// public static extern SAFEARRAY * SafeArrayCreateEx(VARTYPE vt, uint cDims, ref SAFEARRAYBOUND rgsabound, IntPtr pvExtra);
public static extern SafeSAFEARRAY SafeArrayCreateEx(VARTYPE vt, uint cDims, in SAFEARRAYBOUND rgsabound, IRecordInfo pvExtra);
///
/// Creates and returns a safe array descriptor from the specified VARTYPE, number of dimensions and bounds.
///
///
///
/// The base type or the VARTYPE of each element of the array. The FADF_RECORD flag can be set for a variant type VT_RECORD, The
/// FADF_HAVEIID flag can be set for VT_DISPATCH or VT_UNKNOWN, and FADF_HAVEVARTYPE can be set for all other VARTYPEs.
///
///
///
/// The number of dimensions in the array.
///
///
/// A vector of bounds (one for each dimension) to allocate for the array.
///
///
///
/// the type information of the user-defined type, if you are creating a safe array of user-defined types. If the vt parameter is
/// VT_RECORD, then pvExtra will be a pointer to an IRecordInfo describing the record. If the vt parameter is VT_DISPATCH or
/// VT_UNKNOWN, then pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
///
///
///
/// A safe array descriptor, or null if the array could not be created.
///
///
///
/// If the VARTYPE is VT_RECORD then SafeArraySetRecordInfo is called. If the VARTYPE is VT_DISPATCH or VT_UNKNOWN then the elements
/// of the array must contain interfaces of the same type. Part of the process of marshaling this array to other processes does
/// include generating the proxy/stub code of the IID pointed to by the pvExtra parameter. To actually pass heterogeneous interfaces
/// one will need to specify either IID_IUnknown or IID_IDispatch in pvExtra and provide some other means for the caller to identify
/// how to query for the actual interface.
///
/// Examples
/// The following example describes how a safe array of user-defined types is stored into a variant of type VT_RECORD.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreateex SAFEARRAY * SafeArrayCreateEx( VARTYPE
// vt, UINT cDims, SAFEARRAYBOUND *rgsabound, PVOID pvExtra );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "63117428-6676-4fb5-a0ae-7e3b22546d77")]
// public static extern SAFEARRAY * SafeArrayCreateEx(VARTYPE vt, uint cDims, ref SAFEARRAYBOUND rgsabound, IntPtr pvExtra);
public static extern SafeSAFEARRAY SafeArrayCreateEx(VARTYPE vt, uint cDims, in SAFEARRAYBOUND rgsabound, in Guid pvExtra);
///
///
/// Creates a one-dimensional array. A safe array created with SafeArrayCreateVector is a fixed size, so the constant
/// FADF_FIXEDSIZE is always set.
///
///
///
///
/// The base type of the array (the VARTYPE of each element of the array). The VARTYPE is restricted to a subset of the variant
/// types. Neither the VT_ARRAY nor the VT_BYREF flag can be set. VT_EMPTY and VT_NULL are not valid base types for the array. All
/// other types are legal.
///
///
///
/// The lower bound for the array. This parameter can be negative.
///
///
/// The number of elements in the array.
///
///
/// A safe array descriptor, or null if the array could not be created.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreatevector SAFEARRAY * SafeArrayCreateVector(
// VARTYPE vt, LONG lLbound, ULONG cElements );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "b794b8c6-a523-4636-8681-a936dff3fc6f")]
public static extern SafeSAFEARRAY SafeArrayCreateVector(VARTYPE vt, int lLbound, uint cElements);
///
/// Creates and returns a one-dimensional safe array of the specified VARTYPE and bounds.
///
///
///
/// The base type of the array (the VARTYPE of each element of the array). The FADF_RECORD flag can be set for VT_RECORD. The
/// FADF_HAVEIID can be set for VT_DISPATCH or VT_UNKNOWN and FADF_HAVEVARTYPE can be set for all other types.
///
///
///
/// The lower bound for the array. This parameter can be negative.
///
///
/// The number of elements in the array.
///
///
///
/// The type information of the user-defined type, if you are creating a safe array of user-defined types. If the vt parameter is
/// VT_RECORD, then pvExtra will be a pointer to an IRecordInfo describing the record. If the vt parameter is VT_DISPATCH or
/// VT_UNKNOWN, then pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
///
///
///
/// A safe array descriptor, or null if the array could not be created.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreatevectorex SAFEARRAY *
// SafeArrayCreateVectorEx( VARTYPE vt, LONG lLbound, ULONG cElements, PVOID pvExtra );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "45f2ba42-4189-42eb-9f6c-772198296906")]
public static extern SafeSAFEARRAY SafeArrayCreateVectorEx(VARTYPE vt, int lLbound, uint cElements, IntPtr pvExtra);
///
/// Creates and returns a one-dimensional safe array of the specified VARTYPE and bounds.
///
///
///
/// The base type of the array (the VARTYPE of each element of the array). The FADF_RECORD flag can be set for VT_RECORD. The
/// FADF_HAVEIID can be set for VT_DISPATCH or VT_UNKNOWN and FADF_HAVEVARTYPE can be set for all other types.
///
///
///
/// The lower bound for the array. This parameter can be negative.
///
///
/// The number of elements in the array.
///
///
///
/// The type information of the user-defined type, if you are creating a safe array of user-defined types. If the vt parameter is
/// VT_RECORD, then pvExtra will be a pointer to an IRecordInfo describing the record. If the vt parameter is VT_DISPATCH or
/// VT_UNKNOWN, then pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
///
///
///
/// A safe array descriptor, or null if the array could not be created.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreatevectorex SAFEARRAY *
// SafeArrayCreateVectorEx( VARTYPE vt, LONG lLbound, ULONG cElements, PVOID pvExtra );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "45f2ba42-4189-42eb-9f6c-772198296906")]
public static extern SafeSAFEARRAY SafeArrayCreateVectorEx(VARTYPE vt, int lLbound, uint cElements, IRecordInfo pvExtra);
///
/// Creates and returns a one-dimensional safe array of the specified VARTYPE and bounds.
///
///
///
/// The base type of the array (the VARTYPE of each element of the array). The FADF_RECORD flag can be set for VT_RECORD. The
/// FADF_HAVEIID can be set for VT_DISPATCH or VT_UNKNOWN and FADF_HAVEVARTYPE can be set for all other types.
///
///
///
/// The lower bound for the array. This parameter can be negative.
///
///
/// The number of elements in the array.
///
///
///
/// The type information of the user-defined type, if you are creating a safe array of user-defined types. If the vt parameter is
/// VT_RECORD, then pvExtra will be a pointer to an IRecordInfo describing the record. If the vt parameter is VT_DISPATCH or
/// VT_UNKNOWN, then pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
///
///
///
/// A safe array descriptor, or null if the array could not be created.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraycreatevectorex SAFEARRAY *
// SafeArrayCreateVectorEx( VARTYPE vt, LONG lLbound, ULONG cElements, PVOID pvExtra );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "45f2ba42-4189-42eb-9f6c-772198296906")]
public static extern SafeSAFEARRAY SafeArrayCreateVectorEx(VARTYPE vt, int lLbound, uint cElements, in Guid pvExtra);
///
///
/// Destroys an existing array descriptor and all of the data in the array. If objects are stored in the array, Release is
/// called on each object in the array.
///
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is not valid.
///
/// -
/// DISP_E_ARRAYISLOCKED
/// The array is locked.
///
///
///
///
///
/// Safe arrays of variant will have the VariantClear function called on each member and safe arrays of BSTR will have the
/// SysFreeString function called on each element. IRecordInfo::RecordClear will be called to release object references and other
/// values of a record without deallocating the record.
///
/// Examples
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraydestroy HRESULT SafeArrayDestroy( SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "fc94f7e7-b903-4c78-905c-54df1f8d13fa")]
public static extern HRESULT SafeArrayDestroy(IntPtr psa);
///
/// Destroys all the data in the specified safe array.
///
///
/// A safe array descriptor.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa was not valid.
///
/// -
/// DISP_E_ARRAYISLOCKED
/// The array is locked.
///
///
///
///
///
/// This function is typically used when freeing safe arrays that contain elements with data types other than variants. If objects
/// are stored in the array, Release is called on each object in the array. Safe arrays of variant will have the VariantClear
/// function called on each member and safe arrays of BSTR will have the SysFreeString function called on each element.
/// IRecordInfo::RecordClear will be called to release object references and other values of a record without deallocating the record.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraydestroydata HRESULT SafeArrayDestroyData(
// SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "aa9c62ba-79b5-4fcf-b3ed-664016486dfc")]
public static extern HRESULT SafeArrayDestroyData(SafeSAFEARRAY psa);
///
/// Destroys the descriptor of the specified safe array.
///
///
/// A safe array descriptor.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa was not valid.
///
/// -
/// DISP_E_ARRAYISLOCKED
/// The array is locked.
///
///
///
///
///
/// This function is typically used to destroy the descriptor of a safe array that contains elements with data types other than
/// variants. Destroying the array descriptor does not destroy the elements in the array. Before destroying the array descriptor,
/// call SafeArrayDestroyData to free the elements.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraydestroydescriptor HRESULT
// SafeArrayDestroyDescriptor( SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "f1e8de45-673b-4f20-a639-18c724c82df1")]
public static extern HRESULT SafeArrayDestroyDescriptor(IntPtr psa);
///
/// Gets the number of dimensions in the array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The number of dimensions in the array.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetdim UINT SafeArrayGetDim( SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "bc52b23b-d323-478c-881f-d2a31a3289c5")]
public static extern uint SafeArrayGetDim(SafeSAFEARRAY psa);
///
/// Retrieves a single element of the array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
///
/// A vector of indexes for each dimension of the array. The right-most (least significant) dimension is rgIndices[0]. The left-most
/// dimension is stored at .
///
///
///
/// The element of the array.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// DISP_E_BADINDEX
/// The specified index is not valid.
///
/// -
/// E_INVALIDARG
/// One of the arguments is not valid.
///
/// -
/// E_OUTOFMEMORY
/// Memory could not be allocated for the element.
///
///
///
///
///
/// This function calls SafeArrayLock and SafeArrayUnlock automatically, before and after retrieving the element. The caller must
/// provide a storage area of the correct size to receive the data. If the data element is a string, object, or variant, the function
/// copies the element in the correct way.
///
/// Examples
/// The following example is taken from the COM Fundamentals SPoly sample (Cenumpt.cpp).
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetelement HRESULT SafeArrayGetElement( SAFEARRAY
// *psa, LONG *rgIndices, void *pv );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "47e9ee31-1e3b-4193-8467-6ef0db05966e")]
public static extern HRESULT SafeArrayGetElement(SafeSAFEARRAY psa, [MarshalAs(UnmanagedType.LPArray)] int[] rgIndices, [Out] IntPtr pv);
///
/// Gets the size of an element.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The size of an element in a safe array, in bytes.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetelemsize UINT SafeArrayGetElemsize( SAFEARRAY
// *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "27bd4a3f-0e9d-45f7-ad7c-0c0b59579dd0")]
public static extern int SafeArrayGetElemsize(SafeSAFEARRAY psa);
///
/// Gets the GUID of the interface contained within the specified safe array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The GUID of the interface.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is null or the array descriptor does not have the FADF_HAVEIID flag set.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetiid HRESULT SafeArrayGetIID( SAFEARRAY *psa,
// GUID *pguid );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "9416f7f8-aee0-4e6a-be4f-ca6061adb244")]
public static extern HRESULT SafeArrayGetIID(SafeSAFEARRAY psa, out Guid pguid);
///
/// Gets the lower bound for any dimension of the specified safe array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The array dimension for which to get the lower bound.
///
///
/// The lower bound.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// One of the arguments is not valid.
///
/// -
/// DISP_E_BADINDEX
/// The specified index is out of bounds.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetlbound HRESULT SafeArrayGetLBound( SAFEARRAY
// *psa, UINT nDim, LONG *plLbound );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "f3134cc9-759b-4908-ada0-d025a525e795")]
public static extern HRESULT SafeArrayGetLBound(SafeSAFEARRAY psa, uint nDim, out int plLbound);
///
/// Retrieves the IRecordInfo interface of the UDT contained in the specified safe array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The IRecordInfo interface.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is null or the array descriptor does not have the FADF_RECORD flag set.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetrecordinfo HRESULT SafeArrayGetRecordInfo(
// SAFEARRAY *psa, IRecordInfo **prinfo );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "1584c00e-06a5-44f4-8c4b-a2b23737a652")]
public static extern HRESULT SafeArrayGetRecordInfo(SafeSAFEARRAY psa, out IRecordInfo prinfo);
///
/// Gets the upper bound for any dimension of the specified safe array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The array dimension for which to get the upper bound.
///
///
/// The upper bound.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// DISP_E_BADINDEX
/// The specified index is out of bounds.
///
/// -
/// DISP_E_OVERFLOW
/// Overflow occurred while computing the upper bound.
///
/// -
/// E_INVALIDARG
/// One of the arguments is not valid.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetubound HRESULT SafeArrayGetUBound( SAFEARRAY
// *psa, UINT nDim, LONG *plUbound );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "aed339d5-d962-4adc-ac01-6c15a54c51ca")]
public static extern HRESULT SafeArrayGetUBound(SafeSAFEARRAY psa, uint nDim, out int plUbound);
///
/// Gets the VARTYPE stored in the specified safe array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// The VARTYPE.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// One of the arguments is not valid.
///
///
///
///
///
/// If FADF_HAVEVARTYPE is set, SafeArrayGetVartype returns the VARTYPE stored in the array descriptor. If FADF_RECORD is set,
/// it returns VT_RECORD; if FADF_DISPATCH is set, it returns VT_DISPATCH; and if FADF_UNKNOWN is set, it returns VT_UNKNOWN.
///
///
/// SafeArrayGetVartype can fail to return VT_UNKNOWN for SAFEARRAY types that are based on IUnknown. Callers should
/// additionally check whether the SAFEARRAY type's fFeatures field has the FADF_UNKNOWN flag set.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraygetvartype HRESULT SafeArrayGetVartype( SAFEARRAY
// *psa, VARTYPE *pvt );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "8ec0e736-bac8-4df4-ba32-433cd8478c55")]
public static extern HRESULT SafeArrayGetVartype(SafeSAFEARRAY psa, out VARTYPE pvt);
///
/// Increments the lock count of an array, and places a pointer to the array data in pvData of the array descriptor.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is not valid.
///
/// -
/// E_UNEXPECTED
/// The array could not be locked.
///
///
///
///
///
/// The pointer in the array descriptor is valid until the SafeArrayUnlock function is called. Calls to SafeArrayLock can be
/// nested, in which case an equal number of calls to SafeArrayUnlock are required.
///
/// An array cannot be deleted while it is locked.
/// Thread Safety
///
/// All public static (Shared in Visual Basic) members of the SAFEARRAY data type are thread safe. Instance members are not
/// guaranteed to be thread safe.
///
///
/// For example, consider an application that uses the SafeArrayLock and SafeArrayUnlock functions. If these functions are called
/// concurrently from different threads on the same SAFEARRAY data type instance, an inconsistent lock count may be created. This
/// will eventually cause the SafeArrayUnlock function to return E_UNEXPECTED. You can prevent this by providing your own
/// synchronization code.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraylock HRESULT SafeArrayLock( SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "cb29d862-c7c5-4852-b017-c29e88d5f1c4")]
public static extern HRESULT SafeArrayLock(SafeSAFEARRAY psa);
/// Gets a pointer to an array element.
/// An array descriptor created by SafeArrayCreate.
///
/// An array of index values that identify an element of the array. All indexes for the element must be specified.
///
/// The array element.
///
/// This function can return one of these values.
///
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// DISP_E_BADINDEX
/// The specified index is not valid.
///
/// -
/// E_INVALIDARG
/// One of the arguments is not valid.
///
///
///
///
// HRESULT SafeArrayPtrOfIndex( _In_ SAFEARRAY *psa, _In_ LONG *rgIndices, _Out_ void **ppvData); https://msdn.microsoft.com/en-us/library/windows/desktop/ms221452(v=vs.85).aspx
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("OleAuto.h", MSDNShortId = "ms221452")]
public static extern HRESULT SafeArrayPtrOfIndex(SafeSAFEARRAY psa, [In] int[] rgIndices, out IntPtr ppvData);
///
/// Stores the data element at the specified location in the array.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
///
/// A vector of indexes for each dimension of the array. The right-most (least significant) dimension is rgIndices[0]. The left-most
/// dimension is stored at .
///
///
///
///
/// The data to assign to the array. The variant types VT_DISPATCH, VT_UNKNOWN, and VT_BSTR are pointers, and do not require another
/// level of indirection.
///
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// DISP_E_BADINDEX
/// The specified index is not valid.
///
/// -
/// E_INVALIDARG
/// One of the arguments is not valid.
///
/// -
/// E_OUTOFMEMORY
/// Memory could not be allocated for the element.
///
///
///
///
///
/// This function automatically calls SafeArrayLock and SafeArrayUnlock before and after assigning the element. If the data element
/// is a string, object, or variant, the function copies it correctly when the safe array is destroyed. If the existing element is a
/// string, object, or variant, it is cleared correctly. If the data element is a VT_DISPATCH or VT_UNKNOWN, AddRef is called
/// to increment the object's reference count.
///
/// Note Multiple locks can be on an array. Elements can be put into an array while the array is locked by other operations.
///
/// For an example that demonstrates calling SafeArrayPutElement, see the COM Fundamentals Lines sample (CLines::Add in Lines.cpp).
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayputelement HRESULT SafeArrayPutElement( SAFEARRAY
// *psa, LONG *rgIndices, void *pv );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "7c837b4f-d319-4d98-934a-b585fe521bf8")]
public static extern HRESULT SafeArrayPutElement(SafeSAFEARRAY psa, [MarshalAs(UnmanagedType.LPArray)] int[] rgIndicies, [In] IntPtr pv);
///
/// Changes the right-most (least significant) bound of the specified safe array.
///
///
/// A safe array descriptor.
///
///
///
/// A new safe array bound structure that contains the new array boundary. You can change only the least significant dimension of an array.
///
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is not valid.
///
/// -
/// DISP_E_ARRAYISLOCKED
/// The array is locked.
///
///
///
///
///
/// If you reduce the bound of an array, SafeArrayRedim deallocates the array elements outside the new array boundary. If the
/// bound of an array is increased, SafeArrayRedim allocates and initializes the new array elements. The data is preserved for
/// elements that exist in both the old and new array.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayredim HRESULT SafeArrayRedim( SAFEARRAY *psa,
// SAFEARRAYBOUND *psaboundNew );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "1c7fa627-e5e4-4bb9-8237-2f7358ebc4b8")]
public static extern HRESULT SafeArrayRedim(SafeSAFEARRAY psa, in SAFEARRAYBOUND psaboundNew);
///
/// The safe array data for which the pinning reference count should decrease.
///
///
/// The safe array data for which the pinning reference count should decrease.
///
///
/// This function does not return a value.
///
///
///
/// A call to the SafeArrayReleaseData function should match every previous call to the SafeArrayAddRef function that returned
/// a non-null value in the ppDataToRelease parameter.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayreleasedata void SafeArrayReleaseData( PVOID
// pData );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "AF3C36A3-2B3A-4159-8183-DB082FBFD215")]
public static extern void SafeArrayReleaseData(IntPtr pData);
///
/// The safe array for which the pinning reference count of the descriptor should decrease.
///
///
/// The safe array for which the pinning reference count of the descriptor should decrease.
///
///
/// This function does not return a value.
///
///
/// A call to the SafeArrayReleaseDescriptor function should match every previous call to the SafeArrayAddRef function.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayreleasedescriptor void
// SafeArrayReleaseDescriptor( SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "D6678B17-B537-46CF-AC64-4D0C0DC4CDF3")]
public static extern void SafeArrayReleaseDescriptor(SafeSAFEARRAY psa);
///
/// Sets the GUID of the interface for the specified safe array.
///
///
/// The safe array descriptor.
///
///
/// The IID.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is null or the array descriptor does not have the FADF_HAVEIID flag set.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraysetiid HRESULT SafeArraySetIID( SAFEARRAY *psa,
// REFGUID guid );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "851b8a44-9da4-418c-88bc-80c9fc55d25c")]
public static extern HRESULT SafeArraySetIID(SafeSAFEARRAY psa, in Guid guid);
///
/// Sets the record info in the specified safe array.
///
///
/// The array descriptor.
///
///
/// The record info.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is null or the array descriptor does not have the FADF_RECORD flag set.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearraysetrecordinfo HRESULT SafeArraySetRecordInfo(
// SAFEARRAY *psa, IRecordInfo *prinfo );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "85317e8e-7625-4799-9c34-73245f164f85")]
public static extern HRESULT SafeArraySetRecordInfo(SafeSAFEARRAY psa, IRecordInfo prinfo);
///
/// Decrements the lock count of an array, and invalidates the pointer retrieved by SafeArrayAccessData.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is not valid.
///
/// -
/// E_UNEXPECTED
/// The array could not be unlocked.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayunaccessdata HRESULT SafeArrayUnaccessData(
// SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "61b482cb-f0a3-4efb-9a68-f373f241e89a")]
public static extern HRESULT SafeArrayUnaccessData(SafeSAFEARRAY psa);
///
/// Decrements the lock count of an array so it can be freed or resized.
///
///
/// An array descriptor created by SafeArrayCreate.
///
///
/// This function can return one of these values.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// Success.
///
/// -
/// E_INVALIDARG
/// The argument psa is not valid.
///
/// -
/// E_UNEXPECTED
/// The array could not be unlocked.
///
///
///
///
/// This function is called after access to the data in an array is finished.
/// Thread Safety
///
/// All public static members of the SAFEARRAY data type are thread safe. Instance members are not guaranteed to be thread safe.
///
///
/// For example, consider an application that uses the SafeArrayLock and SafeArrayUnlock functions. If these functions are called
/// concurrently from different threads on the same SAFEARRAY data type instance, an inconsistent lock count may be created. This
/// will eventually cause the SafeArrayUnlock function to return E_UNEXPECTED. You can prevent this by providing your own
/// synchronization code.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-safearrayunlock HRESULT SafeArrayUnlock( SAFEARRAY *psa );
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("oleauto.h", MSDNShortId = "654995ab-1959-44dc-9e26-11c34e489c14")]
public static extern HRESULT SafeArrayUnlock(SafeSAFEARRAY psa);
/// Represents a safe array.
///
[StructLayout(LayoutKind.Sequential, Pack = 4)]
[PInvokeData("OaIdl.h", MSDNShortId = "ms221482")]
public struct SAFEARRAY
{
/// The number of dimensions.
public ushort cDims;
/// Flags.
public ADVFEATUREFLAGS fFeatures;
/// The size of an array element.
public uint cbElements;
/// The number of times the array has been locked without a corresponding unlock.
public uint cLocks;
/// The data.
public IntPtr pvData;
/// One bound for each dimension.
public IntPtr rgsabound;
/// Gets the bounds pointed to by .
public SAFEARRAYBOUND[] Bounds => rgsabound.ToArray(cDims);
}
/// Represents the bounds of one dimension of the array.
[StructLayout(LayoutKind.Sequential, Pack = 4)]
[PInvokeData("OaIdl.h", MSDNShortId = "ms221167")]
public struct SAFEARRAYBOUND
{
/// The number of elements in the dimension.
public uint cElements;
/// The lower bound of the dimension.
public int lLbound;
/// Initializes a new instance of the struct.
/// The number of elements in the dimension.
/// The lower bound of the dimension.
public SAFEARRAYBOUND(uint upperBound, int lowerBound = 0)
{
cElements = upperBound;
lLbound = lowerBound;
}
}
/// Provides a to a safe array that releases a created SAFEARRAY instance at disposal using SafeArrayDestroy.
public class SafeSAFEARRAY : HANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
public SafeSAFEARRAY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
protected SafeSAFEARRAY() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator SAFEARRAY(SafeSAFEARRAY h) => h.IsInvalid ? new SAFEARRAY() : (SAFEARRAY)Marshal.PtrToStructure(h.handle, typeof(SAFEARRAY));
///
protected override bool InternalReleaseHandle() => SafeArrayDestroy(handle).Succeeded;
}
public class SafeDescriptorSAFEARRAY : SafeSAFEARRAY
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
public SafeDescriptorSAFEARRAY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeDescriptorSAFEARRAY() : base() { }
///
protected override bool InternalReleaseHandle() => SafeArrayDestroyDescriptor(handle).Succeeded;
}
/// Construct for handling the paired calling of and .
///
///
/// using (var data = new SafeArrayScopedAccessData(safeArray))
/// {
/// // The Data property provides access to the array's data while in scope.
/// FILETIME ft = (FILETIME)Marshal.PtrToStructure(data.Data, typeof(FILETIME));
/// }
///
///
///
[PInvokeData("OleAuto.h")]
public class SafeArrayScopedAccessData : IDisposable
{
private readonly SafeSAFEARRAY psa;
private IntPtr ppvData;
///
/// Initializes a new instance of the class using the array descriptor that holds the data.
///
/// An array descriptor created by SafeArrayCreate.
public SafeArrayScopedAccessData(SafeSAFEARRAY psa)
{
var hr = SafeArrayAccessData(psa, out ppvData);
hr.ThrowIfFailed();
this.psa = psa;
}
/// Gets the pointer exposed by the call to .
/// A pointer to the raw data within the array descriptor.
public IntPtr Data => ppvData;
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
{
SafeArrayUnaccessData(psa);
ppvData = IntPtr.Zero;
}
}
}
}