Completed all interfaces for OleDb

nullableenabled
David Hall 2024-05-07 12:18:21 -06:00
parent 01114f73b0
commit ffd6799910
10 changed files with 23696 additions and 3342 deletions

View File

@ -706,29 +706,60 @@ public static partial class OleDb
DBCOLUMNFLAGS_ROWSPECIFICCOLUMN = 0x400000
}
/// <summary>Options for persisting command definition.</summary>
[Flags]
public enum DBCOMMANDPERSISTFLAG
{
/// <summary>The behavior of DBCOMMANDPERSISTFLAGS_DEFAULT is provider specific.</summary>
DBCOMMANDPERSISTFLAG_DEFAULT = 0,
/// <summary>You can use DBCOMMANDPERSISTFLAG_NOSAVE to associate or obtain a new DBID for the command without actually persisting the definition.</summary>
DBCOMMANDPERSISTFLAG_NOSAVE = 0x1,
/// <summary>The command is to be persisted as a view. Views are row-returning objects that do not contain parameters or return values and can generally be used anywhere a base table is used. Views can be enumerated through the DBSCHEMA_VIEWS schema rowset.</summary>
DBCOMMANDPERSISTFLAG_PERSISTVIEW = 0x2,
/// <summary>The command is to be persisted as a procedure. Procedures may or may not return rows and may or may not contain parameters or return values. Procedures can be enumerated through the DBSCHEMA_PROCEDURES schema rowset.</summary>
DBCOMMANDPERSISTFLAG_PERSISTPROCEDURE = 0x4
}
/// <summary>
/// Operation to use in comparing the row values.
/// </summary>
[PInvokeData("oledb.h")]
public enum DBCOMPAREOPS
{
/// <summary>Match the first value that is less than the search value.</summary>
DBCOMPAREOPS_LT,
/// <summary>Match the first value that is less than or equal to the search value.</summary>
DBCOMPAREOPS_LE = 1,
/// <summary>Match the first value that is equal to the search value.</summary>
DBCOMPAREOPS_EQ = 2,
/// <summary>Match the first value that is greater than or equal to the search value.</summary>
DBCOMPAREOPS_GE = 3,
/// <summary>Match the first value that is greater than the search value.</summary>
DBCOMPAREOPS_GT = 4,
/// <summary>Match the first value that has the search value as its first characters. This is valid only for values bound as string data types.</summary>
DBCOMPAREOPS_BEGINSWITH = 5,
/// <summary>Match the first value that contains the search value. This is valid only for values bound as string data types.</summary>
DBCOMPAREOPS_CONTAINS = 6,
/// <summary>Match the first value that is not equal to the search value. If the search value is NULL, this matches the first non-NULL value. If the search value is non-NULL, this matches the first non-NULL value that is not equal to the search value.</summary>
DBCOMPAREOPS_NE = 7,
/// <summary>
/// <para>Ignore the corresponding value.</para>
/// <para>The provider ignores <em>pFindValue</em> and returns the next <em>cRows</em> rows starting from the row indicated by <em>pBookmark</em>, skipping the number of rows indicated by <em>lRowsOffset</em>.</para>
/// </summary>
DBCOMPAREOPS_IGNORE = 8,
/// <summary>
/// <para>Specify whether the search is case-sensitive or case-insensitive.</para>
/// <para>You can join DBCOMPAREOPS_CASESENSITIVE or DBCOMPAREOPS_CASEINSENSITIVE with any of the other DBCOMPAREOPS values in a bitwise OR operation. If neither is used, the search is handled according to the provider's implementation. Both DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE are ignored when searching for nonstring values.</para>
/// </summary>
DBCOMPAREOPS_CASESENSITIVE = 0x1000,
/// <summary>
/// <para>Specify whether the search is case-sensitive or case-insensitive.</para>
/// <para>You can join DBCOMPAREOPS_CASESENSITIVE or DBCOMPAREOPS_CASEINSENSITIVE with any of the other DBCOMPAREOPS values in a bitwise OR operation. If neither is used, the search is handled according to the provider's implementation. Both DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE are ignored when searching for nonstring values.</para>
/// </summary>
DBCOMPAREOPS_CASEINSENSITIVE = 0x2000,
/// <summary>Match the first value that does not have the search value as its first characters. This is valid only for values bound as string data types.</summary>
DBCOMPAREOPS_NOTBEGINSWITH = 9,
/// <summary>Match the first value that does not contain the search value. This is valid only for values bound as string data types.</summary>
DBCOMPAREOPS_NOTCONTAINS = 10
}
@ -4201,17 +4232,35 @@ public static partial class OleDb
public byte bScale;
}
/// <summary>Gets or sets the value of the specified column in the rowset.</summary>
[PInvokeData("oledb.h")]
[StructLayout(LayoutKind.Sequential)]
public struct DBCOLUMNACCESS
{
/// <summary>
/// <para>Pointer of type wType to caller-allocated storage. On return, the area of storage contains the value stored in the column specified by columnid. The provider should attempt to coerce the column value to type wType. If wType is DBTYPE_VARIANT, the provider is responsible for allocating any variable-length storage pointed to by the VARIANT. If the caller passes a null pointer, the provider returns only the untruncated length (cbDataLen) and status (dwStatus) and does not return a data value.</para>
/// <para>If the row is in immediate mode and a row-specific columns has been deleted, the provider returns DBSTATUS_E_DOESNOTEXIST. If the row is in deferred mode and a row-specific column has been deleted, the provider returns a null value and DBSTATUS_S_ISNULL.</para>
/// <para>For more information, see Getting and Setting Data.</para>
/// </summary>
public IntPtr pData;
/// <summary>columnid is a DBID that identifies the column to be accessed. columnid values must be unique within a row.</summary>
public DBID columnid;
/// <summary>The returned length of the value contained in *pData. If the length of the column value is greater than cbMaxLen, the provider truncates the data to fit the buffer, returns the full data size in cbDataLen, and sets dwStatus to DBSTATUS_S_TRUNCATED.</summary>
public DBLENGTH cbDataLen;
/// <summary>A DBSTATUS status field set by the provider on return, indicating whether pData or some other value should be used. On return, dwStatus indicates whether the field was successfully retrieved and provides other information about this column. For more information about status values, see Status in Getting and Setting Data.</summary>
public DBSTATUS dwStatus;
/// <summary>The maximum length of the caller-initialized memory pointed to by pData. For more information on cbMaxLen in the binding structure, see DBBINDING Structures in Getting and Setting Data.</summary>
public DBLENGTH cbMaxLen;
/// <summary>Reserved. Consumers should set this parameter to zero.</summary>
public DB_DWRESERVE dwReserved;
/// <summary>
/// <para>On input, wType identifies the data type requested by the consumer. The provider attempts to convert the value from the type of the column to this type.</para>
/// <para>wType should not change on return; if the provider could not convert, a status of DBSTATUS_E_CANTCONVERTVALUE would be returned.</para>
/// </summary>
public DBTYPE wType;
/// <summary>The maximum precision to use when getting data and wType is DBTYPE_NUMERIC. bPrecision is ignored when setting data or if wType is not DBTYPE_NUMERIC. For more information, see Conversions Involving DBTYPE_NUMERIC or DBTYPE_DECIMAL in Appendix A: Data Types.</summary>
public byte bPrecision;
/// <summary>The scale to use when getting data and wType is DBTYPE_NUMERIC or DBTYPE_DECIMAL. This is ignored when setting data. It is also ignored if wType is not DBTYPE_NUMERIC or DBTYPE_DECIMAL. For more information, see Conversions Involving DBTYPE_NUMERIC or DBTYPE_DECIMAL in Appendix A: Data Types.</summary>
public byte bScale;
}
@ -4230,17 +4279,34 @@ public static partial class OleDb
public byte bScale;
}
[StructLayout(LayoutKind.Sequential)]
/// <summary>
/// Defines the columns of a row object.
/// </summary>
[PInvokeData("oledb.h")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DBCOLUMNINFO
{
public StrPtrUni pwszName;
/// <summary>
/// <para>Pointer to the name of the column; this might not be unique. If this cannot be determined, a null pointer is returned.</para>
/// <para>The name can be different from the string part of the column ID if the column has been renamed by the command text. This name always reflects the most recent renaming of the column in the current view or command text.</para>
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string? pwszName;
/// <summary>Reserved for future use. Providers should return a null pointer in pTypeInfo.</summary>
public IntPtr pTypeInfo;
/// <summary>The ordinal of the column. This is zero for the bookmark column of the row, if any. Other columns are numbered starting from one.</summary>
public DBORDINAL iOrdinal;
/// <summary>A bitmask that describes consumer-specified row column characteristics. The DBCOLUMNFLAGS enumerated type specifies the bits in the bitmask, which are described in the reference entry for IColumnsInfo::GetColumnInfo.</summary>
public DBCOLUMNFLAGS dwFlags;
/// <summary>Minimum size required to store the consumer's largest data for this column. For fixed-length data types, this is the size of the data type in bytes. For variable-length data types, this is the maximum number of bytes (for DBTYPE_BYTES) or characters (for DBTYPE_STR or DBTYPE_WSTR). For more information, see the description of DBCOLUMNINFO in the reference entry for IColumnsInfo::GetColumnInfo.</summary>
public DBLENGTH ulColumnSize;
/// <summary>Requested DBTYPE data type for this column.</summary>
public DBTYPE wType;
/// <summary>Maximum precision of the column.</summary>
public byte bPrecision;
/// <summary>Number of digits to the right of the decimal point.</summary>
public byte bScale;
/// <summary>Unique DBID used to name this row column. For example, if columns are named (eKind is DBKIND_NAME), uName.pwszName points to the column name.</summary>
public DBID columnid;
}
@ -4314,11 +4380,25 @@ public static partial class OleDb
public IntPtr pSession;
}
/// <summary>Describes how to construct the index.</summary>
[PInvokeData("dbs.h")]
[StructLayout(LayoutKind.Sequential)]
public struct DBINDEXCOLUMNDESC
{
/// <summary>A pointer to the ID of the base table column.</summary>
public IntPtr pColumnID;
/// <summary>
/// <para>Whether the index is ascending or descending in this column.</para>
/// <list type="bullet">
/// <item>DBINDEX_COL_ORDER_ASC ? Ascending</item>
/// <item>DBINDEX_COL_ORDER_DESC ? Descending</item>
/// </list>
/// </summary>
public DBINDEX_COL_ORDER eIndexColOrder;
/// <summary>The ID of the base table column.</summary>
public readonly DBID? ColumnId => pColumnID.ToNullableStructure<DBID>();
}
[StructLayout(LayoutKind.Sequential)]
@ -4331,13 +4411,66 @@ public static partial class OleDb
[StructLayout(LayoutKind.Sequential)]
public struct DBPARAMINFO
{
/// <summary>
/// <para>A bitmask describing parameter characteristics; these values have the following meaning:</para>
/// <list type="bullet">
/// <item>DBPARAMFLAGS_ISINPUT ? Whether a parameter accepts values on input. Not set if this is unknown.</item>
/// <item>
/// DBPARAMFLAGS_ISOUTPUT ? Whether a parameter returns values on output. Not set if this is unknown. Providers support only those
/// parameter types that make sense for their data store.
/// </item>
/// <item>
/// DBPARAMFLAGS_ISSIGNED ? Whether a parameter is signed. This is ignored if the type is inherently signed, such as DBTYPE_I2 or if
/// the sign does not apply to the type, such as DBTYPE_BSTR. It is generally used in ICommandWithParameters::SetParameterInfo so
/// that the consumer can tell the provider if a provider-specific type name refers to a signed or unsigned type.
/// </item>
/// <item>DBPARAMFLAGS_ISNULLABLE ? Whether a parameter accepts NULLs. If nullability is unknown, this flag is set.</item>
/// <item>
/// <para>
/// DBPARAMFLAGS_ISLONG ? Whether a parameter contains a BLOB that contains very long data. The definition of very long data is
/// provider specific. The flag setting corresponds to the value of the IS_LONG column in the PROVIDER_TYPES schema rowset for the
/// data type.
/// </para>
/// <para>
/// When this flag is set, the BLOB is best manipulated through one of the storage interfaces. Although such BLOBs can be sent in a
/// single piece with ICommand::Execute, there can be provider-specific problems in doing so. For example, the BLOB might be
/// truncated due to machine limits on memory. Furthermore, when this flag is set, the provider might not be able to accurately
/// return the maximum length of the BLOB data in ulParamSize in ICommandWithParameters::GetParameterInfo.
/// </para>
/// <para>When this flag is not set, the BLOB can be accessed either through ICommand::Execute or through a storage interface.</para>
/// <para>For more information, see Accessing BLOB Data.</para>
/// </item>
/// <item>
/// DBPARAMFLAGS_SCALEISNEGATIVE ? Set if the parameter type is DBTYPE_VARNUMERIC and bScale represents the absolute value of the
/// negative scale of the parameter. This flag is used when setting data in a DBTYPE_VARNUMERIC parameter. For more information,
/// refer to Conversions Involving DBTYPE_NUMERIC or DBTYPE_DECIMAL in Appendix A.
/// </item>
/// </list>
/// </summary>
public DBPARAMFLAGS dwFlags;
/// <summary>The ordinal of the parameter. Parameters are numbered from left to right as they appear in the command, with the first parameter in the command having an iOrdinal value of 1.</summary>
public DBORDINAL iOrdinal;
public StrPtrUni pwszName;
public IntPtr pTypeInfo;
/// <summary>The name of the parameter; it is a null pointer if there is no name. Names are normal names. The colon prefix (where used within SQL text) is stripped.</summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string? pwszName;
/// <summary>ITypeInfo describes the type, if pTypeInfo is not a null pointer.</summary>
[MarshalAs(UnmanagedType.IUnknown)]
public ITypeInfo? pTypeInfo;
/// <summary>
/// <para>The maximum possible length of a value in the parameter. For parameters that use a fixed-length data type, this is the size of the data type. For parameters that use a variable-length data type, this is one of the following:</para>
/// <list type="bullet">
/// <item>The maximum length of the parameters in characters (for DBTYPE_STR and DBTYPE_WSTR) or in bytes (for DBTYPE_BYTES and DBTYPE_VARNUMERIC), if one is defined. For example, a parameter for a CHAR(5) column in an SQL table has a maximum length of 5.</item>
/// <item>The maximum length of the data type in characters (for DBTYPE_STR and DBTYPE_WSTR) or in bytes (for DBTYPE_BYTES and DBTYPE_VARNUMERIC), if the parameter does not have a defined length.</item>
/// <item>~0 (bitwise, the value is not 0; all bits are set to 1) if neither the parameter nor the data type has a defined maximum length.</item>
/// </list>
/// <para>For data types that do not have a length, this is set to ~0 (bitwise, the value is not 0; all bits are set to 1).</para>
/// </summary>
public DBLENGTH ulParamSize;
/// <summary>The indicator of the parameter's data type, or a type from which the data can be converted for the parameter if the provider cannot determine the exact data type of the parameter.</summary>
public DBTYPE wType;
/// <summary>If wType is a numeric type or DBTYPE_DBTIMESTAMP, bPrecision is the maximum number of digits, expressed in base 10. Otherwise, this is ~0 (bitwise, the value is not 0; all bits are set to 1).</summary>
public byte bPrecision;
/// <summary>If wType is a numeric type with a fixed scale or if wType is DBTYPE_DBTIMESTAMP, bScale is the number of digits to the right (if bScale is positive) or left (if bScale is negative) of the decimal point. Otherwise, this is ~0 (bitwise, the value is not 0; all bits are set to 1).</summary>
public byte bScale;
}

