/*
 * Copyright 2002 Ove Kaaven
 *
 * 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
 */

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

interface IStream;
interface IEnumString;
interface IRunningObjectTable;
interface IMoniker;
interface IAdviseSink;
interface IAsyncManager;
interface ISynchronize;

typedef struct _COSERVERINFO {
  DWORD dwReserved1;
  LPWSTR pwszName;
  COAUTHINFO *pAuthInfo;
  DWORD dwReserved2;
} COSERVERINFO;

/******************** Fundamentals ********************/

[
  local,
  object,
  uuid(00000003-0000-0000-C000-000000000046)
]
interface IMarshal : IUnknown
{
  typedef [unique] IMarshal *LPMARSHAL;

  HRESULT GetUnmarshalClass(
    [in] REFIID riid,
    [in, unique] void *pv,
    [in] DWORD dwDestContext,
    [in, unique] void *pvDestContext,
    [in] DWORD mshlflags,
    [out] CLSID *pCid);

  HRESULT GetMarshalSizeMax(
    [in] REFIID riid,
    [in, unique] void *pv,
    [in] DWORD dwDestContext,
    [in, unique] void *pvDestContext,
    [in] DWORD mshlflags,
    [out] DWORD *pSize);

  HRESULT MarshalInterface(
    [in, unique] IStream *pStm,
    [in] REFIID riid,
    [in, unique] void *pv,
    [in] DWORD dwDestContext,
    [in, unique] void *pvDestContext,
    [in] DWORD mshlflags);

  HRESULT UnmarshalInterface(
    [in, unique] IStream *pStm,
    [in] REFIID riid,
    [out] void **ppv);

  HRESULT ReleaseMarshalData(
    [in, unique] IStream *pStm);

  HRESULT DisconnectObject(
    [in] DWORD dwReserved);
}

[
    local,
    object,
    uuid(000001cf-0000-0000-C000-000000000046)
]
interface IMarshal2 : IMarshal
{
    typedef [unique] IMarshal2 *LPMARSHAL2;
}

[
  local,
  object,
  uuid(00000018-0000-0000-C000-000000000046)
]
interface IStdMarshalInfo : IUnknown
{
  typedef [unique] IStdMarshalInfo *LPSTDMARSHALINFO;

  HRESULT GetClassForHandler(
    [in] DWORD dwDestContext,
    [in, unique] void *pvDestContext,
    [out] CLSID *pClsid);
}

[
  local,
  object,
  uuid(00000019-0000-0000-C000-000000000046)
]
interface IExternalConnection : IUnknown
{
  typedef [unique] IExternalConnection *LPEXTERNALCONNECTION;

  typedef enum tagEXTCONN {
    EXTCONN_STRONG   = 0x0001,
    EXTCONN_WEAK     = 0x0002,
    EXTCONN_CALLABLE = 0x0004
  } EXTCONN;

  DWORD AddConnection(
    [in] DWORD extconn,
    [in] DWORD reserved);

  DWORD ReleaseConnection(
    [in] DWORD extconn,
    [in] DWORD reserved,
    [in] BOOL fLastReleaseCloses);
}

[
  local,
  object,
  uuid(00000020-0000-0000-C000-000000000046)
]
interface IMultiQI : IUnknown
{
  typedef [unique] IMultiQI *LPMULTIQI;

  typedef struct tagMULTI_QI {
    const IID *pIID;
    IUnknown *pItf;
    HRESULT hr;
  } MULTI_QI;

  HRESULT QueryMultipleInterfaces(
    [in] ULONG cMQIs,
    [in, out] MULTI_QI *pMQIs);
}

[
  local,
  object,
  uuid(00000002-0000-0000-C000-000000000046)
]
interface IMalloc : IUnknown
{
  typedef [unique] IMalloc *LPMALLOC;

  LPVOID Alloc(
    [in] SIZE_T cb);

  LPVOID Realloc(
    [in] LPVOID pv,
    [in] SIZE_T cb);

  void Free(
    [in] LPVOID pv);

  SIZE_T GetSize(
    [in] LPVOID pv);

  int DidAlloc(LPVOID pv);

  void HeapMinimize();
}

[
  local,
  object,
  uuid(0000001d-0000-0000-C000-000000000046)
]
interface IMallocSpy : IUnknown
{
  typedef [unique] IMallocSpy *LPMALLOCSPY;

  SIZE_T PreAlloc(
    [in] SIZE_T cbRequest);

  LPVOID PostAlloc(
    [in] LPVOID pActual);

  LPVOID PreFree(
    [in] LPVOID pRequest,
    [in] BOOL fSpyed);

  void PostFree(
    [in] BOOL fSpyed);

  SIZE_T PreRealloc(
    [in] LPVOID pRequest,
    [in] SIZE_T cbRequest,
    [out] LPVOID *ppNewRequest,
    [in] BOOL fSpyed);

  LPVOID PostRealloc(
    [in] LPVOID pActual,
    [in] BOOL fSpyed);

  LPVOID PreGetSize(
    [in] LPVOID pRequest,
    [in] BOOL fSpyed);

  SIZE_T PostGetSize(
    [in] SIZE_T cbActual,
    [in] BOOL fSpyed);

  LPVOID PreDidAlloc(
    [in] LPVOID pRequest,
    [in] BOOL fSpyed);

  int PostDidAlloc(
    [in] LPVOID pRequest,
    [in] BOOL fSpyed,
    [in] int fActual);

  void PreHeapMinimize();

  void PostHeapMinimize();
}

[
  local,
  object,
  uuid(00000021-0000-0000-C000-000000000046)
]
interface IInternalUnknown : IUnknown
{
  HRESULT QueryInternalInterface(
    [in] REFIID riid,
    [out] void **ppv);
}

