/*
 * 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";
#define DO_NO_IMPORTS
#define OBJIDL_UNDEF_DO_NO_IMPORTS
#endif

#include "objidlbase.idl"
#ifdef OBJIDL_UNDEF_DO_NO_IMPORTS
#undef DO_NO_IMPORTS
#endif

interface IRunningObjectTable;
interface IMoniker;
interface IAdviseSink;

[
  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();
}

/******************** 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(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);
}

[
  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);
}

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

    HRESULT ReleaseWriteAccess();

    HRESULT HaveWriteAccess();
}

[
    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(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);
}

[
    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);
}