26
PInvoke/OleDb/Globals.cs Normal file
View File

@ -0,0 +1,26 @@
global using static Vanara.PInvoke.Ole32;
global using HWATCHREGION = System.IntPtr;
global using HACCESSOR = System.IntPtr;
global using HROW = System.IntPtr;
global using HCHAPTER = System.IntPtr;
global using DB_DWRESERVE = nuint;
global using DB_LORDINAL = nint;
global using DB_LPARAMS = nint;
global using DB_LRESERVE = nint;
global using DB_UPARAMS = nuint;
global using DB_URESERVE = nuint;
global using DBBKMARK = nuint;
global using DBBYTEOFFSET = nuint;
global using DBCOUNTITEM = nuint;
global using DBKIND = uint;
global using DBHASHVALUE = uint;
global using DBLENGTH = nuint;
global using DBNUMBERIC = Vanara.PInvoke.Odbc32.SQL_NUMERIC_STRUCT;
global using DBDATE = Vanara.PInvoke.Odbc32.DATE_STRUCT;
global using DBTIME = Vanara.PInvoke.Odbc32.TIME_STRUCT;
global using DBTIMESTAMP = Vanara.PInvoke.Odbc32.TIMESTAMP_STRUCT;
global using DBORDINAL = nuint;
global using DBREFCOUNT = uint;
global using DBROWCOUNT = nint;
global using DBROWOFFSET = nint;
global using DISPPARAMS = System.Runtime.InteropServices.ComTypes.DISPPARAMS;