[
  object,
  uuid(00000100-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IEnumUnknown : IUnknown
{
  typedef [unique] IEnumUnknown *LPENUMUNKNOWN;

  [local]
  HRESULT Next(
    [in] ULONG celt,
    [out] IUnknown **rgelt,
    [out] ULONG *pceltFetched);

  [call_as(Next)]
  HRESULT RemoteNext(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    IUnknown **rgelt,
    [out] ULONG *pceltFetched);

  HRESULT Skip(
    [in] ULONG celt);

  HRESULT Reset();

  HRESULT Clone(
    [out] IEnumUnknown **ppenum);
}

[
  object,
  uuid(00000022-0000-0000-C000-000000000046),
  version(1.0),
  pointer_default(unique)
]
interface ISurrogate : IUnknown
{
  typedef [unique] ISurrogate *LPSURROGATE;

  HRESULT LoadDllServer(
    [in] REFCLSID Clsid);
  HRESULT FreeSurrogate();
}

[
  local,
  object,
  uuid(00000146-0000-0000-C000-000000000046)
]
interface IGlobalInterfaceTable : IUnknown
{
  typedef [unique] IGlobalInterfaceTable *LPGLOBALINTERFACETABLE;

  HRESULT RegisterInterfaceInGlobal(
    [in] IUnknown *pUnk,
    [in] REFIID riid,
    [out] DWORD *pdwCookie);

  HRESULT RevokeInterfaceFromGlobal(
    [in] DWORD dwCookie);

  HRESULT GetInterfaceFromGlobal(
    [in] DWORD dwCookie,
    [in] REFIID riid,
    [out, iid_is(riid)] void **ppv);
}

/******************** Monikers ********************/

[
  object,
  uuid(0000000e-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IBindCtx : IUnknown
{
  typedef [unique] IBindCtx *LPBINDCTX;
  typedef [unique] IBindCtx *LPBC;

  typedef struct tagBIND_OPTS {
    DWORD cbStruct;
    DWORD grfFlags;
    DWORD grfMode;
    DWORD dwTickCountDeadline;
  } BIND_OPTS, *LPBIND_OPTS;

  /* FIXME: C++ crap */
  typedef struct tagBIND_OPTS2 {
    DWORD cbStruct;
    DWORD grfFlags;
    DWORD grfMode;
    DWORD dwTickCountDeadline;
    DWORD dwTrackFlags;
    DWORD dwClassContext;
    LCID  locale;
    COSERVERINFO *pServerInfo;
  } BIND_OPTS2, *LPBIND_OPTS2;

  typedef struct tagBIND_OPTS3 {
    DWORD cbStruct;
    DWORD grfFlags;
    DWORD grfMode;
    DWORD dwTickCountDeadline;
    DWORD dwTrackFlags;
    DWORD dwClassContext;
    LCID  locale;
    COSERVERINFO *pServerInfo;
    HWND hwnd;
  } BIND_OPTS3, *LPBIND_OPTS3;

  typedef enum tagBIND_FLAGS {
    BIND_MAYBOTHERUSER   = 1,
    BIND_JUSTTESTEXISTENCE = 2
  } BIND_FLAGS;

  HRESULT RegisterObjectBound(
    [in, unique] IUnknown *punk);

  HRESULT RevokeObjectBound(
    [in, unique] IUnknown *punk);

  HRESULT ReleaseBoundObjects();

  [local]
  HRESULT SetBindOptions(
    [in] BIND_OPTS *pbindopts);

  [call_as(SetBindOptions)]
  HRESULT RemoteSetBindOptions(
    [in] BIND_OPTS2 *pbindopts);

  [local]
  HRESULT GetBindOptions(
    [in, out] BIND_OPTS *pbindopts);

  [call_as(GetBindOptions)]
  HRESULT RemoteGetBindOptions(
    [in, out] BIND_OPTS2 *pbindopts);

  HRESULT GetRunningObjectTable(
    [out] IRunningObjectTable **pprot);

  HRESULT RegisterObjectParam(
    [in] LPOLESTR pszKey,
    [in, unique] IUnknown *punk);

  HRESULT GetObjectParam(
    [in] LPOLESTR pszKey,
    [out] IUnknown **ppunk);

  HRESULT EnumObjectParam(
    [out] IEnumString **ppenum);

  HRESULT RevokeObjectParam(
    [in] LPOLESTR pszKey);
}

[
  object,
  uuid(00000102-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IEnumMoniker : IUnknown
{
  typedef [unique] IEnumMoniker *LPENUMMONIKER;

  [local]
  HRESULT Next(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    IMoniker **rgelt,
    [out] ULONG *pceltFetched);

  [call_as(Next)]
  HRESULT RemoteNext(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    IMoniker **rgelt,
    [out] ULONG *pceltFetched);

  HRESULT Skip(
    [in] ULONG celt);

  HRESULT Reset();

  HRESULT Clone(
    [out] IEnumMoniker **ppenum);
}

[
  object,
  uuid(00000126-0000-0000-C000-000000000046)
]
interface IRunnableObject : IUnknown
{
  typedef [unique] IRunnableObject *LPRUNNABLEOBJECT;

  HRESULT GetRunningClass(
    [out] LPCLSID lpClsid);

  HRESULT Run(
    [in] LPBINDCTX pbc);

  [local]
  BOOL IsRunning();

  [call_as(IsRunning)]
  HRESULT RemoteIsRunning();

  HRESULT LockRunning(
    [in] BOOL fLock,
    [in] BOOL fLastUnlockCloses);

  HRESULT SetContainedObject(
    [in] BOOL fContained);
}

/* GetObject is defined in wingdi.h as WINELIB_NAME_AW(GetObject),
 * which resolves to a compilation failure if WINE_NO_UNICODE_MACROS is defined,
 * but GetObject is used as a valid method name below, so we have
 * to undefine it in that case */
cpp_quote("#ifdef WINE_NO_UNICODE_MACROS")
cpp_quote("#undef GetObject")
cpp_quote("#endif")

[
  object,
  uuid(00000010-0000-0000-C000-000000000046)
]
interface IRunningObjectTable : IUnknown
{
  typedef [unique] IRunningObjectTable *LPRUNNINGOBJECTTABLE;

  HRESULT Register(
    [in] DWORD grfFlags,
    [in, unique] IUnknown *punkObject,
    [in, unique] IMoniker *pmkObjectName,
    [out] DWORD *pdwRegister);

  HRESULT Revoke(
    [in] DWORD dwRegister);

  HRESULT IsRunning(
    [in, unique] IMoniker *pmkObjectName);

  HRESULT GetObject(
    [in, unique] IMoniker *pmkObjectName,
    [out] IUnknown **ppunkObject);

  HRESULT NoteChangeTime(
    [in] DWORD dwRegister,
    [in] FILETIME *pfiletime);

  HRESULT GetTimeOfLastChange(
    [in, unique] IMoniker *pmkObjectName,
    [out] FILETIME *pfiletime);

  HRESULT EnumRunning(
    [out] IEnumMoniker **ppenumMoniker);
}

[
  object,
  uuid(0000010c-0000-0000-C000-000000000046)
]
interface IPersist : IUnknown
{
  typedef [unique] IPersist *LPPERSIST;

  HRESULT GetClassID(
    [out] CLSID *pClassID);
}

[
  object,
  uuid(00000109-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IPersistStream : IPersist
{
  typedef [unique] IPersistStream *LPPERSISTSTREAM;

  HRESULT IsDirty();

  HRESULT Load(
    [in, unique] IStream *pStm);

  HRESULT Save(
    [in, unique] IStream *pStm,
    [in] BOOL fClearDirty);

  HRESULT GetSizeMax(
    [out] ULARGE_INTEGER *pcbSize);
}

[
  object,
  uuid(0000000f-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IMoniker : IPersistStream
{
  typedef [unique] IMoniker *LPMONIKER;

  typedef enum tagMKSYS {
    MKSYS_NONE             = 0,
    MKSYS_GENERICCOMPOSITE = 1,
    MKSYS_FILEMONIKER      = 2,
    MKSYS_ANTIMONIKER      = 3,
    MKSYS_ITEMMONIKER      = 4,
    MKSYS_POINTERMONIKER   = 5,
    /* MKSYS_URLMONIKER       = 6, */ /* defined in urlmon.idl */
    MKSYS_CLASSMONIKER     = 7
  } MKSYS;

  typedef [v1_enum] enum tagMKREDUCE {
    MKRREDUCE_ONE         = 3 << 16,
    MKRREDUCE_TOUSER      = 2 << 16,
    MKRREDUCE_THROUGHUSER = 1 << 16,
    MKRREDUCE_ALL         = 0
  } MKRREDUCE;

  [local]
  HRESULT BindToObject(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [in] REFIID riidResult,
    [out, iid_is(riidResult)] void **ppvResult);

  [call_as(BindToObject)]
  HRESULT RemoteBindToObject(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [in] REFIID riidResult,
    [out, iid_is(riidResult)] IUnknown **ppvResult);

  [local]
  HRESULT BindToStorage(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [in] REFIID riid,
    [out, iid_is(riid)] void **ppvObj);

  [call_as(BindToStorage)]
  HRESULT RemoteBindToStorage(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [in] REFIID riid,
    [out, iid_is(riid)] IUnknown **ppvObj);

  HRESULT Reduce(
    [in, unique] IBindCtx *pbc,
    [in] DWORD dwReduceHowFar,
    [in, out, unique] IMoniker **ppmkToLeft,
    [out] IMoniker **ppmkReduced);

  HRESULT ComposeWith(
    [in, unique] IMoniker *pmkRight,
    [in] BOOL fOnlyIfNotGeneric,
    [out] IMoniker **ppmkComposite);

  HRESULT Enum(
    [in] BOOL fForward,
    [out] IEnumMoniker **ppenumMoniker);

  HRESULT IsEqual(
    [in, unique] IMoniker *pmkOtherMoniker);

  HRESULT Hash(
    [out] DWORD *pdwHash);

  HRESULT IsRunning(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [in, unique] IMoniker *pmkNewlyRunning);

  HRESULT GetTimeOfLastChange(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [out] FILETIME *pFileTime);

  HRESULT Inverse(
    [out] IMoniker **ppmk);

  HRESULT CommonPrefixWith(
    [in, unique] IMoniker *pmkOther,
    [out] IMoniker **ppmkPrefix);

  HRESULT RelativePathTo(
    [in, unique] IMoniker *pmkOther,
    [out] IMoniker **ppmkRelPath);

  HRESULT GetDisplayName(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [out] LPOLESTR *ppszDisplayName);

  HRESULT ParseDisplayName(
    [in, unique] IBindCtx *pbc,
    [in, unique] IMoniker *pmkToLeft,
    [in] LPOLESTR pszDisplayName,
    [out] ULONG *pchEaten,
    [out] IMoniker **ppmkOut);

  HRESULT IsSystemMoniker(
    [out] DWORD *pdwMksys);
}

[
  object,
  uuid(f29f6bc0-5021-11ce-aa15-00006901293f),
  pointer_default(unique)
]
interface IROTData : IUnknown
{
  HRESULT GetComparisonData(
    [out, size_is(cbMax)] byte *pbData,
    [in] ULONG cbMax,
    [out] ULONG *pcbData);
}

[
  object,
  uuid(00000101-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IEnumString : IUnknown
{
  typedef [unique] IEnumString *LPENUMSTRING;

  [local]
  HRESULT Next(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    LPOLESTR *rgelt,
    [out] ULONG *pceltFetched);

  [call_as(Next)]
  HRESULT RemoteNext(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    LPOLESTR *rgelt,
    [out] ULONG *pceltFetched);

  HRESULT Skip(
    [in] ULONG celt);

  HRESULT Reset();

  HRESULT Clone(
    [out] IEnumString **ppenum);
}

[
  object,
  uuid(00000140-0000-0000-C000-000000000046)
]
interface IClassActivator : IUnknown
{
  HRESULT GetClassObject(
    [in] REFCLSID rclsid,
    [in] DWORD dwClassContext,
    [in] LCID locale,
    [in] REFIID riid,
    [out, iid_is(riid)] void **ppv);
}

/******************** Storage ********************/

[
  object,
  uuid(0c733a30-2a1c-11ce-ade5-00aa0044773d),
  pointer_default(unique)
]
interface ISequentialStream : IUnknown
{
  [local]
  HRESULT Read(
    [out, size_is(cb), length_is(*pcbRead)]
    void *pv,
    [in] ULONG cb,
    [out] ULONG *pcbRead);

  [call_as(Read)]
  HRESULT RemoteRead(
    [out, size_is(cb), length_is(*pcbRead)]
    byte *pv,
    [in] ULONG cb,
    [out] ULONG *pcbRead);

  [local]
  HRESULT Write(
    [in, size_is(cb)] const void *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);

  [call_as(Write)]
  HRESULT RemoteWrite(
    [in, size_is(cb)] const byte *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);
}

[
  object,
  uuid(0000000c-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IStream : ISequentialStream
{
  typedef [unique] IStream *LPSTREAM;

  typedef struct tagSTATSTG {
    LPOLESTR pwcsName;
    DWORD type;
    ULARGE_INTEGER cbSize;
    FILETIME mtime;
    FILETIME ctime;
    FILETIME atime;
    DWORD grfMode;
    DWORD grfLocksSupported;
    CLSID clsid;
    DWORD grfStateBits;
    DWORD reserved;
  } STATSTG;

  typedef enum tagSTGTY {
    STGTY_STORAGE   = 1,
    STGTY_STREAM    = 2,
    STGTY_LOCKBYTES = 3,
    STGTY_PROPERTY  = 4
  } STGTY;

  typedef enum tagSTREAM_SEEK {
    STREAM_SEEK_SET = 0,
    STREAM_SEEK_CUR = 1,
    STREAM_SEEK_END = 2
  } STREAM_SEEK;

  /* these are defined in Linux's fcntl.h,
   * undefine them to avoid conflicts */
  cpp_quote("#undef LOCK_MAND")
  cpp_quote("#undef LOCK_READ")
  cpp_quote("#undef LOCK_WRITE")
  cpp_quote("#undef LOCK_RW")

  typedef enum tagLOCKTYPE {
    LOCK_WRITE      = 1,
    LOCK_EXCLUSIVE  = 2,
    LOCK_ONLYONCE   = 4
  } LOCKTYPE;

  [local]
  HRESULT Seek(
    [in] LARGE_INTEGER dlibMove,
    [in] DWORD dwOrigin,
    [out] ULARGE_INTEGER *plibNewPosition);

  [call_as(Seek)]
  HRESULT RemoteSeek(
    [in] LARGE_INTEGER dlibMove,
    [in] DWORD dwOrigin,
    [out] ULARGE_INTEGER *plibNewPosition);

  HRESULT SetSize(
    [in] ULARGE_INTEGER libNewSize);

  [local]
  HRESULT CopyTo(
    [in, unique] IStream *pstm,
    [in] ULARGE_INTEGER cb,
    [out] ULARGE_INTEGER *pcbRead,
    [out] ULARGE_INTEGER *pcbWritten);

  [call_as(CopyTo)]
  HRESULT RemoteCopyTo(
    [in, unique] IStream *pstm,
    [in] ULARGE_INTEGER cb,
    [out] ULARGE_INTEGER *pcbRead,
    [out] ULARGE_INTEGER *pcbWritten);

  HRESULT Commit(
    [in] DWORD grfCommitFlags);

  HRESULT Revert();

  HRESULT LockRegion(
    [in] ULARGE_INTEGER libOffset,
    [in] ULARGE_INTEGER cb,
    [in] DWORD dwLockType);

  HRESULT UnlockRegion(
    [in] ULARGE_INTEGER libOffset,
    [in] ULARGE_INTEGER cb,
    [in] DWORD dwLockType);

  HRESULT Stat(
    [out] STATSTG *pstatstg,
    [in] DWORD grfStatFlag);

  HRESULT Clone(
    [out] IStream **ppstm);
}

[
  object,
  uuid(0000000d-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IEnumSTATSTG : IUnknown
{
  typedef [unique] IEnumSTATSTG *LPENUMSTATSTG;

  [local]
  HRESULT Next(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    STATSTG *rgelt,
    [out] ULONG *pceltFetched);

  [call_as(Next)]
  HRESULT RemoteNext(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    STATSTG *rgelt,
    [out] ULONG *pceltFetched);

  HRESULT Skip(
    [in] ULONG celt);

  HRESULT Reset();

  HRESULT Clone(
    [out] IEnumSTATSTG **ppenum);
}

[
  object,
  uuid(0000000b-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IStorage : IUnknown
{
  typedef [unique] IStorage *LPSTORAGE;

  typedef struct tagRemSNB {
    unsigned long ulCntStr;
    unsigned long ulCntChar;
    [size_is(ulCntChar)] OLECHAR rgString[];
  } RemSNB;

  typedef [unique] RemSNB *wireSNB;
  typedef [wire_marshal(wireSNB)] OLECHAR **SNB;

  HRESULT CreateStream(
    [in] LPCOLESTR pwcsName,
    [in] DWORD grfMode,
    [in] DWORD reserved1,
    [in] DWORD reserved2,
    [out] IStream **ppstm);

  [local]
  HRESULT OpenStream(
    [in] LPCOLESTR pwcsName,
    [in, unique] void *reserved1,
    [in] DWORD grfMode,
    [in] DWORD reserved2,
    [out] IStream **ppstm);

  [call_as(OpenStream)]
  HRESULT RemoteOpenStream(
    [in] LPCOLESTR pwcsName,
    [in] unsigned long cbReserved1,
    [in, unique, size_is(cbReserved1)] byte *reserved1,
    [in] DWORD grfMode,
    [in] DWORD reserved2,
    [out] IStream **ppstm);

  HRESULT CreateStorage(
    [in] LPCOLESTR pwcsName,
    [in] DWORD grfMode,
    [in] DWORD dwStgFmt,
    [in] DWORD reserved2,
    [out] IStorage **ppstg);

  HRESULT OpenStorage(
    [in, unique] LPCOLESTR pwcsName,
    [in, unique] IStorage *pstgPriority,
    [in] DWORD grfMode,
    [in, unique] SNB snbExclude,
    [in] DWORD reserved,
    [out] IStorage **ppstg);

  HRESULT CopyTo(
    [in] DWORD ciidExclude,
    [in, unique, size_is(ciidExclude)] const IID *rgiidExclude,
    [in, unique] SNB snbExclude,
    [in, unique] IStorage *pstgDest);

  HRESULT MoveElementTo(
    [in] LPCOLESTR pwcsName,
    [in, unique] IStorage *pstgDest,
    [in] LPCOLESTR pwcsNewName,
    [in] DWORD grfFlags);

  HRESULT Commit(
    [in] DWORD grfCommitFlags);

  HRESULT Revert();

  [local]
  HRESULT EnumElements(
    [in] DWORD reserved1,
    [in, unique, size_is(1)] void *reserved2,
    [in] DWORD reserved3,
    [out] IEnumSTATSTG **ppenum);

  [call_as(EnumElements)]
  HRESULT RemoteEnumElements(
    [in] DWORD reserved1,
    [in] unsigned long cbReserved2,
    [in, unique, size_is(cbReserved2)] byte *reserved2,
    [in] DWORD reserved3,
    [out] IEnumSTATSTG **ppenum);

  HRESULT DestroyElement(
    [in] LPCOLESTR pwcsName);

  HRESULT RenameElement(
    [in] LPCOLESTR pwcsOldName,
    [in] LPCOLESTR pwcsNewName);

  HRESULT SetElementTimes(
    [in, unique] LPCOLESTR pwcsName,
    [in, unique] const FILETIME *pctime,
    [in, unique] const FILETIME *patime,
    [in, unique] const FILETIME *pmtime);

  HRESULT SetClass(
    [in] REFCLSID clsid);

  HRESULT SetStateBits(
    [in] DWORD grfStateBits,
    [in] DWORD grfMask);

  HRESULT Stat(
    [out] STATSTG *pstatstg,
    [in] DWORD grfStatFlag);
}

[
  object,
  uuid(0000010b-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IPersistFile : IPersist
{
  typedef [unique] IPersistFile *LPPERSISTFILE;

  HRESULT IsDirty();

  HRESULT Load(
    [in] LPCOLESTR pszFileName,
    [in] DWORD dwMode);

  HRESULT Save(
    [in, unique] LPCOLESTR pszFileName,
    [in] BOOL fRemember);

  HRESULT SaveCompleted(
    [in, unique] LPCOLESTR pszFileName);

  HRESULT GetCurFile(
    [out] LPOLESTR *ppszFileName);
}

[
  object,
  uuid(0000010a-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IPersistStorage : IPersist
{
  typedef [unique] IPersistStorage *LPPERSISTSTORAGE;

  HRESULT IsDirty();

  HRESULT InitNew(
    [in, unique] IStorage *pStg);

  HRESULT Load(
    [in, unique] IStorage *pStg);

  HRESULT Save(
    [in, unique] IStorage *pStgSave,
    [in] BOOL fSameAsLoad);

  HRESULT SaveCompleted(
    [in, unique] IStorage *pStgNew);

  HRESULT HandsOffStorage();
}

[
  object,
  uuid(00000012-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IRootStorage : IUnknown
{
  typedef [unique] IRootStorage *LPROOTSTORAGE;

  HRESULT SwitchToFile(
    [in] LPOLESTR pszFile);
}

[
  object,
  uuid(0000000a-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface ILockBytes : IUnknown
{
  typedef [unique] ILockBytes *LPLOCKBYTES;

  [local]
  HRESULT ReadAt(
    [in] ULARGE_INTEGER ulOffset,
    [out, size_is(cb), length_is(*pcbRead)]
    void *pv,
    [in] ULONG cb,
    [out] ULONG *pcbRead);

  [call_as(ReadAt)]
  HRESULT RemoteReadAt(
    [in] ULARGE_INTEGER ulOffset,
    [out, size_is(cb), length_is(*pcbRead)]
    byte *pv,
    [in] ULONG cb,
    [out] ULONG *pcbRead);

  [local]
  HRESULT WriteAt(
    [in] ULARGE_INTEGER ulOffset,
    [in, size_is(cb)] const void *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);

  [call_as(WriteAt)]
  HRESULT RemoteWriteAt(
    [in] ULARGE_INTEGER ulOffset,
    [in, size_is(cb)] const byte *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);

  HRESULT Flush();

  HRESULT SetSize(
    [in] ULARGE_INTEGER cb);

  HRESULT LockRegion(
    [in] ULARGE_INTEGER libOffset,
    [in] ULARGE_INTEGER cb,
    [in] DWORD dwLockType);

  HRESULT UnlockRegion(
    [in] ULARGE_INTEGER libOffset,
    [in] ULARGE_INTEGER cb,
    [in] DWORD dwLockType);

  HRESULT Stat(
    [out] STATSTG *pstatstg,
    [in] DWORD grfStatFlag);
}

[
  object,
  uuid(99caf010-415e-11cf-8814-00aa00b569f5),
  pointer_default(unique)
]
interface IFillLockBytes : IUnknown
{
  [local]
  HRESULT FillAppend(
    [in, size_is(cb)] const void *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);

  [call_as(FillAppend)]
  HRESULT RemoteFillAppend(
    [in, size_is(cb)] const byte *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);

  [local]
  HRESULT FillAt(
    [in] ULARGE_INTEGER ulOffset,
    [in, size_is(cb)] const void *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);

  [call_as(FillAt)]
  HRESULT RemoteFillAt(
    [in] ULARGE_INTEGER ulOffset,
    [in, size_is(cb)] const byte *pv,
    [in] ULONG cb,
    [out] ULONG *pcbWritten);

  HRESULT SetFillSize(
    [in] ULARGE_INTEGER ulSize);

  HRESULT Terminate(
    [in] BOOL bCanceled);
}

[
  object,
  uuid(a9d758a0-4617-11cf-95fc-00aa00680db4),
  pointer_default(unique)
]
interface IProgressNotify : IUnknown
{
  HRESULT OnProgress(
    [in] DWORD dwProgressCurrent,
    [in] DWORD dwProgressMaximum,
    [in] BOOL fAccurate,
    [in] BOOL fOwner);
}

[
  local,
  object,
  uuid(0e6d4d90-6738-11cf-9608-00aa00680db4),
  pointer_default(unique)
]
interface ILayoutStorage : IUnknown
{
  typedef struct tagStorageLayout {
    DWORD LayoutType;
    OLECHAR *pwcsElementName;
    LARGE_INTEGER cOffset;
    LARGE_INTEGER cBytes;
  } StorageLayout;

  HRESULT LayoutScript(
    [in] StorageLayout *pStorageLayout,
    [in] DWORD nEntries,
    [in] DWORD glfInterleavedFlag);

  HRESULT BeginMonitor();

  HRESULT EndMonitor();

  HRESULT ReLayoutDocfile(
    [in] OLECHAR *pwcsNewDfName);

  HRESULT ReLayoutDocfileOnILockBytes(
    [in] ILockBytes *pILockBytes);
}

[
    object,
    uuid(30f3d47a-6447-11d1-8e3c-00c04fb9386d)
]
interface IBlockingLock : IUnknown
{
    HRESULT Lock(
        [in] DWORD dwTimeout);

    HRESULT Unlock();
}


[
    object,
    uuid(bc0bf6ae-8878-11d1-83e9-00c04fc2c6d4)
]
interface ITimeAndNoticeControl : IUnknown
{
    HRESULT SuppressChanges(
        [in] DWORD res1,
        [in] DWORD res2);

}



[
    object,
    uuid(8d19c834-8879-11d1-83e9-00c04fc2c6d4)
]
interface IOplockStorage: IUnknown
{
    HRESULT CreateStorageEx(
        [in] LPCWSTR pwcsName,
        [in] DWORD grfMode,
        [in] DWORD stgfmt,
        [in] DWORD grfAttrs,
        [in] REFIID riid,
        [out, iid_is(riid)] void **ppstgOpen);

    HRESULT OpenStorageEx(
        [in] LPCWSTR pwcsName,
        [in] DWORD grfMode,
        [in] DWORD stgfmt,
        [in] DWORD grfAttrs,
        [in] REFIID riid,
        [out, iid_is(riid)] void **ppstgOpen);
}

/******************** Data Object ********************/

[
  object,
  uuid(00000103-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IEnumFORMATETC : IUnknown
{
  typedef [unique] IEnumFORMATETC *LPENUMFORMATETC;

  typedef struct tagDVTARGETDEVICE {
    DWORD tdSize;
    WORD tdDriverNameOffset;
    WORD tdDeviceNameOffset;
    WORD tdPortNameOffset;
    WORD tdExtDevmodeOffset;
    [size_is(tdSize - sizeof(DWORD) - 4*sizeof(WORD))]
    BYTE tdData[];
  } DVTARGETDEVICE;

  typedef CLIPFORMAT *LPCLIPFORMAT;

  typedef struct tagFORMATETC {
    CLIPFORMAT cfFormat;
    [unique] DVTARGETDEVICE *ptd;
    DWORD dwAspect;
    LONG lindex;
    DWORD tymed;
  } FORMATETC, *LPFORMATETC;

  [local]
  HRESULT Next(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    FORMATETC *rgelt,
    [out] ULONG *pceltFetched);

  [call_as(Next)]
  HRESULT RemoteNext(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    FORMATETC *rgelt,
    [out] ULONG *pceltFetched);

  HRESULT Skip(
    [in] ULONG celt);

  HRESULT Reset();

  HRESULT Clone(
    [out] IEnumFORMATETC **ppenum);
}

[
  object,
  uuid(00000105-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IEnumSTATDATA : IUnknown
{
  typedef [unique] IEnumSTATDATA *LPENUMSTATDATA;

  typedef enum tagADVF {
    ADVF_NODATA            = 1,
    ADVF_PRIMEFIRST        = 2,
    ADVF_ONLYONCE          = 4,
    ADVF_DATAONSTOP        = 64,
    ADVFCACHE_NOHANDLER    = 8,
    ADVFCACHE_FORCEBUILTIN = 16,
    ADVFCACHE_ONSAVE       = 32
  } ADVF;

  typedef struct tagSTATDATA
  {
    FORMATETC formatetc;
    DWORD advf;
    [unique] IAdviseSink *pAdvSink;
    DWORD dwConnection;
  } STATDATA, *LPSTATDATA;

  [local]
  HRESULT Next(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    STATDATA *rgelt,
    [out] ULONG *pceltFetched);

  [call_as(Next)]
  HRESULT RemoteNext(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)]
    STATDATA *rgelt,
    [out] ULONG *pceltFetched);

  HRESULT Skip(
    [in] ULONG celt);

  HRESULT Reset();

  HRESULT Clone(
    [out] IEnumSTATDATA **ppenum);
}

[
  object,
  uuid(0000010f-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IAdviseSink : IUnknown
{
  typedef IAdviseSink *LPADVISESINK;

  typedef [v1_enum] enum tagTYMED {
    TYMED_HGLOBAL  = 1,
    TYMED_FILE     = 2,
    TYMED_ISTREAM  = 4,
    TYMED_ISTORAGE = 8,
    TYMED_GDI      = 16,
    TYMED_MFPICT   = 32,
    TYMED_ENHMF    = 64,
    TYMED_NULL     = 0
  } TYMED;

  typedef struct tagRemSTGMEDIUM {
    DWORD tymed;
    DWORD dwHandleType;
    unsigned long pData;
    unsigned long pUnkForRelease;
    unsigned long cbData;
    [size_is(cbData)] byte data[];
  } RemSTGMEDIUM;

  typedef struct tagSTGMEDIUM {
    DWORD tymed;
    [switch_is(tymed)] union {
    [case(TYMED_GDI)]      HBITMAP hBitmap;
    [case(TYMED_MFPICT)]   HMETAFILEPICT hMetaFilePict;
    [case(TYMED_ENHMF)]    HENHMETAFILE hEnhMetaFile;
    [case(TYMED_HGLOBAL)]  HGLOBAL hGlobal;
    [case(TYMED_FILE)]     LPOLESTR lpszFileName;
    [case(TYMED_ISTREAM)]  IStream *pstm;
    [case(TYMED_ISTORAGE)] IStorage *pstg;
    [default]              ;
    } DUMMYUNIONNAME;
    [unique] IUnknown *pUnkForRelease;
  } uSTGMEDIUM;

/* copied from wingdi.h */
#define OBJ_PEN             1
#define OBJ_BRUSH           2
#define OBJ_DC              3
#define OBJ_METADC          4
#define OBJ_PAL             5
#define OBJ_FONT            6
#define OBJ_BITMAP          7
#define OBJ_REGION          8
#define OBJ_METAFILE        9
#define OBJ_MEMDC           10
#define OBJ_EXTPEN          11
#define OBJ_ENHMETADC       12
#define OBJ_ENHMETAFILE     13

  typedef union _GDI_OBJECT switch(DWORD ObjectType) u {
    case OBJ_BITMAP: wireHBITMAP hBitmap;
    case OBJ_PAL:    wireHPALETTE hPalette;
    default:         wireHGLOBAL hGeneric;
  } GDI_OBJECT;

  /* When NONAMELESSUNION is not defined, the presence of _STGMEDIUM_UNION
   * violates the C spec, but is necessary for C++.  Avoid C spec violation. */
  cpp_quote("#if !defined(NONAMELESSUNION) && !defined(__cplusplus)")
  cpp_quote("#define _STGMEDIUM_UNION")
  cpp_quote("#endif")

  typedef struct _userSTGMEDIUM {
    union _STGMEDIUM_UNION switch(DWORD tymed) u {
    case TYMED_NULL:     ;
    case TYMED_MFPICT:   wireHMETAFILEPICT hMetaFilePict;
    case TYMED_ENHMF:    wireHENHMETAFILE hHEnhMetaFile;
    case TYMED_GDI:      GDI_OBJECT *hGdiHandle;
    case TYMED_HGLOBAL:  wireHGLOBAL hGlobal;
    case TYMED_FILE:     LPOLESTR lpszFileName;
    case TYMED_ISTREAM:  BYTE_BLOB *pstm;
    case TYMED_ISTORAGE: BYTE_BLOB *pstg;
    } DUMMYUNIONNAME;
    IUnknown *pUnkForRelease;
  } userSTGMEDIUM;

  cpp_quote("#if !defined(NONAMELESSUNION) && !defined(__cplusplus)")
  cpp_quote("#undef _STGMEDIUM_UNION")
  cpp_quote("#endif")

  typedef [unique] userSTGMEDIUM *wireSTGMEDIUM;
  typedef [wire_marshal(wireSTGMEDIUM)] uSTGMEDIUM STGMEDIUM;

  typedef [unique] userSTGMEDIUM *wireASYNC_STGMEDIUM;
  typedef [wire_marshal(wireASYNC_STGMEDIUM)] STGMEDIUM ASYNC_STGMEDIUM;

  typedef STGMEDIUM *LPSTGMEDIUM;

  typedef struct _userFLAG_STGMEDIUM {
    long ContextFlags;
    long fPassOwnership;
    userSTGMEDIUM Stgmed;
  } userFLAG_STGMEDIUM;

  typedef [unique] userFLAG_STGMEDIUM *wireFLAG_STGMEDIUM;

  typedef [wire_marshal(wireFLAG_STGMEDIUM)] struct _FLAG_STGMEDIUM {
    long ContextFlags;
    long fPassOwnership;
    STGMEDIUM Stgmed;
  } FLAG_STGMEDIUM;

  [local]
  void OnDataChange(
    [in, unique] FORMATETC *pFormatetc,
    [in, unique] STGMEDIUM *pStgmed);

  [call_as(OnDataChange)]
  HRESULT  RemoteOnDataChange(
    [in, unique] FORMATETC *pFormatetc,
    [in, unique] ASYNC_STGMEDIUM *pStgmed);

  [local]
  void OnViewChange(
    [in] DWORD dwAspect,
    [in] LONG lindex);

  [call_as(OnViewChange)]
  HRESULT RemoteOnViewChange(
    [in] DWORD dwAspect,
    [in] LONG lindex);

  [local]
  void OnRename(
    [in] IMoniker *pmk);

  [call_as(OnRename)]
  HRESULT RemoteOnRename(
    [in] IMoniker *pmk);

  [local]
  void OnSave();

  [call_as(OnSave)]
  HRESULT RemoteOnSave();

  [local]
  void OnClose();

  [call_as(OnClose)]
  HRESULT RemoteOnClose();
}

[
  object,
  uuid(00000125-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IAdviseSink2 : IAdviseSink
{
  typedef [unique] IAdviseSink2 *LPADVISESINK2;

  [local]
  void OnLinkSrcChange(
    [in, unique] IMoniker *pmk);

  [call_as(OnLinkSrcChange)]
  HRESULT RemoteOnLinkSrcChange(
    [in, unique] IMoniker *pmk);
}

[
  object,
  uuid(0000010e-0000-0000-C000-000000000046),
  pointer_default(unique)
]
interface IDataObject : IUnknown
{
  typedef [unique] IDataObject *LPDATAOBJECT;

  typedef enum tagDATADIR {
    DATADIR_GET = 1,
    DATADIR_SET = 2
  } DATADIR;

  [local]
  HRESULT GetData(
    [in, unique] FORMATETC *pformatetcIn,
    [out] STGMEDIUM *pmedium);

  [call_as(GetData)]
  HRESULT RemoteGetData(
    [in, unique] FORMATETC *pformatetcIn,
    [out] STGMEDIUM *pRemoteMedium);

  [local]
  HRESULT GetDataHere(
    [in, unique] FORMATETC *pformatetc,
    [in, out] STGMEDIUM *pmedium);

  [call_as(GetDataHere)]
  HRESULT RemoteGetDataHere(
    [in, unique] FORMATETC *pformatetc,
    [in, out] STGMEDIUM *pRemoteMedium);

  HRESULT QueryGetData(
    [in, unique] FORMATETC *pformatetc);

  HRESULT GetCanonicalFormatEtc(
    [in, unique] FORMATETC *pformatectIn,
    [out] FORMATETC *pformatetcOut);

  [local]
  HRESULT SetData(
    [in, unique] FORMATETC *pformatetc,
    [in, unique] STGMEDIUM *pmedium,
    [in] BOOL fRelease);

  [call_as(SetData)]
  HRESULT RemoteSetData(
    [in, unique] FORMATETC *pformatetc,
    [in, unique] FLAG_STGMEDIUM *pmedium,
    [in] BOOL fRelease);

  HRESULT EnumFormatEtc(
    [in] DWORD dwDirection,
    [out] IEnumFORMATETC **ppenumFormatEtc);

  HRESULT DAdvise(
    [in] FORMATETC *pformatetc,
    [in] DWORD advf,
    [in, unique] IAdviseSink *pAdvSink,
    [out] DWORD *pdwConnection);

  HRESULT DUnadvise(
    [in] DWORD dwConnection);

  HRESULT EnumDAdvise(
    [out] IEnumSTATDATA **ppenumAdvise);
}

[
  local,
  object,
  uuid(00000110-0000-0000-C000-000000000046)
]
interface IDataAdviseHolder : IUnknown
{
  typedef [unique] IDataAdviseHolder *LPDATAADVISEHOLDER;

  HRESULT Advise(
    [in, unique] IDataObject *pDataObject,
    [in, unique] FORMATETC *pFetc,
    [in] DWORD advf,
    [in, unique] IAdviseSink *pAdvise,
    [out] DWORD *pdwConnection);

  HRESULT Unadvise(
    [in] DWORD dwConnection);

  HRESULT EnumAdvise(
    [out] IEnumSTATDATA **ppenumAdvise);

  HRESULT SendOnDataChange(
    [in, unique] IDataObject *pDataObject,
    [in] DWORD dwReserved,
    [in] DWORD advf);
}

/******************** Remoting ********************/

[
  local,
  object,
  uuid(00000016-0000-0000-C000-000000000046)
]
interface IMessageFilter : IUnknown
{
  typedef [unique] IMessageFilter *LPMESSAGEFILTER;

  typedef enum tagCALLTYPE {
    CALLTYPE_TOPLEVEL = 1,
    CALLTYPE_NESTED   = 2,
    CALLTYPE_ASYNC    = 3,
    CALLTYPE_TOPLEVEL_CALLPENDING = 4,
    CALLTYPE_ASYNC_CALLPENDING    = 5
  } CALLTYPE;

  typedef enum tagSERVERCALL {
    SERVERCALL_ISHANDLED  = 0,
    SERVERCALL_REJECTED   = 1,
    SERVERCALL_RETRYLATER = 2
  } SERVERCALL;

  typedef enum tagPENDINGTYPE {
    PENDINGTYPE_TOPLEVEL = 1,
    PENDINGTYPE_NESTED   = 2
  } PENDINGTYPE;

  typedef enum tagPENDINGMSG {
    PENDINGMSG_CANCELCALL     = 0,
    PENDINGMSG_WAITNOPROCESS  = 1,
    PENDINGMSG_WAITDEFPROCESS = 2
  } PENDINGMSG;

  typedef struct tagINTERFACEINFO {
    IUnknown *pUnk;
    IID iid;
    WORD wMethod;
  } INTERFACEINFO, *LPINTERFACEINFO;

  DWORD HandleInComingCall(
    [in] DWORD dwCallType,
    [in] HTASK htaskCaller,
    [in] DWORD dwTickCount,
    [in] LPINTERFACEINFO lpInterfaceInfo);

  DWORD RetryRejectedCall(
    [in] HTASK htaskCallee,
    [in] DWORD dwTickCount,
    [in] DWORD dwRejectType);

  DWORD MessagePending(
    [in] HTASK htaskCallee,
    [in] DWORD dwTickCount,
    [in] DWORD dwPendingType);
}

[
  local,
  object,
  uuid(D5F56B60-593B-101A-B569-08002B2DBF7A)
]
interface IRpcChannelBuffer : IUnknown
{
  typedef [unique] IRpcChannelBuffer *LPRPCCHANNELBUFFER;

  typedef unsigned long RPCOLEDATAREP;

  typedef struct tagRPCOLEMESSAGE {
    void *reserved1;
    RPCOLEDATAREP dataRepresentation;
    void *Buffer;
    ULONG cbBuffer;
    ULONG iMethod;
    void *reserved2[5];
    ULONG rpcFlags;
  } RPCOLEMESSAGE;

  typedef RPCOLEMESSAGE *PRPCOLEMESSAGE;

  HRESULT GetBuffer(
    [in] RPCOLEMESSAGE *pMessage,
    [in] REFIID riid);

  HRESULT SendReceive(
    [in,out] RPCOLEMESSAGE *pMessage,
    [out] ULONG *pStatus);

  HRESULT FreeBuffer(
    [in] RPCOLEMESSAGE *pMessage);

  HRESULT GetDestCtx(
    [out] DWORD *pdwDestContext,
    [out] void **ppvDestContext);

  HRESULT IsConnected();
}

[
  local,
  object,
  uuid(594f31d0-7f19-11d0-b194-00a0c90dc8bf)
]
interface IRpcChannelBuffer2 : IRpcChannelBuffer
{
  typedef [unique] IRpcChannelBuffer2 *LPRPCCHANNELBUFFER2;

  HRESULT GetProtocolVersion(
    [in,out] DWORD *pdwVersion);
}

[
  local,
  object,
  uuid(25B15600-0115-11d0-BF0D-00AA00B8DFD2)
]
interface IRpcChannelBuffer3 : IRpcChannelBuffer2
{
  typedef [unique] IRpcChannelBuffer3 *LPRPCCHANNELBUFFER3;

  HRESULT Send(
    [in,out] RPCOLEMESSAGE *pMsg,
    [out] ULONG *pulStatus);

  HRESULT Receive(
    [in,out] RPCOLEMESSAGE *pMsg,
    [in] ULONG ulSize,
    [out] ULONG *pulStatus);

  HRESULT Cancel(
    [in] RPCOLEMESSAGE *pMsg);

  HRESULT GetCallContext(
    [in] RPCOLEMESSAGE *pMsg,
    [in] REFIID riid,
    [out] void **pInterface);

  HRESULT GetDestCtxEx(
    [in] RPCOLEMESSAGE *pMsg,
    [out] DWORD *pdwDestContext,
    [out] void **ppvDestContext);

  HRESULT GetState(
    [in] RPCOLEMESSAGE *pMsg,
    [out] DWORD *pState);

  HRESULT RegisterAsync(
    [in] RPCOLEMESSAGE *pMsg,
    [in] IAsyncManager *pAsyncMgr);
}

[
    local,
    object,
    uuid(a5029fb6-3c34-11d1-9c99-00c04fb998aa),
    pointer_default(unique)
]
interface IAsyncRpcChannelBuffer : IRpcChannelBuffer2
{
    HRESULT Send(
        [in, out] RPCOLEMESSAGE *pMsg,
        [in] ISynchronize *pSync,
        [out] ULONG *pulStatus);

    HRESULT Receive(
        [in, out] RPCOLEMESSAGE *pMsg,
        [out] ULONG *pulStatus);

    HRESULT GetDestCtxEx(
        [in] RPCOLEMESSAGE *pMsg,
        [out] DWORD *pdwDestContext,
        [out] void **ppvDestContext);
}

[
    local,
    object,
    uuid(58a08519-24c8-4935-b482-3fd823333a4f)
]
interface IRpcSyntaxNegotiate : IUnknown
{
    HRESULT NegotiateSyntax(
        [in, out] RPCOLEMESSAGE *pMsg);
}

[
  local,
  object,
  uuid(D5F56A34-593B-101A-B569-08002B2DBF7A)
]
interface IRpcProxyBuffer : IUnknown
{
  typedef [unique] IRpcProxyBuffer *LPRPCPROXYBUFFER;

  HRESULT Connect(
    [in, unique] IRpcChannelBuffer *pRpcChannelBuffer);

  void Disconnect();
}

[
  local,
  object,
  uuid(D5F56AFC-593B-101A-B569-08002B2DBF7A)
]
interface IRpcStubBuffer : IUnknown
{
  typedef [unique] IRpcStubBuffer *LPRPCSTUBBUFFER;

  HRESULT Connect(
    [in] IUnknown *pUnkServer);

  void Disconnect();

  HRESULT Invoke(
    [in] RPCOLEMESSAGE *_prpcmsg,
    [in] IRpcChannelBuffer *_pRpcChannelBuffer);

  IRpcStubBuffer *IsIIDSupported(
    [in] REFIID riid);

  ULONG CountRefs();

  HRESULT DebugServerQueryInterface(
    void **ppv);

  void DebugServerRelease(
    void *pv);
}

[
  local,
  object,
  uuid(D5F569D0-593B-101A-B569-08002B2DBF7A)
]
interface IPSFactoryBuffer : IUnknown
{
  typedef [unique] IPSFactoryBuffer *LPPSFACTORYBUFFER;

  HRESULT CreateProxy(
    [in] IUnknown *pUnkOuter,
    [in] REFIID riid,
    [out] IRpcProxyBuffer **ppProxy,
    [out] void **ppv);

  HRESULT CreateStub(
    [in] REFIID riid,
    [in, unique] IUnknown *pUnkServer,
    [out] IRpcStubBuffer **ppStub);
}

[
  local,
  object,
  uuid(1008c4a0-7613-11cf-9af1-0020af6e72f4)
]
interface IChannelHook : IUnknown
{
  typedef [unique] IChannelHook *LPCHANNELHOOK;

  typedef struct SChannelHookCallInfo {
    IID iid;
    DWORD cbSize;
    GUID uCausality;
    DWORD dwServerPid;
    DWORD iMethod;
    void *pObject;
  } SChannelHookCallInfo;

  void ClientGetSize(
    [in] REFGUID uExtent,
    [in] REFIID riid,
    [out] ULONG *pDataSize);

  void ClientFillBuffer(
    [in] REFGUID uExtent,
    [in] REFIID riid,
    [in, out] ULONG *pDataSize,
    [in] void *pDataBuffer);

  void ClientNotify(
    [in] REFGUID uExtent,
    [in] REFIID riid,
    [in] ULONG cbDataSize,
    [in] void *pDataBuffer,
    [in] DWORD lDataRep,
    [in] HRESULT hrFault);

  void ServerNotify(
    [in] REFGUID uExtent,
    [in] REFIID riid,
    [in] ULONG cbDataSize,
    [in] void *pDataBuffer,
    [in] DWORD lDataRep);

  void ServerGetSize(
    [in] REFGUID uExtent,
    [in] REFIID riid,
    [in] HRESULT hrFault,
    [out] ULONG *pDataSize);

  void ServerFillBuffer(
    [in] REFGUID uExtent,
    [in] REFIID riid,
    [in, out] ULONG *pDataSize,
    [in] void *pDataBuffer,
    [in] HRESULT hrFault );
}

extern const FMTID FMTID_SummaryInformation;
extern const FMTID FMTID_DocSummaryInformation;
extern const FMTID FMTID_UserDefinedProperties;


/******************** Connection Points ********************/
/* FIXME */

/******************** DCOM ********************/

[
  local,
  object,
  uuid(0000013D-0000-0000-C000-000000000046)
]
interface IClientSecurity : IUnknown
{
  typedef struct tagSOLE_AUTHENTICATION_SERVICE {
    DWORD dwAuthnSvc;
    DWORD dwAuthzSvc;
    OLECHAR *pPrincipalName;
    HRESULT hr;
  } SOLE_AUTHENTICATION_SERVICE;

  typedef SOLE_AUTHENTICATION_SERVICE *PSOLE_AUTHENTICATION_SERVICE;

  typedef struct tagSOLE_AUTHENTICATION_INFO {
    DWORD dwAuthnSvc;
    DWORD dwAuthzSvc;
    void *pAuthInfo;
  } SOLE_AUTHENTICATION_INFO;

  const OLECHAR *COLE_DEFAULT_PRINCIPAL = (OLECHAR*) -1;
  const void *COLE_DEFAULT_AUTHINFO = (void*) -1;

  typedef struct tagSOLE_AUTHENTICATION_LIST {
    DWORD cAuthInfo;
    SOLE_AUTHENTICATION_INFO *aAuthInfo;
  } SOLE_AUTHENTICATION_LIST;

  typedef enum tagEOLE_AUTHENTICATION_CAPABILITIES {
    EOAC_NONE               = 0x0,
    EOAC_MUTUAL_AUTH        = 0x1,
    EOAC_SECURE_REFS        = 0x2, /* CoInitializeSecurity only */
    EOAC_ACCESS_CONTROL     = 0x4, /* CoInitializeSecurity only */
    EOAC_APPID              = 0x8, /* CoInitializeSecurity only */
    EOAC_DYNAMIC            = 0x10, /* CoInitializeSecurity only */
    EOAC_STATIC_CLOAKING    = 0x20,
    EOAC_DYNAMIC_CLOAKING   = 0x40,
    EOAC_ANY_AUTHORITY      = 0x80,
    EOAC_MAKE_FULLSIC       = 0x100,
    EOAC_REQUIRE_FULLSIC    = 0x200, /* CoInitializeSecurity only */
    EOAC_AUTO_IMPERSONATE   = 0x400, /* CoInitializeSecurity only */
    EOAC_DEFAULT            = 0x800,
    EOAC_DISABLE_AAA        = 0x1000, /* CoInitializeSecurity only */
    EOAC_NO_CUSTOM_MARSHAL  = 0x2000, /* CoInitializeSecurity only */
  } EOLE_AUTHENTICATION_CAPABILITIES;

  HRESULT QueryBlanket(
    [in] IUnknown *pProxy,
    [out] DWORD *pAuthnSvc,
    [out] DWORD *pAuthzSvc,
    [out] OLECHAR **pServerPrincName,
    [out] DWORD *pAuthnLevel,
    [out] DWORD *pImpLevel,
    [out] void **pAuthInfo,
    [out] DWORD *pCapabilities);

  HRESULT SetBlanket(
    [in] IUnknown *pProxy,
    [in] DWORD AuthnSvc,
    [in] DWORD AuthzSvc,
    [in] OLECHAR *pServerPrincName,
    [in] DWORD AuthnLevel,
    [in] DWORD ImpLevel,
    [in] void *pAuthInfo,
    [in] DWORD Capabilities);

  HRESULT CopyProxy(
    [in] IUnknown *pProxy,
    [out] IUnknown **ppCopy);
}

[
  local,
  object,
  uuid(0000013E-0000-0000-C000-000000000046)
]
interface IServerSecurity : IUnknown
{
  HRESULT QueryBlanket(
    [out] DWORD *pAuthnSvc,
    [out] DWORD *pAuthzSvc,
    [out] OLECHAR **pServerPrincName,
    [out] DWORD *pAuthnLevel,
    [out] DWORD *pImpLevel,
    [out] void **pPrivs,
    [out] DWORD *pCapabilities);

  HRESULT ImpersonateClient();

  HRESULT RevertToSelf();

  BOOL IsImpersonating();
}

[
  local,
  object,
  uuid(00000024-0000-0000-C000-000000000046)
]
interface IAsyncSetup : IUnknown
{
  HRESULT GetAsyncManager(
    [in] REFIID riid,
    [in] IUnknown *pOuter,
    [in] DWORD dwFlags,
    [out] IUnknown **ppInner,
    [out] IAsyncManager **ppAsyncMgr);
}

[
    object,
    uuid(0e6d4d92-6738-11cf-9608-00aa00680db4)
]
interface IDirectWriterLock : IUnknown
{
    HRESULT WaitForWriteAccess(
        [in] DWORD dwTimeout);

    HRESULT ReleaseWriteAccess();

    HRESULT HaveWriteAccess();
}

[
    object,
    uuid(00000030-0000-0000-C000-000000000046)
]

interface ISynchronize : IUnknown
{
    HRESULT Wait(
        [in] DWORD dwFlags,
        [in] DWORD dwMilliseconds);

    HRESULT Signal();

    HRESULT Reset();
}


[
    local,
    object,
    uuid(00000031-0000-0000-C000-000000000046)
]
interface ISynchronizeHandle : IUnknown
{
    HRESULT GetHandle(
        [out] HANDLE *ph);
}


[
    local,
    object,
    uuid(00000032-0000-0000-C000-000000000046)
]
interface ISynchronizeEvent : ISynchronizeHandle
{
    HRESULT SetEventHandle(
        [in] HANDLE *ph);
}


[
    local,
    object,
    uuid(00000033-0000-0000-C000-000000000046)
]
interface ISynchronizeContainer : IUnknown
{
    HRESULT AddSynchronize(
        [in] ISynchronize *pSync);

    HRESULT WaitMultiple(
        [in] DWORD dwFlags,
        [in] DWORD dwTimeOut,
        [out] ISynchronize **ppSync);
}

[
    local,
    object,
    uuid(00000025-0000-0000-C000-000000000046)
]
interface ISynchronizeMutex : ISynchronize
{
    HRESULT ReleaseMutex();
}

[
    local,
    object,
    uuid(00000029-0000-0000-C000-000000000046)
]

interface ICancelMethodCalls : IUnknown
{
    typedef [unique] ICancelMethodCalls *LPCANCELMETHODCALLS;

    HRESULT Cancel(
        [in] ULONG ulSeconds);

    HRESULT TestCancel();
}

[
  local,
  object,
  uuid(0000002A-0000-0000-C000-000000000046)
]
interface IAsyncManager : IUnknown
{
  typedef enum tagDCOM_CALL_STATE {
    DCOM_NONE          = 0,
    DCOM_CALL_COMPLETE = 1,
    DCOM_CALL_CANCELED = 2
  } DCOM_CALL_STATE;

  HRESULT CompleteCall(
    [in] HRESULT Result);

  HRESULT GetCallContext(
    [in] REFIID riid,
    [out] void **pInterface);

  HRESULT GetState(
    [out] ULONG *pulStateFlags);
}

[
    local,
    object,
    uuid(1c733a30-2a1c-11ce-ade5-00aa0044773d),
    pointer_default(unique)
]
interface ICallFactory : IUnknown
{
    HRESULT CreateCall(
        [in] REFIID riid,
        [in] IUnknown *pCtrlUnk,
        [in] REFIID riid2,
        [out, iid_is(riid2)] IUnknown **ppv);
}

[
    local,
    object,
    uuid(00000144-0000-0000-C000-000000000046)
]
interface IRpcOptions : IUnknown
{
    HRESULT Set(
        [in] IUnknown *pPrx,
        [in] DWORD dwProperty,
        [in] ULONG_PTR dwValue);

    HRESULT Query(
        [in] IUnknown *pPrx,
        [in] DWORD dwProperty,
        [out] ULONG_PTR *pdwValue);
}

enum {
   COMBND_RPCTIMEOUT = 1,
   COMBND_SERVER_LOCALITY = 2
};  

enum {
   SERVER_LOCALITY_PROCESS_LOCAL = 0,
   SERVER_LOCALITY_MACHINE_LOCAL = 1,
   SERVER_LOCALITY_REMOTE = 2
};

[
    local,
    object,
    uuid(00000149-0000-0000-C000-000000000046),
    pointer_default(unique)
]
interface IRpcHelper : IUnknown
{
    HRESULT GetDCOMProtocolVersion(
        [out] DWORD *pComVersion);

    HRESULT GetIIDFromOBJREF(
        [in] void *pObjRef,
        [out] IID **piid);
}

[
    local,
    object,
    uuid(eb0cb9e8-7996-11d2-872e-0000f8080859)
]
interface IReleaseMarshalBuffers : IUnknown
{
    HRESULT ReleaseMarshalBuffer(
        [in] RPCOLEMESSAGE *pMsg,
        [in] DWORD dwFlags,
        [in, unique] IUnknown *pChnl);
}

[
    local,
    object,
    uuid(0000002B-0000-0000-C000-000000000046)
]
interface IWaitMultiple : IUnknown
{
    HRESULT WaitMultiple(
        [in] DWORD timeout,
        [out] ISynchronize **pSync);
    HRESULT AddSynchronize(
        [in] ISynchronize *pSync);
}


[
    object,
    uuid(00000026-0000-0000-C000-000000000046)
]
interface IUrlMon : IUnknown
{
    HRESULT AsyncGetClassBits(
        [in] REFCLSID rclsid,
        [in, unique] LPCWSTR pszTYPE,
        [in, unique] LPCWSTR pszExt,
        [in] DWORD dwFileVersionMS,
        [in] DWORD dwFileVersionLS,
        [in, unique] LPCWSTR pszCodeBase,
        [in] IBindCtx *pbc,
        [in] DWORD dwClassContext,
        [in] REFIID riid,
        [in] DWORD flags);
}

[
    local,
    object,
    uuid(00000145-0000-0000-C000-000000000046)
]
interface IForegroundTransfer : IUnknown
{
    HRESULT AllowForegroundTransfer(
        [in] void *lpvReserved);
}

[
    local,
    object,
    uuid(00000147-0000-0000-C000-000000000046)
]
interface IAddrTrackingControl : IUnknown
{
    typedef [unique] IAddrTrackingControl *LPADDRTRACKINGCONTROL;

    HRESULT EnableCOMDynamicAddrTracking();
    HRESULT DisableCOMDynamicAddrTracking();
}

[
    local,
    object,
    uuid(00000148-0000-0000-C000-000000000046)
]
interface IAddrExclusionControl : IUnknown
{
    typedef [unique] IAddrExclusionControl *LPADDREXCLUSIONCONTROL;

    HRESULT GetCurrentAddrExclusionList(
        [in] REFIID riid,
        [out, iid_is(riid)] void **ppEnumerator);
    HRESULT UpdateAddrExclusionList(
        [in] IUnknown *pEnumerator);
}

typedef enum _APTTYPE {
    APTTYPE_CURRENT = -1,
    APTTYPE_STA     = 0,
    APTTYPE_MTA     = 1,
    APTTYPE_NA      = 2,
    APTTYPE_MAINSTA = 3
} APTTYPE;

typedef enum _APTTYPEQUALIFIER {
    APTTYPEQUALIFIER_NONE,
    APTTYPEQUALIFIER_IMPLICIT_MTA,
    APTTYPEQUALIFIER_NA_ON_MTA,
    APTTYPEQUALIFIER_NA_ON_STA,
    APTTYPEQUALIFIER_NA_ON_IMPLICIT_MTA,
    APTTYPEQUALIFIER_NA_ON_MAINSTA
} APTTYPEQUALIFIER;

typedef enum _THDTYPE {
    THDTYPE_BLOCKMESSAGES   = 0,
    THDTYPE_PROCESSMESSAGES = 1
} THDTYPE;

[
    local,
    object,
    uuid(000001ce-0000-0000-C000-000000000046),
    pointer_default(unique)
]
interface IComThreadingInfo : IUnknown
{
    HRESULT GetCurrentApartmentType(
        [out] APTTYPE *pAptType);
    HRESULT GetCurrentThreadType(
        [out] THDTYPE *pThreadType);
    HRESULT GetCurrentLogicalThreadId(
        [out] GUID *pguidLogicalThreadId);
    HRESULT SetCurrentLogicalThreadId(
        [in] REFGUID rguid);
}


[
    object,
    pointer_default(unique),
    uuid(72380d55-8d2b-43a3-8513-2b6ef31434e9)
]
interface IProcessInitControl : IUnknown
{
    HRESULT ResetInitializerTimeout(
        [in] DWORD dwSecondsRemaining);
}

[
    local,
    object,
    uuid(00000034-0000-0000-C000-000000000046),
    pointer_default(unique)
]
interface IInitializeSpy : IUnknown
{
    typedef [unique] IInitializeSpy *LPINITIALIZESPY;

    HRESULT PreInitialize(
        [in] DWORD dwCoInit,
        [in] DWORD dwCurThreadAptRefs);

    HRESULT PostInitialize(
        [in] HRESULT hrCoInit,
        [in] DWORD dwCoInit,
        [in] DWORD dwNewThreadAptRefs);

    HRESULT PreUninitialize(
        [in] DWORD dwCurThreadAptRefs);

    HRESULT PostUninitialize(
        [in] DWORD dwNewThreadAptRefs);
}

[
    object,
    uuid(969dc708-5c76-11d1-8d86-0000f804b057)
]
interface IThumbnailExtractor : IUnknown
{
    HRESULT ExtractThumbnail(
        [in] IStorage *pStg,
        [in] ULONG ulLength,
        [in] ULONG ulHeight,
        [out] ULONG *pulOutputLength,
        [out] ULONG *pulOutputHeight,
        [out] HBITMAP *phOutputBitmap);


    HRESULT OnFileUpdated(
        [in] IStorage *pStg);
}

typedef enum tagGLOBALOPT_PROPERTIES
{
    COMGLB_EXCEPTION_HANDLING     = 1,
    COMGLB_APPID                  = 2,
    COMGLB_RPC_THREADPOOL_SETTING = 3
} GLOBALOPT_PROPERTIES;

typedef enum tagGLOBALOPT_EH_VALUES
{
    COMGLB_EXCEPTION_HANDLE               = 0,
    COMGLB_EXCEPTION_DONOT_HANDLE_FATAL   = 1,
    COMGLB_EXCEPTION_DONOT_HANDLE         = COMGLB_EXCEPTION_DONOT_HANDLE_FATAL,
    COMGLB_EXCEPTION_DONOT_HANDLE_ANY     = 2
} GLOBALOPT_EH_VALUES;

typedef enum tagGLOBALOPT_RPCTP_VALUES
{
    COMGLB_RPC_THREADPOOL_SETTING_DEFAULT_POOL = 0,
    COMGLB_RPC_THREADPOOL_SETTING_PRIVATE_POOL = 1
} GLOBALOPT_RPCTP_VALUES;


[
    object,
    local,
    pointer_default(unique),
    uuid(0000015B-0000-0000-C000-000000000046)
]
interface IGlobalOptions : IUnknown
{
    HRESULT Set([in] GLOBALOPT_PROPERTIES property, [in] ULONG_PTR value);
    HRESULT Query([in] GLOBALOPT_PROPERTIES property, [out ] ULONG_PTR *value);
}

[
    object,
    pointer_default(unique),
    uuid(947990de-cc28-11d2-a0f7-00805f858fb1)
]
interface IDummyHICONIncluder : IUnknown
{
    HRESULT Dummy([in] HICON hIcon, [in] HDC hdc);
}

[
    object,
    local,
    pointer_default(unique),
    uuid(a2f05a09-27a2-42b5-bc0e-ac163ef49d9b)
]
interface IApartmentShutdown : IUnknown
{
    void OnUninitialize([in] UINT64 identifier);
}

cpp_quote("#ifdef USE_COM_CONTEXT_DEF")

typedef DWORD CPFLAGS;

typedef struct tagContextProperty
{
    GUID policyId;
    CPFLAGS flags;
    [unique] IUnknown *pUnk;
} ContextProperty;

[
    local,
    object,
    uuid(000001c1-0000-0000-C000-000000000046)
]
interface IEnumContextProps : IUnknown
{
    typedef [unique] IEnumContextProps *LPENUMCONTEXTPROPS;

    HRESULT Next(
        [in] ULONG celt,
        [out, size_is(celt), length_is(*pceltFetched)] ContextProperty *pContextProperties,
        [out] ULONG *pceltFetched);

    HRESULT Skip(
        [in] ULONG celt);

    HRESULT Reset();

    HRESULT Clone(
        [out] IEnumContextProps **ppEnumContextProps);

    HRESULT Count(
        [out] ULONG *pcelt);
}

[
    local,
    object,
    uuid(000001c0-0000-0000-C000-000000000046)
]
interface IContext : IUnknown
{
    HRESULT SetProperty(
        [in] REFGUID policyId,
        [in] CPFLAGS flags,
        [in] IUnknown *pUnk);

    HRESULT RemoveProperty(
        [in] REFGUID policyId);

    HRESULT GetProperty(
        [in] REFGUID guid,
        [out] CPFLAGS *pFlags,
        [out] IUnknown **ppUnk);

    HRESULT EnumContextProps(
        [out] IEnumContextProps **ppEnumContextProps);
}

[
    local,
    object,
    uuid(000001c6-0000-0000-c000-000000000046),
    pointer_default(unique)
]
interface IObjContext : IContext
{
    void Reserved1();
    void Reserved2();
    void Reserved3();
    void Reserved4();
    void Reserved5();
    void Reserved6();
    void Reserved7();
}

cpp_quote("#endif /* defined USE_COM_CONTEXT_DEF */")
