/*
 * Copyright (C) 2013 Daniel Jeliński
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "unknwn.idl";

cpp_quote("#include <winerror.h>")

interface ITransaction;
interface ITransactionCloner;
interface ITransaction2;
interface ITransactionDispenser;
interface ITransactionOptions;
interface ITransactionOutcomeEvents;
interface ITmNodeName;

typedef struct BOID {
    byte rgb[16];
} BOID;

cpp_quote("#ifndef MAX_TRAN_DESC_DEFINED")
cpp_quote("#define MAX_TRAN_DESC_DEFINED")
typedef enum TX_MISC_CONSTANTS {
    MAX_TRAN_DESC = 40
} TX_MISC_CONSTANTS;
cpp_quote("#endif")

typedef BOID XACTUOW;
typedef LONG ISOLEVEL;

typedef enum ISOLATIONLEVEL {
    ISOLATIONLEVEL_UNSPECIFIED = 0xffffffff,
    ISOLATIONLEVEL_CHAOS = 0x10,
    ISOLATIONLEVEL_READUNCOMMITTED = 0x100,
    ISOLATIONLEVEL_BROWSE = 0x100,
    ISOLATIONLEVEL_CURSORSTABILITY = 0x1000,
    ISOLATIONLEVEL_READCOMMITTED = 0x1000,
    ISOLATIONLEVEL_REPEATABLEREAD = 0x10000,
    ISOLATIONLEVEL_SERIALIZABLE = 0x100000,
    ISOLATIONLEVEL_ISOLATED = 0x100000
} ISOLATIONLEVEL;

typedef struct XACTTRANSINFO {
    XACTUOW uow;
    ISOLEVEL isoLevel;
    ULONG isoFlags;
    DWORD grfTCSupported;
    DWORD grfRMSupported;
    DWORD grfTCSupportedRetaining;
    DWORD grfRMSupportedRetaining;
} XACTTRANSINFO;

typedef struct XACTSTATS {
    ULONG cOpen;
    ULONG cCommitting;
    ULONG cCommitted;
    ULONG cAborting;
    ULONG cAborted;
    ULONG cInDoubt;
    ULONG cHeuristicDecision;
    FILETIME timeTransactionsUp;
} XACTSTATS;

typedef enum ISOFLAG {
    ISOFLAG_RETAIN_COMMIT_DC = 1,
    ISOFLAG_RETAIN_COMMIT = 2,
    ISOFLAG_RETAIN_COMMIT_NO = 3,
    ISOFLAG_RETAIN_ABORT_DC = 4,
    ISOFLAG_RETAIN_ABORT = 8,
    ISOFLAG_RETAIN_ABORT_NO = 12,
    ISOFLAG_RETAIN_DONTCARE = ISOFLAG_RETAIN_COMMIT_DC | ISOFLAG_RETAIN_ABORT_DC,
    ISOFLAG_RETAIN_BOTH = ISOFLAG_RETAIN_COMMIT | ISOFLAG_RETAIN_ABORT,
    ISOFLAG_RETAIN_NONE = ISOFLAG_RETAIN_COMMIT_NO | ISOFLAG_RETAIN_ABORT_NO,
    ISOFLAG_OPTIMISTIC = 16,
    ISOFLAG_READONLY = 32
} ISOFLAG;

typedef enum XACTTC {
    XACTTC_NONE = 0,
    XACTTC_SYNC_PHASEONE = 1,
    XACTTC_SYNC_PHASETWO = 2,
    XACTTC_SYNC = 2,
    XACTTC_ASYNC_PHASEONE = 4,
    XACTTC_ASYNC = 4
} XACTTC;

typedef enum XACTRM {
    XACTRM_OPTIMISTICLASTWINS = 1,
    XACTRM_NOREADONLYPREPARES
} XACTRM;

typedef enum XACTCONST {
    XACTCONST_TIMEOUTINFINITE
} XACTCONST;

typedef enum XACTHEURISTIC {
    XACTHEURISTIC_ABORT = 1,
    XACTHEURISTIC_COMMIT,
    XACTHEURISTIC_DAMAGE,
    XACTHEURISTIC_DANGER
} XACTHEURISTIC;

typedef enum XACTSTAT {
    XACTSTAT_NONE = 0,
    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
} XACTSTAT;

typedef struct XACTOPT {
    ULONG ulTimeout;
    char szDescription[40 ];
} XACTOPT;

[
    object,
    uuid(0fb15084-af41-11ce-bd2b-204c4f4f5020)
]
interface ITransaction : IUnknown {
    HRESULT Commit([in] BOOL fRetaining,
                   [in] DWORD grfTC,
                   [in] DWORD grfRM);
    HRESULT Abort([in, unique] BOID *pboidReason,
                  [in] BOOL fRetaining,
                  [in] BOOL fAsync);
    HRESULT GetTransactionInfo([out] XACTTRANSINFO *pinfo);
}

[
    object,
    uuid(02656950-2152-11d0-944C-00A0C905416E)
]
interface ITransactionCloner : ITransaction {
    HRESULT CloneWithCommitDisabled([out] ITransaction **ppITransaction);
}

[
    object,
    uuid(34021548-0065-11d3-bac1-00c04f797be2)
]
interface ITransaction2 : ITransactionCloner {
    HRESULT GetTransactionInfo2([out] XACTTRANSINFO *pinfo);
}

[
    object,
    uuid(3A6AD9E1-23B9-11cf-AD60-00AA00A74CCD)
]
interface ITransactionDispenser : IUnknown {
    HRESULT GetOptionsObject([out] ITransactionOptions **ppOptions);
    HRESULT BeginTransaction([in, unique] IUnknown *punkOuter,
                             [in] ISOLEVEL isoLevel,
                             [in] ULONG isoFlags,
                             [in, unique] ITransactionOptions *pOptions,
                             [out] ITransaction **ppTransaction);
}

[
    object,
    uuid(3A6AD9E0-23B9-11cf-AD60-00AA00A74CCD)
]
interface ITransactionOptions : IUnknown {
    HRESULT SetOptions([in] XACTOPT *pOptions);
    HRESULT GetOptions([in, out] XACTOPT *pOptions);
}

[
    object,
    uuid(3A6AD9E2-23B9-11cf-AD60-00AA00A74CCD)
]
interface ITransactionOutcomeEvents : IUnknown {
    HRESULT Committed([in] BOOL fRetaining,
                      [in, unique] XACTUOW *pNewUOW,
                      [in] HRESULT hr);
    HRESULT Aborted([in, unique] BOID *pboidReason,
                    [in] BOOL fRetaining,
                    [in, unique] XACTUOW *pNewUOW,
                    [in] HRESULT hr);
    HRESULT HeuristicDecision([in] DWORD dwDecision,
                              [in, unique] BOID *pboidReason,
                              [in] HRESULT hr);
    HRESULT Indoubt(void);
}

[
    object,
    uuid(30274F88-6EE4-474e-9B95-7807BC9EF8CF)
]
interface ITmNodeName : IUnknown {
    HRESULT GetNodeNameSize([out] ULONG *pcbNodeNameSize);
    HRESULT GetNodeName([in] ULONG cbNodeNameBufferSize,
                        [in, out] LPWSTR pNodeNameBuffer);
}
