/*
 * 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("#ifndef WINE_NO_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);
}
