/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the w64 mingw-runtime package.
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 */

#ifndef DO_NO_IMPORTS
import "wtypes.idl";
#endif

cpp_quote("#if defined(__cplusplus) && !defined(CINTERFACE) && !defined(__IUnknown_INTERFACE_DEFINED__)")
cpp_quote("#define __IUnknown_INTERFACE_DEFINED__")
cpp_quote("  typedef IUnknown *LPUNKNOWN;")
cpp_quote("  EXTERN_C const IID IID_IUnknown;")
cpp_quote("  extern \"C++\" {")
cpp_quote("    struct IUnknown {")
cpp_quote("    public:")
cpp_quote("      BEGIN_INTERFACE")
cpp_quote("	virtual HRESULT WINAPI QueryInterface(REFIID riid,void **ppvObject) = 0;")
cpp_quote("	virtual ULONG WINAPI AddRef(void) = 0;")
cpp_quote("	virtual ULONG WINAPI Release(void) = 0;")
cpp_quote("#ifndef __STRICT_ANSI__")
cpp_quote("	template<class Q> HRESULT WINAPI QueryInterface(Q **pp) { return QueryInterface(__uuidof(*pp),(void **)pp); }")
cpp_quote("#endif")
cpp_quote("      END_INTERFACE")
cpp_quote("    };")
cpp_quote("  }")
cpp_quote("  HRESULT WINAPI IUnknown_QueryInterface_Proxy(IUnknown *This,REFIID riid,void **ppvObject);")
cpp_quote("  void __RPC_STUB IUnknown_QueryInterface_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);")
cpp_quote("  ULONG WINAPI IUnknown_AddRef_Proxy(IUnknown *This);")
cpp_quote("  void __RPC_STUB IUnknown_AddRef_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);")
cpp_quote("  ULONG WINAPI IUnknown_Release_Proxy(IUnknown *This);")
cpp_quote("  void __RPC_STUB IUnknown_Release_Stub(IRpcStubBuffer *This,IRpcChannelBuffer *_pRpcChannelBuffer,PRPC_MESSAGE _pRpcMessage,DWORD *_pdwStubPhase);")
cpp_quote("__CRT_UUID_DECL(IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46)")
cpp_quote("#else")

[
  local,
  object,
  uuid(00000000-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IUnknown
{
    typedef [unique] IUnknown *LPUNKNOWN;

    HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject);
    ULONG AddRef();
    ULONG Release();
}

cpp_quote("#endif")

[
  local,
  object,
  uuid(000e0000-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface AsyncIUnknown : IUnknown
{
    HRESULT Begin_QueryInterface([in] REFIID riid);
    HRESULT Finish_QueryInterface([out] void **ppvObject);
    HRESULT Begin_AddRef();
    ULONG Finish_AddRef();
    HRESULT Begin_Release();
    ULONG Finish_Release();
}

[
  object,
  uuid(00000001-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IClassFactory : IUnknown
{
    typedef [unique] IClassFactory *LPCLASSFACTORY;

    [local]
    HRESULT CreateInstance(
            [in, unique] IUnknown *pUnkOuter,
            [in] REFIID riid,
            [out, iid_is(riid)] void **ppvObject);

    [call_as(CreateInstance)]
    HRESULT RemoteCreateInstance(
            [in] REFIID riid,
            [out, iid_is(riid)] IUnknown **ppvObject);

    [local] HRESULT LockServer([in] BOOL fLock);
    [call_as(LockServer)] HRESULT RemoteLockServer([in] BOOL fLock);
}
