/*
 * Copyright (C) 2007 Francois Gouget
 * Copyright (C) 2008 Alistair Leslie-Hughes
 *
 * 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("/* FIXME: #include <gcghost.h> */")
cpp_quote("/* FIXME: #include <ivalidator.h> */")

cpp_quote("HRESULT     WINAPI CorBindToRuntimeHost(LPCWSTR,LPCWSTR,LPCWSTR,VOID*,DWORD,REFCLSID,REFIID,LPVOID*);")
cpp_quote("void        WINAPI CorExitProcess(int);")
cpp_quote("HRESULT     WINAPI GetCORSystemDirectory(LPWSTR,DWORD,DWORD*);")
cpp_quote("HRESULT     WINAPI GetCORVersion(LPWSTR,DWORD,DWORD*);")
cpp_quote("HRESULT     WINAPI GetRequestedRuntimeInfo(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,DWORD,LPWSTR,DWORD,DWORD*,LPWSTR,DWORD,DWORD*);")
cpp_quote("HRESULT     WINAPI LoadLibraryShim(LPCWSTR,LPCWSTR,LPVOID,HMODULE*);")
cpp_quote("#ifdef WINE_STRICT_PROTOTYPES")
cpp_quote("typedef HRESULT (__stdcall *FLockClrVersionCallback)(void);")
cpp_quote("#else")
cpp_quote("typedef HRESULT (__stdcall *FLockClrVersionCallback)();")
cpp_quote("#endif")
cpp_quote("HRESULT     WINAPI LockClrVersion(FLockClrVersionCallback,FLockClrVersionCallback*,FLockClrVersionCallback*);")

typedef void* HDOMAINENUM;

typedef enum RUNTIME_INFO_FLAGS {
    RUNTIME_INFO_UPGRADE_VERSION = 0x1,
    RUNTIME_INFO_REQUEST_IA64 = 0x2,
    RUNTIME_INFO_REQUEST_AMD64 = 0x4,
    RUNTIME_INFO_REQUEST_X86 = 0x8,
    RUNTIME_INFO_DONT_RETURN_DIRECTORY = 0x10,
    RUNTIME_INFO_DONT_RETURN_VERSION = 0x20,
    RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG = 0x40
} RUNTIME_INFO_FLAGS;

typedef HRESULT (__stdcall *FExecuteInAppDomainCallback)([in] void* cookie);

[
    uuid(F31D1788-C397-4725-87A5-6AF3472C2791),
    version(1.0),
    object,
    local
]
interface IGCThreadControl : IUnknown
{
    HRESULT ThreadIsBlockingForSuspension();

    HRESULT SuspensionStarting();

    HRESULT SuspensionEnding(DWORD generation);
}

[
    uuid(5513D564-8374-4cb9-AED9-0083F4160A1D),
    version(1.1),
    local,
    object
]
interface IGCHostControl : IUnknown
{
    HRESULT RequestVirtualMemLimit([in] SIZE_T nMaxVirtualMemMB,
                                   [in, out] SIZE_T* nNewMaxVirtualMemMB);
}

[
    uuid(23D86786-0BB5-4774-8FB5-E3522ADD6246),
    version(1.0),
    local,
    object
]
interface IDebuggerThreadControl : IUnknown
{
    HRESULT ThreadIsBlockingForDebugger();

    HRESULT ReleaseAllRuntimeThreads();

    HRESULT StartBlockingForDebugger(DWORD dwUnused);
}

[
    uuid(5C2B07A5-1E98-11d3-872F-00C04F79ED0D),
    version(1.0),
    local,
    object
]
interface ICorConfiguration : IUnknown
{
    HRESULT SetGCThreadControl([in] IGCThreadControl* GCThreadControl);

    HRESULT SetGCHostControl([in] IGCHostControl* GCHostControl);

    HRESULT SetDebuggerThreadControl([in] IDebuggerThreadControl* debuggerThreadControl);

    HRESULT AddDebuggerSpecialThread([in] DWORD specialThreadId);
}

[
    uuid(9065597E-D1A1-4fb2-B6BA-7E1FCE230F61),
    version(1.0),
    local
]
interface ICLRControl : IUnknown
{
    HRESULT GetCLRManager([in] REFIID riid, [out] void **ppObject);

        HRESULT SetAppDomainManagerType([in] LPCWSTR appDomainManagerAssembly,
                          [in] LPCWSTR appDomainManagerType);
}

