/*
 * Copyright 2011 Hans Leidekker for CodeWeavers
 *
 * 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
 */

#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "transact.h"
#include "initguid.h"
#include "txdtc.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(xolehlp);

/* Resource manager start */

typedef struct {
    IResourceManager IResourceManager_iface;
    LONG ref;
} ResourceManager;

static inline ResourceManager *impl_from_IResourceManager(IResourceManager *iface)
{
    return CONTAINING_RECORD(iface, ResourceManager, IResourceManager_iface);
}

static HRESULT WINAPI ResourceManager_QueryInterface(IResourceManager *iface, REFIID iid,
    void **ppv)
{
    ResourceManager *This = impl_from_IResourceManager(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IResourceManager, iid))
    {
        *ppv = &This->IResourceManager_iface;
    }
    else
    {
        FIXME("(%s): not implemented\n", debugstr_guid(iid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI ResourceManager_AddRef(IResourceManager *iface)
{
    ResourceManager *This = impl_from_IResourceManager(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI ResourceManager_Release(IResourceManager *iface)
{
    ResourceManager *This = impl_from_IResourceManager(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}
static HRESULT WINAPI ResourceManager_Enlist(IResourceManager *iface,
	ITransaction *pTransaction,ITransactionResourceAsync *pRes,XACTUOW *pUOW,
	LONG *pisoLevel,ITransactionEnlistmentAsync **ppEnlist)
{
    FIXME("(%p, %p, %p, %p, %p, %p): stub\n", iface, pTransaction,pRes,pUOW,
        pisoLevel,ppEnlist);
    return E_NOTIMPL;
}
static HRESULT WINAPI ResourceManager_Reenlist(IResourceManager *iface,
        byte *pPrepInfo,ULONG cbPrepInfo,DWORD lTimeout,XACTSTAT *pXactStat)
{
    FIXME("(%p, %p, %u, %u, %p): stub\n", iface, pPrepInfo, cbPrepInfo, lTimeout, pXactStat);
    return E_NOTIMPL;
}
static HRESULT WINAPI ResourceManager_ReenlistmentComplete(IResourceManager *iface)
{
    FIXME("(%p): stub\n", iface);
    return S_OK;
}
static HRESULT WINAPI ResourceManager_GetDistributedTransactionManager(IResourceManager *iface,
        REFIID iid,void **ppvObject)
{
    FIXME("(%p, %s, %p): stub\n", iface, debugstr_guid(iid), ppvObject);
    return E_NOTIMPL;
}

static const IResourceManagerVtbl ResourceManager_Vtbl = {
    ResourceManager_QueryInterface,
    ResourceManager_AddRef,
    ResourceManager_Release,
    ResourceManager_Enlist,
    ResourceManager_Reenlist,
    ResourceManager_ReenlistmentComplete,
    ResourceManager_GetDistributedTransactionManager
};

static HRESULT ResourceManager_Create(REFIID riid, void **ppv)
{
    ResourceManager *This;
    HRESULT ret;

    if (!ppv) return E_INVALIDARG;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(ResourceManager));
    if (!This) return E_OUTOFMEMORY;

    This->IResourceManager_iface.lpVtbl = &ResourceManager_Vtbl;
    This->ref = 1;

    ret = IResourceManager_QueryInterface(&This->IResourceManager_iface, riid, ppv);
    IResourceManager_Release(&This->IResourceManager_iface);

    return ret;
}

/* Resource manager end */

/* Transaction options start */

typedef struct {
    ITransactionOptions ITransactionOptions_iface;
    LONG ref;
    XACTOPT opts;
} TransactionOptions;

static inline TransactionOptions *impl_from_ITransactionOptions(ITransactionOptions *iface)
{
    return CONTAINING_RECORD(iface, TransactionOptions, ITransactionOptions_iface);
}

static HRESULT WINAPI TransactionOptions_QueryInterface(ITransactionOptions *iface, REFIID iid,
    void **ppv)
{
    TransactionOptions *This = impl_from_ITransactionOptions(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_ITransactionOptions, iid))
    {
        *ppv = &This->ITransactionOptions_iface;
    }
    else
    {
        FIXME("(%s): not implemented\n", debugstr_guid(iid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI TransactionOptions_AddRef(ITransactionOptions *iface)
{
    TransactionOptions *This = impl_from_ITransactionOptions(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI TransactionOptions_Release(ITransactionOptions *iface)
{
    TransactionOptions *This = impl_from_ITransactionOptions(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}
static HRESULT WINAPI TransactionOptions_SetOptions(ITransactionOptions *iface,
    XACTOPT *pOptions)
{
    TransactionOptions *This = impl_from_ITransactionOptions(iface);

    if (!pOptions) return E_INVALIDARG;
    TRACE("(%p, %u, %s)\n", iface, pOptions->ulTimeout, debugstr_a(pOptions->szDescription));
    This->opts = *pOptions;
    return S_OK;
}
static HRESULT WINAPI TransactionOptions_GetOptions(ITransactionOptions *iface,
    XACTOPT *pOptions)
{
    TransactionOptions *This = impl_from_ITransactionOptions(iface);

    TRACE("(%p, %p)\n", iface, pOptions);
    if (!pOptions) return E_INVALIDARG;
    *pOptions = This->opts;
    return S_OK;
}

static const ITransactionOptionsVtbl TransactionOptions_Vtbl = {
    TransactionOptions_QueryInterface,
    TransactionOptions_AddRef,
    TransactionOptions_Release,
    TransactionOptions_SetOptions,
    TransactionOptions_GetOptions
};

static HRESULT TransactionOptions_Create(ITransactionOptions **ppv)
{
    TransactionOptions *This;

    if (!ppv) return E_INVALIDARG;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(TransactionOptions));
    if (!This) return E_OUTOFMEMORY;

    This->ITransactionOptions_iface.lpVtbl = &TransactionOptions_Vtbl;
    This->ref = 1;

    *ppv = &This->ITransactionOptions_iface;

    return S_OK;
}

/* Transaction options end */

/* Transaction start */

typedef struct {
    ITransaction ITransaction_iface;
    LONG ref;
    XACTTRANSINFO info;
} Transaction;

static inline Transaction *impl_from_ITransaction(ITransaction *iface)
{
    return CONTAINING_RECORD(iface, Transaction, ITransaction_iface);
}

static HRESULT WINAPI Transaction_QueryInterface(ITransaction *iface, REFIID iid,
    void **ppv)
{
    Transaction *This = impl_from_ITransaction(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_ITransaction, iid))
    {
        *ppv = &This->ITransaction_iface;
    }
    else
    {
        FIXME("(%s): not implemented\n", debugstr_guid(iid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI Transaction_AddRef(ITransaction *iface)
{
    Transaction *This = impl_from_ITransaction(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI Transaction_Release(ITransaction *iface)
{
    Transaction *This = impl_from_ITransaction(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}
static HRESULT WINAPI Transaction_Commit(ITransaction *iface,
    BOOL fRetaining, DWORD grfTC, DWORD grfRM)
{
    FIXME("(%p, %d, %08x, %08x): stub\n", iface, fRetaining, grfTC, grfRM);
    return E_NOTIMPL;
}
static HRESULT WINAPI Transaction_Abort(ITransaction *iface,
    BOID *pboidReason, BOOL fRetaining, BOOL fAsync)
{
    FIXME("(%p, %p, %d, %d): stub\n", iface, pboidReason, fRetaining, fAsync);
    return E_NOTIMPL;
}
static HRESULT WINAPI Transaction_GetTransactionInfo(ITransaction *iface,
    XACTTRANSINFO *pinfo)
{
    Transaction *This = impl_from_ITransaction(iface);
    TRACE("(%p, %p)\n", iface, pinfo);
    if (!pinfo) return E_INVALIDARG;
    *pinfo = This->info;
    return S_OK;
}

static const ITransactionVtbl Transaction_Vtbl = {
    Transaction_QueryInterface,
    Transaction_AddRef,
    Transaction_Release,
    Transaction_Commit,
    Transaction_Abort,
    Transaction_GetTransactionInfo
};

static HRESULT Transaction_Create(ISOLEVEL isoLevel, ULONG isoFlags,
        ITransactionOptions *pOptions, ITransaction **ppv)
{
    Transaction *This;

    if (!ppv) return E_INVALIDARG;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(Transaction));
    if (!This) return E_OUTOFMEMORY;
    ZeroMemory(&This->info, sizeof(This->info));

    This->ITransaction_iface.lpVtbl = &Transaction_Vtbl;
    This->ref = 1;
    This->info.isoLevel = isoLevel;
    This->info.isoFlags = isoFlags;

    *ppv = &This->ITransaction_iface;

    return S_OK;
}

/* Transaction end */

/* DTC Proxy Core Object start */

typedef struct {
    ITransactionDispenser ITransactionDispenser_iface;
    LONG ref;
    IResourceManagerFactory2 IResourceManagerFactory2_iface;
    ITransactionImportWhereabouts ITransactionImportWhereabouts_iface;
    ITransactionImport ITransactionImport_iface;
} TransactionManager;

static inline TransactionManager *impl_from_ITransactionDispenser(ITransactionDispenser *iface)
{
    return CONTAINING_RECORD(iface, TransactionManager, ITransactionDispenser_iface);
}

static HRESULT WINAPI TransactionDispenser_QueryInterface(ITransactionDispenser *iface, REFIID iid,
    void **ppv)
{
    TransactionManager *This = impl_from_ITransactionDispenser(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_ITransactionDispenser, iid))
    {
        *ppv = &This->ITransactionDispenser_iface;
    }
    else if (IsEqualIID(&IID_IResourceManagerFactory, iid) ||
        IsEqualIID(&IID_IResourceManagerFactory2, iid))
    {
        *ppv = &This->IResourceManagerFactory2_iface;
    }
    else if (IsEqualIID(&IID_ITransactionImportWhereabouts, iid))
    {
        *ppv = &This->ITransactionImportWhereabouts_iface;
    }
    else if (IsEqualIID(&IID_ITransactionImport, iid))
    {
        *ppv = &This->ITransactionImport_iface;
    }
    else
    {
        FIXME("(%s): not implemented\n", debugstr_guid(iid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI TransactionDispenser_AddRef(ITransactionDispenser *iface)
{
    TransactionManager *This = impl_from_ITransactionDispenser(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI TransactionDispenser_Release(ITransactionDispenser *iface)
{
    TransactionManager *This = impl_from_ITransactionDispenser(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI TransactionDispenser_GetOptionsObject(ITransactionDispenser *iface,
        ITransactionOptions **ppOptions)
{
    TRACE("(%p, %p)\n", iface, ppOptions);

    if (!ppOptions) return E_INVALIDARG;
    return TransactionOptions_Create(ppOptions);
}
static HRESULT WINAPI TransactionDispenser_BeginTransaction(ITransactionDispenser *iface,
        IUnknown *punkOuter,
        ISOLEVEL isoLevel,
        ULONG isoFlags,
        ITransactionOptions *pOptions,
        ITransaction **ppTransaction)
{
    FIXME("(%p, %p, %08x, %08x, %p, %p): semi-stub\n", iface, punkOuter,
        isoLevel, isoFlags, pOptions, ppTransaction);

    if (!ppTransaction) return E_INVALIDARG;
    if (punkOuter) return CLASS_E_NOAGGREGATION;
    return Transaction_Create(isoLevel, isoFlags, pOptions, ppTransaction);
}
static const ITransactionDispenserVtbl TransactionDispenser_Vtbl = {
    TransactionDispenser_QueryInterface,
    TransactionDispenser_AddRef,
    TransactionDispenser_Release,
    TransactionDispenser_GetOptionsObject,
    TransactionDispenser_BeginTransaction
};

static inline TransactionManager *impl_from_IResourceManagerFactory2(IResourceManagerFactory2 *iface)
{
    return CONTAINING_RECORD(iface, TransactionManager, IResourceManagerFactory2_iface);
}

static HRESULT WINAPI ResourceManagerFactory2_QueryInterface(IResourceManagerFactory2 *iface, REFIID iid,
    void **ppv)
{
    TransactionManager *This = impl_from_IResourceManagerFactory2(iface);
    return TransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, iid, ppv);
}

static ULONG WINAPI ResourceManagerFactory2_AddRef(IResourceManagerFactory2 *iface)
{
    TransactionManager *This = impl_from_IResourceManagerFactory2(iface);
    return TransactionDispenser_AddRef(&This->ITransactionDispenser_iface);
}

static ULONG WINAPI ResourceManagerFactory2_Release(IResourceManagerFactory2 *iface)
{
    TransactionManager *This = impl_from_IResourceManagerFactory2(iface);
    return TransactionDispenser_Release(&This->ITransactionDispenser_iface);
}
static HRESULT WINAPI ResourceManagerFactory2_Create(IResourceManagerFactory2 *iface,
        GUID *pguidRM, CHAR *pszRMName, IResourceManagerSink *pIResMgrSink, IResourceManager **ppResMgr)
{
    FIXME("(%p, %s, %s, %p, %p): semi-stub\n", iface, debugstr_guid(pguidRM),
        debugstr_a(pszRMName), pIResMgrSink, ppResMgr);
    return ResourceManager_Create(&IID_IResourceManager, (void**)ppResMgr);
}
static HRESULT WINAPI ResourceManagerFactory2_CreateEx(IResourceManagerFactory2 *iface,
        GUID *pguidRM, CHAR *pszRMName, IResourceManagerSink *pIResMgrSink, REFIID riidRequested, void **ppResMgr)
{
    FIXME("(%p, %s, %s, %p, %s, %p): semi-stub\n", iface, debugstr_guid(pguidRM),
        debugstr_a(pszRMName), pIResMgrSink, debugstr_guid(riidRequested), ppResMgr);

    return ResourceManager_Create(riidRequested, ppResMgr);
}
static const IResourceManagerFactory2Vtbl ResourceManagerFactory2_Vtbl = {
    ResourceManagerFactory2_QueryInterface,
    ResourceManagerFactory2_AddRef,
    ResourceManagerFactory2_Release,
    ResourceManagerFactory2_Create,
    ResourceManagerFactory2_CreateEx
};

static inline TransactionManager *impl_from_ITransactionImportWhereabouts(ITransactionImportWhereabouts *iface)
{
    return CONTAINING_RECORD(iface, TransactionManager, ITransactionImportWhereabouts_iface);
}

static HRESULT WINAPI TransactionImportWhereabouts_QueryInterface(ITransactionImportWhereabouts *iface, REFIID iid,
    void **ppv)
{
    TransactionManager *This = impl_from_ITransactionImportWhereabouts(iface);
    return TransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, iid, ppv);
}

static ULONG WINAPI TransactionImportWhereabouts_AddRef(ITransactionImportWhereabouts *iface)
{
    TransactionManager *This = impl_from_ITransactionImportWhereabouts(iface);
    return TransactionDispenser_AddRef(&This->ITransactionDispenser_iface);
}

static ULONG WINAPI TransactionImportWhereabouts_Release(ITransactionImportWhereabouts *iface)
{
    TransactionManager *This = impl_from_ITransactionImportWhereabouts(iface);
    return TransactionDispenser_Release(&This->ITransactionDispenser_iface);
}
static HRESULT WINAPI TransactionImportWhereabouts_GetWhereaboutsSize(ITransactionImportWhereabouts *iface,
        ULONG *pcbWhereabouts)
{
    FIXME("(%p, %p): stub returning fake value\n", iface, pcbWhereabouts);

    if (!pcbWhereabouts) return E_INVALIDARG;
    *pcbWhereabouts = 1;
    return S_OK;
}
static HRESULT WINAPI TransactionImportWhereabouts_GetWhereabouts(ITransactionImportWhereabouts *iface,
        ULONG cbWhereabouts, BYTE *rgbWhereabouts,ULONG *pcbUsed)
{
    FIXME("(%p, %u, %p, %p): stub returning fake value\n", iface, cbWhereabouts, rgbWhereabouts, pcbUsed);

    if (!rgbWhereabouts || !pcbUsed) return E_INVALIDARG;
    *rgbWhereabouts = 0;
    *pcbUsed = 1;
    return S_OK;
}
static const ITransactionImportWhereaboutsVtbl TransactionImportWhereabouts_Vtbl = {
    TransactionImportWhereabouts_QueryInterface,
    TransactionImportWhereabouts_AddRef,
    TransactionImportWhereabouts_Release,
    TransactionImportWhereabouts_GetWhereaboutsSize,
    TransactionImportWhereabouts_GetWhereabouts
};

static inline TransactionManager *impl_from_ITransactionImport(ITransactionImport *iface)
{
    return CONTAINING_RECORD(iface, TransactionManager, ITransactionImport_iface);
}

static HRESULT WINAPI TransactionImport_QueryInterface(ITransactionImport *iface, REFIID iid,
    void **ppv)
{
    TransactionManager *This = impl_from_ITransactionImport(iface);
    return TransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, iid, ppv);
}

static ULONG WINAPI TransactionImport_AddRef(ITransactionImport *iface)
{
    TransactionManager *This = impl_from_ITransactionImport(iface);
    return TransactionDispenser_AddRef(&This->ITransactionDispenser_iface);
}

static ULONG WINAPI TransactionImport_Release(ITransactionImport *iface)
{
    TransactionManager *This = impl_from_ITransactionImport(iface);
    return TransactionDispenser_Release(&This->ITransactionDispenser_iface);
}
static HRESULT WINAPI TransactionImport_Import(ITransactionImport *iface,
    ULONG cbTransactionCookie, byte *rgbTransactionCookie, IID *piid, void **ppvTransaction)
{
    FIXME("(%p, %u, %p, %s, %p): stub\n", iface, cbTransactionCookie, rgbTransactionCookie, debugstr_guid(piid), ppvTransaction);

    if (!rgbTransactionCookie || !piid || !ppvTransaction) return E_INVALIDARG;
    return E_NOTIMPL;
}
static const ITransactionImportVtbl TransactionImport_Vtbl = {
    TransactionImport_QueryInterface,
    TransactionImport_AddRef,
    TransactionImport_Release,
    TransactionImport_Import
};

static HRESULT TransactionManager_Create(REFIID riid, void **ppv)
{
    TransactionManager *This;
    HRESULT ret;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(TransactionManager));
    if (!This) return E_OUTOFMEMORY;

    This->ITransactionDispenser_iface.lpVtbl = &TransactionDispenser_Vtbl;
    This->IResourceManagerFactory2_iface.lpVtbl = &ResourceManagerFactory2_Vtbl;
    This->ITransactionImportWhereabouts_iface.lpVtbl = &TransactionImportWhereabouts_Vtbl;
    This->ITransactionImport_iface.lpVtbl = &TransactionImport_Vtbl;
    This->ref = 1;

    ret = ITransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, riid, ppv);
    ITransactionDispenser_Release(&This->ITransactionDispenser_iface);

    return ret;
}
/* DTC Proxy Core Object end */

BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
    TRACE("%p, %u, %p\n", hinst, reason, reserved);

    switch (reason)
    {
        case DLL_WINE_PREATTACH:
            return FALSE;    /* prefer native version */
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls( hinst );
            break;
    }
    return TRUE;
}

static BOOL is_local_machineA( const CHAR *server )
{
    static const CHAR dot[] = ".";
    CHAR buffer[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD len = sizeof(buffer) / sizeof(buffer[0]);

    if (!server || !strcmp( server, dot )) return TRUE;
    if (GetComputerNameA( buffer, &len ) && !lstrcmpiA( server, buffer )) return TRUE;
    return FALSE;
}
static BOOL is_local_machineW( const WCHAR *server )
{
    static const WCHAR dotW[] = {'.',0};
    WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD len = sizeof(buffer) / sizeof(buffer[0]);

    if (!server || !strcmpW( server, dotW )) return TRUE;
    if (GetComputerNameW( buffer, &len ) && !strcmpiW( server, buffer )) return TRUE;
    return FALSE;
}

HRESULT CDECL DtcGetTransactionManager(char *host, char *tm_name, REFIID riid,
        DWORD dwReserved1, WORD wcbReserved2, void *pvReserved2, void **ppv)
{
    TRACE("(%s, %s, %s, %d, %d, %p, %p)\n", debugstr_a(host), debugstr_a(tm_name),
          debugstr_guid(riid), dwReserved1, wcbReserved2, pvReserved2, ppv);

    if (!is_local_machineA(host))
    {
        FIXME("remote computer not supported\n");
        return E_NOTIMPL;
    }
    return TransactionManager_Create(riid, ppv);
}

HRESULT CDECL DtcGetTransactionManagerExA(CHAR *host, CHAR *tm_name, REFIID riid,
        DWORD options, void *config, void **ppv)
{
    TRACE("(%s, %s, %s, %d, %p, %p)\n", debugstr_a(host), debugstr_a(tm_name),
          debugstr_guid(riid), options, config, ppv);

    if (!is_local_machineA(host))
    {
        FIXME("remote computer not supported\n");
        return E_NOTIMPL;
    }
    return TransactionManager_Create(riid, ppv);
}

HRESULT CDECL DtcGetTransactionManagerExW(WCHAR *host, WCHAR *tm_name, REFIID riid,
        DWORD options, void *config, void **ppv)
{
    TRACE("(%s, %s, %s, %d, %p, %p)\n", debugstr_w(host), debugstr_w(tm_name),
            debugstr_guid(riid), options, config, ppv);

    if (!is_local_machineW(host))
    {
        FIXME("remote computer not supported\n");
        return E_NOTIMPL;
    }
    return TransactionManager_Create(riid, ppv);
}