5299
PInvoke/OleDb/OleDb1.cs Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

4039
PInvoke/OleDb/OleDb3.cs Normal file

File diff suppressed because it is too large Load Diff

4169
PInvoke/OleDb/OleDb4.cs Normal file

File diff suppressed because it is too large Load Diff

6934
PInvoke/OleDb/OleDb5.cs Normal file

File diff suppressed because it is too large Load Diff

861
PInvoke/OleDb/Transact.cs Normal file
View File

@ -0,0 +1,861 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Runtime.CompilerServices;
namespace Vanara.PInvoke;
public static partial class OleDb
{
/// <summary>infinite time-out value</summary>
public const uint XACTCONST_TIMEOUTINFINITE = 0;
/// <summary>The ISOFLAG enumeration values specify certain flags for a transaction.</summary>
[PInvokeData("transact.h")]
[Flags]
public enum ISOFLAG
{
/// <summary>Use just one of ISOFLAG_RETAIN_COMMIT values.</summary>
ISOFLAG_RETAIN_COMMIT_DC = 1,
/// <summary></summary>
ISOFLAG_RETAIN_COMMIT = 2,
/// <summary></summary>
ISOFLAG_RETAIN_COMMIT_NO = 3,
/// <summary>Use just one of ISOFLAG_RETAIN_ABORT values.</summary>
ISOFLAG_RETAIN_ABORT_DC = 4,
/// <summary></summary>
ISOFLAG_RETAIN_ABORT = 8,
/// <summary></summary>
ISOFLAG_RETAIN_ABORT_NO = 12,
/// <summary></summary>
ISOFLAG_RETAIN_DONTCARE = ISOFLAG_RETAIN_COMMIT_DC | ISOFLAG_RETAIN_ABORT_DC,
/// <summary></summary>
ISOFLAG_RETAIN_BOTH = ISOFLAG_RETAIN_COMMIT | ISOFLAG_RETAIN_ABORT,
/// <summary></summary>
ISOFLAG_RETAIN_NONE = ISOFLAG_RETAIN_COMMIT_NO | ISOFLAG_RETAIN_ABORT_NO,
/// <summary></summary>
ISOFLAG_OPTIMISTIC = 16,
/// <summary></summary>
ISOFLAG_READONLY = 32
}
/// <summary>The ISOLATIONLEVEL enumeration values specify the isolation levels of a transaction.</summary>
[PInvokeData("transact.h")]
public enum ISOLEVEL : uint
{
/// <summary>
/// No isolation level was specified. Any isolation level is supported. A downstream component that has this isolation level always
/// uses the same isolation level that its immediate upstream component uses. If the root object in a transaction has its isolation
/// level configured to ISOLATIONLEVEL_UNSPECIFIED, its isolation level becomes ISOLATIONLEVEL_SERIALIZABLE.
/// </summary>
ISOLATIONLEVEL_UNSPECIFIED = 0xffffffff,
/// <summary>No isolation level is used. It is not safe to use this level of isolation.</summary>
ISOLATIONLEVEL_CHAOS = 0x10,
/// <summary>
/// A transaction can read any data, even if it is being modified by another transaction. Any type of new data can be inserted during
/// a transaction. This is the least safe isolation level but allows the highest concurrency.
/// </summary>
ISOLATIONLEVEL_READUNCOMMITTED = 0x100,
/// <summary>Same as ISOLATIONLEVEL_READUNCOMMITTED.</summary>
ISOLATIONLEVEL_BROWSE = 0x100,
/// <summary>Same as ISOLATIONLEVEL_READCOMMITTED.</summary>
ISOLATIONLEVEL_CURSORSTABILITY = 0x1000,
/// <summary>
/// A transaction cannot read data that is being modified by another transaction that has not committed. Any type of new data can be
/// inserted during a transaction. This is the default isolation level in Microsoft SQL Server.
/// </summary>
ISOLATIONLEVEL_READCOMMITTED = 0x1000,
/// <summary>
/// Data read by a current transaction cannot be changed by another transaction until the current transaction finishes. Any type of
/// new data can be inserted during a transaction.
/// </summary>
ISOLATIONLEVEL_REPEATABLEREAD = 0x10000,
/// <summary>
/// Data read by a current transaction cannot be changed by another transaction until the current transaction finishes. No new data
/// can be inserted that would affect the current transaction. This is the safest isolation level and is the default, but allows the
/// lowest level of concurrency.
/// </summary>
ISOLATIONLEVEL_SERIALIZABLE = 0x100000,
/// <summary>Same as ISOLATIONLEVEL_SERIALIZABLE.</summary>
ISOLATIONLEVEL_ISOLATED = 0x100000
}
/// <summary>Specifies any configuration or startup options for the transaction manager object.</summary>
[PInvokeData("xolehlp.h")]
[Flags]
public enum OLE_TM : uint
{
/// <summary>
/// External callers should use this flag if they want the default behavior (which is to demand start DTC). This approach provides
/// meaningful text and is preferable to directly using the value 0 for i_grfOptions.
/// </summary>
OLE_TM_FLAG_NONE = 0x00000000,
/// <summary>Callers can specify this option if they do not want demand start of DTC.</summary>
OLE_TM_FLAG_NODEMANDSTART = 0x00000001,
/// <summary>
/// If this flag is set, the application specifies that it does not wish to take advantage of any features that need agile recovery
/// support. As a consequence, the application will be restricted to using the default transaction manager on a cluster. <br/>
/// </summary>
OLE_TM_FLAG_NOAGILERECOVERY = 0x00000002,
/// <summary>
/// Specifying this flag will cause DTC to query the lock status and fail demand start if someone else is holding SCM lock. This flag
/// should not be used by external callers.
/// </summary>
OLE_TM_FLAG_QUERY_SERVICE_LOCKSTATUS = 0x80000000,
/// <summary>
/// Only components internal to the Transaction manager (such as XATM) should use this flag. This flag should not be used by external callers.
/// </summary>
OLE_TM_FLAG_INTERNAL_TO_TM = 0x40000000,
}
[PInvokeData("transact.h")]
public enum XACTHEURISTIC
{
XACTHEURISTIC_ABORT = 1,
XACTHEURISTIC_COMMIT = 2,
XACTHEURISTIC_DAMAGE = 3,
XACTHEURISTIC_DANGER = 4
}
[PInvokeData("transact.h")]
public enum XACTRM
{
XACTRM_OPTIMISTICLASTWINS = 1,
XACTRM_NOREADONLYPREPARES = 2
}
[PInvokeData("transact.h")]
[Flags]
public enum XACTSTAT
{
XACTSTAT_NONE,
XACTSTAT_OPENNORMAL = 0x1,
XACTSTAT_OPENREFUSED = 0x2,
XACTSTAT_PREPARING = 0x4,
XACTSTAT_PREPARED = 0x8,
XACTSTAT_PREPARERETAINING = 0x10,
XACTSTAT_PREPARERETAINED = 0x20,
XACTSTAT_COMMITTING = 0x40,
XACTSTAT_COMMITRETAINING = 0x80,
XACTSTAT_ABORTING = 0x100,
XACTSTAT_ABORTED = 0x200,
XACTSTAT_COMMITTED = 0x400,
XACTSTAT_HEURISTIC_ABORT = 0x800,
XACTSTAT_HEURISTIC_COMMIT = 0x1000,
XACTSTAT_HEURISTIC_DAMAGE = 0x2000,
XACTSTAT_HEURISTIC_DANGER = 0x4000,
XACTSTAT_FORCED_ABORT = 0x8000,
XACTSTAT_FORCED_COMMIT = 0x10000,
XACTSTAT_INDOUBT = 0x20000,
XACTSTAT_CLOSED = 0x40000,
XACTSTAT_OPEN = 0x3,
XACTSTAT_NOTPREPARED = 0x7ffc3,
XACTSTAT_ALL = 0x7ffff
}
[PInvokeData("transact.h")]
[Flags]
public enum XACTTC
{
XACTTC_NONE,
XACTTC_SYNC_PHASEONE = 1,
XACTTC_SYNC_PHASETWO = 2,
XACTTC_SYNC = 2,
XACTTC_ASYNC_PHASEONE = 4,
XACTTC_ASYNC = 4
}
/// <summary>The <c>ITransaction</c> interface is used to commit and abort transactions and to obtain status information about transactions.</summary>
/// <remarks>
/// You obtain a pointer to this interface by calling the ITransactionDispenser::BeginTransaction method or the
/// ITransactionImport::Import method.
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms686531(v=vs.85)
[PInvokeData("transact.h")]
[ComImport, Guid("0fb15084-af41-11ce-bd2b-204c4f4f5020"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITransaction
{
/// <summary>Commits a transaction.</summary>
/// <param name="fRetaining">
/// <para>[in] Whether the commit is retaining or nonretaining.</para>
/// <para>
/// <para>Note</para>
/// <para>
/// A retaining commit or abort should not change the characteristics (isolation level, isolation flags, transaction options) of the
/// transaction. The new unit of work retains the same characteristics as the committed work.
/// </para>
/// </para>
/// </param>
/// <param name="grfTC">
/// <para>
/// [in] Values taken from the enumeration XACTTC. Values that may be specified in grfTC are as follows. These values are mutually exclusive.
/// </para>
/// <list type="table">
/// <listheader>
/// <description>Flag</description>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <description>XACTTC_ASYNC_PHASEONE</description>
/// <description>When this flag is specified, an asynchronous commit is performed.</description>
/// </item>
/// <item>
/// <description>XACTTC_SYNC_PHASEONE</description>
/// <description>
/// When this flag is specified, the call to <c>ITransaction::Commit</c> returns after phase one of the two-phase commit protocol.
/// </description>
/// </item>
/// <item>
/// <description>XACTTC_SYNC_PHASETWO</description>
/// <description>
/// When this flag is specified, the call to <c>ITransaction::Commit</c> returns after phase two of the two-phase commit protocol.
/// </description>
/// </item>
/// <item>
/// <description>XACTTC_SYNC</description>
/// <description>Synonym for XACTTC_SYNC_PHASETWO.</description>
/// </item>
/// </list>
/// </param>
/// <param name="grfRM">[in] Must be zero.</param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The transaction was successfully committed.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// XACT_S_ASYNC An asynchronous commit was specified. The commit operation has begun, but its outcome is not yet known. When the
/// transaction is complete, notification will be sent by <c>ITransactionOutcomeEvents</c>.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred. The transaction was aborted.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_UNEXPECTED An unexpected error occurred. The transaction status is unknown.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>XACT_E_ABORTED The transaction was implicitly aborted before <c>ITransaction::Commit</c> was called.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>XACT_E_ALREADYINPROGRESS A commit or abort operation was already in progress. This call was ignored.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// XACT_E_CANTRETAIN Retaining commit is not supported, or a new unit of work could not be created. The commit succeeded and the
/// session is in auto-commit mode.
/// </para>
/// <para>Commit was called on a distributed transaction with fRetaining set to TRUE.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>XACT_E_COMMITFAILED The transaction failed to commit for an unknown reason. The transaction was aborted.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>XACT_E_CONNECTION_DOWN The connection to the transaction manager failed. The transaction was aborted.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// XACT_E_INDOUBT The transaction status is in doubt. A communication failure occurred, or a transaction manager or resource manager
/// has failed.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// XACT_E_NOTRANSACTION Unable to commit the transaction because it had already been explicitly committed or aborted. This call was ignored.
/// </para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// XACT_E_NOTSUPPORTED An invalid combination of commit flags was specified, or grfRM was not equal to zero. This call was ignored.
/// </para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms713008(v=vs.85) HRESULT Commit( BOOL fRetaining, DWORD
// grfTC, DWORD grfRM);
[PreserveSig]
HRESULT Commit(bool fRetaining, XACTTC grfTC, uint grfRM = 0);
/// <summary>
/// <para></para>
/// <para>
/// Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012,
/// Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista
/// </para>
/// <para>This method aborts the transaction.</para>
/// </summary>
/// <param name="pboidReason">
/// [in] An optional BOID that indicates why the transaction is being aborted. This argument may be NULL indicating that no abort
/// reason is provided.
/// </param>
/// <param name="fRetaining">[in] Must be FALSE.</param>
/// <param name="fAsync">
/// [in] When fAsync is TRUE, an asynchronous abort is performed and the caller must use <c>ITransactionOutcomeEvents</c> to learn
/// the outcome of the transaction.
/// </param>
/// <returns></returns>
/// <remarks>
/// <para>The initiator of the transaction may abort the transaction as may any resource manager enlisted on the transaction.</para>
/// <para>
/// <c>Abort</c> may be invoked on a transaction repeatedly. XACT_S_ABORTING HRESULT will be returned following the first invocation
/// of <c>Abort</c>.
/// </para>
/// <para>If a communication failure occurs during a call to <c>Commit</c> or <c>Abort</c>, the status of the transaction is unknown.</para>
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms688267(v=vs.85) HRESULT Abort( BOID * pboidReason, BOOL
// fRetaining, BOOL fAsync);
[PreserveSig]
HRESULT Abort([In, Optional] IntPtr pboidReason, bool fRetaining, bool fAsync);
/// <summary>Returns information regarding a transaction.</summary>
/// <param name="pInfo">
/// <para>
/// [out] A pointer to the caller-allocated XACTTRANSINFO structure in which the method returns information about the transaction.
/// pInfo must not be a null pointer.
/// </para>
/// <para>The elements of this structure are used as described in the following table.</para>
/// <list type="table">
/// <listheader>
/// <description>Element</description>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <description><c>uow</c></description>
/// <description>The unit of work associated with this transaction. Cannot be NULL and must be unique per transaction.</description>
/// </item>
/// <item>
/// <description><c>isoLevel</c></description>
/// <description>
/// The isolation level associated with this transaction. ISOLATIONLEVEL_UNSPECIFIED indicates that no isolation level was specified.
/// For more information, see ITransactionLocal::StartTransaction.
/// </description>
/// </item>
/// <item>
/// <description><c>isoFlags</c></description>
/// <description>Will be zero.</description>
/// </item>
/// <item>
/// <description><c>grfTCSupported</c></description>
/// <description>This bitmask indicates the XACTTC flags that this transaction implementation supports.</description>
/// </item>
/// <item>
/// <description><c>grfRMSupported</c></description>
/// <description>Will be zero.</description>
/// </item>
/// <item>
/// <description><c>grfTCSupportedRetaining</c></description>
/// <description>Will be zero.</description>
/// </item>
/// <item>
/// <description><c>grfRMSupportedRetaining</c></description>
/// <description>Will be zero.</description>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The method succeeded.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_INVALIDARG pInfo was a null pointer.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_UNEXPECTED An unknown error occurred. No information is returned.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// XACT_E_NOTRANSACTION Unable to retrieve information for the transaction because it was already completed. No information is returned.
/// </para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms714975(v=vs.85) HRESULT GetTransactionInfo( XACTTRANSINFO *pInfo);
[PreserveSig]
HRESULT GetTransactionInfo(out XACTTRANSINFO pInfo);
}
/// <summary>
/// This interface contains two methods. The <c>BeginTransaction</c> method creates new transaction objects. The <c>GetOptionsObject</c>
/// method creates new transaction options objects.
/// </summary>
/// <remarks>
/// Call the DtcGetTransactionManager function with an riid of IID_ITransactionDispenser when initially connecting to DTC. You can also
/// call <c>QueryInterface</c> on any interface on the DTC proxy core object with an riid of IID_ITransactionDispenser.
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms687604(v=vs.85)
[PInvokeData("transact.h")]
[ComImport, Guid("3A6AD9E1-23B9-11cf-AD60-00AA00A74CCD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITransactionDispenser
{
/// <summary>This method creates a transaction options object.</summary>
/// <param name="ppOptions">
/// [out] Pointer to the pointer to the <c>ITransactionOptions</c> interface on the transaction options object. Must not be NULL.
/// </param>
/// <returns></returns>
/// <remarks>
/// <para>
/// The transaction options object obtained from the <c>GetOptionsObject</c> call can be assigned transaction attributes by calling
/// the ITransactionOptions::SetOptions method. The transaction options object can then be passed to
/// ITransactionDispenser::BeginTransaction. The transaction attributes from the transaction options object will be inherited by the
/// newly created transaction object.
/// </para>
/// <para>A process may create as many transaction options objects as it wishes.</para>
/// <para>
/// Two or more threads may simultaneously invoke the <c>BeginTransaction</c> method using the same transaction options object.
/// However, the attributes of the transaction options object must not be changed while the object is in use by the
/// <c>BeginTransaction</c> method.
/// </para>
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms679525(v=vs.85) HRESULT GetOptionsObject(
// ITransactionOptions ** ppOptions);
[PreserveSig]
HRESULT GetOptionsObject(out ITransactionOptions? ppOptions);
/// <summary>This method initiates a new transaction and returns a new transaction object which represents the transaction.</summary>
/// <param name="punkOuter">[in] Must be NULL.</param>
/// <param name="isoLevel">
/// [in] The isolation level to be used for this transaction, specified by the ISOLATIONLEVEL enumeration. This value is ignored by
/// DTC and passed on to the resource managers.
/// </param>
/// <param name="isoFlags">[in] Values from ISOFLAG enumeration.</param>
/// <param name="pOptions">
/// [in] A pointer to a transaction options object. This value may be NULL. If pOptions is NULL the time-out value for the
/// transaction is infinite and the transaction will not have a description.
/// </param>
/// <param name="ppTransaction">[out] Pointer to the pointer to the <c>ITransaction</c> interface on the new transaction object.</param>
/// <returns></returns>
/// <remarks>
/// A transaction options object which is passed as a parameter to <c>BeginTransaction</c> must not be altered while the
/// <c>BeginTransaction</c> method invocation is outstanding.
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms686676(v=vs.85) HRESULT BeginTransaction( IUnknown *
// punkOuter, ISOLEVEL isoLevel, ULONG isoFlags, ITransactionOptions * pOptions, ITransaction ** ppTransaction);
[PreserveSig]
HRESULT BeginTransaction([In, Optional] object? punkOuter, ISOLEVEL isoLevel, ISOFLAG isoFlags,
[In, Optional] ITransactionOptions? pOptions, out ITransaction? ppTransaction);
}
/// <summary>
/// <para>This interface contains methods that control the attributes of new transactions such as their time-out periods and descriptions.</para>
/// <para>
/// This interface is used to get and set attributes within a transaction options object. The transaction options object can be passed as
/// a parameter to the ITransactionDispenser::BeginTransaction method. The attributes of the transaction options object are inherited by
/// the newly initiated transaction. This lets the caller of the <c>BeginTransaction</c> method to control the attributes of a
/// transaction such as its time-out period and transaction description.
/// </para>
/// <para>
/// This interface is also used to get the transaction option attributes of an existing transaction object. It cannot be used to set the
/// attributes, because the transaction has already begun.
/// </para>
/// </summary>
/// <remarks>You obtain a pointer to this interface by calling the ITransactionDispenser::GetOptionsObject method.</remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms684388(v=vs.85)
[PInvokeData("transact.h")]
[ComImport, Guid("3A6AD9E0-23B9-11cf-AD60-00AA00A74CCD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITransactionOptions
{
/// <summary>Sets a suite of options associated with a transaction.</summary>
/// <param name="pOptions">
/// <para>[in] A pointer to an XACTOPT structure containing the options to be set in this transaction. This cannot be a null pointer.</para>
/// <para>The elements of this structure are used as described in the following table.</para>
/// <list type="table">
/// <listheader>
/// <description>Element</description>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <description><c>ulTimeout</c></description>
/// <description>
/// The amount of real time in milliseconds before the transaction is to be aborted automatically. Zero indicates an infinite
/// time-out. If no options have been previously set, <c>ulTimeout</c> is zero.
/// </description>
/// </item>
/// <item>
/// <description><c>szDescription</c></description>
/// <description>
/// A pointer to a textual description associated with this transaction. This string is appropriate for display in various end-user
/// administration tools that might monitor or log the transaction. If no options have been previously set, <c>szDescription</c> is
/// an empty string.
/// </description>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <list type="bullet">
/// <item>
/// <description>
/// <para>S_OK The method succeeded.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_FAIL A provider-specific error occurred.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_INVALIDARG pOptions was a null pointer.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>E_UNEXPECTED An unknown error occurred; the method failed.</para>
/// </description>
/// </item>
/// </list>
/// </returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms714204(v=vs.85) HRESULT SetOptions( XACTOPT *pOptions);
[PreserveSig]
HRESULT SetOptions(in XACTOPT pOptions);
/// <summary>The <c>GetOptions</c> method is used to read transaction attributes from a transaction options object.</summary>
/// <param name="pOptions">
/// [in, out] Reference to a XACTOPT structure containing attribute information for a transaction options object. The szDescription
/// field must be pre-allocated with the correct length.
/// </param>
/// <returns></returns>
/// <remarks>
/// This method can used to determine the description and the transaction timeout of a transaction that is already in progress, as
/// shown in the following sample code.
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms683541(v=vs.85) HRESULT GetOptions( XACTOPT * pOptions);
[PreserveSig]
HRESULT GetOptions(ref XACTOPT pOptions);
}
/// <summary>
/// This interface is used by application programs that require asynchronous notification about transaction outcomes. The application
/// program implements the methods in this interface and registers the interface with the connection point mechanism. DTC calls the
/// appropriate method on this interface to inform the application about the outcome of a transaction.
/// </summary>
/// <remarks>
/// <para>
/// Typically, <c>ITransaction::Commit</c> or <c>Abort</c> calls are performed synchronously. This means that the calling thread is
/// blocked until DTC makes a commit or abort decision (usually at the end of phase one of the two-phase commit protocol).
/// </para>
/// <para>
/// It is possible to avoid blocking the calling thread by using asynchronous <c>Commit</c> or <c>Abort</c> calls. Asynchronous
/// <c>Commit</c> or <c>Abort</c> require the following:
/// </para>
/// <para>
/// The <c>ITransactionOutcomeEvents</c> events are raised when the transaction's outcome is known. On the root transaction manager's
/// system, the transaction outcome event is raised at the end of phase one. On the subordinate transaction managers' systems, the
/// transaction outcome events are raised at the beginning of phase two.
/// </para>
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms686465(v=vs.85)
[PInvokeData("transact.h")]
[ComImport, Guid("3A6AD9E2-23B9-11cf-AD60-00AA00A74CCD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITransactionOutcomeEvents
{
/// <summary>This event is raised when the transaction committed.</summary>
/// <param name="fRetaining">[in] Indicates whether retaining <c>Commit</c> was specified. Will be FALSE.</param>
/// <param name="pNewUOW">[in] Always NULL.</param>
/// <param name="hr">[in] Always S_OK.</param>
/// <returns></returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms687677(v=vs.85) HRESULT Committed( BOOL fRetaining, XACTUOW
// * pNewUOW, HRESULT hr);
[PreserveSig]
HRESULT Committed(bool fRetaining, [In, Optional] IntPtr pNewUOW, HRESULT hr);
/// <summary>
/// This event is raised when the transaction aborted, either as a result of a call to <c>Abort</c> or an unsuccessful call to <c>Commit</c>*.*
/// </summary>
/// <param name="pboidReason">[in] A BOID indicating why the transaction aborted.</param>
/// <param name="fRetaining">[in] Indicates whether retaining Commit was specified. Will be FALSE.</param>
/// <param name="pNewUOW">[in] Always NULL.</param>
/// <param name="hr">[in] Always S_OK.</param>
/// <returns></returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms688494(v=vs.85) HRESULT Aborted( BOID * pboidReason, BOOL
// fRetaining, XACTUOW * pNewUOW, HRESULT hr);
[PreserveSig]
HRESULT Aborted([In, Optional] IntPtr pboidReason, bool fRetaining, [In, Optional] IntPtr pNewUOW, HRESULT hr);
/// <summary>
/// This event is raised when one of the participants in the transaction chooses to heuristically decide the outcome of the transaction.
/// </summary>
/// <param name="dwDecision">[in] Values from the enumeration XACTHEURISTIC.</param>
/// <param name="pboidReason">
/// [in] A BOID indicating why the transaction was heuristically decided. This value is provided by the party making the heuristic decision.
/// </param>
/// <param name="hr">[in] Always S_OK.</param>
/// <returns></returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms678855(v=vs.85) HRESULT HeuristicDecision( DWORD dwDecision,
// BOID * pboidReason, HRESULT hr);
[PreserveSig]
HRESULT HeuristicDecision(XACTHEURISTIC dwDecision, [In, Optional] IntPtr pboidReason, HRESULT hr);
/// <summary>
/// This event is raised when the outcome of the transaction is in-doubt. The outcome of the transaction can be in-doubt if the
/// connection between the MSDTC proxy and the MSDTC TM was broken after the proxy asked the transaction manager to commit or abort a
/// transaction but before the transaction manager's response to the commit or abort was received by the proxy. Note: Receiving this
/// method call is not the same as the state of the transaction being in-doubt.
/// </summary>
/// <returns></returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms687104(v=vs.85) HRESULT Indoubt(void);
[PreserveSig]
HRESULT Indoubt();
}
/// <summary>
/// <para>
/// The <c>DtcGetTransactionManagerEx</c> function is typically the first DTC call that application programs and resource managers make
/// when using DTC. This helper function establishes the initial connection to DTC. It returns an interface pointer to one of the
/// interfaces on the DTC proxy core object. This function helps reduce the boot time and minimize resource consumption and adds the
/// ability to demand start DTC to compensate for removing boot start.
/// </para>
/// </summary>
/// <param name="pszHost">
/// <para>[in] Name of the host system which will serve as the transaction commit coordinator.</para>
/// <para>
/// <para>Note</para>
/// <para>If the host system is not found the HRESULT XACT_E_UNABLE_TO_READ_DTC_CONFIG is returned.</para>
/// </para>
/// </param>
/// <param name="pszTmName">
/// [in] String Name of the transaction manager which will serve as the transaction commit coordinator. Must be NULL.
/// </param>
/// <param name="riid">[in] IID of the requested interface.</param>
/// <param name="grfOptions">
/// <para>[in] Specifies any configuration or startup options for the transaction manager object. Currently the supported flags are:</para>
/// <para>OLE_TM_FLAG_NODEMANDSTART (Value = 0x00000001)</para>
/// <para>Callers can specify this option if they do not want demand start of DTC.</para>
/// <para>OLE_TM_FLAG_NONE (Value = 0x00000000)</para>
/// <para>
/// External callers should use this flag if they want the default behavior (which is to demand start DTC). This approach provides
/// meaningful text and is preferable to directly using the value 0 for i_grfOptions.
/// </para>
/// <para>OLE_TM_FLAG_INTERNAL_TO_TM (Internal only)</para>
/// <para>
/// Only components internal to the Transaction manager (such as XATM) should use this flag. This flag should not be used by external callers.
/// </para>
/// <para>OLE_TM_FLAG_QUERY_SERVICE_LOCKSTATUS (Internal only)</para>
/// <para>
/// Specifying this flag will cause DTC to query the lock status and fail demand start if someone else is holding SCM lock. This flag
/// should not be used by external callers.
/// </para>
/// </param>
/// <param name="pvConfigParams">
/// [in] Pointer to a self-describing structure. You can use the structure to pass various configuration parameters into the TM object.
/// Must be NULL.
/// </param>
/// <param name="ppvObject">[out] Pointer to the pointer to the requested interface.</param>
/// <remarks>
/// <para>
/// <para>Note</para>
/// <para>This API should not be called without the OLE_TM_FLAG_NO_DEMANDSTART during service startup.</para>
/// </para>
/// <para>
/// If the value refers to a remote computer, then you must configure the computers participating in the transaction as follows,
/// otherwise the call will fail:
/// </para>
/// <list type="number">
/// <item>
/// <description>
/// <para>On the computer where the application that makes this call resides, make sure the Remote Registry service is running.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// On the remote computer referred to by the parameter, make sure the MSDTC service is configured to accept Network Transactions and
/// allows remote clients.
/// </para>
/// </description>
/// </item>
/// </list>
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms678898(v=vs.85) EXTERN_C EXPORTAPI __cdecl
// DtcGetTransactionManagerEx( tchar * pszHost, tchar * pszTmName, REFIIDriid, DWORDgrfOptions, void * pvConfigParams, void ** ppvObject);
[PInvokeData("xolehlp.h")]
[DllImport("xolehlp.dll", SetLastError = false, CharSet = CharSet.Auto)]
public static extern HRESULT DtcGetTransactionManagerEx(string? pszHost, string? pszTmName, in Guid riid,
OLE_TM grfOptions, [In, Optional] IntPtr pvConfigParams, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 2)] out object? ppvObject);
/// <summary>
/// The <c>DtcGetTransactionManagerEx</c> function is typically the first DTC call that application programs and resource managers make
/// when using DTC. This helper function establishes the initial connection to DTC. It returns an interface pointer to one of the
/// interfaces on the DTC proxy core object. This function helps reduce the boot time and minimize resource consumption and adds the
/// ability to demand start DTC to compensate for removing boot start.
/// </summary>
/// <typeparam name="T">The type of the interface to return.</typeparam>
/// <param name="pszHost">
/// <para>[in] Name of the host system which will serve as the transaction commit coordinator.</para>
/// <para>
/// <para>Note</para>
/// <para>If the host system is not found the HRESULT XACT_E_UNABLE_TO_READ_DTC_CONFIG is returned.</para>
/// </para>
/// </param>
/// <param name="grfOptions">
/// <para>[in] Specifies any configuration or startup options for the transaction manager object. Currently the supported flags are:</para>
/// <para>OLE_TM_FLAG_NODEMANDSTART (Value = 0x00000001)</para>
/// <para>Callers can specify this option if they do not want demand start of DTC.</para>
/// <para>OLE_TM_FLAG_NONE (Value = 0x00000000)</para>
/// <para>
/// External callers should use this flag if they want the default behavior (which is to demand start DTC). This approach provides
/// meaningful text and is preferable to directly using the value 0 for i_grfOptions.
/// </para>
/// <para>OLE_TM_FLAG_INTERNAL_TO_TM (Internal only)</para>
/// <para>
/// Only components internal to the Transaction manager (such as XATM) should use this flag. This flag should not be used by external callers.
/// </para>
/// <para>OLE_TM_FLAG_QUERY_SERVICE_LOCKSTATUS (Internal only)</para>
/// <para>
/// Specifying this flag will cause DTC to query the lock status and fail demand start if someone else is holding SCM lock. This flag
/// should not be used by external callers.
/// </para>
/// </param>
/// <returns>[out] Pointer to the pointer to the requested interface.</returns>
/// <remarks>
/// <para>
/// <para>Note</para>
/// <para>This API should not be called without the OLE_TM_FLAG_NO_DEMANDSTART during service startup.</para>
/// </para>
/// <para>
/// If the value refers to a remote computer, then you must configure the computers participating in the transaction as follows,
/// otherwise the call will fail:
/// </para>
/// <list type="number">
/// <item>
/// <description>
/// <para>On the computer where the application that makes this call resides, make sure the Remote Registry service is running.</para>
/// </description>
/// </item>
/// <item>
/// <description>
/// <para>
/// On the remote computer referred to by the parameter, make sure the MSDTC service is configured to accept Network Transactions and
/// allows remote clients.
/// </para>
/// </description>
/// </item>
/// </list>
/// </remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms678898(v=vs.85) EXTERN_C EXPORTAPI __cdecl
// DtcGetTransactionManagerEx( tchar * pszHost, tchar * pszTmName, REFIIDriid, DWORDgrfOptions, void * pvConfigParams, void ** ppvObject);
[PInvokeData("xolehlp.h")]
public static T DtcGetTransactionManagerEx<T>(string? pszHost = null, OLE_TM grfOptions = 0) where T : class
{
DtcGetTransactionManagerEx(pszHost, null, typeof(T).GUID, grfOptions, IntPtr.Zero, out var ppvObject).ThrowIfFailed();
return (T)ppvObject!;
}
/// <summary/>
[StructLayout(LayoutKind.Sequential, Size = 16)]
[UnsafeValueType]
[NativeCppClass]
[PInvokeData("transact.h")]
public struct BOID
{
}
/// <summary>The XACTOPT structure contains information for a transaction options object.</summary>
[PInvokeData("transact.h")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct XACTOPT
{
/// <summary>
/// This parameter limits the duration of the transaction and therefore bounds the amount of time that locks are held on database
/// records and system resources. If the time-out period expires before the transaction commits, the DTC automatically aborts the
/// transaction. The time-out is specified in milliseconds. A time-out value of zero indicates no time-out.
/// </summary>
public uint ulTimeout;
/// <summary>
/// A textual description for a transaction. The description is displayed by the DTC administration tool in the DTC Transactions
/// window. The description is meaningful only to the DTC administrator and is not processed or interpreted by the DTC itself.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public string szDescription;
}
/// <summary>The XACTTRANSINFO structure stores information about the transaction.</summary>
[PInvokeData("transact.h")]
[StructLayout(LayoutKind.Sequential)]
public struct XACTTRANSINFO
{
/// <summary>The unit of work associated with this transaction.</summary>
public BOID uow;
/// <summary>
/// The isolation level associated with this transaction object, specified by the ISOLATIONLEVEL enumeration.
/// ISOLATIONLEVEL_UNSPECIFIED indicates that no isolation level was specified.
/// </summary>
public ISOLEVEL isoLevel;
/// <summary>Values from ISOFLAG enumeration.</summary>
public ISOFLAG isoFlags;
/// <summary>This bit mask indicates which grfTC flags that this transaction implementation supports.</summary>
public uint grfTCSupported;
/// <summary>Must be zero.</summary>
public uint grfRMSupported;
/// <summary>Must be zero.</summary>
public uint grfTCSupportedRetaining;
/// <summary>Must be zero.</summary>
public uint grfRMSupportedRetaining;
}
}

41
PInvoke/OleDb/adoint.cs Normal file
View File

@ -0,0 +1,41 @@
namespace Vanara.PInvoke;
public static partial class OleDb
{
/// <summary>
/// <para>
/// <c>IADOConnectionConstruction</c> allows you to create an ADO connection from existing OLE DB objects. Using this interface is only
/// feasible from C or C++ code that uses a mix of OLE DB and ADO. To do this, you typically create an empty ADO connection by using
/// <c>CoCreateInstance</c>; query the object for the <c>IADOConnectionConstuction</c> interface; and then call <c>WrapDSOandSession</c>
/// to initialize from an existing OLE DB data source object and session.
/// </para>
/// </summary>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/aa965351(v=vs.85)
[PInvokeData("adoint.h")]
[ComImport, Guid("00000516-0000-0010-8000-00AA006D2EA4"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IADOConnectionConstruction
{
/// <summary>Returns the underlying OLEDB Data Source object for this connection.</summary>
/// <remarks>In the header file, this method is called ADOCommandConstruction::DSO.</remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/aa965468(v=vs.85) HRESULT get_DSO( IUnknown** ppDSO);
[PreserveSig]
HRESULT get_DSO([MarshalAs(UnmanagedType.IUnknown)] out object? ppDSO);
/// <summary>Returns the underlying OLEDB Session for this connection.</summary>
/// <remarks>In the header file, this method is called ADOCommandConstruction::Session.</remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/aa965359(v=vs.85) HRESULT get_Session( IUnknown** ppSession);
[PreserveSig]
HRESULT get_Session([MarshalAs(UnmanagedType.IUnknown)] out object? ppSession);
/// <summary>Initializes a connection from an existing OLEDB Data Source object and Session.</summary>
/// <param name="pDSO">[in] An interface pointer to the Data Source object. It must point to an IDBInitialize interface.</param>
/// <param name="pSession">
/// [in] An interface pointer to the Session object. It must be queryable for the ISessionProperties, IBindResource, and ICreateRow interfaces.
/// </param>
/// <remarks>In the header file, this method is called ADOCommandConstruction::WrapDSOandSession.</remarks>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/aa965326(v=vs.85) HRESULT WrapDSOandSession( IUnknown* pDSO
// IUnknown* pSession);
[PreserveSig]
HRESULT WrapDSOandSession([In, Optional, MarshalAs(UnmanagedType.IUnknown)] object? pDSO, [In, Optional, MarshalAs(UnmanagedType.IUnknown)] object? pSession);
}
}

View File

@ -374,6 +374,38 @@ public static partial class OleDb
void WriteStringToStorage([In, Optional] string? pwszFileName, [In, Optional] string? pwszInitializationString, Kernel32.CreationOption dwCreationDisposition);
}
/// <summary>
/// <para>Created for reference use in Visual Basic. Provides implementation for the <c>promptNew</c> and <c>promptEdit</c> methods.</para>
/// </summary>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms722628(v=vs.85)
[ComImport, Guid("2206CCB2-19C1-11D1-89E0-00C04FD7A829"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IDataSourceLocator
{
/// <summary>The parent window handle for dialog boxes to be displayed. The dialog box will always be centered within this window. Returns the currently assigned window handle.</summary>
/// <value>A HWND value. The handle of the parent window where the dialog will be displayed.</value>
public HWND hWnd { get; set; }
/// <summary>
/// Opens the <c>Data Link Properties</c> window. Allows the user to select the properties for a new connection. The properties are returned in a connection string.
/// </summary>
/// <returns>An ADO connection object. Contains preset connection properties that will be displayed in the Data Link Properties window.</returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms725384(v=vs.85)
[return: MarshalAs(UnmanagedType.IDispatch)]
object? PromptNew();
/// <summary>
/// Opens the <c>Data Link Properties</c> window. Allows the user to change the properties for an existing ADO connection object. The
/// properties for the connection object are changed directly at the connection object.
/// </summary>
/// <param name="ppADOConnection">
/// An ADO connection object. Contains preset connection properties that will be displayed in the Data Link Properties window.
/// </param>
/// <returns>A Boolean value. True if user pressed <c>OK</c> in the Data Link Properties window; False if <c>Cancel</c> was pressed.</returns>
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms709747(v=vs.85)
[return: MarshalAs(UnmanagedType.Bool)]
bool PromptEdit([MarshalAs(UnmanagedType.IDispatch)] ref object? ppADOConnection);
}
/// <summary>
/// <para>
/// The <c>IDBPromptInitialize</c> interface allows the display of the data link dialog boxes programmatically. Using the data link user
@ -616,6 +648,18 @@ public static partial class OleDb
[In, MarshalAs(UnmanagedType.LPWStr)] string pwszInitialFile, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszSelectedFile);
}
/// <summary/>
[PInvokeData("msdasc.h")]
[ComImport, Guid("06210E88-01F5-11D1-B512-0080C781C384"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IService
{
/// <summary/>
/// <param name="pUnkInner"/>
/// <returns/>
[PreserveSig]
HRESULT InvokeService([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkInner);
}
/// <summary>Creates a data source object; analogous to <c>CoCreateInstance</c>.</summary>
/// <typeparam name="T">The interface type to create.</typeparam>
/// <param name="dataInit">The <see cref="IDataInitialize"/> instance.</param>
@ -809,9 +853,4 @@ public static partial class OleDb
/// <summary>CLSID_RootBinder</summary>
[ComImport, Guid("FF151822-B0BF-11D1-A80D-000000000000"), ClassInterface(ClassInterfaceType.None)]
public class RootBinder { }
/*
IService
IDataSourceLocator
*/
}