[
    uuid(02CA073C-7079-4860-880A-C2F7A449C991),
    version(1.0),
    local
]
interface IHostControl : IUnknown
{
    HRESULT GetHostManager( [in] REFIID riid, [out] void **ppObject);

    HRESULT SetAppDomainManager([in] DWORD appDomainID,
                            [in] IUnknown* appDomainManager);
}

cpp_quote("DEFINE_GUID(CLSID_CorRuntimeHost, 0xcb2f6723,0xab3a,0x11d2,0x9c,0x40,0x00,0xc0,0x4f,0xa3,0x0a,0x3e);")

[
    uuid(CB2F6722-AB3A-11d2-9C40-00C04FA30A3E),
    version(1.0),
    local,
    object
]
interface ICorRuntimeHost : IUnknown
{
    HRESULT CreateLogicalThreadState();
    HRESULT DeleteLogicalThreadState();
    HRESULT SwitchInLogicalThreadState([in] DWORD *fiberCookie);

    HRESULT SwitchOutLogicalThreadState([out] DWORD **fiberCookie);

    HRESULT LocksHeldByLogicalThread( [out] DWORD *pCount );

    HRESULT MapFile([in] HANDLE hFile, [out] HMODULE* mapAddress);

    HRESULT GetConfiguration([out] ICorConfiguration** pConfiguration);

    HRESULT Start();

    HRESULT Stop();

    HRESULT CreateDomain([in] LPCWSTR friendlyName,
                         [in] IUnknown* identityArray,
                         [out] IUnknown** appDomain);

    HRESULT GetDefaultDomain([out] IUnknown** pAppDomain);

    HRESULT EnumDomains([out] HDOMAINENUM *hEnum);

    HRESULT NextDomain([in] HDOMAINENUM hEnum, [out] IUnknown** appDomain);

    HRESULT CloseEnum([in] HDOMAINENUM hEnum);

    HRESULT CreateDomainEx([in] LPCWSTR friendlyName,
                           [in] IUnknown* setup,
                           [in] IUnknown* evidence,
                           [out] IUnknown** appDomain);

    HRESULT CreateDomainSetup([out] IUnknown** appDomainSetup);

    HRESULT CreateEvidence([out] IUnknown** evidence);

    HRESULT UnloadDomain([in] IUnknown* appDomain);

    HRESULT CurrentDomain([out] IUnknown** appDomain);
}

cpp_quote("DEFINE_GUID(CLSID_CLRRuntimeHost, 0x90f1a06e,0x7712,0x4762,0x86,0xb5,0x7a,0x5e,0xba,0x6b,0xdb,0x02);")

[
    uuid(90f1a06c-7712-4762-86b5-7a5eba6bdb02),
    local,
    object
]
interface ICLRRuntimeHost : IUnknown
{
    HRESULT Start();

    HRESULT Stop();

    HRESULT SetHostControl([in] IHostControl *pHostControl);

    HRESULT GetCLRControl([out] ICLRControl **pCLRControl);

    HRESULT UnloadAppDomain([in] DWORD dwAppDomainId,
                            [in] BOOL fWaitUntilDone);

    HRESULT ExecuteInAppDomain([in] DWORD dwAppDomainId,
                               [in] FExecuteInAppDomainCallback pCallback,
                               [in] void *cookie);

    HRESULT GetCurrentAppDomainId([out] DWORD *pdwAppDomainId);

    HRESULT ExecuteApplication([in] LPCWSTR pwzAppFullName,
                               [in] DWORD dwManifestPaths,
                               [in] LPCWSTR *ppwzManifestPaths,
                               [in] DWORD dwActivationData,
                               [in] LPCWSTR *ppwzActivationData,
                               [out] int *pReturnValue);

    HRESULT ExecuteInDefaultAppDomain([in] LPCWSTR pwzAssemblyPath,
                                      [in] LPCWSTR pwzTypeName,
                                      [in] LPCWSTR pwzMethodName,
                                      [in] LPCWSTR pwzArgument,
                                      [out] DWORD *pReturnValue);
}

[
    uuid(C3FCC19E-A970-11d2-8B5A-00A0C9B7C9C4),
    local,
    object
]
interface IManagedObject : IUnknown
{
    HRESULT GetSerializedBuffer([out] BSTR *pBSTR);

    HRESULT GetObjectIdentity([out] BSTR *pBSTRGUID,
                              [out] int *AppDomainID,
                             [out] int *pCCW);
}
