mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
Need to remove existing files before doing vendor import
svn path=/trunk/; revision=12574
This commit is contained in:
@@ -1,74 +0,0 @@
|
||||
EXTRADEFS = -D_OLE32_ -DCOM_NO_WINDOWS_H
|
||||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = ole32.dll
|
||||
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
|
||||
EXTRALIBS = -luuid
|
||||
|
||||
C_SRCS = \
|
||||
antimoniker.c \
|
||||
bindctx.c \
|
||||
clipboard.c \
|
||||
compobj.c \
|
||||
compositemoniker.c \
|
||||
datacache.c \
|
||||
defaulthandler.c \
|
||||
errorinfo.c \
|
||||
filemoniker.c \
|
||||
ftmarshal.c \
|
||||
git.c \
|
||||
hglobalstream.c \
|
||||
ifs.c \
|
||||
itemmoniker.c \
|
||||
marshal.c \
|
||||
memlockbytes.c \
|
||||
moniker.c \
|
||||
ole2.c \
|
||||
ole2stubs.c \
|
||||
ole2impl.c \
|
||||
ole32_main.c \
|
||||
oleobj.c \
|
||||
oleproxy.c \
|
||||
regsvr.c \
|
||||
rpc.c \
|
||||
stg_bigblockfile.c \
|
||||
stg_stream.c \
|
||||
storage32.c
|
||||
|
||||
C_SRCS16 = \
|
||||
memlockbytes16.c \
|
||||
ole16.c \
|
||||
ole2_16.c \
|
||||
ole2nls.c \
|
||||
storage.c
|
||||
|
||||
SPEC_SRCS16 = \
|
||||
compobj.spec \
|
||||
ole2.spec \
|
||||
ole2conv.spec \
|
||||
ole2nls.spec \
|
||||
ole2prox.spec \
|
||||
ole2thk.spec \
|
||||
storage.spec
|
||||
|
||||
RC_SRCS = ole32res.rc
|
||||
RC_BINSRC = ole32res.rc
|
||||
RC_BINARIES = \
|
||||
drag_copy.cur \
|
||||
drag_link.cur \
|
||||
drag_move.cur \
|
||||
nodrop.cur
|
||||
|
||||
IDL_SRCS = \
|
||||
dcom.idl
|
||||
|
||||
SUBDIRS = tests
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
||||
|
||||
# note: this will get overwritten by make depend
|
||||
$(ALL_OBJS): $(IDL_SRCS:.idl=.h)
|
||||
@@ -1,21 +0,0 @@
|
||||
# $Id: Makefile.ros-template,v 1.3 2004/12/03 23:37:42 blight Exp $
|
||||
|
||||
TARGET_NAME = ole32
|
||||
|
||||
TARGET_OBJECTS = @C_SRCS@
|
||||
|
||||
TARGET_CFLAGS = @EXTRADEFS@
|
||||
|
||||
TARGET_SDKLIBS = @IMPORTS@ wine.a wine_uuid.a ntdll.a
|
||||
|
||||
TARGET_BASE = $(TARGET_BASE_LIB_OLE32)
|
||||
|
||||
TARGET_RC_SRCS = @RC_SRCS@
|
||||
TARGET_RC_BINSRC = @RC_BINSRC@
|
||||
TARGET_RC_BINARIES = @RC_BINARIES@
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
||||
@@ -1,666 +0,0 @@
|
||||
/***************************************************************************************
|
||||
* AntiMonikers implementation
|
||||
*
|
||||
* Copyright 1999 Noomen Hamza
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "objbase.h"
|
||||
#include "wine/debug.h"
|
||||
#include "moniker.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
const CLSID CLSID_AntiMoniker = {
|
||||
0x305, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
|
||||
};
|
||||
|
||||
/* AntiMoniker data structure */
|
||||
typedef struct AntiMonikerImpl{
|
||||
|
||||
IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/
|
||||
|
||||
/* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
|
||||
* two monikers are equal. That's whay IROTData interface is implemented by monikers.
|
||||
*/
|
||||
IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/
|
||||
|
||||
ULONG ref; /* reference counter for this object */
|
||||
|
||||
} AntiMonikerImpl;
|
||||
|
||||
/********************************************************************************/
|
||||
/* AntiMoniker prototype functions : */
|
||||
|
||||
/* IUnknown prototype functions */
|
||||
static HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
|
||||
static ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker* iface);
|
||||
static ULONG WINAPI AntiMonikerImpl_Release(IMoniker* iface);
|
||||
|
||||
/* IPersist prototype functions */
|
||||
static HRESULT WINAPI AntiMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
|
||||
|
||||
/* IPersistStream prototype functions */
|
||||
static HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface);
|
||||
static HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface, IStream* pStm);
|
||||
static HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
|
||||
static HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
|
||||
|
||||
/* IMoniker prototype functions */
|
||||
static HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
|
||||
static HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
|
||||
static HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
|
||||
static HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
|
||||
static HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
|
||||
static HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
|
||||
static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
|
||||
static HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
|
||||
static HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pAntiTime);
|
||||
static HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
|
||||
static HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
|
||||
static HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
|
||||
static HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
|
||||
static HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
|
||||
static HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
|
||||
|
||||
/********************************************************************************/
|
||||
/* IROTData prototype functions */
|
||||
|
||||
/* IUnknown prototype functions */
|
||||
static HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
|
||||
static ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData* iface);
|
||||
static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface);
|
||||
|
||||
/* IROTData prototype function */
|
||||
static HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
|
||||
|
||||
/* Local function used by AntiMoniker implementation */
|
||||
HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* iface);
|
||||
HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* iface);
|
||||
|
||||
/********************************************************************************/
|
||||
/* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
|
||||
/* IPersistStream and IMoniker functions. */
|
||||
static IMonikerVtbl VT_AntiMonikerImpl =
|
||||
{
|
||||
AntiMonikerImpl_QueryInterface,
|
||||
AntiMonikerImpl_AddRef,
|
||||
AntiMonikerImpl_Release,
|
||||
AntiMonikerImpl_GetClassID,
|
||||
AntiMonikerImpl_IsDirty,
|
||||
AntiMonikerImpl_Load,
|
||||
AntiMonikerImpl_Save,
|
||||
AntiMonikerImpl_GetSizeMax,
|
||||
AntiMonikerImpl_BindToObject,
|
||||
AntiMonikerImpl_BindToStorage,
|
||||
AntiMonikerImpl_Reduce,
|
||||
AntiMonikerImpl_ComposeWith,
|
||||
AntiMonikerImpl_Enum,
|
||||
AntiMonikerImpl_IsEqual,
|
||||
AntiMonikerImpl_Hash,
|
||||
AntiMonikerImpl_IsRunning,
|
||||
AntiMonikerImpl_GetTimeOfLastChange,
|
||||
AntiMonikerImpl_Inverse,
|
||||
AntiMonikerImpl_CommonPrefixWith,
|
||||
AntiMonikerImpl_RelativePathTo,
|
||||
AntiMonikerImpl_GetDisplayName,
|
||||
AntiMonikerImpl_ParseDisplayName,
|
||||
AntiMonikerImpl_IsSystemMoniker
|
||||
};
|
||||
|
||||
/********************************************************************************/
|
||||
/* Virtual function table for the IROTData class. */
|
||||
static IROTDataVtbl VT_ROTDataImpl =
|
||||
{
|
||||
AntiMonikerROTDataImpl_QueryInterface,
|
||||
AntiMonikerROTDataImpl_AddRef,
|
||||
AntiMonikerROTDataImpl_Release,
|
||||
AntiMonikerROTDataImpl_GetComparaisonData
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* AntiMoniker_QueryInterface
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
|
||||
{
|
||||
AntiMonikerImpl *This = (AntiMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
|
||||
|
||||
/* Perform a sanity check on the parameters.*/
|
||||
if ( (This==0) || (ppvObject==0) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Initialize the return parameter */
|
||||
*ppvObject = 0;
|
||||
|
||||
/* Compare the riid with the interface IDs implemented by this object.*/
|
||||
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||
IsEqualIID(&IID_IPersist, riid) ||
|
||||
IsEqualIID(&IID_IPersistStream, riid) ||
|
||||
IsEqualIID(&IID_IMoniker, riid)
|
||||
)
|
||||
*ppvObject = iface;
|
||||
else if (IsEqualIID(&IID_IROTData, riid))
|
||||
*ppvObject = (IROTData*)&(This->lpvtbl2);
|
||||
|
||||
/* Check that we obtained an interface.*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/* Query Interface always increases the reference count by one when it is successful */
|
||||
AntiMonikerImpl_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_AddRef
|
||||
******************************************************************************/
|
||||
ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker* iface)
|
||||
{
|
||||
AntiMonikerImpl *This = (AntiMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Release
|
||||
******************************************************************************/
|
||||
ULONG WINAPI AntiMonikerImpl_Release(IMoniker* iface)
|
||||
{
|
||||
AntiMonikerImpl *This = (AntiMonikerImpl *)iface;
|
||||
ULONG ref;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
/* destroy the object if there's no more reference on it */
|
||||
if (ref == 0) AntiMonikerImpl_Destroy(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_GetClassID
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
|
||||
{
|
||||
TRACE("(%p,%p),stub!\n",iface,pClassID);
|
||||
|
||||
if (pClassID==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*pClassID = CLSID_AntiMoniker;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_IsDirty
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface)
|
||||
{
|
||||
/* Note that the OLE-provided implementations of the IPersistStream::IsDirty
|
||||
method in the OLE-provided moniker interfaces always return S_FALSE because
|
||||
their internal state never changes. */
|
||||
|
||||
TRACE("(%p)\n",iface);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Load
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
||||
{
|
||||
DWORD constant=1,dwbuffer;
|
||||
HRESULT res;
|
||||
|
||||
/* data read by this function is only a DWORD constant (must be 1) ! */
|
||||
res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),NULL);
|
||||
|
||||
if (SUCCEEDED(res)&& dwbuffer!=constant)
|
||||
return E_FAIL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Save
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
|
||||
{
|
||||
DWORD constant=1;
|
||||
HRESULT res;
|
||||
|
||||
/* data written by this function is only a DWORD constant set to 1 ! */
|
||||
res=IStream_Write(pStm,&constant,sizeof(constant),NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_GetSizeMax
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface,
|
||||
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
|
||||
{
|
||||
TRACE("(%p,%p)\n",iface,pcbSize);
|
||||
|
||||
if (pcbSize!=NULL)
|
||||
return E_POINTER;
|
||||
|
||||
/* for more details see AntiMonikerImpl_Save coments */
|
||||
|
||||
/* Normaly the sizemax must be the size of DWORD ! but I tested this function it ususlly return 16 bytes */
|
||||
/* more than the number of bytes used by AntiMoniker::Save function */
|
||||
pcbSize->u.LowPart = sizeof(DWORD)+16;
|
||||
|
||||
pcbSize->u.HighPart=0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Construct (local function)
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* This)
|
||||
{
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
/* Initialize the virtual fgunction table. */
|
||||
This->lpvtbl1 = &VT_AntiMonikerImpl;
|
||||
This->lpvtbl2 = &VT_ROTDataImpl;
|
||||
This->ref = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Destroy (local function)
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
return HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_BindToObject
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riid,
|
||||
VOID** ppvResult)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_BindToStorage
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riid,
|
||||
VOID** ppvResult)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Reduce
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
DWORD dwReduceHowFar,
|
||||
IMoniker** ppmkToLeft,
|
||||
IMoniker** ppmkReduced)
|
||||
{
|
||||
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
||||
|
||||
if (ppmkReduced==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
AntiMonikerImpl_AddRef(iface);
|
||||
|
||||
*ppmkReduced=iface;
|
||||
|
||||
return MK_S_REDUCED_TO_SELF;
|
||||
}
|
||||
/******************************************************************************
|
||||
* AntiMoniker_ComposeWith
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface,
|
||||
IMoniker* pmkRight,
|
||||
BOOL fOnlyIfNotGeneric,
|
||||
IMoniker** ppmkComposite)
|
||||
{
|
||||
|
||||
TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
|
||||
|
||||
if ((ppmkComposite==NULL)||(pmkRight==NULL))
|
||||
return E_POINTER;
|
||||
|
||||
*ppmkComposite=0;
|
||||
|
||||
if (fOnlyIfNotGeneric)
|
||||
return MK_E_NEEDGENERIC;
|
||||
else
|
||||
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Enum
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
|
||||
{
|
||||
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
|
||||
|
||||
if (ppenumMoniker == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppenumMoniker = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_IsEqual
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
||||
{
|
||||
DWORD mkSys;
|
||||
|
||||
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
|
||||
|
||||
if (pmkOtherMoniker==NULL)
|
||||
return S_FALSE;
|
||||
|
||||
IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys);
|
||||
|
||||
if (mkSys==MKSYS_ANTIMONIKER)
|
||||
return S_OK;
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Hash
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
||||
{
|
||||
if (pdwHash==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*pdwHash=0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_IsRunning
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
IMoniker* pmkNewlyRunning)
|
||||
{
|
||||
IRunningObjectTable* rot;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
|
||||
|
||||
if (pbc==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
|
||||
|
||||
if (FAILED(res))
|
||||
return res;
|
||||
|
||||
res = IRunningObjectTable_IsRunning(rot,iface);
|
||||
|
||||
IRunningObjectTable_Release(rot);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_GetTimeOfLastChange
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
FILETIME* pAntiTime)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_Inverse
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
|
||||
{
|
||||
TRACE("(%p,%p)\n",iface,ppmk);
|
||||
|
||||
if (ppmk==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppmk=0;
|
||||
|
||||
return MK_E_NOINVERSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_CommonPrefixWith
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
|
||||
{
|
||||
DWORD mkSys;
|
||||
|
||||
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
|
||||
|
||||
if(mkSys==MKSYS_ITEMMONIKER){
|
||||
|
||||
IMoniker_AddRef(iface);
|
||||
|
||||
*ppmkPrefix=iface;
|
||||
|
||||
IMoniker_AddRef(iface);
|
||||
|
||||
return MK_S_US;
|
||||
}
|
||||
else
|
||||
return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_RelativePathTo
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
|
||||
{
|
||||
TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
|
||||
|
||||
if (ppmkRelPath==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
IMoniker_AddRef(pmOther);
|
||||
|
||||
*ppmkRelPath=pmOther;
|
||||
|
||||
return MK_S_HIM;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_GetDisplayName
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR *ppszDisplayName)
|
||||
{
|
||||
static const WCHAR back[]={'\\','.','.',0};
|
||||
|
||||
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
|
||||
|
||||
if (ppszDisplayName==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
if (pmkToLeft!=NULL){
|
||||
FIXME("() pmkToLeft!=NULL not implemented \n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
*ppszDisplayName=CoTaskMemAlloc(sizeof(back));
|
||||
|
||||
if (*ppszDisplayName==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
strcpyW(*ppszDisplayName,back);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_ParseDisplayName
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR pszDisplayName,
|
||||
ULONG* pchEaten,
|
||||
IMoniker** ppmkOut)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMoniker_IsSystemMoniker
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
||||
{
|
||||
TRACE("(%p,%p)\n",iface,pwdMksys);
|
||||
|
||||
if (!pwdMksys)
|
||||
return E_POINTER;
|
||||
|
||||
(*pwdMksys)=MKSYS_ANTIMONIKER;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* AntiMonikerIROTData_QueryInterface
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
|
||||
{
|
||||
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
|
||||
|
||||
return AntiMonikerImpl_QueryInterface(This, riid, ppvObject);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* AntiMonikerIROTData_AddRef
|
||||
*/
|
||||
ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData *iface)
|
||||
{
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
TRACE("(%p)\n",iface);
|
||||
|
||||
return AntiMonikerImpl_AddRef(This);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* AntiMonikerIROTData_Release
|
||||
*/
|
||||
ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
|
||||
{
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
TRACE("(%p)\n",iface);
|
||||
|
||||
return AntiMonikerImpl_Release(This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* AntiMonikerIROTData_GetComparaisonData
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
|
||||
BYTE* pbData,
|
||||
ULONG cbMax,
|
||||
ULONG* pcbData)
|
||||
{
|
||||
FIXME("(),stub!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateAntiMoniker [OLE32.@]
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk)
|
||||
{
|
||||
AntiMonikerImpl* newAntiMoniker = 0;
|
||||
HRESULT hr = S_OK;
|
||||
IID riid=IID_IMoniker;
|
||||
|
||||
TRACE("(%p)\n",ppmk);
|
||||
|
||||
newAntiMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl));
|
||||
|
||||
if (newAntiMoniker == 0)
|
||||
return STG_E_INSUFFICIENTMEMORY;
|
||||
|
||||
hr = AntiMonikerImpl_Construct(newAntiMoniker);
|
||||
|
||||
if (FAILED(hr)){
|
||||
|
||||
HeapFree(GetProcessHeap(),0,newAntiMoniker);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = AntiMonikerImpl_QueryInterface((IMoniker*)newAntiMoniker,&riid,(void**)ppmk);
|
||||
|
||||
return hr;
|
||||
}
|
||||
@@ -1,590 +0,0 @@
|
||||
/***************************************************************************************
|
||||
* BindCtx implementation
|
||||
*
|
||||
* Copyright 1999 Noomen Hamza
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************************/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "winerror.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "objbase.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/* represent the first size table and it's increment block size */
|
||||
#define BLOCK_TAB_SIZE 10
|
||||
#define MAX_TAB_SIZE 0xFFFFFFFF
|
||||
|
||||
/* data structure of the BindCtx table elements */
|
||||
typedef struct BindCtxObject{
|
||||
|
||||
IUnknown* pObj; /* point on a bound object */
|
||||
|
||||
LPOLESTR pkeyObj; /* key associated to this bound object */
|
||||
|
||||
BYTE regType; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */
|
||||
|
||||
} BindCtxObject;
|
||||
|
||||
/* BindCtx data strucrture */
|
||||
typedef struct BindCtxImpl{
|
||||
|
||||
IBindCtxVtbl *lpVtbl; /* VTable relative to the IBindCtx interface.*/
|
||||
|
||||
ULONG ref; /* reference counter for this object */
|
||||
|
||||
BindCtxObject* bindCtxTable; /* this is a table in which all bounded objects are stored*/
|
||||
DWORD bindCtxTableLastIndex; /* first free index in the table */
|
||||
DWORD bindCtxTableSize; /* size table */
|
||||
|
||||
BIND_OPTS2 bindOption2; /* a structure which contains the bind options*/
|
||||
|
||||
} BindCtxImpl;
|
||||
|
||||
/* IBindCtx prototype functions : */
|
||||
|
||||
/* IUnknown functions*/
|
||||
static HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject);
|
||||
static ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface);
|
||||
static ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface);
|
||||
/* IBindCtx functions */
|
||||
static HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk);
|
||||
static HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk);
|
||||
static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface);
|
||||
static HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts);
|
||||
static HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts);
|
||||
static HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot);
|
||||
static HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk);
|
||||
static HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk);
|
||||
static HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** ppenum);
|
||||
static HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR pszkey);
|
||||
/* Local functions*/
|
||||
HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This);
|
||||
HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This);
|
||||
HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,IUnknown* punk,LPOLESTR pszkey,DWORD *index);
|
||||
|
||||
/* Virtual function table for the BindCtx class. */
|
||||
static IBindCtxVtbl VT_BindCtxImpl =
|
||||
{
|
||||
BindCtxImpl_QueryInterface,
|
||||
BindCtxImpl_AddRef,
|
||||
BindCtxImpl_Release,
|
||||
BindCtxImpl_RegisterObjectBound,
|
||||
BindCtxImpl_RevokeObjectBound,
|
||||
BindCtxImpl_ReleaseBoundObjects,
|
||||
BindCtxImpl_SetBindOptions,
|
||||
BindCtxImpl_GetBindOptions,
|
||||
BindCtxImpl_GetRunningObjectTable,
|
||||
BindCtxImpl_RegisterObjectParam,
|
||||
BindCtxImpl_GetObjectParam,
|
||||
BindCtxImpl_EnumObjectParam,
|
||||
BindCtxImpl_RevokeObjectParam
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* BindCtx_QueryInterface
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
|
||||
{
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
|
||||
|
||||
/* Perform a sanity check on the parameters.*/
|
||||
if ( (This==0) || (ppvObject==0) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Initialize the return parameter.*/
|
||||
*ppvObject = 0;
|
||||
|
||||
/* Compare the riid with the interface IDs implemented by this object.*/
|
||||
if (IsEqualIID(&IID_IUnknown, riid))
|
||||
*ppvObject = (IBindCtx*)This;
|
||||
else
|
||||
if (IsEqualIID(&IID_IBindCtx, riid))
|
||||
*ppvObject = (IBindCtx*)This;
|
||||
|
||||
/* Check that we obtained an interface.*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/* Query Interface always increases the reference count by one when it is successful */
|
||||
BindCtxImpl_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_AddRef
|
||||
******************************************************************************/
|
||||
ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface)
|
||||
{
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_Release
|
||||
******************************************************************************/
|
||||
ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface)
|
||||
{
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
ULONG ref;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0){
|
||||
/* release all registered objects */
|
||||
BindCtxImpl_ReleaseBoundObjects((IBindCtx*)This);
|
||||
|
||||
BindCtxImpl_Destroy(This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_Construct (local function)
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
/* Initialize the virtual function table.*/
|
||||
This->lpVtbl = &VT_BindCtxImpl;
|
||||
This->ref = 0;
|
||||
|
||||
/* Initialize the BIND_OPTS2 structure */
|
||||
This->bindOption2.cbStruct = sizeof(BIND_OPTS2);
|
||||
This->bindOption2.grfFlags = 0;
|
||||
This->bindOption2.grfMode = STGM_READWRITE;
|
||||
This->bindOption2.dwTickCountDeadline = 0;
|
||||
|
||||
This->bindOption2.dwTrackFlags = 0;
|
||||
This->bindOption2.dwClassContext = CLSCTX_SERVER;
|
||||
This->bindOption2.locale = 1033;
|
||||
This->bindOption2.pServerInfo = 0;
|
||||
|
||||
/* Initialize the bindctx table */
|
||||
This->bindCtxTableSize=BLOCK_TAB_SIZE;
|
||||
This->bindCtxTableLastIndex=0;
|
||||
This->bindCtxTable= HeapAlloc(GetProcessHeap(), 0,This->bindCtxTableSize*sizeof(BindCtxObject));
|
||||
|
||||
if (This->bindCtxTable==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_Destroy (local function)
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
/* free the table space memory */
|
||||
HeapFree(GetProcessHeap(),0,This->bindCtxTable);
|
||||
|
||||
/* free the bindctx structure */
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_RegisterObjectBound
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
|
||||
{
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
DWORD lastIndex=This->bindCtxTableLastIndex;
|
||||
|
||||
TRACE("(%p,%p)\n",This,punk);
|
||||
|
||||
if (punk==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
IUnknown_AddRef(punk);
|
||||
|
||||
/* put the object in the first free element in the table */
|
||||
This->bindCtxTable[lastIndex].pObj = punk;
|
||||
This->bindCtxTable[lastIndex].pkeyObj = NULL;
|
||||
This->bindCtxTable[lastIndex].regType = 0;
|
||||
lastIndex= ++This->bindCtxTableLastIndex;
|
||||
|
||||
if (lastIndex == This->bindCtxTableSize){ /* the table is full so it must be resized */
|
||||
|
||||
if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
|
||||
FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
|
||||
|
||||
This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
|
||||
This->bindCtxTableSize * sizeof(BindCtxObject));
|
||||
if (!This->bindCtxTable)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_RevokeObjectBound
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
|
||||
{
|
||||
DWORD index,j;
|
||||
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p)\n",This,punk);
|
||||
|
||||
/* check if the object was registered or not */
|
||||
if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
|
||||
return MK_E_NOTBOUND;
|
||||
|
||||
if(This->bindCtxTable[index].pObj)
|
||||
IUnknown_Release(This->bindCtxTable[index].pObj);
|
||||
if(This->bindCtxTable[index].pkeyObj)
|
||||
HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
|
||||
|
||||
/* left-shift all elements in the right side of the current revoked object */
|
||||
for(j=index; j<This->bindCtxTableLastIndex-1; j++)
|
||||
This->bindCtxTable[j]= This->bindCtxTable[j+1];
|
||||
|
||||
This->bindCtxTableLastIndex--;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_ReleaseBoundObjects
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
for(i=0;i<This->bindCtxTableLastIndex;i++)
|
||||
{
|
||||
if(This->bindCtxTable[i].pObj)
|
||||
IUnknown_Release(This->bindCtxTable[i].pObj);
|
||||
if(This->bindCtxTable[i].pkeyObj)
|
||||
HeapFree(GetProcessHeap(),0,This->bindCtxTable[i].pkeyObj);
|
||||
}
|
||||
|
||||
This->bindCtxTableLastIndex = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_SetBindOptions
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
|
||||
{
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p)\n",This,pbindopts);
|
||||
|
||||
if (pbindopts==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
|
||||
{
|
||||
WARN("invalid size\n");
|
||||
return E_INVALIDARG; /* FIXME : not verified */
|
||||
}
|
||||
memcpy(&This->bindOption2, pbindopts, pbindopts->cbStruct);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_GetBindOptions
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
|
||||
{
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p)\n",This,pbindopts);
|
||||
|
||||
if (pbindopts==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
|
||||
{
|
||||
WARN("invalid size\n");
|
||||
return E_INVALIDARG; /* FIXME : not verified */
|
||||
}
|
||||
memcpy(pbindopts, &This->bindOption2, pbindopts->cbStruct);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_GetRunningObjectTable
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot)
|
||||
{
|
||||
HRESULT res;
|
||||
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p)\n",This,pprot);
|
||||
|
||||
if (pprot==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
res=GetRunningObjectTable(0, pprot);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_RegisterObjectParam
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
|
||||
{
|
||||
DWORD index=0;
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
|
||||
|
||||
if (punk==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (pszkey!=NULL && BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_OK)
|
||||
{
|
||||
TRACE("Overwriting existing key\n");
|
||||
if(This->bindCtxTable[index].pObj!=NULL)
|
||||
IUnknown_Release(This->bindCtxTable[index].pObj);
|
||||
This->bindCtxTable[index].pObj=punk;
|
||||
IUnknown_AddRef(punk);
|
||||
return S_OK;
|
||||
}
|
||||
This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
|
||||
This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
|
||||
|
||||
if (pszkey==NULL)
|
||||
|
||||
This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=NULL;
|
||||
|
||||
else{
|
||||
|
||||
This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=
|
||||
HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR)*(1+lstrlenW(pszkey))));
|
||||
|
||||
if (This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
strcpyW(This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj,pszkey);
|
||||
}
|
||||
|
||||
This->bindCtxTableLastIndex++;
|
||||
|
||||
if (This->bindCtxTableLastIndex == This->bindCtxTableSize){ /* table is full ! must be resized */
|
||||
|
||||
This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
|
||||
|
||||
if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
|
||||
FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
|
||||
return E_FAIL;
|
||||
}
|
||||
This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
|
||||
This->bindCtxTableSize * sizeof(BindCtxObject));
|
||||
if (!This->bindCtxTable)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
IUnknown_AddRef(punk);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_GetObjectParam
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk)
|
||||
{
|
||||
DWORD index;
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_w(pszkey),punk);
|
||||
|
||||
if (punk==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*punk=0;
|
||||
|
||||
if (BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_FALSE)
|
||||
return E_FAIL;
|
||||
|
||||
IUnknown_AddRef(This->bindCtxTable[index].pObj);
|
||||
|
||||
*punk = This->bindCtxTable[index].pObj;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_RevokeObjectParam
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
|
||||
{
|
||||
DWORD index,j;
|
||||
|
||||
BindCtxImpl *This = (BindCtxImpl *)iface;
|
||||
|
||||
TRACE("(%p,%s)\n",This,debugstr_w(ppenum));
|
||||
|
||||
if (BindCtxImpl_GetObjectIndex(This,NULL,ppenum,&index)==S_FALSE)
|
||||
return E_FAIL;
|
||||
|
||||
/* release the object if it's found */
|
||||
if(This->bindCtxTable[index].pObj)
|
||||
IUnknown_Release(This->bindCtxTable[index].pObj);
|
||||
if(This->bindCtxTable[index].pkeyObj)
|
||||
HeapFree(GetProcessHeap(),0,This->bindCtxTable[index].pkeyObj);
|
||||
|
||||
/* remove the object from the table with a left-shifting of all objects in the right side */
|
||||
for(j=index; j<This->bindCtxTableLastIndex-1; j++)
|
||||
This->bindCtxTable[j]= This->bindCtxTable[j+1];
|
||||
|
||||
This->bindCtxTableLastIndex--;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BindCtx_EnumObjectParam
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
|
||||
{
|
||||
FIXME("(%p,%p),stub!\n",iface,pszkey);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* GetObjectIndex (local function)
|
||||
********************************************************************************/
|
||||
HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
|
||||
IUnknown* punk,
|
||||
LPOLESTR pszkey,
|
||||
DWORD *index)
|
||||
{
|
||||
|
||||
DWORD i;
|
||||
BYTE found=0;
|
||||
|
||||
TRACE("(%p,%p,%p,%p)\n",This,punk,pszkey,index);
|
||||
|
||||
if (punk==NULL)
|
||||
/* search object identified by a register key */
|
||||
for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++){
|
||||
|
||||
if(This->bindCtxTable[i].regType==1){
|
||||
|
||||
if ( ( (This->bindCtxTable[i].pkeyObj==NULL) && (pszkey==NULL) ) ||
|
||||
( (This->bindCtxTable[i].pkeyObj!=NULL) &&
|
||||
(pszkey!=NULL) &&
|
||||
(lstrcmpW(This->bindCtxTable[i].pkeyObj,pszkey)==0)
|
||||
)
|
||||
)
|
||||
|
||||
found=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* search object identified by a moniker*/
|
||||
for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
|
||||
if(This->bindCtxTable[i].pObj==punk)
|
||||
found=1;
|
||||
|
||||
if (index != NULL)
|
||||
*index=i-1;
|
||||
|
||||
if (found)
|
||||
return S_OK;
|
||||
TRACE("key not found\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateBindCtx16
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC * ppbc)
|
||||
{
|
||||
FIXME("(%ld,%p),stub!\n",reserved,ppbc);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateBindCtx (OLE32.@)
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
|
||||
{
|
||||
BindCtxImpl* newBindCtx = 0;
|
||||
HRESULT hr;
|
||||
IID riid=IID_IBindCtx;
|
||||
|
||||
TRACE("(%ld,%p)\n",reserved,ppbc);
|
||||
|
||||
newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
|
||||
|
||||
if (newBindCtx == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hr = BindCtxImpl_Construct(newBindCtx);
|
||||
|
||||
if (FAILED(hr)){
|
||||
|
||||
HeapFree(GetProcessHeap(),0,newBindCtx);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = BindCtxImpl_QueryInterface((IBindCtx*)newBindCtx,&riid,(void**)ppbc);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID riid, LPVOID * ppvResult)
|
||||
{
|
||||
HRESULT res;
|
||||
IBindCtx * pbc;
|
||||
|
||||
TRACE("(%p, %lx, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult);
|
||||
|
||||
res = CreateBindCtx(grfOpt, &pbc);
|
||||
if (SUCCEEDED(res))
|
||||
res = IMoniker_BindToObject(pmk, pbc, NULL, riid, ppvResult);
|
||||
return res;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,218 +0,0 @@
|
||||
1 pascal CoBuildVersion() CoBuildVersion
|
||||
2 pascal CoInitialize(long) CoInitialize16
|
||||
3 pascal CoUninitialize() CoUninitialize16
|
||||
4 pascal CoGetMalloc(long ptr) CoGetMalloc16
|
||||
5 pascal CoRegisterClassObject(ptr ptr long long ptr) CoRegisterClassObject16
|
||||
6 pascal CoRevokeClassObject(long) CoRevokeClassObject16
|
||||
7 pascal CoGetClassObject(ptr long ptr ptr ptr) CoGetClassObject
|
||||
8 stub COMARSHALINTERFACE
|
||||
9 stub COUNMARSHALINTERFACE
|
||||
10 stub COLOADLIBRARY
|
||||
11 stub COFREELIBRARY
|
||||
12 stub COFREEALLLIBRARIES
|
||||
13 pascal CoCreateInstance(ptr ptr long ptr ptr) CoCreateInstance
|
||||
14 stub STRINGFROMIID
|
||||
15 pascal CoDisconnectObject(ptr long) CoDisconnectObject
|
||||
16 stub CORELEASEMARSHALDATA
|
||||
17 pascal -ret16 CoFreeUnusedLibraries() CoFreeUnusedLibraries
|
||||
18 pascal -ret16 IsEqualGUID(ptr ptr) IsEqualGUID16
|
||||
19 pascal StringFromCLSID(ptr ptr) StringFromCLSID16
|
||||
20 pascal CLSIDFromString(str ptr) CLSIDFromString16
|
||||
21 stub ISVALIDPTRIN
|
||||
22 stub ISVALIDPTROUT
|
||||
23 stub ISVALIDINTERFACE
|
||||
24 stub ISVALIDIID
|
||||
25 stub RESULTFROMSCODE
|
||||
26 stub GETSCODE
|
||||
27 pascal CoRegisterMessageFilter(ptr ptr) CoRegisterMessageFilter16
|
||||
28 stub COISHANDLERCONNECTED
|
||||
29 stub SHRADDREF
|
||||
30 pascal -ret16 CoFileTimeToDosDateTime(ptr ptr ptr) CoFileTimeToDosDateTime16
|
||||
31 pascal -ret16 CoDosDateTimeToFileTime(word word ptr) CoDosDateTimeToFileTime16
|
||||
32 stub COMARSHALHRESULT
|
||||
33 stub COUNMARSHALHRESULT
|
||||
34 pascal CoGetCurrentProcess() CoGetCurrentProcess
|
||||
35 stub SHRCREATE
|
||||
36 stub COISOLE1CLASS
|
||||
37 stub _GUID_NULL
|
||||
38 stub _IID_IUNKNOWN
|
||||
39 stub _IID_ICLASSFACTORY
|
||||
40 stub _IID_IMALLOC
|
||||
41 stub _IID_IMARSHAL
|
||||
42 stub _IID_IRPCCHANNEL
|
||||
43 stub _IID_IRPCSTUB
|
||||
44 stub _IID_ISTUBMANAGER
|
||||
45 stub _IID_IRPCPROXY
|
||||
46 stub _IID_IPROXYMANAGER
|
||||
47 stub _IID_IPSFACTORY
|
||||
48 stub _IID_ILOCKBYTES
|
||||
49 stub _IID_ISTORAGE
|
||||
50 stub _IID_ISTREAM
|
||||
51 stub _IID_IENUMSTATSTG
|
||||
52 stub _IID_IBINDCTX
|
||||
53 stub _IID_IMONIKER
|
||||
54 stub _IID_IRUNNINGOBJECTTABLE
|
||||
55 stub _IID_IINTERNALMONIKER
|
||||
56 stub _IID_IROOTSTORAGE
|
||||
57 stub _IID_IDFRESERVED1
|
||||
58 stub _IID_IDFRESERVED2
|
||||
59 stub _IID_IDFRESERVED3
|
||||
60 stub _IID_IMESSAGEFILTER
|
||||
61 pascal CLSIDFromProgID(str ptr) CLSIDFromProgID16
|
||||
62 pascal ProgIDFromCLSID(ptr ptr) ProgIDFromCLSID16
|
||||
63 pascal CoLockObjectExternal(segptr word word) CoLockObjectExternal16
|
||||
64 stub _CLSID_STDMARSHAL
|
||||
65 stub COGETTREATASCLASS
|
||||
66 stub COTREATASCLASS
|
||||
67 stub COGETSTANDARDMARSHAL
|
||||
68 stub PROPAGATERESULT
|
||||
69 stub IIDFROMSTRING
|
||||
70 stub _IID_ISTDMARSHALINFO
|
||||
71 pascal CoCreateStandardMalloc(long ptr) CoCreateStandardMalloc16
|
||||
72 stub _IID_IEXTERNALCONNECTION
|
||||
73 stub COCREATEGUID
|
||||
75 stub FNASSERT
|
||||
76 pascal StringFromGUID2(ptr ptr word) StringFromGUID2
|
||||
77 stub COGETCLASSEXT
|
||||
78 stub OLE1CLASSFROMCLSID2
|
||||
79 stub CLSIDFROMOLE1CLASS
|
||||
80 stub COOPENCLASSKEY
|
||||
81 stub GUIDFROMSTRING
|
||||
82 pascal CoFileTimeNow(ptr) CoFileTimeNow
|
||||
83 stub REMALLOCOID
|
||||
84 stub REMFREEOID
|
||||
85 stub REMCREATEREMOTEHANDLER
|
||||
86 stub REMCONNECTTOOBJECT
|
||||
87 stub REMGETINFOFORCID
|
||||
88 stub LRPCCALL
|
||||
89 stub LRPCDISPATCH
|
||||
90 stub LRPCREGISTERMONITOR
|
||||
91 stub LRPCREVOKEMONITOR
|
||||
92 stub LRPCGETTHREADWINDOW
|
||||
93 stub TIMERCALLBACKPROC
|
||||
94 pascal LookupETask(ptr ptr) LookupETask16
|
||||
95 pascal -ret16 SetETask(word ptr) SetETask16
|
||||
96 stub LRPCFREEMONITORDATA
|
||||
97 stub REMLOOKUPSHUNK
|
||||
98 stub SHRGETSIZE
|
||||
99 stub CALLTHKMGRUNINITIALIZE
|
||||
100 stub ??0CARRAYFVALUE@@REC@KI@Z
|
||||
101 stub ??1CARRAYFVALUE@@REC@XZ
|
||||
102 stub ?ASSERTVALID@CARRAYFVALUE@@RFCXXZ
|
||||
103 stub ?FREEEXTRA@CARRAYFVALUE@@RECXXZ
|
||||
104 stub ?_GETAT@CARRAYFVALUE@@RFCPEXH@Z
|
||||
105 stub ?GETSIZE@CARRAYFVALUE@@RFCHXZ
|
||||
106 stub ?REMOVEALL@CARRAYFVALUE@@RECXXZ
|
||||
107 stub SHRDESTROY
|
||||
108 stub ?INDEXOF@CARRAYFVALUE@@RECHPEXII@Z
|
||||
109 stub ?INSERTAT@CARRAYFVALUE@@RECHHPEXH@Z
|
||||
110 stub COSETSTATE
|
||||
111 stub ?REMOVEAT@CARRAYFVALUE@@RECXHH@Z
|
||||
112 stub ?SETAT@CARRAYFVALUE@@RECXHPEX@Z
|
||||
113 stub ?SETATGROW@CARRAYFVALUE@@RECHHPEX@Z
|
||||
114 stub ?SETSIZE@CARRAYFVALUE@@RECHHH@Z
|
||||
115 pascal CoGetState(ptr) CoGetState16
|
||||
116 pascal DllEntryPoint(long word word word long word) COMPOBJ_DllEntryPoint
|
||||
117 stub ?RELEASE@CSTDMALLOC@@VEAKXZ
|
||||
118 stub ?ALLOC@CSTDMALLOC@@VEAPEXK@Z
|
||||
119 stub SHRRELEASE
|
||||
120 stub ?GETASSOCAT@CMAPKEYTOVALUE@@BFCPEUCASSOC@1@PEXIAEI@Z
|
||||
121 stub ?SETASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
|
||||
122 stub ??1CMAPKEYTOVALUE@@REC@XZ
|
||||
123 stub ?GETASSOCKEYPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEXPEI@Z
|
||||
124 stub ?NEWASSOC@CMAPKEYTOVALUE@@BECPEUCASSOC@1@IPEXI0@Z
|
||||
125 stub ?SIZEASSOC@CMAPKEYTOVALUE@@BFCIXZ
|
||||
126 stub ?FREEASSOC@CMAPKEYTOVALUE@@BECXPEUCASSOC@1@@Z
|
||||
127 stub ?GETSTARTPOSITION@CMAPKEYTOVALUE@@RFCPEXXZ
|
||||
128 stub ?GETNEXTASSOC@CMAPKEYTOVALUE@@RFCXPEPEXPEXPEI1@Z
|
||||
129 stub ?COMPAREASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
|
||||
130 stub ?REMOVEHKEY@CMAPKEYTOVALUE@@RECHK@Z
|
||||
131 stub ?GETHKEY@CMAPKEYTOVALUE@@RFCKPEXI@Z
|
||||
132 stub ?GETCOUNT@CMAPKEYTOVALUE@@RFCHXZ
|
||||
133 stub ?LOOKUP@CMAPKEYTOVALUE@@RFCHPEXI0@Z
|
||||
134 stub ?GETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
|
||||
135 stub ?REMOVEKEY@CMAPKEYTOVALUE@@RECHPEXI@Z
|
||||
136 stub ?REMOVEALL@CMAPKEYTOVALUE@@RECXXZ
|
||||
137 stub SHRALLOC
|
||||
138 stub ?FREEASSOCKEY@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@@Z
|
||||
139 stub ?SETAT@CMAPKEYTOVALUE@@RECHPEXI0@Z
|
||||
140 stub ?LOOKUPHKEY@CMAPKEYTOVALUE@@RFCHKPEX@Z
|
||||
141 stub ?ASSERTVALID@CMAPKEYTOVALUE@@RFCXXZ
|
||||
142 stub ?SETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
|
||||
143 stub ?SETATHKEY@CMAPKEYTOVALUE@@RECHKPEX@Z
|
||||
144 stub ??0CMAPKEYTOVALUE@@REC@KIIHP7CIPEXI@ZI@Z
|
||||
145 stub ?INITHASHTABLE@CMAPKEYTOVALUE@@BECHXZ
|
||||
146 stub ?GETASSOCVALUEPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEX@Z
|
||||
147 stub ?LOOKUPADD@CMAPKEYTOVALUE@@RFCHPEXI0@Z
|
||||
148 stub MKVDEFAULTHASHKEY
|
||||
149 stub DELETE16
|
||||
150 stub COMEMCTXOF
|
||||
151 stub COMEMALLOC
|
||||
152 stub COMEMFREE
|
||||
153 stub SHRREALLOC
|
||||
154 stub ___EXPORTEDSTUB
|
||||
155 stub LRPCREGISTERWIN32SMONITOR
|
||||
156 stub MYREMGETINFOFORCID
|
||||
157 stub SHRFREE
|
||||
158 stub OPNEW16
|
||||
159 stub ADDCOINFO
|
||||
160 stub CORUNMODALLOOP
|
||||
161 stub COHANDLEINCOMINGCALL
|
||||
162 stub COSETACKSTATE
|
||||
163 stub SHRDIDALLOC
|
||||
164 stub ?GETAT@CARRAYFVALUE@@RFCPEXH@Z
|
||||
165 stub ?GETUPPERBOUND@CARRAYFVALUE@@RFCHXZ
|
||||
166 stub OPDELETE16
|
||||
167 stub ?GETSIZEVALUE@CARRAYFVALUE@@RFCHXZ
|
||||
168 stub ?PROXY1632ADDREF@@ZAKPEVCPROXY1632@@@Z
|
||||
# FIXME: 169 is a duplicate of 97
|
||||
169 stub REMLOOKUPSHUNK_dup
|
||||
170 stub ?ISEMPTY@CMAPKEYTOVALUE@@RFCHXZ
|
||||
171 stub ?FREE@CSTDMALLOC@@VEAXPEX@Z
|
||||
172 stub CALLTHKMGRINITIALIZE
|
||||
173 stub ?REALLOC@CSTDMALLOC@@VEAPEXPEXK@Z
|
||||
174 stub ?SM16RHQI@@ZAPEXPEVCSM16RELEASEHANDLER@@AFUGUID@@PEPEX@Z
|
||||
175 stub ?PROXY1632METHOD10@@ZAKPEVCPROXY1632@@@Z
|
||||
# FIXME: 176 is a duplicate of 154
|
||||
176 stub ___EXPORTEDSTUB_dup
|
||||
177 stub ?PROXY1632METHOD20@@ZAKPEVCPROXY1632@@@Z
|
||||
178 stub ?PROXY1632METHOD11@@ZAKPEVCPROXY1632@@@Z
|
||||
179 stub ?PROXY1632METHOD30@@ZAKPEVCPROXY1632@@@Z
|
||||
180 stub ?PROXY1632METHOD21@@ZAKPEVCPROXY1632@@@Z
|
||||
181 stub ?PROXY1632METHOD12@@ZAKPEVCPROXY1632@@@Z
|
||||
182 stub ?PROXY1632METHOD31@@ZAKPEVCPROXY1632@@@Z
|
||||
183 stub ?PROXY1632METHOD22@@ZAKPEVCPROXY1632@@@Z
|
||||
184 stub ?PROXY1632METHOD13@@ZAKPEVCPROXY1632@@@Z
|
||||
185 stub ?GETSIZE@CSTDMALLOC@@VEAKPEX@Z
|
||||
186 stub ?PROXY1632METHOD23@@ZAKPEVCPROXY1632@@@Z
|
||||
187 stub ?PROXY1632METHOD14@@ZAKPEVCPROXY1632@@@Z
|
||||
188 stub ?PROXY1632METHOD24@@ZAKPEVCPROXY1632@@@Z
|
||||
189 stub ?PROXY1632METHOD15@@ZAKPEVCPROXY1632@@@Z
|
||||
190 stub ?PROXY1632METHOD25@@ZAKPEVCPROXY1632@@@Z
|
||||
191 stub ?PROXY1632METHOD16@@ZAKPEVCPROXY1632@@@Z
|
||||
192 stub ?PROXY1632METHOD26@@ZAKPEVCPROXY1632@@@Z
|
||||
193 stub ?PROXY1632METHOD17@@ZAKPEVCPROXY1632@@@Z
|
||||
194 stub ?PROXY1632METHOD27@@ZAKPEVCPROXY1632@@@Z
|
||||
195 stub ?PROXY1632METHOD18@@ZAKPEVCPROXY1632@@@Z
|
||||
196 stub ?PROXY1632METHOD28@@ZAKPEVCPROXY1632@@@Z
|
||||
197 stub ?ADDREF@CSTDMALLOC@@VEAKXZ
|
||||
198 stub ?PROXY1632METHOD19@@ZAKPEVCPROXY1632@@@Z
|
||||
199 stub ?PROXY1632METHOD29@@ZAKPEVCPROXY1632@@@Z
|
||||
200 stub CALL32INITIALIZE
|
||||
201 pascal CALLOBJECTINWOW(ptr ptr) CallObjectInWOW
|
||||
203 stub CALLOBJECTINWOWCHECKINIT
|
||||
204 stub CALLOBJECTINWOWCHECKTHKMGR
|
||||
205 stub CONVERTHR1632
|
||||
206 stub CONVERTHR3216
|
||||
207 stub ADDAPPCOMPATFLAG
|
||||
|
||||
# WINE internal relays (for Win16 interfaces)
|
||||
500 cdecl IMalloc16_QueryInterface(ptr ptr ptr) IMalloc16_fnQueryInterface
|
||||
501 cdecl IMalloc16_AddRef(ptr) IMalloc16_fnAddRef
|
||||
502 cdecl IMalloc16_Release(ptr) IMalloc16_fnRelease
|
||||
503 cdecl IMalloc16_Alloc(ptr long) IMalloc16_fnAlloc
|
||||
504 cdecl IMalloc16_Realloc(ptr segptr long) IMalloc16_fnRealloc
|
||||
505 cdecl IMalloc16_Free(ptr segptr) IMalloc16_fnFree
|
||||
506 cdecl IMalloc16_GetSize(ptr segptr) IMalloc16_fnGetSize
|
||||
507 cdecl IMalloc16_DidAlloc(ptr segptr) IMalloc16_fnDidAlloc
|
||||
508 cdecl IMalloc16_HeapMinimize(ptr) IMalloc16_fnHeapMinimize
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
* Copyright 1995 Martin von Loewis
|
||||
* Copyright 1998 Justin Bradford
|
||||
* Copyright 1999 Francis Beaudet
|
||||
* Copyright 1999 Sylvain St-Germain
|
||||
* Copyright 2002 Marcus Meissner
|
||||
* Copyright 2003 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_OLE_COMPOBJ_H
|
||||
#define __WINE_OLE_COMPOBJ_H
|
||||
|
||||
/* All private prototype functions used by OLE will be added to this header file */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wtypes.h"
|
||||
#include "dcom.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
/* Windows maps COINIT values to 0x80 for apartment threaded, 0x140
|
||||
* for free threaded, and 0 for uninitialized apartments. There is
|
||||
* no real advantage in us doing this and certainly no release version
|
||||
* of an app should be poking around with these flags. So we need a
|
||||
* special value for uninitialized */
|
||||
#define COINIT_UNINITIALIZED 0x100
|
||||
|
||||
/* exported interface */
|
||||
typedef struct tagXIF {
|
||||
struct tagXIF *next;
|
||||
LPVOID iface; /* interface pointer */
|
||||
IID iid; /* interface ID */
|
||||
IPID ipid; /* exported interface ID */
|
||||
LPRPCSTUBBUFFER stub; /* interface stub */
|
||||
DWORD refs; /* external reference count */
|
||||
HRESULT hres; /* result of stub creation attempt */
|
||||
} XIF;
|
||||
|
||||
/* exported object */
|
||||
typedef struct tagXOBJECT {
|
||||
IRpcStubBufferVtbl *lpVtbl;
|
||||
struct tagAPARTMENT *parent;
|
||||
struct tagXOBJECT *next;
|
||||
LPUNKNOWN obj; /* object identity (IUnknown) */
|
||||
OID oid; /* object ID */
|
||||
DWORD ifc; /* interface ID counter */
|
||||
XIF *ifaces; /* exported interfaces */
|
||||
DWORD refs; /* external reference count */
|
||||
} XOBJECT;
|
||||
|
||||
/* imported interface */
|
||||
typedef struct tagIIF {
|
||||
struct tagIIF *next;
|
||||
LPVOID iface; /* interface pointer */
|
||||
IID iid; /* interface ID */
|
||||
IPID ipid; /* imported interface ID */
|
||||
LPRPCPROXYBUFFER proxy; /* interface proxy */
|
||||
DWORD refs; /* imported (public) references */
|
||||
HRESULT hres; /* result of proxy creation attempt */
|
||||
} IIF;
|
||||
|
||||
/* imported object */
|
||||
typedef struct tagIOBJECT {
|
||||
IRemUnknownVtbl *lpVtbl;
|
||||
struct tagAPARTMENT *parent;
|
||||
struct tagIOBJECT *next;
|
||||
LPRPCCHANNELBUFFER chan; /* channel to object */
|
||||
OXID oxid; /* object exported ID */
|
||||
OID oid; /* object ID */
|
||||
IPID ipid; /* first imported interface ID */
|
||||
IIF *ifaces; /* imported interfaces */
|
||||
DWORD refs; /* proxy reference count */
|
||||
} IOBJECT;
|
||||
|
||||
/* apartment */
|
||||
typedef struct tagAPARTMENT {
|
||||
struct tagAPARTMENT *next, *prev, *parent;
|
||||
DWORD model; /* threading model */
|
||||
DWORD inits; /* CoInitialize count */
|
||||
DWORD tid; /* thread id */
|
||||
HANDLE thread; /* thread handle */
|
||||
OXID oxid; /* object exporter ID */
|
||||
OID oidc; /* object ID counter */
|
||||
HWND win; /* message window */
|
||||
CRITICAL_SECTION cs; /* thread safety */
|
||||
LPMESSAGEFILTER filter; /* message filter */
|
||||
XOBJECT *objs; /* exported objects */
|
||||
IOBJECT *proxies; /* imported objects */
|
||||
LPUNKNOWN state; /* state object (see Co[Get,Set]State) */
|
||||
LPVOID ErrorInfo; /* thread error info */
|
||||
} APARTMENT;
|
||||
|
||||
extern APARTMENT MTA, *apts;
|
||||
|
||||
extern void* StdGlobalInterfaceTable_Construct();
|
||||
extern void StdGlobalInterfaceTable_Destroy(void* self);
|
||||
extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);
|
||||
|
||||
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
|
||||
extern HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
|
||||
|
||||
extern void* StdGlobalInterfaceTableInstance;
|
||||
|
||||
#define PIPEPREF "\\\\.\\pipe\\"
|
||||
#define OLESTUBMGR PIPEPREF"WINE_OLE_StubMgr"
|
||||
|
||||
/* Standard Marshalling definitions */
|
||||
typedef struct _wine_marshal_id {
|
||||
DWORD processid;
|
||||
DWORD objectid; /* unique value corresp. IUnknown of object */
|
||||
IID iid;
|
||||
} wine_marshal_id;
|
||||
|
||||
inline static BOOL
|
||||
MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
|
||||
return
|
||||
(mid1->processid == mid2->processid) &&
|
||||
(mid1->objectid == mid2->objectid) &&
|
||||
IsEqualIID(&(mid1->iid),&(mid2->iid))
|
||||
;
|
||||
}
|
||||
|
||||
/* compare without interface compare */
|
||||
inline static BOOL
|
||||
MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id *mid2) {
|
||||
return
|
||||
(mid1->processid == mid2->processid) &&
|
||||
(mid1->objectid == mid2->objectid)
|
||||
;
|
||||
}
|
||||
|
||||
HRESULT MARSHAL_Find_Stub_Buffer(wine_marshal_id *mid,IRpcStubBuffer **stub);
|
||||
void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid);
|
||||
HRESULT MARSHAL_Disconnect_Proxies();
|
||||
|
||||
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
|
||||
|
||||
void STUBMGR_Start();
|
||||
|
||||
extern HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf);
|
||||
|
||||
/* This function initialize the Running Object Table */
|
||||
HRESULT WINAPI RunningObjectTableImpl_Initialize();
|
||||
|
||||
/* This function uninitialize the Running Object Table */
|
||||
HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
|
||||
|
||||
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
|
||||
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
|
||||
|
||||
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
|
||||
|
||||
/*
|
||||
* Per-thread values are stored in the TEB on offset 0xF80,
|
||||
* see http://www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm
|
||||
*/
|
||||
static inline APARTMENT* COM_CurrentInfo(void)
|
||||
{
|
||||
APARTMENT* apt = NtCurrentTeb()->ReservedForOle;
|
||||
return apt;
|
||||
}
|
||||
static inline APARTMENT* COM_CurrentApt(void)
|
||||
{
|
||||
APARTMENT* apt = COM_CurrentInfo();
|
||||
if (apt && apt->parent) apt = apt->parent;
|
||||
return apt;
|
||||
}
|
||||
|
||||
/* compobj.c */
|
||||
APARTMENT* COM_CreateApartment(DWORD model);
|
||||
HWND COM_GetApartmentWin(OXID oxid);
|
||||
|
||||
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
||||
|
||||
#endif /* __WINE_OLE_COMPOBJ_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,515 +0,0 @@
|
||||
/*** Autogenerated by WIDL 0.1 from dcom.idl - Do not edit ***/
|
||||
#include <rpc.h>
|
||||
#include <rpcndr.h>
|
||||
|
||||
#ifndef __WIDL_DCOM_H
|
||||
#define __WIDL_DCOM_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <unknwn.h>
|
||||
typedef MIDL_uhyper ID;
|
||||
|
||||
typedef ID MID;
|
||||
|
||||
typedef ID OXID;
|
||||
|
||||
typedef ID OID;
|
||||
|
||||
typedef ID SETID;
|
||||
|
||||
typedef GUID IPID;
|
||||
|
||||
typedef GUID CID;
|
||||
|
||||
typedef REFGUID REFIPID;
|
||||
|
||||
#define COM_MINOR_VERSION_1 (1)
|
||||
|
||||
#define COM_MINOR_VERSION_2 (2)
|
||||
|
||||
#define COM_MAJOR_VERSION (5)
|
||||
|
||||
#define COM_MINOR_VERSION (3)
|
||||
|
||||
typedef struct tagCOMVERSION {
|
||||
unsigned short MajorVersion;
|
||||
unsigned short MinorVersion;
|
||||
} COMVERSION;
|
||||
|
||||
#define ORPCF_NULL (0)
|
||||
|
||||
#define ORPCF_LOCAL (1)
|
||||
|
||||
#define ORPCF_RESERVED1 (2)
|
||||
|
||||
#define ORPCF_RESERVED2 (4)
|
||||
|
||||
#define ORPCF_RESERVED3 (8)
|
||||
|
||||
#define ORPCF_RESERVED4 (16)
|
||||
|
||||
typedef struct tagORPC_EXTENT {
|
||||
GUID id;
|
||||
unsigned long size;
|
||||
byte data[1];
|
||||
} ORPC_EXTENT;
|
||||
|
||||
typedef struct tagORPC_EXTENT_ARRAY {
|
||||
unsigned long size;
|
||||
unsigned long reserved;
|
||||
ORPC_EXTENT **extent;
|
||||
} ORPC_EXTENT_ARRAY;
|
||||
|
||||
typedef struct tagORPCTHIS {
|
||||
COMVERSION version;
|
||||
unsigned long flags;
|
||||
unsigned long reserved1;
|
||||
CID cid;
|
||||
ORPC_EXTENT_ARRAY *extensions;
|
||||
} ORPCTHIS;
|
||||
|
||||
typedef struct tagORPCTHAT {
|
||||
unsigned long flags;
|
||||
ORPC_EXTENT_ARRAY *extensions;
|
||||
} ORPCTHAT;
|
||||
|
||||
#define NCADG_IP_UDP (0x8)
|
||||
|
||||
#define NCACN_IP_TCP (0x7)
|
||||
|
||||
#define NCADG_IPX (0xe)
|
||||
|
||||
#define NCACN_SPX (0xc)
|
||||
|
||||
#define NCACN_NB_NB (0x12)
|
||||
|
||||
#define NCACN_NB_IPX (0xd)
|
||||
|
||||
#define NCACN_DNET_NSP (0x4)
|
||||
|
||||
#define NCACN_HTTP (0x1f)
|
||||
|
||||
typedef struct tagSTRINGBINDING {
|
||||
unsigned short wTowerId;
|
||||
unsigned short aNetworkAddr[1];
|
||||
} STRINGBINDING;
|
||||
|
||||
#define COM_C_AUTHZ_NONE (0xffff)
|
||||
|
||||
typedef struct tagSECURITYBINDING {
|
||||
unsigned short wAuthnSvc;
|
||||
unsigned short wAuthzSvc;
|
||||
unsigned short aPrincName[1];
|
||||
} SECURITYBINDING;
|
||||
|
||||
typedef struct tagDUALSTRINGARRAY {
|
||||
unsigned short wNumEntries;
|
||||
unsigned short wSecurityOffset;
|
||||
unsigned short aStringArray[1];
|
||||
} DUALSTRINGARRAY;
|
||||
|
||||
#define OBJREF_SIGNATURE (0x574f454d)
|
||||
|
||||
#define OBJREF_STANDARD (0x1)
|
||||
|
||||
#define OBJREF_HANDLER (0x2)
|
||||
|
||||
#define OBJREF_CUSTOM (0x4)
|
||||
|
||||
#define SORF_OXRES1 (0x1)
|
||||
|
||||
#define SORF_OXRES2 (0x20)
|
||||
|
||||
#define SORF_OXRES3 (0x40)
|
||||
|
||||
#define SORF_OXRES4 (0x80)
|
||||
|
||||
#define SORF_OXRES5 (0x100)
|
||||
|
||||
#define SORF_OXRES6 (0x200)
|
||||
|
||||
#define SORF_OXRES7 (0x400)
|
||||
|
||||
#define SORF_OXRES8 (0x800)
|
||||
|
||||
#define SORF_NULL (0x0)
|
||||
|
||||
#define SORF_NOPING (0x1000)
|
||||
|
||||
typedef struct tagSTDOBJREF {
|
||||
unsigned long flags;
|
||||
unsigned long cPublicRefs;
|
||||
OXID oxid;
|
||||
OID oid;
|
||||
IPID ipid;
|
||||
} STDOBJREF;
|
||||
|
||||
typedef struct tagOBJREF {
|
||||
unsigned long signature;
|
||||
unsigned long flags;
|
||||
GUID iid;
|
||||
union {
|
||||
struct OR_STANDARD {
|
||||
STDOBJREF std;
|
||||
DUALSTRINGARRAY saResAddr;
|
||||
} u_standard;
|
||||
struct OR_HANDLER {
|
||||
STDOBJREF std;
|
||||
CLSID clsid;
|
||||
DUALSTRINGARRAY saResAddr;
|
||||
} u_handler;
|
||||
struct OR_CUSTOM {
|
||||
CLSID clsid;
|
||||
unsigned long cbExtension;
|
||||
unsigned long size;
|
||||
byte *pData;
|
||||
} u_custom;
|
||||
} u_objref;
|
||||
} OBJREF;
|
||||
|
||||
typedef struct tagMInterfacePointer {
|
||||
ULONG ulCntData;
|
||||
BYTE abData[1];
|
||||
} MInterfacePointer;
|
||||
|
||||
typedef MInterfacePointer *PMInterfacePointer;
|
||||
|
||||
#ifndef __IRemUnknown_FWD_DEFINED__
|
||||
#define __IRemUnknown_FWD_DEFINED__
|
||||
typedef struct IRemUnknown IRemUnknown;
|
||||
#endif
|
||||
|
||||
typedef IRemUnknown *LPREMUNKNOWN;
|
||||
|
||||
typedef struct tagREMQIRESULT {
|
||||
HRESULT hResult;
|
||||
STDOBJREF std;
|
||||
} REMQIRESULT;
|
||||
|
||||
typedef struct tagREMINTERFACEREF {
|
||||
IPID ipid;
|
||||
unsigned long cPublicRefs;
|
||||
unsigned long cPrivateRefs;
|
||||
} REMINTERFACEREF;
|
||||
|
||||
/*****************************************************************************
|
||||
* IRemUnknown interface
|
||||
*/
|
||||
#ifndef __IRemUnknown_INTERFACE_DEFINED__
|
||||
#define __IRemUnknown_INTERFACE_DEFINED__
|
||||
|
||||
DEFINE_GUID(IID_IRemUnknown, 0x00000131, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
struct IRemUnknown : public IUnknown
|
||||
{
|
||||
virtual HRESULT STDMETHODCALLTYPE RemQueryInterface(
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE RemAddRef(
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE RemRelease(
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs) = 0;
|
||||
|
||||
};
|
||||
#else
|
||||
typedef struct IRemUnknownVtbl IRemUnknownVtbl;
|
||||
struct IRemUnknown {
|
||||
const IRemUnknownVtbl* lpVtbl;
|
||||
};
|
||||
struct IRemUnknownVtbl {
|
||||
BEGIN_INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
|
||||
IRemUnknown* This,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *AddRef)(
|
||||
IRemUnknown* This);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *Release)(
|
||||
IRemUnknown* This);
|
||||
|
||||
/*** IRemUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *RemQueryInterface)(
|
||||
IRemUnknown* This,
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemAddRef)(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemRelease)(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs);
|
||||
|
||||
END_INTERFACE
|
||||
};
|
||||
|
||||
#ifdef COBJMACROS
|
||||
/*** IUnknown methods ***/
|
||||
#define IRemUnknown_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IRemUnknown_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IRemUnknown_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IRemUnknown methods ***/
|
||||
#define IRemUnknown_RemQueryInterface(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface(p,a,b,c,d,e)
|
||||
#define IRemUnknown_RemAddRef(p,a,b,c) (p)->lpVtbl->RemAddRef(p,a,b,c)
|
||||
#define IRemUnknown_RemRelease(p,a,b) (p)->lpVtbl->RemRelease(p,a,b)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define IRemUnknown_METHODS \
|
||||
/*** IUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE; \
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE; \
|
||||
/*** IRemUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,RemQueryInterface)(THIS_ REFIPID ripid, unsigned long cRefs, unsigned short cIids, IID* iids, REMQIRESULT** ppQIResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemAddRef)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs, HRESULT* pResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemRelease)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs) PURE;
|
||||
|
||||
HRESULT CALLBACK IRemUnknown_RemQueryInterface_Proxy(
|
||||
IRemUnknown* This,
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults);
|
||||
void __RPC_STUB IRemUnknown_RemQueryInterface_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IRemUnknown_RemAddRef_Proxy(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults);
|
||||
void __RPC_STUB IRemUnknown_RemAddRef_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IRemUnknown_RemRelease_Proxy(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs);
|
||||
void __RPC_STUB IRemUnknown_RemRelease_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
|
||||
#endif /* __IRemUnknown_INTERFACE_DEFINED__ */
|
||||
|
||||
#ifndef __IRemUnknown2_FWD_DEFINED__
|
||||
#define __IRemUnknown2_FWD_DEFINED__
|
||||
typedef struct IRemUnknown2 IRemUnknown2;
|
||||
#endif
|
||||
|
||||
typedef IRemUnknown2 *LPREMUNKNOWN2;
|
||||
|
||||
/*****************************************************************************
|
||||
* IRemUnknown2 interface
|
||||
*/
|
||||
#ifndef __IRemUnknown2_INTERFACE_DEFINED__
|
||||
#define __IRemUnknown2_INTERFACE_DEFINED__
|
||||
|
||||
DEFINE_GUID(IID_IRemUnknown2, 0x00000142, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
struct IRemUnknown2 : public IRemUnknown
|
||||
{
|
||||
virtual HRESULT STDMETHODCALLTYPE RemQueryInterface2(
|
||||
REFIPID ripid,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppMIF) = 0;
|
||||
|
||||
};
|
||||
#else
|
||||
typedef struct IRemUnknown2Vtbl IRemUnknown2Vtbl;
|
||||
struct IRemUnknown2 {
|
||||
const IRemUnknown2Vtbl* lpVtbl;
|
||||
};
|
||||
struct IRemUnknown2Vtbl {
|
||||
BEGIN_INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
|
||||
IRemUnknown2* This,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *AddRef)(
|
||||
IRemUnknown2* This);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *Release)(
|
||||
IRemUnknown2* This);
|
||||
|
||||
/*** IRemUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *RemQueryInterface)(
|
||||
IRemUnknown2* This,
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemAddRef)(
|
||||
IRemUnknown2* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemRelease)(
|
||||
IRemUnknown2* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs);
|
||||
|
||||
/*** IRemUnknown2 methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *RemQueryInterface2)(
|
||||
IRemUnknown2* This,
|
||||
REFIPID ripid,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppMIF);
|
||||
|
||||
END_INTERFACE
|
||||
};
|
||||
|
||||
#ifdef COBJMACROS
|
||||
/*** IUnknown methods ***/
|
||||
#define IRemUnknown2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IRemUnknown2_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IRemUnknown2_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IRemUnknown methods ***/
|
||||
#define IRemUnknown2_RemQueryInterface(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface(p,a,b,c,d,e)
|
||||
#define IRemUnknown2_RemAddRef(p,a,b,c) (p)->lpVtbl->RemAddRef(p,a,b,c)
|
||||
#define IRemUnknown2_RemRelease(p,a,b) (p)->lpVtbl->RemRelease(p,a,b)
|
||||
/*** IRemUnknown2 methods ***/
|
||||
#define IRemUnknown2_RemQueryInterface2(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface2(p,a,b,c,d,e)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define IRemUnknown2_METHODS \
|
||||
/*** IUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE; \
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE; \
|
||||
/*** IRemUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,RemQueryInterface)(THIS_ REFIPID ripid, unsigned long cRefs, unsigned short cIids, IID* iids, REMQIRESULT** ppQIResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemAddRef)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs, HRESULT* pResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemRelease)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs) PURE; \
|
||||
/*** IRemUnknown2 methods ***/ \
|
||||
STDMETHOD_(HRESULT,RemQueryInterface2)(THIS_ REFIPID ripid, unsigned short cIids, IID* iids, HRESULT* phr, MInterfacePointer** ppMIF) PURE;
|
||||
|
||||
HRESULT CALLBACK IRemUnknown2_RemQueryInterface2_Proxy(
|
||||
IRemUnknown2* This,
|
||||
REFIPID ripid,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppMIF);
|
||||
void __RPC_STUB IRemUnknown2_RemQueryInterface2_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
|
||||
#endif /* __IRemUnknown2_INTERFACE_DEFINED__ */
|
||||
|
||||
#if 0
|
||||
/*****************************************************************************
|
||||
* IOXIDResolver interface (v0.0)
|
||||
*/
|
||||
DEFINE_GUID(IID_IOXIDResolver, 0x99fcfec4, 0x5260, 0x101b, 0xbb,0xcb, 0x00,0xaa,0x00,0x21,0x34,0x7a);
|
||||
extern RPC_IF_HANDLE IOXIDResolver_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE IOXIDResolver_v0_0_s_ifspec;
|
||||
error_status_t ResolveOxid(
|
||||
handle_t hRpc,
|
||||
OXID* pOxid,
|
||||
unsigned short cRequestedProtseqs,
|
||||
unsigned short arRequestedProtseqs[],
|
||||
DUALSTRINGARRAY** ppdsaOxidBindings,
|
||||
IPID* pipidRemUnknown,
|
||||
DWORD* pAuthnHint);
|
||||
error_status_t SimplePing(
|
||||
handle_t hRpc,
|
||||
SETID* pSetId);
|
||||
error_status_t ComplexPing(
|
||||
handle_t hRpc,
|
||||
SETID* pSetId,
|
||||
unsigned short SequenceNum,
|
||||
unsigned short cAddToSet,
|
||||
unsigned short cDelFromSet,
|
||||
OID AddToSet[],
|
||||
OID DelFromSet[],
|
||||
unsigned short* pPingBackoffFactor);
|
||||
error_status_t ServerAlive(
|
||||
handle_t hRpc);
|
||||
error_status_t ResolveOxid2(
|
||||
handle_t hRpc,
|
||||
OXID* pOxid,
|
||||
unsigned short cRequestedProtseqs,
|
||||
unsigned short arRequestedProtseqs[],
|
||||
DUALSTRINGARRAY** ppdsaOxidBindings,
|
||||
IPID* pipidRemUnknown,
|
||||
DWORD* pAuthnHint,
|
||||
COMVERSION* pComVersion);
|
||||
|
||||
#define MODE_GET_CLASS_OBJECT (0xffffffff)
|
||||
|
||||
/*****************************************************************************
|
||||
* IRemoteActivation interface (v0.0)
|
||||
*/
|
||||
DEFINE_GUID(IID_IRemoteActivation, 0x4d9f4ab8, 0x7d1c, 0x11cf, 0x86,0x1e, 0x00,0x20,0xaf,0x6e,0x7c,0x57);
|
||||
extern RPC_IF_HANDLE IRemoteActivation_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE IRemoteActivation_v0_0_s_ifspec;
|
||||
HRESULT RemoteActivation(
|
||||
handle_t hRpc,
|
||||
ORPCTHIS* ORPCthis,
|
||||
ORPCTHAT* ORPCthat,
|
||||
GUID* Clsid,
|
||||
WCHAR* pwszObjectName,
|
||||
MInterfacePointer* pObjectStorage,
|
||||
DWORD ClientImpLevel,
|
||||
DWORD Mode,
|
||||
DWORD Interfaces,
|
||||
IID* pIIDs,
|
||||
unsigned short cRequestedProtseqs,
|
||||
unsigned short RequestedProtseqs[],
|
||||
OXID* pOxid,
|
||||
DUALSTRINGARRAY** ppdsaOxidBindings,
|
||||
IPID* pipidRemUnknown,
|
||||
DWORD* pAuthnHint,
|
||||
COMVERSION* pServerVersion,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppInterfaceData,
|
||||
HRESULT* pResults);
|
||||
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __WIDL_DCOM_H */
|
||||
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* see http://www.microsoft.com/msj/0398/dcom.htm */
|
||||
/* and the official DCOM specification
|
||||
* (there's a copy at http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm) */
|
||||
|
||||
import "unknwn.idl";
|
||||
|
||||
[
|
||||
uuid(99fcfe60-5260-101b-bbcb-00aa0021347a),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ObjectRpcBaseTypes
|
||||
{
|
||||
typedef unsigned hyper ID;
|
||||
typedef ID MID;
|
||||
typedef ID OXID;
|
||||
typedef ID OID;
|
||||
typedef ID SETID;
|
||||
typedef GUID IPID;
|
||||
typedef GUID CID;
|
||||
typedef REFGUID REFIPID;
|
||||
|
||||
const unsigned short COM_MINOR_VERSION_1 = 1;
|
||||
const unsigned short COM_MINOR_VERSION_2 = 2;
|
||||
|
||||
const unsigned short COM_MAJOR_VERSION = 5;
|
||||
const unsigned short COM_MINOR_VERSION = 3;
|
||||
|
||||
typedef struct tagCOMVERSION {
|
||||
unsigned short MajorVersion;
|
||||
unsigned short MinorVersion;
|
||||
} COMVERSION;
|
||||
|
||||
const unsigned long ORPCF_NULL = 0;
|
||||
const unsigned long ORPCF_LOCAL = 1;
|
||||
const unsigned long ORPCF_RESERVED1 = 2;
|
||||
const unsigned long ORPCF_RESERVED2 = 4;
|
||||
const unsigned long ORPCF_RESERVED3 = 8;
|
||||
const unsigned long ORPCF_RESERVED4 = 16;
|
||||
|
||||
typedef struct tagORPC_EXTENT {
|
||||
GUID id;
|
||||
unsigned long size;
|
||||
[size_is((size+7)&~7)] byte data[];
|
||||
} ORPC_EXTENT;
|
||||
|
||||
typedef struct tagORPC_EXTENT_ARRAY {
|
||||
unsigned long size;
|
||||
unsigned long reserved;
|
||||
[size_is((size+1)&~1,), unique] ORPC_EXTENT **extent;
|
||||
} ORPC_EXTENT_ARRAY;
|
||||
|
||||
typedef struct tagORPCTHIS {
|
||||
COMVERSION version;
|
||||
unsigned long flags;
|
||||
unsigned long reserved1;
|
||||
CID cid;
|
||||
[unique] ORPC_EXTENT_ARRAY *extensions;
|
||||
} ORPCTHIS;
|
||||
|
||||
typedef struct tagORPCTHAT {
|
||||
unsigned long flags;
|
||||
[unique] ORPC_EXTENT_ARRAY *extensions;
|
||||
} ORPCTHAT;
|
||||
|
||||
const unsigned short NCADG_IP_UDP = 0x08;
|
||||
const unsigned short NCACN_IP_TCP = 0x07;
|
||||
const unsigned short NCADG_IPX = 0x0E;
|
||||
const unsigned short NCACN_SPX = 0x0C;
|
||||
const unsigned short NCACN_NB_NB = 0x12;
|
||||
const unsigned short NCACN_NB_IPX = 0x0D;
|
||||
const unsigned short NCACN_DNET_NSP = 0x04;
|
||||
const unsigned short NCACN_HTTP = 0x1F;
|
||||
|
||||
typedef struct tagSTRINGBINDING {
|
||||
unsigned short wTowerId;
|
||||
[string] unsigned short aNetworkAddr[];
|
||||
} STRINGBINDING;
|
||||
|
||||
const unsigned short COM_C_AUTHZ_NONE = 0xffff;
|
||||
|
||||
typedef struct tagSECURITYBINDING {
|
||||
unsigned short wAuthnSvc;
|
||||
unsigned short wAuthzSvc;
|
||||
[string] unsigned short aPrincName[];
|
||||
} SECURITYBINDING;
|
||||
|
||||
typedef struct tagDUALSTRINGARRAY {
|
||||
unsigned short wNumEntries;
|
||||
unsigned short wSecurityOffset;
|
||||
[size_is(wNumEntries)] unsigned short aStringArray[];
|
||||
} DUALSTRINGARRAY;
|
||||
|
||||
const unsigned long OBJREF_SIGNATURE = 0x574f454d; /* "MEOW" */
|
||||
const unsigned long OBJREF_STANDARD = 0x1;
|
||||
const unsigned long OBJREF_HANDLER = 0x2;
|
||||
const unsigned long OBJREF_CUSTOM = 0x4;
|
||||
const unsigned long SORF_OXRES1 = 0x1;
|
||||
const unsigned long SORF_OXRES2 = 0x20;
|
||||
const unsigned long SORF_OXRES3 = 0x40;
|
||||
const unsigned long SORF_OXRES4 = 0x80;
|
||||
const unsigned long SORF_OXRES5 = 0x100;
|
||||
const unsigned long SORF_OXRES6 = 0x200;
|
||||
const unsigned long SORF_OXRES7 = 0x400;
|
||||
const unsigned long SORF_OXRES8 = 0x800;
|
||||
const unsigned long SORF_NULL = 0x0;
|
||||
const unsigned long SORF_NOPING = 0x1000;
|
||||
|
||||
typedef struct tagSTDOBJREF {
|
||||
unsigned long flags;
|
||||
unsigned long cPublicRefs;
|
||||
OXID oxid;
|
||||
OID oid;
|
||||
IPID ipid;
|
||||
} STDOBJREF;
|
||||
|
||||
typedef struct tagOBJREF {
|
||||
unsigned long signature;
|
||||
unsigned long flags;
|
||||
GUID iid;
|
||||
[switch_is(flags)] union {
|
||||
[case(OBJREF_STANDARD)] struct OR_STANDARD {
|
||||
STDOBJREF std;
|
||||
DUALSTRINGARRAY saResAddr;
|
||||
} u_standard;
|
||||
[case(OBJREF_HANDLER)] struct OR_HANDLER {
|
||||
STDOBJREF std;
|
||||
CLSID clsid;
|
||||
DUALSTRINGARRAY saResAddr;
|
||||
} u_handler;
|
||||
[case(OBJREF_CUSTOM)] struct OR_CUSTOM {
|
||||
CLSID clsid;
|
||||
unsigned long cbExtension;
|
||||
unsigned long size;
|
||||
[size_is(size), ref] byte *pData;
|
||||
} u_custom;
|
||||
} u_objref;
|
||||
} OBJREF;
|
||||
|
||||
typedef struct tagMInterfacePointer {
|
||||
ULONG ulCntData;
|
||||
[size_is(ulCntData)] BYTE abData[];
|
||||
} MInterfacePointer;
|
||||
|
||||
typedef [unique] MInterfacePointer *PMInterfacePointer;
|
||||
|
||||
} /* interface ObjectRpcBaseTypes */
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(00000131-0000-0000-C000-000000000046)
|
||||
]
|
||||
interface IRemUnknown : IUnknown
|
||||
{
|
||||
typedef [unique] IRemUnknown *LPREMUNKNOWN;
|
||||
|
||||
typedef struct tagREMQIRESULT {
|
||||
HRESULT hResult;
|
||||
STDOBJREF std;
|
||||
} REMQIRESULT;
|
||||
|
||||
typedef struct tagREMINTERFACEREF {
|
||||
IPID ipid;
|
||||
unsigned long cPublicRefs;
|
||||
unsigned long cPrivateRefs;
|
||||
} REMINTERFACEREF;
|
||||
|
||||
HRESULT RemQueryInterface(
|
||||
[in] REFIPID ripid,
|
||||
[in] unsigned long cRefs,
|
||||
[in] unsigned short cIids,
|
||||
[in, size_is(cIids)] IID *iids,
|
||||
[out, size_is(,cIids)] REMQIRESULT **ppQIResults);
|
||||
|
||||
HRESULT RemAddRef(
|
||||
[in] unsigned short cInterfaceRefs,
|
||||
[in, size_is(cInterfaceRefs)] REMINTERFACEREF* InterfaceRefs,
|
||||
[out, size_is(cInterfaceRefs)] HRESULT *pResults);
|
||||
|
||||
HRESULT RemRelease(
|
||||
[in] unsigned short cInterfaceRefs,
|
||||
[in, size_is(cInterfaceRefs)] REMINTERFACEREF* InterfaceRefs);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(00000142-0000-0000-C000-000000000046)
|
||||
]
|
||||
interface IRemUnknown2 : IRemUnknown
|
||||
{
|
||||
typedef [unique] IRemUnknown2 *LPREMUNKNOWN2;
|
||||
|
||||
HRESULT RemQueryInterface2(
|
||||
[in] REFIPID ripid,
|
||||
[in] unsigned short cIids,
|
||||
[in, size_is(cIids)] IID *iids,
|
||||
[out, size_is(cIids)] HRESULT *phr,
|
||||
[out, size_is(cIids)] MInterfacePointer **ppMIF);
|
||||
}
|
||||
|
||||
cpp_quote("#if 0")
|
||||
[
|
||||
uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IOXIDResolver
|
||||
{
|
||||
[idempotent] error_status_t ResolveOxid(
|
||||
[in] handle_t hRpc,
|
||||
[in] OXID *pOxid,
|
||||
[in] unsigned short cRequestedProtseqs,
|
||||
[in, ref, size_is(cRequestedProtseqs)] unsigned short arRequestedProtseqs[],
|
||||
[out, ref] DUALSTRINGARRAY **ppdsaOxidBindings,
|
||||
[out, ref] IPID *pipidRemUnknown,
|
||||
[out, ref] DWORD *pAuthnHint);
|
||||
|
||||
[idempotent] error_status_t SimplePing(
|
||||
[in] handle_t hRpc,
|
||||
[in] SETID *pSetId);
|
||||
|
||||
[idempotent] error_status_t ComplexPing(
|
||||
[in] handle_t hRpc,
|
||||
[in, out] SETID *pSetId,
|
||||
[in] unsigned short SequenceNum,
|
||||
[in] unsigned short cAddToSet,
|
||||
[in] unsigned short cDelFromSet,
|
||||
[in, unique, size_is(cAddToSet)] OID AddToSet[],
|
||||
[in, unique, size_is(cDelFromSet)] OID DelFromSet[],
|
||||
[out] unsigned short *pPingBackoffFactor);
|
||||
|
||||
[idempotent] error_status_t ServerAlive(
|
||||
[in] handle_t hRpc);
|
||||
|
||||
[idempotent] error_status_t ResolveOxid2(
|
||||
[in] handle_t hRpc,
|
||||
[in] OXID *pOxid,
|
||||
[in] unsigned short cRequestedProtseqs,
|
||||
[in, ref, size_is(cRequestedProtseqs)] unsigned short arRequestedProtseqs[],
|
||||
[out, ref] DUALSTRINGARRAY **ppdsaOxidBindings,
|
||||
[out, ref] IPID *pipidRemUnknown,
|
||||
[out, ref] DWORD *pAuthnHint,
|
||||
[out, ref] COMVERSION *pComVersion);
|
||||
}
|
||||
|
||||
[
|
||||
uuid(4d9f4ab8-7d1c-11cf-861e-0020af6e7c57),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IRemoteActivation
|
||||
{
|
||||
const unsigned long MODE_GET_CLASS_OBJECT = 0xffffffff;
|
||||
|
||||
HRESULT RemoteActivation(
|
||||
[in] handle_t hRpc,
|
||||
[in] ORPCTHIS *ORPCthis,
|
||||
[out] ORPCTHAT *ORPCthat,
|
||||
[in] GUID *Clsid,
|
||||
[in, string, unique] WCHAR *pwszObjectName,
|
||||
[in, unique] MInterfacePointer *pObjectStorage,
|
||||
[in] DWORD ClientImpLevel,
|
||||
[in] DWORD Mode,
|
||||
[in] DWORD Interfaces,
|
||||
[in, unique, size_is(Interfaces)] IID *pIIDs,
|
||||
[in] unsigned short cRequestedProtseqs,
|
||||
[in, size_is(cRequestedProtseqs)] unsigned short RequestedProtseqs[],
|
||||
[out] OXID *pOxid,
|
||||
[out] DUALSTRINGARRAY **ppdsaOxidBindings,
|
||||
[out] IPID *pipidRemUnknown,
|
||||
[out] DWORD *pAuthnHint,
|
||||
[out] COMVERSION *pServerVersion,
|
||||
[out] HRESULT *phr,
|
||||
[out,size_is(Interfaces)] MInterfacePointer **ppInterfaceData,
|
||||
[out,size_is(Interfaces)] HRESULT *pResults);
|
||||
}
|
||||
cpp_quote("#endif")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,523 +0,0 @@
|
||||
/*
|
||||
* ErrorInfo API
|
||||
*
|
||||
* Copyright 2000 Patrik Stridvall, Juergen Schmied
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* The errorinfo is a per-thread object. The reference is stored in the
|
||||
* TEB at offset 0xf80
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
#include "oleauto.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "compobj_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/* this code is from SysAllocStringLen (ole2disp.c in oleaut32) */
|
||||
static BSTR WINAPI ERRORINFO_SysAllocString(const OLECHAR* in)
|
||||
{
|
||||
DWORD bufferSize;
|
||||
DWORD* newBuffer;
|
||||
WCHAR* stringBuffer;
|
||||
DWORD len;
|
||||
|
||||
if (in == NULL)
|
||||
return NULL;
|
||||
/*
|
||||
* Find the lenth of the buffer passed-in in bytes.
|
||||
*/
|
||||
len = strlenW(in);
|
||||
bufferSize = len * sizeof (WCHAR);
|
||||
|
||||
/*
|
||||
* Allocate a new buffer to hold the string.
|
||||
* don't forget to keep an empty spot at the beginning of the
|
||||
* buffer for the character count and an extra character at the
|
||||
* end for the '\0'.
|
||||
*/
|
||||
newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
bufferSize + sizeof(WCHAR) + sizeof(DWORD));
|
||||
|
||||
/*
|
||||
* If the memory allocation failed, return a null pointer.
|
||||
*/
|
||||
if (newBuffer==0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Copy the length of the string in the placeholder.
|
||||
*/
|
||||
*newBuffer = bufferSize;
|
||||
|
||||
/*
|
||||
* Skip the byte count.
|
||||
*/
|
||||
newBuffer++;
|
||||
|
||||
/*
|
||||
* Copy the information in the buffer.
|
||||
* Since it is valid to pass a NULL pointer here, we'll initialize the
|
||||
* buffer to nul if it is the case.
|
||||
*/
|
||||
if (in != 0)
|
||||
memcpy(newBuffer, in, bufferSize);
|
||||
else
|
||||
memset(newBuffer, 0, bufferSize);
|
||||
|
||||
/*
|
||||
* Make sure that there is a nul character at the end of the
|
||||
* string.
|
||||
*/
|
||||
stringBuffer = (WCHAR*)newBuffer;
|
||||
stringBuffer[len] = 0;
|
||||
|
||||
return (LPWSTR)stringBuffer;
|
||||
}
|
||||
|
||||
/* this code is from SysFreeString (ole2disp.c in oleaut32)*/
|
||||
static VOID WINAPI ERRORINFO_SysFreeString(BSTR in)
|
||||
{
|
||||
DWORD* bufferPointer;
|
||||
|
||||
/* NULL is a valid parameter */
|
||||
if(!in) return;
|
||||
|
||||
/*
|
||||
* We have to be careful when we free a BSTR pointer, it points to
|
||||
* the beginning of the string but it skips the byte count contained
|
||||
* before the string.
|
||||
*/
|
||||
bufferPointer = (DWORD*)in;
|
||||
|
||||
bufferPointer--;
|
||||
|
||||
/*
|
||||
* Free the memory from it's "real" origin.
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, bufferPointer);
|
||||
}
|
||||
|
||||
|
||||
typedef struct ErrorInfoImpl
|
||||
{
|
||||
IErrorInfoVtbl *lpvtei;
|
||||
ICreateErrorInfoVtbl *lpvtcei;
|
||||
ISupportErrorInfoVtbl *lpvtsei;
|
||||
DWORD ref;
|
||||
|
||||
GUID m_Guid;
|
||||
BSTR bstrSource;
|
||||
BSTR bstrDescription;
|
||||
BSTR bstrHelpFile;
|
||||
DWORD m_dwHelpContext;
|
||||
} ErrorInfoImpl;
|
||||
|
||||
static IErrorInfoVtbl IErrorInfoImpl_VTable;
|
||||
static ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable;
|
||||
static ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable;
|
||||
|
||||
/*
|
||||
converts a objectpointer to This
|
||||
*/
|
||||
#define _IErrorInfo_Offset ((int)(&(((ErrorInfoImpl*)0)->lpvtei)))
|
||||
#define _ICOM_THIS_From_IErrorInfo(class, name) class* This = (class*)(((char*)name)-_IErrorInfo_Offset);
|
||||
|
||||
#define _ICreateErrorInfo_Offset ((int)(&(((ErrorInfoImpl*)0)->lpvtcei)))
|
||||
#define _ICOM_THIS_From_ICreateErrorInfo(class, name) class* This = (class*)(((char*)name)-_ICreateErrorInfo_Offset);
|
||||
|
||||
#define _ISupportErrorInfo_Offset ((int)(&(((ErrorInfoImpl*)0)->lpvtsei)))
|
||||
#define _ICOM_THIS_From_ISupportErrorInfo(class, name) class* This = (class*)(((char*)name)-_ISupportErrorInfo_Offset);
|
||||
|
||||
/*
|
||||
converts This to a objectpointer
|
||||
*/
|
||||
#define _IErrorInfo_(This) (IErrorInfo*)&(This->lpvtei)
|
||||
#define _ICreateErrorInfo_(This) (ICreateErrorInfo*)&(This->lpvtcei)
|
||||
#define _ISupportErrorInfo_(This) (ISupportErrorInfo*)&(This->lpvtsei)
|
||||
|
||||
IErrorInfo * IErrorInfoImpl_Constructor()
|
||||
{
|
||||
ErrorInfoImpl * ei = HeapAlloc(GetProcessHeap(), 0, sizeof(ErrorInfoImpl));
|
||||
if (ei)
|
||||
{
|
||||
ei->lpvtei = &IErrorInfoImpl_VTable;
|
||||
ei->lpvtcei = &ICreateErrorInfoImpl_VTable;
|
||||
ei->lpvtsei = &ISupportErrorInfoImpl_VTable;
|
||||
ei->ref = 1;
|
||||
ei->bstrSource = NULL;
|
||||
ei->bstrDescription = NULL;
|
||||
ei->bstrHelpFile = NULL;
|
||||
ei->m_dwHelpContext = 0;
|
||||
}
|
||||
return (IErrorInfo *)ei;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI IErrorInfoImpl_QueryInterface(
|
||||
IErrorInfo* iface,
|
||||
REFIID riid,
|
||||
VOID** ppvoid)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvoid);
|
||||
|
||||
*ppvoid = NULL;
|
||||
|
||||
if(IsEqualIID(riid, &IID_IErrorInfo))
|
||||
{
|
||||
*ppvoid = _IErrorInfo_(This);
|
||||
}
|
||||
else if(IsEqualIID(riid, &IID_ICreateErrorInfo))
|
||||
{
|
||||
*ppvoid = _ICreateErrorInfo_(This);
|
||||
}
|
||||
else if(IsEqualIID(riid, &IID_ISupportErrorInfo))
|
||||
{
|
||||
*ppvoid = _ISupportErrorInfo_(This);
|
||||
}
|
||||
|
||||
if(*ppvoid)
|
||||
{
|
||||
IUnknown_AddRef( (IUnknown*)*ppvoid );
|
||||
TRACE("-- Interface: (%p)->(%p)\n",ppvoid,*ppvoid);
|
||||
return S_OK;
|
||||
}
|
||||
TRACE("-- Interface: E_NOINTERFACE\n");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IErrorInfoImpl_AddRef(
|
||||
IErrorInfo* iface)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(count=%lu)\n",This,This->ref);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IErrorInfoImpl_Release(
|
||||
IErrorInfo* iface)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(count=%lu)\n",This,This->ref);
|
||||
|
||||
if (!InterlockedDecrement(&This->ref))
|
||||
{
|
||||
TRACE("-- destroying IErrorInfo(%p)\n",This);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
return This->ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IErrorInfoImpl_GetGUID(
|
||||
IErrorInfo* iface,
|
||||
GUID * pGUID)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(count=%lu)\n",This,This->ref);
|
||||
if(!pGUID )return E_INVALIDARG;
|
||||
memcpy(pGUID, &This->m_Guid, sizeof(GUID));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IErrorInfoImpl_GetSource(
|
||||
IErrorInfo* iface,
|
||||
BSTR *pBstrSource)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(pBstrSource=%p)\n",This,pBstrSource);
|
||||
if (pBstrSource == NULL)
|
||||
return E_INVALIDARG;
|
||||
*pBstrSource = ERRORINFO_SysAllocString(This->bstrSource);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IErrorInfoImpl_GetDescription(
|
||||
IErrorInfo* iface,
|
||||
BSTR *pBstrDescription)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
|
||||
TRACE("(%p)->(pBstrDescription=%p)\n",This,pBstrDescription);
|
||||
if (pBstrDescription == NULL)
|
||||
return E_INVALIDARG;
|
||||
*pBstrDescription = ERRORINFO_SysAllocString(This->bstrDescription);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IErrorInfoImpl_GetHelpFile(
|
||||
IErrorInfo* iface,
|
||||
BSTR *pBstrHelpFile)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
|
||||
TRACE("(%p)->(pBstrHelpFile=%p)\n",This, pBstrHelpFile);
|
||||
if (pBstrHelpFile == NULL)
|
||||
return E_INVALIDARG;
|
||||
*pBstrHelpFile = ERRORINFO_SysAllocString(This->bstrHelpFile);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IErrorInfoImpl_GetHelpContext(
|
||||
IErrorInfo* iface,
|
||||
DWORD *pdwHelpContext)
|
||||
{
|
||||
_ICOM_THIS_From_IErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(pdwHelpContext=%p)\n",This, pdwHelpContext);
|
||||
if (pdwHelpContext == NULL)
|
||||
return E_INVALIDARG;
|
||||
*pdwHelpContext = This->m_dwHelpContext;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IErrorInfoVtbl IErrorInfoImpl_VTable =
|
||||
{
|
||||
IErrorInfoImpl_QueryInterface,
|
||||
IErrorInfoImpl_AddRef,
|
||||
IErrorInfoImpl_Release,
|
||||
|
||||
IErrorInfoImpl_GetGUID,
|
||||
IErrorInfoImpl_GetSource,
|
||||
IErrorInfoImpl_GetDescription,
|
||||
IErrorInfoImpl_GetHelpFile,
|
||||
IErrorInfoImpl_GetHelpContext
|
||||
};
|
||||
|
||||
|
||||
static HRESULT WINAPI ICreateErrorInfoImpl_QueryInterface(
|
||||
ICreateErrorInfo* iface,
|
||||
REFIID riid,
|
||||
VOID** ppvoid)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n", This);
|
||||
return IErrorInfo_QueryInterface(_IErrorInfo_(This), riid, ppvoid);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ICreateErrorInfoImpl_AddRef(
|
||||
ICreateErrorInfo* iface)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n", This);
|
||||
return IErrorInfo_AddRef(_IErrorInfo_(This));
|
||||
}
|
||||
|
||||
static ULONG WINAPI ICreateErrorInfoImpl_Release(
|
||||
ICreateErrorInfo* iface)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n", This);
|
||||
return IErrorInfo_Release(_IErrorInfo_(This));
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI ICreateErrorInfoImpl_SetGUID(
|
||||
ICreateErrorInfo* iface,
|
||||
REFGUID rguid)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(%s)\n", This, debugstr_guid(rguid));
|
||||
memcpy(&This->m_Guid, rguid, sizeof(GUID));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ICreateErrorInfoImpl_SetSource(
|
||||
ICreateErrorInfo* iface,
|
||||
LPOLESTR szSource)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p): %s\n",This, debugstr_w(szSource));
|
||||
if (This->bstrSource != NULL)
|
||||
ERRORINFO_SysFreeString(This->bstrSource);
|
||||
This->bstrSource = ERRORINFO_SysAllocString(szSource);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ICreateErrorInfoImpl_SetDescription(
|
||||
ICreateErrorInfo* iface,
|
||||
LPOLESTR szDescription)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p): %s\n",This, debugstr_w(szDescription));
|
||||
if (This->bstrDescription != NULL)
|
||||
ERRORINFO_SysFreeString(This->bstrDescription);
|
||||
This->bstrDescription = ERRORINFO_SysAllocString(szDescription);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpFile(
|
||||
ICreateErrorInfo* iface,
|
||||
LPOLESTR szHelpFile)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n",This);
|
||||
if (This->bstrHelpFile != NULL)
|
||||
ERRORINFO_SysFreeString(This->bstrHelpFile);
|
||||
This->bstrHelpFile = ERRORINFO_SysAllocString(szHelpFile);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext(
|
||||
ICreateErrorInfo* iface,
|
||||
DWORD dwHelpContext)
|
||||
{
|
||||
_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n",This);
|
||||
This->m_dwHelpContext = dwHelpContext;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable =
|
||||
{
|
||||
ICreateErrorInfoImpl_QueryInterface,
|
||||
ICreateErrorInfoImpl_AddRef,
|
||||
ICreateErrorInfoImpl_Release,
|
||||
|
||||
ICreateErrorInfoImpl_SetGUID,
|
||||
ICreateErrorInfoImpl_SetSource,
|
||||
ICreateErrorInfoImpl_SetDescription,
|
||||
ICreateErrorInfoImpl_SetHelpFile,
|
||||
ICreateErrorInfoImpl_SetHelpContext
|
||||
};
|
||||
|
||||
static HRESULT WINAPI ISupportErrorInfoImpl_QueryInterface(
|
||||
ISupportErrorInfo* iface,
|
||||
REFIID riid,
|
||||
VOID** ppvoid)
|
||||
{
|
||||
_ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return IErrorInfo_QueryInterface(_IErrorInfo_(This), riid, ppvoid);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ISupportErrorInfoImpl_AddRef(
|
||||
ISupportErrorInfo* iface)
|
||||
{
|
||||
_ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n", This);
|
||||
return IErrorInfo_AddRef(_IErrorInfo_(This));
|
||||
}
|
||||
|
||||
static ULONG WINAPI ISupportErrorInfoImpl_Release(
|
||||
ISupportErrorInfo* iface)
|
||||
{
|
||||
_ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)\n", This);
|
||||
return IErrorInfo_Release(_IErrorInfo_(This));
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI ISupportErrorInfoImpl_InterfaceSupportsErrorInfo(
|
||||
ISupportErrorInfo* iface,
|
||||
REFIID riid)
|
||||
{
|
||||
_ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl, iface);
|
||||
TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));
|
||||
return (IsEqualIID(riid, &This->m_Guid)) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
static ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable =
|
||||
{
|
||||
ISupportErrorInfoImpl_QueryInterface,
|
||||
ISupportErrorInfoImpl_AddRef,
|
||||
ISupportErrorInfoImpl_Release,
|
||||
|
||||
|
||||
ISupportErrorInfoImpl_InterfaceSupportsErrorInfo
|
||||
};
|
||||
/***********************************************************************
|
||||
* CreateErrorInfo (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
|
||||
{
|
||||
IErrorInfo * pei;
|
||||
HRESULT res;
|
||||
TRACE("(%p): stub:\n", pperrinfo);
|
||||
if(! pperrinfo ) return E_INVALIDARG;
|
||||
if(!(pei=IErrorInfoImpl_Constructor()))return E_OUTOFMEMORY;
|
||||
|
||||
res = IErrorInfo_QueryInterface(pei, &IID_ICreateErrorInfo, (LPVOID*)pperrinfo);
|
||||
IErrorInfo_Release(pei);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetErrorInfo (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
|
||||
{
|
||||
APARTMENT * apt = COM_CurrentInfo();
|
||||
|
||||
TRACE("(%ld, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->ErrorInfo);
|
||||
|
||||
if(!pperrinfo) return E_INVALIDARG;
|
||||
if (!apt || !apt->ErrorInfo)
|
||||
{
|
||||
*pperrinfo = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
*pperrinfo = (IErrorInfo*)(apt->ErrorInfo);
|
||||
/* clear thread error state */
|
||||
apt->ErrorInfo = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetErrorInfo (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
|
||||
{
|
||||
IErrorInfo * pei;
|
||||
APARTMENT * apt = COM_CurrentInfo();
|
||||
|
||||
TRACE("(%ld, %p)\n", dwReserved, perrinfo);
|
||||
|
||||
if (!apt) apt = COM_CreateApartment(COINIT_UNINITIALIZED);
|
||||
|
||||
/* release old errorinfo */
|
||||
pei = (IErrorInfo*)apt->ErrorInfo;
|
||||
if(pei) IErrorInfo_Release(pei);
|
||||
|
||||
/* set to new value */
|
||||
apt->ErrorInfo = perrinfo;
|
||||
if(perrinfo) IErrorInfo_AddRef(perrinfo);
|
||||
return S_OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* free threaded marshaller
|
||||
*
|
||||
* Copyright 2002 Juergen Schmied
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
typedef struct _FTMarshalImpl {
|
||||
IUnknownVtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
IMarshalVtbl *lpvtblFTM;
|
||||
|
||||
IUnknown *pUnkOuter;
|
||||
} FTMarshalImpl;
|
||||
|
||||
#define _IFTMUnknown_(This)(IUnknown*)&(This->lpVtbl)
|
||||
#define _IFTMarshal_(This) (IMarshal*)&(This->lpvtblFTM)
|
||||
|
||||
#define _IFTMarshall_Offset ((int)(&(((FTMarshalImpl*)0)->lpvtblFTM)))
|
||||
#define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
|
||||
|
||||
/* inner IUnknown to handle aggregation */
|
||||
HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||
|
||||
TRACE ("\n");
|
||||
*ppv = NULL;
|
||||
|
||||
if (IsEqualIID (&IID_IUnknown, riid))
|
||||
*ppv = _IFTMUnknown_ (This);
|
||||
else if (IsEqualIID (&IID_IMarshal, riid))
|
||||
*ppv = _IFTMarshal_ (This);
|
||||
else {
|
||||
FIXME ("No interface for %s.\n", debugstr_guid (riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
IUnknown_AddRef ((IUnknown *) * ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||
|
||||
TRACE ("\n");
|
||||
return InterlockedIncrement (&This->ref);
|
||||
}
|
||||
|
||||
ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||
|
||||
TRACE ("\n");
|
||||
if (InterlockedDecrement (&This->ref))
|
||||
return This->ref;
|
||||
HeapFree (GetProcessHeap (), 0, This);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static IUnknownVtbl iunkvt =
|
||||
{
|
||||
IiFTMUnknown_fnQueryInterface,
|
||||
IiFTMUnknown_fnAddRef,
|
||||
IiFTMUnknown_fnRelease
|
||||
};
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
|
||||
{
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
||||
TRACE ("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid (riid), ppv);
|
||||
return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
|
||||
}
|
||||
|
||||
ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
|
||||
{
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
||||
TRACE ("\n");
|
||||
return IUnknown_AddRef (This->pUnkOuter);
|
||||
}
|
||||
|
||||
ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
|
||||
{
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
||||
TRACE ("\n");
|
||||
return IUnknown_Release (This->pUnkOuter);
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
void *pvDestContext, DWORD mshlflags, CLSID * pCid)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
void *pvDestContext, DWORD mshlflags, DWORD * pSize)
|
||||
{
|
||||
|
||||
IMarshal *pMarshal = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
||||
FIXME ("(), stub!\n");
|
||||
|
||||
/* if the marshalling happens inside the same process the interface pointer is
|
||||
copied between the apartments */
|
||||
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
|
||||
*pSize = sizeof (This);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* use the standard marshaller to handle all other cases */
|
||||
CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
|
||||
hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
|
||||
IMarshal_Release (pMarshal);
|
||||
return hres;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
|
||||
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
|
||||
{
|
||||
|
||||
IMarshal *pMarshal = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
||||
FIXME ("(), stub!\n");
|
||||
|
||||
/* if the marshalling happens inside the same process the interface pointer is
|
||||
copied between the apartments */
|
||||
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
|
||||
return IStream_Write (pStm, This, sizeof (This), 0);
|
||||
}
|
||||
|
||||
/* use the standard marshaler to handle all other cases */
|
||||
CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
|
||||
hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
|
||||
IMarshal_Release (pMarshal);
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IMarshalVtbl ftmvtbl =
|
||||
{
|
||||
FTMarshalImpl_QueryInterface,
|
||||
FTMarshalImpl_AddRef,
|
||||
FTMarshalImpl_Release,
|
||||
FTMarshalImpl_GetUnmarshalClass,
|
||||
FTMarshalImpl_GetMarshalSizeMax,
|
||||
FTMarshalImpl_MarshalInterface,
|
||||
FTMarshalImpl_UnmarshalInterface,
|
||||
FTMarshalImpl_ReleaseMarshalData,
|
||||
FTMarshalImpl_DisconnectObject
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* CoCreateFreeThreadedMarshaler [OLE32.@]
|
||||
*
|
||||
*/
|
||||
HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
|
||||
{
|
||||
|
||||
FTMarshalImpl *ftm;
|
||||
|
||||
TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
|
||||
|
||||
ftm = (FTMarshalImpl *) HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
|
||||
if (!ftm)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ftm->lpVtbl = &iunkvt;
|
||||
ftm->lpvtblFTM = &ftmvtbl;
|
||||
ftm->ref = 1;
|
||||
ftm->pUnkOuter = punkOuter;
|
||||
|
||||
*ppunkMarshal = _IFTMUnknown_ (ftm);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
/*
|
||||
* Implementation of the StdGlobalInterfaceTable object
|
||||
*
|
||||
* The GlobalInterfaceTable (GIT) object is used to marshal interfaces between
|
||||
* threading apartments (contexts). When you want to pass an interface but not
|
||||
* as a parameter, it wouldn't get marshalled automatically, so you can use this
|
||||
* object to insert the interface into a table, and you get back a cookie.
|
||||
* Then when it's retrieved, it'll be unmarshalled into the right apartment.
|
||||
*
|
||||
* Copyright 2003 Mike Hearn <mike@theoretic.com>
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "compobj_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/****************************************************************************
|
||||
* StdGlobalInterfaceTable definition
|
||||
*
|
||||
* This class implements IGlobalInterfaceTable and is a process-wide singleton
|
||||
* used for marshalling interfaces between threading apartments using cookies.
|
||||
*/
|
||||
|
||||
/* Each entry in the linked list of GIT entries */
|
||||
typedef struct StdGITEntry
|
||||
{
|
||||
DWORD cookie;
|
||||
IID iid; /* IID of the interface */
|
||||
IStream* stream; /* Holds the marshalled interface */
|
||||
|
||||
struct StdGITEntry* next;
|
||||
struct StdGITEntry* prev;
|
||||
} StdGITEntry;
|
||||
|
||||
/* Class data */
|
||||
typedef struct StdGlobalInterfaceTableImpl
|
||||
{
|
||||
IGlobalInterfaceTableVtbl *lpVtbl;
|
||||
|
||||
ULONG ref;
|
||||
struct StdGITEntry* firstEntry;
|
||||
struct StdGITEntry* lastEntry;
|
||||
ULONG nextCookie;
|
||||
|
||||
} StdGlobalInterfaceTableImpl;
|
||||
|
||||
void* StdGlobalInterfaceTableInstance;
|
||||
|
||||
|
||||
/* IUnknown */
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject);
|
||||
static ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface);
|
||||
static ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface);
|
||||
/* IGlobalInterfaceTable */
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfaceTable* iface, IUnknown* pUnk, REFIID riid, DWORD* pdwCookie);
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie);
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv);
|
||||
|
||||
/* Virtual function table */
|
||||
static IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
|
||||
{
|
||||
StdGlobalInterfaceTable_QueryInterface,
|
||||
StdGlobalInterfaceTable_AddRef,
|
||||
StdGlobalInterfaceTable_Release,
|
||||
StdGlobalInterfaceTable_RegisterInterfaceInGlobal,
|
||||
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal,
|
||||
StdGlobalInterfaceTable_GetInterfaceFromGlobal
|
||||
};
|
||||
|
||||
static CRITICAL_SECTION git_section;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
{
|
||||
0, 0, &git_section,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
0, 0, { 0, (DWORD)(__FILE__ ": global interface table") }
|
||||
};
|
||||
static CRITICAL_SECTION git_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
/***
|
||||
* Let's go! Here is the constructor and destructor for the class.
|
||||
*
|
||||
*/
|
||||
|
||||
/** This function constructs the GIT. It should only be called once **/
|
||||
void* StdGlobalInterfaceTable_Construct() {
|
||||
StdGlobalInterfaceTableImpl* newGIT;
|
||||
|
||||
newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl));
|
||||
if (newGIT == 0) return newGIT;
|
||||
|
||||
newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
|
||||
newGIT->ref = 1; /* Initialise the reference count */
|
||||
newGIT->firstEntry = NULL; /* we start with an empty table */
|
||||
newGIT->lastEntry = NULL;
|
||||
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
|
||||
TRACE("Created the GIT at %p\n", newGIT);
|
||||
|
||||
return (void*)newGIT;
|
||||
}
|
||||
|
||||
/** This destroys it again. It should revoke all the held interfaces first **/
|
||||
void StdGlobalInterfaceTable_Destroy(void* self) {
|
||||
TRACE("(%p)\n", self);
|
||||
FIXME("Revoke held interfaces here\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, self);
|
||||
StdGlobalInterfaceTableInstance = NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
* A helper function to traverse the list and find the entry that matches the cookie.
|
||||
* Returns NULL if not found
|
||||
*/
|
||||
StdGITEntry* StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie) {
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
StdGITEntry* e;
|
||||
|
||||
TRACE("iface=%p, cookie=0x%x\n", iface, (UINT)cookie);
|
||||
|
||||
EnterCriticalSection(&git_section);
|
||||
e = self->firstEntry;
|
||||
while (e != NULL) {
|
||||
if (e->cookie == cookie) {
|
||||
LeaveCriticalSection(&git_section);
|
||||
return e;
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
LeaveCriticalSection(&git_section);
|
||||
|
||||
TRACE("Entry not found\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
* Here's the boring boilerplate stuff for IUnknown
|
||||
*/
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject) {
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
|
||||
/* Make sure silly coders can't crash us */
|
||||
if (ppvObject == 0) return E_INVALIDARG;
|
||||
|
||||
*ppvObject = 0; /* assume we don't have the interface */
|
||||
|
||||
/* Do we implement that interface? */
|
||||
if (IsEqualIID(&IID_IUnknown, riid)) {
|
||||
*ppvObject = (IGlobalInterfaceTable*) self;
|
||||
} else if (IsEqualIID(&IID_IGlobalInterfaceTable, riid)) {
|
||||
*ppvObject = (IGlobalInterfaceTable*) self;
|
||||
} else return E_NOINTERFACE;
|
||||
|
||||
/* Now inc the refcount */
|
||||
StdGlobalInterfaceTable_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface) {
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
|
||||
/* InterlockedIncrement(&self->ref); */
|
||||
return self->ref;
|
||||
}
|
||||
|
||||
ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) {
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
|
||||
/* InterlockedDecrement(&self->ref); */
|
||||
if (self->ref == 0) {
|
||||
/* Hey ho, it's time to go, so long again 'till next weeks show! */
|
||||
StdGlobalInterfaceTable_Destroy(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return self->ref;
|
||||
}
|
||||
|
||||
/***
|
||||
* Now implement the actual IGlobalInterfaceTable interface
|
||||
*/
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfaceTable* iface, IUnknown* pUnk, REFIID riid, DWORD* pdwCookie) {
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
IStream* stream = NULL;
|
||||
HRESULT hres;
|
||||
StdGITEntry* entry;
|
||||
|
||||
TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);
|
||||
|
||||
if (pUnk == NULL) return E_INVALIDARG;
|
||||
|
||||
/* marshal the interface */
|
||||
TRACE("About to marshal the interface\n");
|
||||
hres = CoMarshalInterThreadInterfaceInStream(riid, pUnk, &stream);
|
||||
if (hres) return hres;
|
||||
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
|
||||
if (entry == NULL) return E_OUTOFMEMORY;
|
||||
|
||||
EnterCriticalSection(&git_section);
|
||||
|
||||
entry->iid = *riid;
|
||||
entry->stream = stream;
|
||||
entry->cookie = self->nextCookie;
|
||||
self->nextCookie++; /* inc the cookie count */
|
||||
|
||||
/* insert the new entry at the end of the list */
|
||||
entry->next = NULL;
|
||||
entry->prev = self->lastEntry;
|
||||
if (entry->prev) entry->prev->next = entry;
|
||||
else self->firstEntry = entry;
|
||||
self->lastEntry = entry;
|
||||
|
||||
/* and return the cookie */
|
||||
*pdwCookie = entry->cookie;
|
||||
|
||||
LeaveCriticalSection(&git_section);
|
||||
|
||||
TRACE("Cookie is 0x%lx\n", entry->cookie);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie) {
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
StdGITEntry* entry;
|
||||
|
||||
TRACE("iface=%p, dwCookie=0x%x\n", iface, (UINT)dwCookie);
|
||||
|
||||
entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
|
||||
if (entry == NULL) {
|
||||
TRACE("Entry not found\n");
|
||||
return E_INVALIDARG; /* not found */
|
||||
}
|
||||
|
||||
/* Free the stream */
|
||||
IStream_Release(entry->stream);
|
||||
|
||||
/* chop entry out of the list, and free the memory */
|
||||
EnterCriticalSection(&git_section);
|
||||
if (entry->prev) entry->prev->next = entry->next;
|
||||
else self->firstEntry = entry->next;
|
||||
if (entry->next) entry->next->prev = entry->prev;
|
||||
else self->lastEntry = entry->prev;
|
||||
LeaveCriticalSection(&git_section);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, entry);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv) {
|
||||
StdGITEntry* entry;
|
||||
HRESULT hres;
|
||||
LARGE_INTEGER move;
|
||||
LPUNKNOWN lpUnk;
|
||||
|
||||
TRACE("dwCookie=0x%lx, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
|
||||
|
||||
entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
|
||||
if (entry == NULL) return E_INVALIDARG;
|
||||
|
||||
if (!IsEqualIID(&entry->iid, riid)) {
|
||||
WARN("entry->iid (%s) != riid\n", debugstr_guid(&entry->iid));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
TRACE("entry=%p\n", entry);
|
||||
|
||||
/* unmarshal the interface */
|
||||
hres = CoUnmarshalInterface(entry->stream, riid, ppv);
|
||||
if (hres) {
|
||||
WARN("Failed to unmarshal stream\n");
|
||||
return hres;
|
||||
}
|
||||
|
||||
/* rewind stream, in case it's used again */
|
||||
move.u.LowPart = 0;
|
||||
move.u.HighPart = 0;
|
||||
IStream_Seek(entry->stream, move, STREAM_SEEK_SET, NULL);
|
||||
|
||||
/* addref it */
|
||||
lpUnk = *ppv;
|
||||
IUnknown_AddRef(lpUnk);
|
||||
TRACE("ppv=%p\n", *ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Classfactory definition - despite what MSDN says, some programs need this */
|
||||
|
||||
static HRESULT WINAPI GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) {
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
|
||||
*ppv = (LPVOID)iface;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
static ULONG WINAPI GITCF_AddRef(LPCLASSFACTORY iface) { return 2; }
|
||||
static ULONG WINAPI GITCF_Release(LPCLASSFACTORY iface) { return 1; }
|
||||
|
||||
static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) {
|
||||
if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
|
||||
if (StdGlobalInterfaceTableInstance == NULL)
|
||||
StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct();
|
||||
return IGlobalInterfaceTable_QueryInterface( (IGlobalInterfaceTable*) StdGlobalInterfaceTableInstance, riid, ppv);
|
||||
}
|
||||
|
||||
FIXME("(%s), not supported.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) {
|
||||
FIXME("(%d), stub!\n",fLock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IClassFactoryVtbl GITClassFactoryVtbl = {
|
||||
GITCF_QueryInterface,
|
||||
GITCF_AddRef,
|
||||
GITCF_Release,
|
||||
GITCF_CreateInstance,
|
||||
GITCF_LockServer
|
||||
};
|
||||
static IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl;
|
||||
|
||||
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) {
|
||||
*ppv = &PGITClassFactoryVtbl;
|
||||
TRACE("Returning GIT classfactory\n");
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,837 +0,0 @@
|
||||
/*
|
||||
* HGLOBAL Stream implementation
|
||||
*
|
||||
* This file contains the implementation of the stream interface
|
||||
* for streams contained supported by an HGLOBAL pointer.
|
||||
*
|
||||
* Copyright 1999 Francis Beaudet
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(storage);
|
||||
|
||||
/****************************************************************************
|
||||
* HGLOBALStreamImpl definition.
|
||||
*
|
||||
* This class imlements the IStream inteface and represents a stream
|
||||
* supported by an HGLOBAL pointer.
|
||||
*/
|
||||
struct HGLOBALStreamImpl
|
||||
{
|
||||
IStreamVtbl *lpVtbl; /* Needs to be the first item in the stuct
|
||||
* since we want to cast this in a IStream pointer */
|
||||
|
||||
/*
|
||||
* Reference count
|
||||
*/
|
||||
ULONG ref;
|
||||
|
||||
/*
|
||||
* Support for the stream
|
||||
*/
|
||||
HGLOBAL supportHandle;
|
||||
|
||||
/*
|
||||
* This flag is TRUE if the HGLOBAL is destroyed when the stream
|
||||
* is finally released.
|
||||
*/
|
||||
BOOL deleteOnRelease;
|
||||
|
||||
/*
|
||||
* Helper variable that contains the size of the stream
|
||||
*/
|
||||
ULARGE_INTEGER streamSize;
|
||||
|
||||
/*
|
||||
* This is the current position of the cursor in the stream
|
||||
*/
|
||||
ULARGE_INTEGER currentPosition;
|
||||
};
|
||||
|
||||
typedef struct HGLOBALStreamImpl HGLOBALStreamImpl;
|
||||
|
||||
/*
|
||||
* Method definition for the StgStreamImpl class.
|
||||
*/
|
||||
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease);
|
||||
|
||||
void HGLOBALStreamImpl_Destroy(
|
||||
HGLOBALStreamImpl* This);
|
||||
|
||||
void HGLOBALStreamImpl_OpenBlockChain(
|
||||
HGLOBALStreamImpl* This);
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||
IStream* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject); /* [iid_is][out] */
|
||||
|
||||
ULONG WINAPI HGLOBALStreamImpl_AddRef(
|
||||
IStream* iface);
|
||||
|
||||
ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||
IStream* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||
IStream* iface,
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||
IStream* iface,
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||
IStream* iface,
|
||||
LARGE_INTEGER dlibMove, /* [in] */
|
||||
DWORD dwOrigin, /* [in] */
|
||||
ULARGE_INTEGER* plibNewPosition); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libNewSize); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
||||
IStream* iface,
|
||||
IStream* pstm, /* [unique][in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
ULARGE_INTEGER* pcbRead, /* [out] */
|
||||
ULARGE_INTEGER* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
||||
IStream* iface,
|
||||
DWORD grfCommitFlags); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
||||
IStream* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||
IStream* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm); /* [out] */
|
||||
|
||||
|
||||
/*
|
||||
* Virtual function table for the HGLOBALStreamImpl class.
|
||||
*/
|
||||
static IStreamVtbl HGLOBALStreamImpl_Vtbl =
|
||||
{
|
||||
HGLOBALStreamImpl_QueryInterface,
|
||||
HGLOBALStreamImpl_AddRef,
|
||||
HGLOBALStreamImpl_Release,
|
||||
HGLOBALStreamImpl_Read,
|
||||
HGLOBALStreamImpl_Write,
|
||||
HGLOBALStreamImpl_Seek,
|
||||
HGLOBALStreamImpl_SetSize,
|
||||
HGLOBALStreamImpl_CopyTo,
|
||||
HGLOBALStreamImpl_Commit,
|
||||
HGLOBALStreamImpl_Revert,
|
||||
HGLOBALStreamImpl_LockRegion,
|
||||
HGLOBALStreamImpl_UnlockRegion,
|
||||
HGLOBALStreamImpl_Stat,
|
||||
HGLOBALStreamImpl_Clone
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* CreateStreamOnHGlobal [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI CreateStreamOnHGlobal(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease,
|
||||
LPSTREAM* ppstm)
|
||||
{
|
||||
HGLOBALStreamImpl* newStream;
|
||||
|
||||
newStream = HGLOBALStreamImpl_Construct(hGlobal,
|
||||
fDeleteOnRelease);
|
||||
|
||||
if (newStream!=NULL)
|
||||
{
|
||||
return IUnknown_QueryInterface((IUnknown*)newStream,
|
||||
&IID_IStream,
|
||||
(void**)ppstm);
|
||||
}
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetHGlobalFromStream [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
|
||||
{
|
||||
HGLOBALStreamImpl* pStream;
|
||||
|
||||
if (pstm == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pStream = (HGLOBALStreamImpl*) pstm;
|
||||
|
||||
/*
|
||||
* Verify that the stream object was created with CreateStreamOnHGlobal.
|
||||
*/
|
||||
if (pStream->lpVtbl == &HGLOBALStreamImpl_Vtbl)
|
||||
*phglobal = pStream->supportHandle;
|
||||
else
|
||||
{
|
||||
*phglobal = 0;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** HGLOBALStreamImpl implementation
|
||||
*/
|
||||
|
||||
/***
|
||||
* This is the constructor for the HGLOBALStreamImpl class.
|
||||
*
|
||||
* Params:
|
||||
* hGlobal - Handle that will support the stream. can be NULL.
|
||||
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
|
||||
* when the IStream object is destroyed.
|
||||
*/
|
||||
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease)
|
||||
{
|
||||
HGLOBALStreamImpl* newStream;
|
||||
|
||||
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
|
||||
|
||||
if (newStream!=0)
|
||||
{
|
||||
/*
|
||||
* Set-up the virtual function table and reference count.
|
||||
*/
|
||||
newStream->lpVtbl = &HGLOBALStreamImpl_Vtbl;
|
||||
newStream->ref = 0;
|
||||
|
||||
/*
|
||||
* Initialize the support.
|
||||
*/
|
||||
newStream->supportHandle = hGlobal;
|
||||
newStream->deleteOnRelease = fDeleteOnRelease;
|
||||
|
||||
/*
|
||||
* This method will allocate a handle if one is not supplied.
|
||||
*/
|
||||
if (!newStream->supportHandle)
|
||||
{
|
||||
newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
|
||||
GMEM_SHARE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the stream at the beginning.
|
||||
*/
|
||||
newStream->currentPosition.u.HighPart = 0;
|
||||
newStream->currentPosition.u.LowPart = 0;
|
||||
|
||||
/*
|
||||
* Initialize the size of the stream to the size of the handle.
|
||||
*/
|
||||
newStream->streamSize.u.HighPart = 0;
|
||||
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
|
||||
}
|
||||
|
||||
return newStream;
|
||||
}
|
||||
|
||||
/***
|
||||
* This is the destructor of the HGLOBALStreamImpl class.
|
||||
*
|
||||
* This method will clean-up all the resources used-up by the given HGLOBALStreamImpl
|
||||
* class. The pointer passed-in to this function will be freed and will not
|
||||
* be valid anymore.
|
||||
*/
|
||||
void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
/*
|
||||
* Release the HGlobal if the constructor asked for that.
|
||||
*/
|
||||
if (This->deleteOnRelease)
|
||||
{
|
||||
GlobalFree(This->supportHandle);
|
||||
This->supportHandle=0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, free the memory used-up by the class.
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method QueryInterface for this
|
||||
* class
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||
IStream* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject) /* [iid_is][out] */
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
|
||||
/*
|
||||
* Perform a sanity check on the parameters.
|
||||
*/
|
||||
if (ppvObject==0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/*
|
||||
* Initialize the return parameter.
|
||||
*/
|
||||
*ppvObject = 0;
|
||||
|
||||
/*
|
||||
* Compare the riid with the interface IDs implemented by this object.
|
||||
*/
|
||||
if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
|
||||
{
|
||||
*ppvObject = (IStream*)This;
|
||||
}
|
||||
else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
|
||||
{
|
||||
*ppvObject = (IStream*)This;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we obtained an interface.
|
||||
*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/*
|
||||
* Query Interface always increases the reference count by one when it is
|
||||
* successful
|
||||
*/
|
||||
HGLOBALStreamImpl_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method AddRef for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALStreamImpl_AddRef(
|
||||
IStream* iface)
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method Release for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||
IStream* iface)
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
ULONG newRef;
|
||||
|
||||
newRef = InterlockedDecrement(&This->ref);
|
||||
|
||||
/*
|
||||
* If the reference count goes down to 0, perform suicide.
|
||||
*/
|
||||
if (newRef==0)
|
||||
{
|
||||
HGLOBALStreamImpl_Destroy(This);
|
||||
}
|
||||
|
||||
return newRef;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the ISequentialStream interface.
|
||||
*
|
||||
* If reads a block of information from the stream at the current
|
||||
* position. It then moves the current position at the end of the
|
||||
* read block
|
||||
*
|
||||
* See the documentation of ISequentialStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||
IStream* iface,
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead) /* [out] */
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
|
||||
void* supportBuffer;
|
||||
ULONG bytesReadBuffer;
|
||||
ULONG bytesToReadFromBuffer;
|
||||
|
||||
TRACE("(%p, %p, %ld, %p)\n", iface,
|
||||
pv, cb, pcbRead);
|
||||
|
||||
/*
|
||||
* If the caller is not interested in the nubmer of bytes read,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbRead==0)
|
||||
pcbRead = &bytesReadBuffer;
|
||||
|
||||
/*
|
||||
* Using the known size of the stream, calculate the number of bytes
|
||||
* to read from the block chain
|
||||
*/
|
||||
bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
|
||||
|
||||
/*
|
||||
* Lock the buffer in position and copy the data.
|
||||
*/
|
||||
supportBuffer = GlobalLock(This->supportHandle);
|
||||
|
||||
memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
|
||||
|
||||
/*
|
||||
* Move the current position to the new position
|
||||
*/
|
||||
This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
|
||||
|
||||
/*
|
||||
* Return the number of bytes read.
|
||||
*/
|
||||
*pcbRead = bytesToReadFromBuffer;
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
GlobalUnlock(This->supportHandle);
|
||||
|
||||
/*
|
||||
* The function returns S_OK if the buffer was filled completely
|
||||
* it returns S_FALSE if the end of the stream is reached before the
|
||||
* buffer is filled
|
||||
*/
|
||||
if(*pcbRead == cb)
|
||||
return S_OK;
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the ISequentialStream interface.
|
||||
*
|
||||
* It writes a block of information to the stream at the current
|
||||
* position. It then moves the current position at the end of the
|
||||
* written block. If the stream is too small to fit the block,
|
||||
* the stream is grown to fit.
|
||||
*
|
||||
* See the documentation of ISequentialStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||
IStream* iface,
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten) /* [out] */
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
|
||||
void* supportBuffer;
|
||||
ULARGE_INTEGER newSize;
|
||||
ULONG bytesWritten = 0;
|
||||
|
||||
TRACE("(%p, %p, %ld, %p)\n", iface,
|
||||
pv, cb, pcbWritten);
|
||||
|
||||
/*
|
||||
* If the caller is not interested in the number of bytes written,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbWritten == 0)
|
||||
pcbWritten = &bytesWritten;
|
||||
|
||||
if (cb == 0)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSize.u.HighPart = 0;
|
||||
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify if we need to grow the stream
|
||||
*/
|
||||
if (newSize.u.LowPart > This->streamSize.u.LowPart)
|
||||
{
|
||||
/* grow stream */
|
||||
IStream_SetSize(iface, newSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock the buffer in position and copy the data.
|
||||
*/
|
||||
supportBuffer = GlobalLock(This->supportHandle);
|
||||
|
||||
memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
|
||||
|
||||
/*
|
||||
* Move the current position to the new position
|
||||
*/
|
||||
This->currentPosition.u.LowPart+=cb;
|
||||
|
||||
/*
|
||||
* Return the number of bytes read.
|
||||
*/
|
||||
*pcbWritten = cb;
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
GlobalUnlock(This->supportHandle);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* It will move the current stream pointer according to the parameters
|
||||
* given.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||
IStream* iface,
|
||||
LARGE_INTEGER dlibMove, /* [in] */
|
||||
DWORD dwOrigin, /* [in] */
|
||||
ULARGE_INTEGER* plibNewPosition) /* [out] */
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
|
||||
ULARGE_INTEGER newPosition;
|
||||
|
||||
TRACE("(%p, %lx%08lx, %ld, %p)\n", iface, dlibMove.u.HighPart,
|
||||
dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
|
||||
/*
|
||||
* The file pointer is moved depending on the given "function"
|
||||
* parameter.
|
||||
*/
|
||||
switch (dwOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET:
|
||||
newPosition.u.HighPart = 0;
|
||||
newPosition.u.LowPart = 0;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
newPosition = This->currentPosition;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
newPosition = This->streamSize;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the actual file pointer
|
||||
* If the file pointer ends-up after the end of the stream, the next Write operation will
|
||||
* make the file larger. This is how it is documented.
|
||||
*/
|
||||
newPosition.QuadPart = RtlLargeIntegerAdd(newPosition.QuadPart, dlibMove.QuadPart);
|
||||
if (newPosition.QuadPart < 0) return STG_E_INVALIDFUNCTION;
|
||||
|
||||
if (plibNewPosition) *plibNewPosition = newPosition;
|
||||
This->currentPosition = newPosition;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* It will change the size of a stream.
|
||||
*
|
||||
* TODO: Switch from small blocks to big blocks and vice versa.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libNewSize) /* [in] */
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
HGLOBAL supportHandle;
|
||||
|
||||
TRACE("(%p, %ld)\n", iface, libNewSize.u.LowPart);
|
||||
|
||||
/*
|
||||
* As documented.
|
||||
*/
|
||||
if (libNewSize.u.HighPart != 0)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
* Re allocate the HGlobal to fit the new size of the stream.
|
||||
*/
|
||||
supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
|
||||
|
||||
if (supportHandle == 0)
|
||||
return STG_E_MEDIUMFULL;
|
||||
|
||||
This->supportHandle = supportHandle;
|
||||
This->streamSize.u.LowPart = libNewSize.u.LowPart;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* It will copy the 'cb' Bytes to 'pstm' IStream.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
||||
IStream* iface,
|
||||
IStream* pstm, /* [unique][in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
ULARGE_INTEGER* pcbRead, /* [out] */
|
||||
ULARGE_INTEGER* pcbWritten) /* [out] */
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
BYTE tmpBuffer[128];
|
||||
ULONG bytesRead, bytesWritten, copySize;
|
||||
ULARGE_INTEGER totalBytesRead;
|
||||
ULARGE_INTEGER totalBytesWritten;
|
||||
|
||||
TRACE("(%p, %p, %ld, %p, %p)\n", iface, pstm,
|
||||
cb.u.LowPart, pcbRead, pcbWritten);
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if ( pstm == 0 )
|
||||
return STG_E_INVALIDPOINTER;
|
||||
|
||||
totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
|
||||
totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
|
||||
|
||||
/*
|
||||
* use stack to store data temporarly
|
||||
* there is surely more performant way of doing it, for now this basic
|
||||
* implementation will do the job
|
||||
*/
|
||||
while ( cb.u.LowPart > 0 )
|
||||
{
|
||||
if ( cb.u.LowPart >= 128 )
|
||||
copySize = 128;
|
||||
else
|
||||
copySize = cb.u.LowPart;
|
||||
|
||||
IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
|
||||
|
||||
totalBytesRead.u.LowPart += bytesRead;
|
||||
|
||||
IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
|
||||
|
||||
totalBytesWritten.u.LowPart += bytesWritten;
|
||||
|
||||
/*
|
||||
* Check that read & write operations were succesfull
|
||||
*/
|
||||
if (bytesRead != bytesWritten)
|
||||
{
|
||||
hr = STG_E_MEDIUMFULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytesRead!=copySize)
|
||||
cb.u.LowPart = 0;
|
||||
else
|
||||
cb.u.LowPart -= bytesRead;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update number of bytes read and written
|
||||
*/
|
||||
if (pcbRead)
|
||||
{
|
||||
pcbRead->u.LowPart = totalBytesRead.u.LowPart;
|
||||
pcbRead->u.HighPart = totalBytesRead.u.HighPart;
|
||||
}
|
||||
|
||||
if (pcbWritten)
|
||||
{
|
||||
pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
|
||||
pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* For streams supported by HGLOBALS, this function does nothing.
|
||||
* This is what the documentation tells us.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
||||
IStream* iface,
|
||||
DWORD grfCommitFlags) /* [in] */
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* For streams supported by HGLOBALS, this function does nothing.
|
||||
* This is what the documentation tells us.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
||||
IStream* iface)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* For streams supported by HGLOBALS, this function does nothing.
|
||||
* This is what the documentation tells us.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* For streams supported by HGLOBALS, this function does nothing.
|
||||
* This is what the documentation tells us.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* This method returns information about the current
|
||||
* stream.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||
IStream* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag) /* [in] */
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
|
||||
memset(pstatstg, 0, sizeof(STATSTG));
|
||||
|
||||
pstatstg->pwcsName = NULL;
|
||||
pstatstg->type = STGTY_STREAM;
|
||||
pstatstg->cbSize = This->streamSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm) /* [out] */
|
||||
{
|
||||
ULARGE_INTEGER dummy;
|
||||
LARGE_INTEGER offset;
|
||||
HRESULT hr;
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart);
|
||||
hr=CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
offset.QuadPart=(LONGLONG)This->currentPosition.QuadPart;
|
||||
HGLOBALStreamImpl_Seek(*ppstm,offset,STREAM_SEEK_SET,&dummy);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,642 +0,0 @@
|
||||
/*
|
||||
* basic interfaces
|
||||
*
|
||||
* Copyright 1997 Marcus Meissner
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(olemalloc);
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32 implementation
|
||||
*
|
||||
* NOTES
|
||||
* For supporting CoRegisterMallocSpy the IMalloc implementation must know if
|
||||
* a given memory block was allocated with a spy active.
|
||||
*
|
||||
*****************************************************************************/
|
||||
/* set the vtable later */
|
||||
static IMallocVtbl VT_IMalloc32;
|
||||
|
||||
typedef struct {
|
||||
IMallocVtbl *lpVtbl;
|
||||
DWORD dummy; /* nothing, we are static */
|
||||
IMallocSpy * pSpy; /* the spy when active */
|
||||
DWORD SpyedAllocationsLeft; /* number of spyed allocations left */
|
||||
BOOL SpyReleasePending; /* CoRevokeMallocSpy called with spyed allocations left*/
|
||||
LPVOID * SpyedBlocks; /* root of the table */
|
||||
int SpyedBlockTableLength; /* size of the table*/
|
||||
} _Malloc32;
|
||||
|
||||
/* this is the static object instance */
|
||||
_Malloc32 Malloc32 = {&VT_IMalloc32, 0, NULL, 0, 0, NULL, 0};
|
||||
|
||||
/* with a spy active all calls from pre to post methods are threadsave */
|
||||
static CRITICAL_SECTION IMalloc32_SpyCS;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
{
|
||||
0, 0, &IMalloc32_SpyCS,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
0, 0, { 0, (DWORD)(__FILE__ ": IMalloc32_SpyCS") }
|
||||
};
|
||||
static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/* resize the old table */
|
||||
static int SetSpyedBlockTableLength ( int NewLength )
|
||||
{
|
||||
LPVOID *NewSpyedBlocks;
|
||||
|
||||
if (!Malloc32.SpyedBlocks) NewSpyedBlocks = LocalAlloc(GMEM_ZEROINIT, NewLength * sizeof(PVOID));
|
||||
else NewSpyedBlocks = LocalReAlloc(Malloc32.SpyedBlocks, NewLength * sizeof(PVOID), GMEM_ZEROINIT);
|
||||
if (NewSpyedBlocks) {
|
||||
Malloc32.SpyedBlocks = NewSpyedBlocks;
|
||||
Malloc32.SpyedBlockTableLength = NewLength;
|
||||
}
|
||||
|
||||
return NewSpyedBlocks != NULL;
|
||||
}
|
||||
|
||||
/* add a location to the table */
|
||||
static int AddMemoryLocation(LPVOID * pMem)
|
||||
{
|
||||
LPVOID * Current;
|
||||
|
||||
/* allocate the table if not already allocated */
|
||||
if (!Malloc32.SpyedBlockTableLength) {
|
||||
if (!SetSpyedBlockTableLength(0x1000)) return 0;
|
||||
}
|
||||
|
||||
/* find a free location */
|
||||
Current = Malloc32.SpyedBlocks;
|
||||
while (*Current) {
|
||||
Current++;
|
||||
if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
|
||||
/* no more space in table, grow it */
|
||||
if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* put the location in our table */
|
||||
*Current = pMem;
|
||||
Malloc32.SpyedAllocationsLeft++;
|
||||
/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int RemoveMemoryLocation(LPVOID * pMem)
|
||||
{
|
||||
LPVOID * Current;
|
||||
|
||||
/* allocate the table if not already allocated */
|
||||
if (!Malloc32.SpyedBlockTableLength) {
|
||||
if (!SetSpyedBlockTableLength(0x1000)) return 0;
|
||||
}
|
||||
|
||||
Current = Malloc32.SpyedBlocks;
|
||||
|
||||
/* find the location */
|
||||
while (*Current != pMem) {
|
||||
Current++;
|
||||
if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) return 0; /* not found */
|
||||
}
|
||||
|
||||
/* location found */
|
||||
Malloc32.SpyedAllocationsLeft--;
|
||||
/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
|
||||
*Current = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_QueryInterface [VTABLE]
|
||||
*/
|
||||
static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) {
|
||||
|
||||
TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) {
|
||||
*obj = (LPMALLOC)&Malloc32;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_AddRefRelease [VTABLE]
|
||||
*/
|
||||
static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_Alloc [VTABLE]
|
||||
*/
|
||||
static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) {
|
||||
|
||||
LPVOID addr;
|
||||
|
||||
TRACE("(%ld)\n",cb);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
DWORD preAllocResult;
|
||||
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
preAllocResult = IMallocSpy_PreAlloc(Malloc32.pSpy, cb);
|
||||
if ((cb != 0) && (preAllocResult == 0)) {
|
||||
/* PreAlloc can force Alloc to fail, but not if cb == 0 */
|
||||
TRACE("returning null\n");
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
addr = HeapAlloc(GetProcessHeap(),0,cb);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
addr = IMallocSpy_PostAlloc(Malloc32.pSpy, addr);
|
||||
if (addr) AddMemoryLocation(addr);
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
}
|
||||
|
||||
TRACE("--(%p)\n",addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_Realloc [VTABLE]
|
||||
*/
|
||||
static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
|
||||
|
||||
LPVOID pNewMemory;
|
||||
|
||||
TRACE("(%p,%ld)\n",pv,cb);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
LPVOID pRealMemory;
|
||||
BOOL fSpyed;
|
||||
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
fSpyed = RemoveMemoryLocation(pv);
|
||||
cb = IMallocSpy_PreRealloc(Malloc32.pSpy, pv, cb, &pRealMemory, fSpyed);
|
||||
|
||||
/* check if can release the spy */
|
||||
if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
|
||||
IMallocSpy_Release(Malloc32.pSpy);
|
||||
Malloc32.SpyReleasePending = FALSE;
|
||||
Malloc32.pSpy = NULL;
|
||||
}
|
||||
|
||||
if (0==cb) {
|
||||
/* PreRealloc can force Realloc to fail */
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
return NULL;
|
||||
}
|
||||
pv = pRealMemory;
|
||||
}
|
||||
|
||||
if (!pv) pNewMemory = HeapAlloc(GetProcessHeap(),0,cb);
|
||||
else if (cb) pNewMemory = HeapReAlloc(GetProcessHeap(),0,pv,cb);
|
||||
else {
|
||||
HeapFree(GetProcessHeap(),0,pv);
|
||||
pNewMemory = NULL;
|
||||
}
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
pNewMemory = IMallocSpy_PostRealloc(Malloc32.pSpy, pNewMemory, TRUE);
|
||||
if (pNewMemory) AddMemoryLocation(pNewMemory);
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
}
|
||||
|
||||
TRACE("--(%p)\n",pNewMemory);
|
||||
return pNewMemory;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_Free [VTABLE]
|
||||
*/
|
||||
static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
|
||||
|
||||
BOOL fSpyed = 0;
|
||||
|
||||
TRACE("(%p)\n",pv);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
fSpyed = RemoveMemoryLocation(pv);
|
||||
pv = IMallocSpy_PreFree(Malloc32.pSpy, pv, fSpyed);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),0,pv);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
IMallocSpy_PostFree(Malloc32.pSpy, fSpyed);
|
||||
|
||||
/* check if can release the spy */
|
||||
if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
|
||||
IMallocSpy_Release(Malloc32.pSpy);
|
||||
Malloc32.SpyReleasePending = FALSE;
|
||||
Malloc32.pSpy = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_GetSize [VTABLE]
|
||||
*
|
||||
* NOTES
|
||||
* FIXME returns:
|
||||
* win95: size allocated (4 byte boundarys)
|
||||
* win2k: size originally requested !!! (allocated on 8 byte boundarys)
|
||||
*/
|
||||
static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) {
|
||||
|
||||
DWORD cb;
|
||||
BOOL fSpyed = 0;
|
||||
|
||||
TRACE("(%p)\n",pv);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
pv = IMallocSpy_PreGetSize(Malloc32.pSpy, pv, fSpyed);
|
||||
}
|
||||
|
||||
cb = HeapSize(GetProcessHeap(),0,pv);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
cb = IMallocSpy_PostGetSize(Malloc32.pSpy, cb, fSpyed);
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_DidAlloc [VTABLE]
|
||||
*/
|
||||
static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
|
||||
|
||||
BOOL fSpyed = 0;
|
||||
int didAlloc;
|
||||
|
||||
TRACE("(%p)\n",pv);
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
pv = IMallocSpy_PreDidAlloc(Malloc32.pSpy, pv, fSpyed);
|
||||
}
|
||||
|
||||
didAlloc = -1;
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
didAlloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, pv, fSpyed, didAlloc);
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
}
|
||||
return didAlloc;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_HeapMinimize [VTABLE]
|
||||
*/
|
||||
static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) {
|
||||
TRACE("()\n");
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
IMallocSpy_PreHeapMinimize(Malloc32.pSpy);
|
||||
}
|
||||
|
||||
if(Malloc32.pSpy) {
|
||||
IMallocSpy_PostHeapMinimize(Malloc32.pSpy);
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
}
|
||||
}
|
||||
|
||||
static IMallocVtbl VT_IMalloc32 =
|
||||
{
|
||||
IMalloc_fnQueryInterface,
|
||||
IMalloc_fnAddRefRelease,
|
||||
IMalloc_fnAddRefRelease,
|
||||
IMalloc_fnAlloc,
|
||||
IMalloc_fnRealloc,
|
||||
IMalloc_fnFree,
|
||||
IMalloc_fnGetSize,
|
||||
IMalloc_fnDidAlloc,
|
||||
IMalloc_fnHeapMinimize
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* IMallocSpy implementation
|
||||
*****************************************************************************/
|
||||
|
||||
/* set the vtable later */
|
||||
static IMallocSpyVtbl VT_IMallocSpy;
|
||||
|
||||
typedef struct {
|
||||
IMallocSpyVtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
} _MallocSpy;
|
||||
|
||||
/* this is the static object instance */
|
||||
_MallocSpy MallocSpy = {&VT_IMallocSpy, 0};
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_QueryInterface [VTABLE]
|
||||
*/
|
||||
static HRESULT WINAPI IMallocSpy_fnQueryInterface(LPMALLOCSPY iface,REFIID refiid,LPVOID *obj)
|
||||
{
|
||||
|
||||
TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMallocSpy,refiid)) {
|
||||
*obj = (LPMALLOC)&MallocSpy;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_AddRef [VTABLE]
|
||||
*/
|
||||
static ULONG WINAPI IMallocSpy_fnAddRef (LPMALLOCSPY iface)
|
||||
{
|
||||
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
|
||||
TRACE ("(%p)->(count=%lu)\n", This, This->ref);
|
||||
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc32_AddRelease [VTABLE]
|
||||
*
|
||||
* NOTES
|
||||
* Our MallocSpy is static. If the count reaches 0 we dump the leaks
|
||||
*/
|
||||
static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
|
||||
{
|
||||
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
|
||||
TRACE ("(%p)->(count=%lu)\n", This, This->ref);
|
||||
|
||||
if (!--(This->ref)) {
|
||||
/* our allocation list MUST be empty here */
|
||||
}
|
||||
return This->ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMallocSpy_fnPreAlloc(LPMALLOCSPY iface, ULONG cbRequest)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%lu)\n", This, cbRequest);
|
||||
return cbRequest;
|
||||
}
|
||||
static PVOID WINAPI IMallocSpy_fnPostAlloc(LPMALLOCSPY iface, void* pActual)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%p)\n", This, pActual);
|
||||
return pActual;
|
||||
}
|
||||
|
||||
static PVOID WINAPI IMallocSpy_fnPreFree(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
|
||||
return pRequest;
|
||||
}
|
||||
static void WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL fSpyed)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%u)\n", This, fSpyed);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMallocSpy_fnPreRealloc(LPMALLOCSPY iface, void* pRequest, ULONG cbRequest, void** ppNewRequest, BOOL fSpyed)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%p %lu %u)\n", This, pRequest, cbRequest, fSpyed);
|
||||
*ppNewRequest = pRequest;
|
||||
return cbRequest;
|
||||
}
|
||||
|
||||
static PVOID WINAPI IMallocSpy_fnPostRealloc(LPMALLOCSPY iface, void* pActual, BOOL fSpyed)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%p %u)\n", This, pActual, fSpyed);
|
||||
return pActual;
|
||||
}
|
||||
|
||||
static PVOID WINAPI IMallocSpy_fnPreGetSize(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IMallocSpy_fnPostGetSize(LPMALLOCSPY iface, ULONG cbActual, BOOL fSpyed)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%lu %u)\n", This, cbActual, fSpyed);
|
||||
return cbActual;
|
||||
}
|
||||
|
||||
static PVOID WINAPI IMallocSpy_fnPreDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
static int WINAPI IMallocSpy_fnPostDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed, int fActual)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->(%p %u %u)\n", This, pRequest, fSpyed, fActual);
|
||||
return fActual;
|
||||
}
|
||||
|
||||
static void WINAPI IMallocSpy_fnPreHeapMinimize(LPMALLOCSPY iface)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->()\n", This);
|
||||
}
|
||||
|
||||
static void WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
|
||||
{
|
||||
_MallocSpy *This = (_MallocSpy *)iface;
|
||||
TRACE ("(%p)->()\n", This);
|
||||
}
|
||||
|
||||
static void MallocSpyDumpLeaks() {
|
||||
TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft);
|
||||
}
|
||||
|
||||
static IMallocSpyVtbl VT_IMallocSpy =
|
||||
{
|
||||
IMallocSpy_fnQueryInterface,
|
||||
IMallocSpy_fnAddRef,
|
||||
IMallocSpy_fnRelease,
|
||||
IMallocSpy_fnPreAlloc,
|
||||
IMallocSpy_fnPostAlloc,
|
||||
IMallocSpy_fnPreFree,
|
||||
IMallocSpy_fnPostFree,
|
||||
IMallocSpy_fnPreRealloc,
|
||||
IMallocSpy_fnPostRealloc,
|
||||
IMallocSpy_fnPreGetSize,
|
||||
IMallocSpy_fnPostGetSize,
|
||||
IMallocSpy_fnPreDidAlloc,
|
||||
IMallocSpy_fnPostDidAlloc,
|
||||
IMallocSpy_fnPreHeapMinimize,
|
||||
IMallocSpy_fnPostHeapMinimize
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* CoGetMalloc [OLE32.@]
|
||||
*
|
||||
* RETURNS
|
||||
* The win32 IMalloc
|
||||
*/
|
||||
HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC *lpMalloc)
|
||||
{
|
||||
*lpMalloc = (LPMALLOC)&Malloc32;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoTaskMemAlloc [OLE32.@]
|
||||
* RETURNS
|
||||
* pointer to newly allocated block
|
||||
*/
|
||||
LPVOID WINAPI CoTaskMemAlloc(ULONG size)
|
||||
{
|
||||
return IMalloc_Alloc((LPMALLOC)&Malloc32,size);
|
||||
}
|
||||
/***********************************************************************
|
||||
* CoTaskMemFree [OLE32.@]
|
||||
*/
|
||||
VOID WINAPI CoTaskMemFree(LPVOID ptr)
|
||||
{
|
||||
IMalloc_Free((LPMALLOC)&Malloc32, ptr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoTaskMemRealloc [OLE32.@]
|
||||
* RETURNS
|
||||
* pointer to newly allocated block
|
||||
*/
|
||||
LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, ULONG size)
|
||||
{
|
||||
return IMalloc_Realloc((LPMALLOC)&Malloc32, pvOld, size);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoRegisterMallocSpy [OLE32.@]
|
||||
*
|
||||
* NOTES
|
||||
* if a mallocspy is already registered, we can't do it again since
|
||||
* only the spy knows, how to free a memory block
|
||||
*/
|
||||
HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy)
|
||||
{
|
||||
IMallocSpy* pSpy;
|
||||
HRESULT hres = E_INVALIDARG;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
/* HACK TO ACTIVATE OUT SPY */
|
||||
if (pMallocSpy == (LPVOID)-1) pMallocSpy =(IMallocSpy*)&MallocSpy;
|
||||
|
||||
if(Malloc32.pSpy) return CO_E_OBJISREG;
|
||||
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
|
||||
if (SUCCEEDED(IUnknown_QueryInterface(pMallocSpy, &IID_IMallocSpy, (LPVOID*)&pSpy))) {
|
||||
Malloc32.pSpy = pSpy;
|
||||
hres = S_OK;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoRevokeMallocSpy [OLE32.@]
|
||||
*
|
||||
* NOTES
|
||||
* we can't revoke a malloc spy as long as memory blocks allocated with
|
||||
* the spy are active since only the spy knows how to free them
|
||||
*/
|
||||
HRESULT WINAPI CoRevokeMallocSpy(void)
|
||||
{
|
||||
HRESULT hres = S_OK;
|
||||
TRACE("\n");
|
||||
|
||||
EnterCriticalSection(&IMalloc32_SpyCS);
|
||||
|
||||
/* if it's our spy it's time to dump the leaks */
|
||||
if (Malloc32.pSpy == (IMallocSpy*)&MallocSpy) {
|
||||
MallocSpyDumpLeaks();
|
||||
}
|
||||
|
||||
if (Malloc32.SpyedAllocationsLeft) {
|
||||
TRACE("SpyReleasePending with %lu allocations left\n", Malloc32.SpyedAllocationsLeft);
|
||||
Malloc32.SpyReleasePending = TRUE;
|
||||
hres = E_ACCESSDENIED;
|
||||
} else {
|
||||
IMallocSpy_Release(Malloc32.pSpy);
|
||||
Malloc32.pSpy = NULL;
|
||||
}
|
||||
LeaveCriticalSection(&IMalloc32_SpyCS);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IsValidInterface [OLE32.@]
|
||||
*
|
||||
* RETURNS
|
||||
* True, if the passed pointer is a valid interface
|
||||
*/
|
||||
BOOL WINAPI IsValidInterface(
|
||||
LPUNKNOWN punk /* [in] interface to be tested */
|
||||
) {
|
||||
return !(
|
||||
IsBadReadPtr(punk,4) ||
|
||||
IsBadReadPtr(punk->lpVtbl,4) ||
|
||||
IsBadReadPtr(punk->lpVtbl->QueryInterface,9) ||
|
||||
IsBadCodePtr((FARPROC)punk->lpVtbl->QueryInterface)
|
||||
);
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 1997 Marcus Meissner
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_OLE_IFS_H
|
||||
#define __WINE_OLE_IFS_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
typedef CHAR OLECHAR16;
|
||||
typedef LPSTR LPOLESTR16;
|
||||
typedef LPCSTR LPCOLESTR16;
|
||||
|
||||
/***********************************************************************
|
||||
* IMalloc16 interface
|
||||
*/
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IMalloc16
|
||||
DECLARE_INTERFACE_(IMalloc16,IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IMalloc16 methods ***/
|
||||
STDMETHOD_(LPVOID,Alloc)(THIS_ DWORD cb) PURE;
|
||||
STDMETHOD_(LPVOID,Realloc)(THIS_ LPVOID pv, DWORD cb) PURE;
|
||||
STDMETHOD_(void,Free)(THIS_ LPVOID pv) PURE;
|
||||
STDMETHOD_(DWORD,GetSize)(THIS_ LPVOID pv) PURE;
|
||||
STDMETHOD_(INT16,DidAlloc)(THIS_ LPVOID pv) PURE;
|
||||
STDMETHOD_(LPVOID,HeapMinimize)(THIS) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
typedef struct IMalloc16 *LPMALLOC16;
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
extern LPMALLOC16 IMalloc16_Constructor();
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
#define INTERFACE ILockBytes16
|
||||
DECLARE_INTERFACE_(ILockBytes16,IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** ILockBytes16 methods ***/
|
||||
STDMETHOD(ReadAt)(THIS_ ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead) PURE;
|
||||
STDMETHOD(WriteAt)(THIS_ ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten) PURE;
|
||||
STDMETHOD(Flush)(THIS) PURE;
|
||||
STDMETHOD(SetSize)(THIS_ ULARGE_INTEGER cb) PURE;
|
||||
STDMETHOD(LockRegion)(THIS_ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) PURE;
|
||||
STDMETHOD(UnlockRegion)(THIS_ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) PURE;
|
||||
STDMETHOD(Stat)(THIS_ STATSTG *pstatstg, DWORD grfStatFlag) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
typedef struct tagSTATSTG16
|
||||
{
|
||||
LPOLESTR16 pwcsName;
|
||||
DWORD type;
|
||||
ULARGE_INTEGER cbSize;
|
||||
FILETIME mtime;
|
||||
FILETIME ctime;
|
||||
FILETIME atime;
|
||||
DWORD grfMode;
|
||||
DWORD grfLocksSupported;
|
||||
CLSID clsid;
|
||||
DWORD grfStateBits;
|
||||
DWORD reserved;
|
||||
} STATSTG16;
|
||||
|
||||
#define INTERFACE IStream16
|
||||
DECLARE_INTERFACE_(IStream16,ISequentialStream)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** ISequentialStream methods ***/
|
||||
STDMETHOD_(HRESULT,Read)(THIS_ void* pv, ULONG cb, ULONG* pcbRead) PURE;
|
||||
STDMETHOD_(HRESULT,Write)(THIS_ const void* pv, ULONG cb, ULONG* pcbWritten) PURE;
|
||||
/*** IStream16 methods ***/
|
||||
STDMETHOD(Seek)(THIS_ LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) PURE;
|
||||
STDMETHOD(SetSize)(THIS_ ULARGE_INTEGER libNewSize) PURE;
|
||||
STDMETHOD(CopyTo)(THIS_ IStream16* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) PURE;
|
||||
STDMETHOD(Commit)(THIS_ DWORD grfCommitFlags) PURE;
|
||||
STDMETHOD(Revert)(THIS) PURE;
|
||||
STDMETHOD(LockRegion)(THIS_ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) PURE;
|
||||
STDMETHOD(UnlockRegion)(THIS_ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) PURE;
|
||||
STDMETHOD(Stat)(THIS_ STATSTG* pstatstg, DWORD grfStatFlag) PURE;
|
||||
STDMETHOD(Clone)(THIS_ IStream16** ppstm) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
typedef OLECHAR16 **SNB16;
|
||||
|
||||
#define INTERFACE IStorage16
|
||||
DECLARE_INTERFACE_(IStorage16,IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IStorage16 methods ***/
|
||||
STDMETHOD_(HRESULT,CreateStream)(THIS_ LPCOLESTR16 pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream16** ppstm) PURE;
|
||||
STDMETHOD_(HRESULT,OpenStream)(THIS_ LPCOLESTR16 pwcsName, void* reserved1, DWORD grfMode, DWORD reserved2, IStream16** ppstm) PURE;
|
||||
STDMETHOD_(HRESULT,CreateStorage)(THIS_ LPCOLESTR16 pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage16** ppstg) PURE;
|
||||
STDMETHOD_(HRESULT,OpenStorage)(THIS_ LPCOLESTR16 pwcsName, IStorage16* pstgPriority, DWORD grfMode, SNB16 snbExclude, DWORD reserved, IStorage16** ppstg) PURE;
|
||||
STDMETHOD_(HRESULT,CopyTo)(THIS_ DWORD ciidExclude, const IID* rgiidExclude, SNB16 snbExclude, IStorage16* pstgDest) PURE;
|
||||
STDMETHOD_(HRESULT,MoveElementTo)(THIS_ LPCOLESTR16 pwcsName, IStorage16* pstgDest, LPCOLESTR16 pwcsNewName, DWORD grfFlags) PURE;
|
||||
STDMETHOD_(HRESULT,Commit)(THIS_ DWORD grfCommitFlags) PURE;
|
||||
STDMETHOD_(HRESULT,Revert)(THIS) PURE;
|
||||
STDMETHOD_(HRESULT,EnumElements)(THIS_ DWORD reserved1, void* reserved2, DWORD reserved3, IEnumSTATSTG** ppenum) PURE;
|
||||
STDMETHOD_(HRESULT,DestroyElement)(THIS_ LPCOLESTR16 pwcsName) PURE;
|
||||
STDMETHOD_(HRESULT,RenameElement)(THIS_ LPCOLESTR16 pwcsOldName, LPCOLESTR16 pwcsNewName) PURE;
|
||||
STDMETHOD_(HRESULT,SetElementTimes)(THIS_ LPCOLESTR16 pwcsName, const FILETIME* pctime, const FILETIME* patime, const FILETIME* pmtime) PURE;
|
||||
STDMETHOD_(HRESULT,SetClass)(THIS_ REFCLSID clsid) PURE;
|
||||
STDMETHOD_(HRESULT,SetStateBits)(THIS_ DWORD grfStateBits, DWORD grfMask) PURE;
|
||||
STDMETHOD_(HRESULT,Stat)(THIS_ STATSTG* pstatstg, DWORD grfStatFlag) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#endif /* __WINE_OLE_IFS_H */
|
||||
@@ -1,982 +0,0 @@
|
||||
/***************************************************************************************
|
||||
* ItemMonikers implementation
|
||||
*
|
||||
* Copyright 1999 Noomen Hamza
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "winerror.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ole2.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "moniker.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
const CLSID CLSID_ItemMoniker = {
|
||||
0x304, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
|
||||
};
|
||||
|
||||
/* ItemMoniker data structure */
|
||||
typedef struct ItemMonikerImpl{
|
||||
|
||||
IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/
|
||||
|
||||
/* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
|
||||
* two monikers are equal. That's whay IROTData interface is implemented by monikers.
|
||||
*/
|
||||
IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/
|
||||
|
||||
ULONG ref; /* reference counter for this object */
|
||||
|
||||
LPOLESTR itemName; /* item name identified by this ItemMoniker */
|
||||
|
||||
LPOLESTR itemDelimiter; /* Delimiter string */
|
||||
|
||||
} ItemMonikerImpl;
|
||||
|
||||
/********************************************************************************/
|
||||
/* ItemMoniker prototype functions : */
|
||||
|
||||
/* IUnknown prototype functions */
|
||||
static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
|
||||
static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
|
||||
static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface);
|
||||
|
||||
/* IPersist prototype functions */
|
||||
static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
|
||||
|
||||
/* IPersistStream prototype functions */
|
||||
static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
|
||||
static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
|
||||
static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
|
||||
static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
|
||||
|
||||
/* IMoniker prototype functions */
|
||||
static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
|
||||
static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
|
||||
static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
|
||||
static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
|
||||
static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
|
||||
static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
|
||||
static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
|
||||
static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
|
||||
static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);
|
||||
static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
|
||||
static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
|
||||
static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
|
||||
static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
|
||||
static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
|
||||
static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
|
||||
|
||||
/* Local function used by ItemMoniker implementation */
|
||||
HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
|
||||
HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
|
||||
|
||||
/********************************************************************************/
|
||||
/* IROTData prototype functions */
|
||||
|
||||
/* IUnknown prototype functions */
|
||||
static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
|
||||
static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
|
||||
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
|
||||
|
||||
/* IROTData prototype function */
|
||||
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
|
||||
|
||||
/********************************************************************************/
|
||||
/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
|
||||
/* IPersistStream and IMoniker functions. */
|
||||
static IMonikerVtbl VT_ItemMonikerImpl =
|
||||
{
|
||||
ItemMonikerImpl_QueryInterface,
|
||||
ItemMonikerImpl_AddRef,
|
||||
ItemMonikerImpl_Release,
|
||||
ItemMonikerImpl_GetClassID,
|
||||
ItemMonikerImpl_IsDirty,
|
||||
ItemMonikerImpl_Load,
|
||||
ItemMonikerImpl_Save,
|
||||
ItemMonikerImpl_GetSizeMax,
|
||||
ItemMonikerImpl_BindToObject,
|
||||
ItemMonikerImpl_BindToStorage,
|
||||
ItemMonikerImpl_Reduce,
|
||||
ItemMonikerImpl_ComposeWith,
|
||||
ItemMonikerImpl_Enum,
|
||||
ItemMonikerImpl_IsEqual,
|
||||
ItemMonikerImpl_Hash,
|
||||
ItemMonikerImpl_IsRunning,
|
||||
ItemMonikerImpl_GetTimeOfLastChange,
|
||||
ItemMonikerImpl_Inverse,
|
||||
ItemMonikerImpl_CommonPrefixWith,
|
||||
ItemMonikerImpl_RelativePathTo,
|
||||
ItemMonikerImpl_GetDisplayName,
|
||||
ItemMonikerImpl_ParseDisplayName,
|
||||
ItemMonikerImpl_IsSystemMoniker
|
||||
};
|
||||
|
||||
/********************************************************************************/
|
||||
/* Virtual function table for the IROTData class. */
|
||||
static IROTDataVtbl VT_ROTDataImpl =
|
||||
{
|
||||
ItemMonikerROTDataImpl_QueryInterface,
|
||||
ItemMonikerROTDataImpl_AddRef,
|
||||
ItemMonikerROTDataImpl_Release,
|
||||
ItemMonikerROTDataImpl_GetComparaisonData
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* ItemMoniker_QueryInterface
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
|
||||
|
||||
/* Perform a sanity check on the parameters.*/
|
||||
if ( (This==0) || (ppvObject==0) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Initialize the return parameter */
|
||||
*ppvObject = 0;
|
||||
|
||||
/* Compare the riid with the interface IDs implemented by this object.*/
|
||||
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||
IsEqualIID(&IID_IPersist, riid) ||
|
||||
IsEqualIID(&IID_IPersistStream, riid) ||
|
||||
IsEqualIID(&IID_IMoniker, riid)
|
||||
)
|
||||
*ppvObject = iface;
|
||||
|
||||
else if (IsEqualIID(&IID_IROTData, riid))
|
||||
*ppvObject = (IROTData*)&(This->lpvtbl2);
|
||||
|
||||
/* Check that we obtained an interface.*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/* Query Interface always increases the reference count by one when it is successful */
|
||||
ItemMonikerImpl_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_AddRef
|
||||
******************************************************************************/
|
||||
ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Release
|
||||
******************************************************************************/
|
||||
ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
ULONG ref;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
/* destroy the object if there's no more reference on it */
|
||||
if (ref == 0) ItemMonikerImpl_Destroy(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_GetClassID
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
|
||||
{
|
||||
TRACE("(%p,%p),stub!\n",iface,pClassID);
|
||||
|
||||
if (pClassID==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*pClassID = CLSID_ItemMoniker;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_IsDirty
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
|
||||
{
|
||||
/* Note that the OLE-provided implementations of the IPersistStream::IsDirty
|
||||
method in the OLE-provided moniker interfaces always return S_FALSE because
|
||||
their internal state never changes. */
|
||||
|
||||
TRACE("(%p)\n",iface);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Load
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
||||
{
|
||||
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
HRESULT res;
|
||||
DWORD delimiterLength,nameLength,lenW;
|
||||
CHAR *itemNameA,*itemDelimiterA;
|
||||
ULONG bread;
|
||||
|
||||
/* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
|
||||
|
||||
/* read item delimiter string length + 1 */
|
||||
res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread);
|
||||
if (bread != sizeof(DWORD))
|
||||
return E_FAIL;
|
||||
|
||||
/* read item delimiter string */
|
||||
if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength)))
|
||||
return E_OUTOFMEMORY;
|
||||
res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread);
|
||||
if (bread != delimiterLength)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, itemDelimiterA );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 );
|
||||
This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR));
|
||||
if (!This->itemDelimiter)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, itemDelimiterA );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW );
|
||||
HeapFree( GetProcessHeap(), 0, itemDelimiterA );
|
||||
|
||||
/* read item name string length + 1*/
|
||||
res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread);
|
||||
if (bread != sizeof(DWORD))
|
||||
return E_FAIL;
|
||||
|
||||
/* read item name string */
|
||||
if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength)))
|
||||
return E_OUTOFMEMORY;
|
||||
res=IStream_Read(pStm,itemNameA,nameLength,&bread);
|
||||
if (bread != nameLength)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, itemNameA );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 );
|
||||
This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR));
|
||||
if (!This->itemName)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, itemNameA );
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW );
|
||||
HeapFree( GetProcessHeap(), 0, itemNameA );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Save
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
|
||||
IStream* pStm,/* pointer to the stream where the object is to be saved */
|
||||
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
HRESULT res;
|
||||
CHAR *itemNameA,*itemDelimiterA;
|
||||
|
||||
/* data written by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */
|
||||
/* 2) String (type A): item delimiter string ('\0' included) */
|
||||
/* 3) DWORD : size of item name string ('\0' included) */
|
||||
/* 4) String (type A): item name string ('\0' included) */
|
||||
|
||||
DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL);
|
||||
DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL);
|
||||
itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength);
|
||||
itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength);
|
||||
WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
|
||||
WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
|
||||
|
||||
res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
|
||||
res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
|
||||
res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
|
||||
res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_GetSizeMax
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
|
||||
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
|
||||
DWORD nameLength=lstrlenW(This->itemName)+1;
|
||||
|
||||
TRACE("(%p,%p)\n",iface,pcbSize);
|
||||
|
||||
if (pcbSize!=NULL)
|
||||
return E_POINTER;
|
||||
|
||||
/* for more details see ItemMonikerImpl_Save coments */
|
||||
|
||||
pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
|
||||
delimiterLength + /* item delimiter string */
|
||||
sizeof(DWORD) + /* DWORD which contains item name length */
|
||||
nameLength + /* item name string */
|
||||
34; /* this constant was added ! because when I tested this function it usually */
|
||||
/* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
|
||||
pcbSize->u.HighPart=0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Construct (local function)
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
|
||||
{
|
||||
|
||||
int sizeStr1=lstrlenW(lpszItem), sizeStr2;
|
||||
static const OLECHAR emptystr[1];
|
||||
LPCOLESTR delim;
|
||||
|
||||
TRACE("(%p,%p)\n",This,lpszItem);
|
||||
|
||||
/* Initialize the virtual fgunction table. */
|
||||
This->lpvtbl1 = &VT_ItemMonikerImpl;
|
||||
This->lpvtbl2 = &VT_ROTDataImpl;
|
||||
This->ref = 0;
|
||||
|
||||
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
|
||||
if (!This->itemName)
|
||||
return E_OUTOFMEMORY;
|
||||
lstrcpyW(This->itemName,lpszItem);
|
||||
|
||||
if (!lpszDelim)
|
||||
FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
|
||||
|
||||
delim = lpszDelim ? lpszDelim : emptystr;
|
||||
|
||||
sizeStr2=lstrlenW(delim);
|
||||
This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
|
||||
if (!This->itemDelimiter) {
|
||||
HeapFree(GetProcessHeap(),0,This->itemName);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
lstrcpyW(This->itemDelimiter,delim);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Destroy (local function)
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if (This->itemName)
|
||||
HeapFree(GetProcessHeap(),0,This->itemName);
|
||||
|
||||
if (This->itemDelimiter)
|
||||
HeapFree(GetProcessHeap(),0,This->itemDelimiter);
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_BindToObject
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riid,
|
||||
VOID** ppvResult)
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
HRESULT res;
|
||||
IID refid=IID_IOleItemContainer;
|
||||
IOleItemContainer *poic=0;
|
||||
|
||||
TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
|
||||
|
||||
if(ppvResult ==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
if(pmkToLeft==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppvResult=0;
|
||||
|
||||
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic);
|
||||
|
||||
if (SUCCEEDED(res)){
|
||||
|
||||
res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult);
|
||||
|
||||
IOleItemContainer_Release(poic);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_BindToStorage
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riid,
|
||||
VOID** ppvResult)
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
HRESULT res;
|
||||
IOleItemContainer *poic=0;
|
||||
|
||||
TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
|
||||
|
||||
*ppvResult=0;
|
||||
|
||||
if(pmkToLeft==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
|
||||
|
||||
if (SUCCEEDED(res)){
|
||||
|
||||
res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult);
|
||||
|
||||
IOleItemContainer_Release(poic);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Reduce
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
DWORD dwReduceHowFar,
|
||||
IMoniker** ppmkToLeft,
|
||||
IMoniker** ppmkReduced)
|
||||
{
|
||||
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
||||
|
||||
if (ppmkReduced==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
ItemMonikerImpl_AddRef(iface);
|
||||
|
||||
*ppmkReduced=iface;
|
||||
|
||||
return MK_S_REDUCED_TO_SELF;
|
||||
}
|
||||
/******************************************************************************
|
||||
* ItemMoniker_ComposeWith
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
|
||||
IMoniker* pmkRight,
|
||||
BOOL fOnlyIfNotGeneric,
|
||||
IMoniker** ppmkComposite)
|
||||
{
|
||||
HRESULT res=S_OK;
|
||||
DWORD mkSys,mkSys2;
|
||||
IEnumMoniker* penumMk=0;
|
||||
IMoniker *pmostLeftMk=0;
|
||||
IMoniker* tempMkComposite=0;
|
||||
|
||||
TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
|
||||
|
||||
if ((ppmkComposite==NULL)||(pmkRight==NULL))
|
||||
return E_POINTER;
|
||||
|
||||
*ppmkComposite=0;
|
||||
|
||||
IMoniker_IsSystemMoniker(pmkRight,&mkSys);
|
||||
|
||||
/* If pmkRight is an anti-moniker, the returned moniker is NULL */
|
||||
if(mkSys==MKSYS_ANTIMONIKER)
|
||||
return res;
|
||||
|
||||
else
|
||||
/* if pmkRight is a composite whose leftmost component is an anti-moniker, */
|
||||
/* the returned moniker is the composite after the leftmost anti-moniker is removed. */
|
||||
|
||||
if(mkSys==MKSYS_GENERICCOMPOSITE){
|
||||
|
||||
res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
|
||||
|
||||
if (FAILED(res))
|
||||
return res;
|
||||
|
||||
res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
|
||||
|
||||
IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
|
||||
|
||||
if(mkSys2==MKSYS_ANTIMONIKER){
|
||||
|
||||
IMoniker_Release(pmostLeftMk);
|
||||
|
||||
tempMkComposite=iface;
|
||||
IMoniker_AddRef(iface);
|
||||
|
||||
while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
|
||||
|
||||
res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
|
||||
|
||||
IMoniker_Release(tempMkComposite);
|
||||
IMoniker_Release(pmostLeftMk);
|
||||
|
||||
tempMkComposite=*ppmkComposite;
|
||||
IMoniker_AddRef(tempMkComposite);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
|
||||
}
|
||||
/* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
|
||||
composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
|
||||
a NULL moniker and a return value of MK_E_NEEDGENERIC */
|
||||
else
|
||||
if (!fOnlyIfNotGeneric)
|
||||
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
|
||||
|
||||
else
|
||||
return MK_E_NEEDGENERIC;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Enum
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
|
||||
{
|
||||
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
|
||||
|
||||
if (ppenumMoniker == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppenumMoniker = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_IsEqual
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
||||
{
|
||||
|
||||
CLSID clsid;
|
||||
LPOLESTR dispName1,dispName2;
|
||||
IBindCtx* bind;
|
||||
HRESULT res = S_FALSE;
|
||||
|
||||
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
|
||||
|
||||
if (!pmkOtherMoniker) return S_FALSE;
|
||||
|
||||
|
||||
/* check if both are ItemMoniker */
|
||||
if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
|
||||
if(!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) return S_FALSE;
|
||||
|
||||
/* check if both displaynames are the same */
|
||||
if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
|
||||
if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
|
||||
if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
|
||||
if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;
|
||||
CoTaskMemFree(dispName2);
|
||||
}
|
||||
CoTaskMemFree(dispName1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Hash
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
int h = 0,i,skip,len;
|
||||
int off = 0;
|
||||
LPOLESTR val;
|
||||
|
||||
if (pdwHash==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
val = This->itemName;
|
||||
len = lstrlenW(val);
|
||||
|
||||
if (len < 16) {
|
||||
for (i = len ; i > 0; i--) {
|
||||
h = (h * 37) + val[off++];
|
||||
}
|
||||
} else {
|
||||
/* only sample some characters */
|
||||
skip = len / 8;
|
||||
for (i = len ; i > 0; i -= skip, off += skip) {
|
||||
h = (h * 39) + val[off];
|
||||
}
|
||||
}
|
||||
|
||||
*pdwHash=h;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_IsRunning
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
IMoniker* pmkNewlyRunning)
|
||||
{
|
||||
IRunningObjectTable* rot;
|
||||
HRESULT res;
|
||||
IOleItemContainer *poic=0;
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
|
||||
|
||||
/* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */
|
||||
/* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */
|
||||
if (pmkToLeft==NULL)
|
||||
if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK))
|
||||
return S_OK;
|
||||
else {
|
||||
if (pbc==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
|
||||
|
||||
if (FAILED(res))
|
||||
return res;
|
||||
|
||||
res = IRunningObjectTable_IsRunning(rot,iface);
|
||||
|
||||
IRunningObjectTable_Release(rot);
|
||||
}
|
||||
else{
|
||||
|
||||
/* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */
|
||||
/* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/
|
||||
/* passing the string contained within this moniker. */
|
||||
|
||||
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
|
||||
|
||||
if (SUCCEEDED(res)){
|
||||
|
||||
res=IOleItemContainer_IsRunning(poic,This->itemName);
|
||||
|
||||
IOleItemContainer_Release(poic);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_GetTimeOfLastChange
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
FILETIME* pItemTime)
|
||||
{
|
||||
IRunningObjectTable* rot;
|
||||
HRESULT res;
|
||||
IMoniker *compositeMk;
|
||||
|
||||
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime);
|
||||
|
||||
if (pItemTime==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */
|
||||
if (pmkToLeft==NULL)
|
||||
|
||||
return MK_E_NOTBINDABLE;
|
||||
else {
|
||||
|
||||
/* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */
|
||||
/* the time of last change. If the object is not in the ROT, the method calls */
|
||||
/* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */
|
||||
|
||||
res=CreateGenericComposite(pmkToLeft,iface,&compositeMk);
|
||||
|
||||
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
|
||||
|
||||
if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK)
|
||||
|
||||
res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime);
|
||||
|
||||
IMoniker_Release(compositeMk);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_Inverse
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
|
||||
{
|
||||
TRACE("(%p,%p)\n",iface,ppmk);
|
||||
|
||||
if (ppmk==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
return CreateAntiMoniker(ppmk);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_CommonPrefixWith
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
|
||||
{
|
||||
DWORD mkSys;
|
||||
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
|
||||
/* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
|
||||
/* to this moniker and returns MK_S_US */
|
||||
|
||||
if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){
|
||||
|
||||
*ppmkPrefix=iface;
|
||||
|
||||
IMoniker_AddRef(iface);
|
||||
|
||||
return MK_S_US;
|
||||
}
|
||||
else
|
||||
/* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
|
||||
/* the case where the other moniker is a generic composite. */
|
||||
return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_RelativePathTo
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
|
||||
{
|
||||
TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
|
||||
|
||||
if (ppmkRelPath==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppmkRelPath=0;
|
||||
|
||||
return MK_E_NOTBINDABLE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_GetDisplayName
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR *ppszDisplayName)
|
||||
{
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
|
||||
|
||||
if (ppszDisplayName==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
if (pmkToLeft!=NULL){
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
*ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1));
|
||||
|
||||
if (*ppszDisplayName==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
lstrcpyW(*ppszDisplayName,This->itemDelimiter);
|
||||
lstrcatW(*ppszDisplayName,This->itemName);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_ParseDisplayName
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR pszDisplayName,
|
||||
ULONG* pchEaten,
|
||||
IMoniker** ppmkOut)
|
||||
{
|
||||
IOleItemContainer* poic=0;
|
||||
IParseDisplayName* ppdn=0;
|
||||
LPOLESTR displayName;
|
||||
HRESULT res;
|
||||
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
|
||||
|
||||
/* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
|
||||
if (pmkToLeft==NULL)
|
||||
|
||||
return MK_E_SYNTAX;
|
||||
|
||||
else{
|
||||
/* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */
|
||||
/* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */
|
||||
/* name to IParseDisplayName::ParseDisplayName */
|
||||
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic);
|
||||
|
||||
if (SUCCEEDED(res)){
|
||||
|
||||
res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn);
|
||||
|
||||
res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName);
|
||||
|
||||
res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut);
|
||||
|
||||
IOleItemContainer_Release(poic);
|
||||
IParseDisplayName_Release(ppdn);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMoniker_IsSystemMoniker
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
||||
{
|
||||
TRACE("(%p,%p)\n",iface,pwdMksys);
|
||||
|
||||
if (!pwdMksys)
|
||||
return E_POINTER;
|
||||
|
||||
(*pwdMksys)=MKSYS_ITEMMONIKER;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* ItemMonikerIROTData_QueryInterface
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
|
||||
{
|
||||
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
|
||||
|
||||
return ItemMonikerImpl_QueryInterface(This, riid, ppvObject);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ItemMonikerIROTData_AddRef
|
||||
*/
|
||||
ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
|
||||
{
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
TRACE("(%p)\n",iface);
|
||||
|
||||
return ItemMonikerImpl_AddRef(This);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ItemMonikerIROTData_Release
|
||||
*/
|
||||
ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
|
||||
{
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
TRACE("(%p)\n",iface);
|
||||
|
||||
return ItemMonikerImpl_Release(This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ItemMonikerIROTData_GetComparaisonData
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
|
||||
BYTE* pbData,
|
||||
ULONG cbMax,
|
||||
ULONG* pcbData)
|
||||
{
|
||||
FIXME("(),stub!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateItemMoniker [OLE32.@]
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk)
|
||||
{
|
||||
ItemMonikerImpl* newItemMoniker = 0;
|
||||
HRESULT hr = S_OK;
|
||||
IID riid=IID_IMoniker;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
|
||||
|
||||
newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
|
||||
|
||||
if (newItemMoniker == 0)
|
||||
return STG_E_INSUFFICIENTMEMORY;
|
||||
|
||||
hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
|
||||
|
||||
if (FAILED(hr)){
|
||||
|
||||
HeapFree(GetProcessHeap(),0,newItemMoniker);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
# $Id: makefile,v 1.9 2004/01/02 19:49:45 gvg Exp $
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
TARGET_TYPE = winedll
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
@@ -1,809 +0,0 @@
|
||||
/*
|
||||
* Marshalling library
|
||||
*
|
||||
* Copyright 2002 Marcus Meissner
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "ole2ver.h"
|
||||
#include "rpc.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "wownt32.h"
|
||||
#include "wtypes.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "compobj_private.h"
|
||||
#include "ifs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
extern const CLSID CLSID_DfMarshal;
|
||||
|
||||
/* Marshalling just passes a unique identifier to the remote client,
|
||||
* that makes it possible to find the passed interface again.
|
||||
*
|
||||
* So basically we need a set of values that make it unique.
|
||||
*
|
||||
* Process Identifier, Object IUnknown ptr, IID
|
||||
*
|
||||
* Note that the IUnknown_QI(ob,xiid,&ppv) always returns the SAME ppv value!
|
||||
*/
|
||||
|
||||
inline static HRESULT
|
||||
get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
|
||||
HRESULT hres;
|
||||
CLSID pxclsid;
|
||||
|
||||
if ((hres = CoGetPSClsid(riid,&pxclsid)))
|
||||
return hres;
|
||||
return CoGetClassObject(&pxclsid,CLSCTX_INPROC_SERVER,NULL,&IID_IPSFactoryBuffer,(LPVOID*)facbuf);
|
||||
}
|
||||
|
||||
typedef struct _wine_marshal_data {
|
||||
DWORD dwDestContext;
|
||||
DWORD mshlflags;
|
||||
} wine_marshal_data;
|
||||
|
||||
typedef struct _mid2unknown {
|
||||
wine_marshal_id mid;
|
||||
LPUNKNOWN pUnk;
|
||||
} mid2unknown;
|
||||
|
||||
typedef struct _mid2stub {
|
||||
wine_marshal_id mid;
|
||||
IRpcStubBuffer *stub;
|
||||
LPUNKNOWN pUnkServer;
|
||||
BOOL valid;
|
||||
} mid2stub;
|
||||
|
||||
static mid2stub *stubs = NULL;
|
||||
static int nrofstubs = 0;
|
||||
|
||||
static mid2unknown *proxies = NULL;
|
||||
static int nrofproxies = 0;
|
||||
|
||||
void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid) {
|
||||
int i;
|
||||
|
||||
for (i=0;i<nrofstubs;i++) {
|
||||
if (!stubs[i].valid) continue;
|
||||
|
||||
if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
|
||||
stubs[i].valid = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MARSHAL_Find_Stub_Buffer(wine_marshal_id *mid,IRpcStubBuffer **stub) {
|
||||
int i;
|
||||
|
||||
for (i=0;i<nrofstubs;i++) {
|
||||
if (!stubs[i].valid) continue;
|
||||
|
||||
if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
|
||||
*stub = stubs[i].stub;
|
||||
IUnknown_AddRef((*stub));
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
MARSHAL_Find_Stub(wine_marshal_id *mid,LPUNKNOWN *pUnk) {
|
||||
int i;
|
||||
|
||||
for (i=0;i<nrofstubs;i++) {
|
||||
if (!stubs[i].valid) continue;
|
||||
|
||||
if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
|
||||
*pUnk = stubs[i].pUnkServer;
|
||||
IUnknown_AddRef((*pUnk));
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
MARSHAL_Register_Stub(wine_marshal_id *mid,LPUNKNOWN pUnk,IRpcStubBuffer *stub) {
|
||||
LPUNKNOWN xPunk;
|
||||
if (!MARSHAL_Find_Stub(mid,&xPunk)) {
|
||||
FIXME("Already have entry for (%lx/%s)!\n",mid->objectid,debugstr_guid(&(mid->iid)));
|
||||
return S_OK;
|
||||
}
|
||||
if (nrofstubs)
|
||||
stubs=HeapReAlloc(GetProcessHeap(),0,stubs,sizeof(stubs[0])*(nrofstubs+1));
|
||||
else
|
||||
stubs=HeapAlloc(GetProcessHeap(),0,sizeof(stubs[0]));
|
||||
if (!stubs) return E_OUTOFMEMORY;
|
||||
stubs[nrofstubs].stub = stub;
|
||||
stubs[nrofstubs].pUnkServer = pUnk;
|
||||
memcpy(&(stubs[nrofstubs].mid),mid,sizeof(*mid));
|
||||
stubs[nrofstubs].valid = TRUE; /* set to false when released by ReleaseMarshalData */
|
||||
nrofstubs++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MARSHAL_Disconnect_Proxies() {
|
||||
int i;
|
||||
|
||||
TRACE("Disconnecting %d proxies\n", nrofproxies);
|
||||
|
||||
for (i = 0; i < nrofproxies; i++)
|
||||
IRpcProxyBuffer_Disconnect((IRpcProxyBuffer*)proxies[i].pUnk);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
MARSHAL_Register_Proxy(wine_marshal_id *mid,LPUNKNOWN punk) {
|
||||
int i;
|
||||
|
||||
for (i=0;i<nrofproxies;i++) {
|
||||
if (MARSHAL_Compare_Mids(mid,&(proxies[i].mid))) {
|
||||
ERR("Already have mid?\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
if (nrofproxies)
|
||||
proxies = HeapReAlloc(GetProcessHeap(),0,proxies,sizeof(proxies[0])*(nrofproxies+1));
|
||||
else
|
||||
proxies = HeapAlloc(GetProcessHeap(),0,sizeof(proxies[0]));
|
||||
memcpy(&(proxies[nrofproxies].mid),mid,sizeof(*mid));
|
||||
proxies[nrofproxies].pUnk = punk;
|
||||
nrofproxies++;
|
||||
IUnknown_AddRef(punk);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/********************** StdMarshal implementation ****************************/
|
||||
typedef struct _StdMarshalImpl {
|
||||
IMarshalVtbl *lpvtbl;
|
||||
DWORD ref;
|
||||
|
||||
IID iid;
|
||||
DWORD dwDestContext;
|
||||
LPVOID pvDestContext;
|
||||
DWORD mshlflags;
|
||||
} StdMarshalImpl;
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_QueryInterface(LPMARSHAL iface,REFIID riid,LPVOID *ppv) {
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(&IID_IUnknown,riid) || IsEqualIID(&IID_IMarshal,riid)) {
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("No interface for %s.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
StdMarshalImpl_AddRef(LPMARSHAL iface) {
|
||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
StdMarshalImpl_Release(LPMARSHAL iface) {
|
||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (!ref) HeapFree(GetProcessHeap(),0,This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_GetUnmarshalClass(
|
||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags, CLSID* pCid
|
||||
) {
|
||||
memcpy(pCid,&CLSID_DfMarshal,sizeof(CLSID_DfMarshal));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_GetMarshalSizeMax(
|
||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags, DWORD* pSize
|
||||
) {
|
||||
*pSize = sizeof(wine_marshal_id)+sizeof(wine_marshal_data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_MarshalInterface(
|
||||
LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags
|
||||
) {
|
||||
wine_marshal_id mid;
|
||||
wine_marshal_data md;
|
||||
IUnknown *pUnk;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
IRpcStubBuffer *stub;
|
||||
IPSFactoryBuffer *psfacbuf;
|
||||
|
||||
TRACE("(...,%s,...)\n",debugstr_guid(riid));
|
||||
|
||||
IUnknown_QueryInterface((LPUNKNOWN)pv,&IID_IUnknown,(LPVOID*)&pUnk);
|
||||
mid.processid = GetCurrentProcessId();
|
||||
mid.objectid = (DWORD)pUnk; /* FIXME */
|
||||
IUnknown_Release(pUnk);
|
||||
memcpy(&mid.iid,riid,sizeof(mid.iid));
|
||||
md.dwDestContext = dwDestContext;
|
||||
md.mshlflags = mshlflags;
|
||||
hres = IStream_Write(pStm,&mid,sizeof(mid),&res);
|
||||
if (hres) return hres;
|
||||
hres = IStream_Write(pStm,&md,sizeof(md),&res);
|
||||
if (hres) return hres;
|
||||
|
||||
if (SUCCEEDED(MARSHAL_Find_Stub_Buffer(&mid,&stub))) {
|
||||
/* Find_Stub_Buffer gives us a ref but we want to keep it, as if we'd created a new one */
|
||||
TRACE("Found RpcStubBuffer %p\n", stub);
|
||||
return S_OK;
|
||||
}
|
||||
hres = get_facbuf_for_iid(riid,&psfacbuf);
|
||||
if (hres) return hres;
|
||||
|
||||
hres = IPSFactoryBuffer_CreateStub(psfacbuf,riid,pv,&stub);
|
||||
IPSFactoryBuffer_Release(psfacbuf);
|
||||
if (hres) {
|
||||
FIXME("Failed to create a stub for %s\n",debugstr_guid(riid));
|
||||
return hres;
|
||||
}
|
||||
IUnknown_QueryInterface((LPUNKNOWN)pv,riid,(LPVOID*)&pUnk);
|
||||
MARSHAL_Register_Stub(&mid,pUnk,stub);
|
||||
IUnknown_Release(pUnk);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_UnmarshalInterface(
|
||||
LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv
|
||||
) {
|
||||
wine_marshal_id mid;
|
||||
wine_marshal_data md;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
IPSFactoryBuffer *psfacbuf;
|
||||
IRpcProxyBuffer *rpcproxy;
|
||||
IRpcChannelBuffer *chanbuf;
|
||||
|
||||
TRACE("(...,%s,....)\n",debugstr_guid(riid));
|
||||
hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
|
||||
if (hres) return hres;
|
||||
hres = IStream_Read(pStm,&md,sizeof(md),&res);
|
||||
if (hres) return hres;
|
||||
if (SUCCEEDED(MARSHAL_Find_Stub(&mid,(LPUNKNOWN*)ppv))) {
|
||||
FIXME("Calling back to ourselves for %s!\n",debugstr_guid(riid));
|
||||
return S_OK;
|
||||
}
|
||||
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_NULL)) {
|
||||
/* should return proxy manager IUnknown object */
|
||||
FIXME("Special treatment required for IID of %s\n", debugstr_guid(riid));
|
||||
}
|
||||
hres = get_facbuf_for_iid(riid,&psfacbuf);
|
||||
if (hres) return hres;
|
||||
hres = IPSFactoryBuffer_CreateProxy(psfacbuf,NULL,riid,&rpcproxy,ppv);
|
||||
if (hres) {
|
||||
FIXME("Failed to create a proxy for %s\n",debugstr_guid(riid));
|
||||
return hres;
|
||||
}
|
||||
|
||||
MARSHAL_Register_Proxy(&mid, (LPUNKNOWN) rpcproxy);
|
||||
|
||||
hres = PIPE_GetNewPipeBuf(&mid,&chanbuf);
|
||||
IPSFactoryBuffer_Release(psfacbuf);
|
||||
if (hres) {
|
||||
ERR("Failed to get an rpc channel buffer for %s\n",debugstr_guid(riid));
|
||||
} else {
|
||||
/* Connect the channel buffer to the proxy and release the no longer
|
||||
* needed proxy.
|
||||
* NOTE: The proxy should have taken an extra reference because it also
|
||||
* aggregates the object, so we can safely release our reference to it. */
|
||||
IRpcProxyBuffer_Connect(rpcproxy,chanbuf);
|
||||
IRpcProxyBuffer_Release(rpcproxy);
|
||||
/* IRpcProxyBuffer takes a reference on the channel buffer and
|
||||
* we no longer need it, so release it */
|
||||
IRpcChannelBuffer_Release(chanbuf);
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
|
||||
wine_marshal_id mid;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
IRpcStubBuffer *stub = NULL;
|
||||
int i;
|
||||
|
||||
hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
|
||||
if (hres) return hres;
|
||||
|
||||
for (i=0; i < nrofstubs; i++)
|
||||
{
|
||||
if (!stubs[i].valid) continue;
|
||||
|
||||
if (MARSHAL_Compare_Mids(&mid, &(stubs[i].mid)))
|
||||
{
|
||||
stub = stubs[i].stub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stub)
|
||||
{
|
||||
FIXME("Could not map MID to stub??\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
res = IRpcStubBuffer_Release(stub);
|
||||
stubs[i].valid = FALSE;
|
||||
TRACE("stub refcount of %p is %ld\n", stub, res);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) {
|
||||
FIXME("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IMarshalVtbl stdmvtbl = {
|
||||
StdMarshalImpl_QueryInterface,
|
||||
StdMarshalImpl_AddRef,
|
||||
StdMarshalImpl_Release,
|
||||
StdMarshalImpl_GetUnmarshalClass,
|
||||
StdMarshalImpl_GetMarshalSizeMax,
|
||||
StdMarshalImpl_MarshalInterface,
|
||||
StdMarshalImpl_UnmarshalInterface,
|
||||
StdMarshalImpl_ReleaseMarshalData,
|
||||
StdMarshalImpl_DisconnectObject
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* CoGetStandardMarshal [OLE32.@]
|
||||
*
|
||||
* When the COM library in the client process receives a marshalled
|
||||
* interface pointer, it looks for a CLSID to be used in creating a proxy
|
||||
* for the purposes of unmarshalling the packet. If the packet does not
|
||||
* contain a CLSID for the proxy, COM calls CoGetStandardMarshal, passing a
|
||||
* NULL pUnk value.
|
||||
* This function creates a standard proxy in the client process and returns
|
||||
* a pointer to that proxy's implementation of IMarshal.
|
||||
* COM uses this pointer to call CoUnmarshalInterface to retrieve the pointer
|
||||
* to the requested interface.
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoGetStandardMarshal(
|
||||
REFIID riid,IUnknown *pUnk,DWORD dwDestContext,LPVOID pvDestContext,
|
||||
DWORD mshlflags, LPMARSHAL *pMarshal
|
||||
) {
|
||||
StdMarshalImpl *dm;
|
||||
|
||||
if (pUnk == NULL) {
|
||||
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
|
||||
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,pMarshal
|
||||
);
|
||||
return E_FAIL;
|
||||
}
|
||||
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
|
||||
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,pMarshal
|
||||
);
|
||||
*pMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
|
||||
dm = (StdMarshalImpl*) *pMarshal;
|
||||
if (!dm) return E_FAIL;
|
||||
dm->lpvtbl = &stdmvtbl;
|
||||
dm->ref = 1;
|
||||
|
||||
memcpy(&dm->iid,riid,sizeof(dm->iid));
|
||||
dm->dwDestContext = dwDestContext;
|
||||
dm->pvDestContext = pvDestContext;
|
||||
dm->mshlflags = mshlflags;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Helper function for getting Marshaler */
|
||||
static HRESULT WINAPI
|
||||
_GetMarshaller(REFIID riid, IUnknown *pUnk,DWORD dwDestContext,
|
||||
void *pvDestContext, DWORD mshlFlags, LPMARSHAL *pMarshal
|
||||
) {
|
||||
HRESULT hres;
|
||||
|
||||
if (!pUnk)
|
||||
return E_POINTER;
|
||||
hres = IUnknown_QueryInterface(pUnk,&IID_IMarshal,(LPVOID*)pMarshal);
|
||||
if (hres)
|
||||
hres = CoGetStandardMarshal(riid,pUnk,dwDestContext,pvDestContext,mshlFlags,pMarshal);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoGetMarshalSizeMax [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
|
||||
DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags
|
||||
) {
|
||||
HRESULT hres;
|
||||
LPMARSHAL pMarshal;
|
||||
|
||||
hres = _GetMarshaller(riid,pUnk,dwDestContext,pvDestContext,mshlFlags,&pMarshal);
|
||||
if (hres)
|
||||
return hres;
|
||||
hres = IMarshal_GetMarshalSizeMax(pMarshal,riid,pUnk,dwDestContext,pvDestContext,mshlFlags,pulSize);
|
||||
*pulSize += sizeof(wine_marshal_id)+sizeof(wine_marshal_data)+sizeof(CLSID);
|
||||
IMarshal_Release(pMarshal);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CoMarshalInterface [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoMarshalInterface( IStream *pStm, REFIID riid, IUnknown *pUnk,
|
||||
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags
|
||||
) {
|
||||
HRESULT hres;
|
||||
LPMARSHAL pMarshal;
|
||||
CLSID xclsid;
|
||||
ULONG writeres;
|
||||
wine_marshal_id mid;
|
||||
wine_marshal_data md;
|
||||
ULONG res;
|
||||
IUnknown *pUnknown;
|
||||
|
||||
TRACE("(%p, %s, %p, %lx, %p, %lx)\n",
|
||||
pStm,debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags
|
||||
);
|
||||
|
||||
if (pUnk == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
STUBMGR_Start(); /* Just to be sure we have one running. */
|
||||
mid.processid = GetCurrentProcessId();
|
||||
IUnknown_QueryInterface(pUnk,&IID_IUnknown,(LPVOID*)&pUnknown);
|
||||
mid.objectid = (DWORD)pUnknown;
|
||||
IUnknown_Release(pUnknown);
|
||||
memcpy(&mid.iid,riid,sizeof(mid.iid));
|
||||
md.dwDestContext = dwDestContext;
|
||||
md.mshlflags = mshlflags;
|
||||
hres = IStream_Write(pStm,&mid,sizeof(mid),&res);
|
||||
if (hres) return hres;
|
||||
hres = IStream_Write(pStm,&md,sizeof(md),&res);
|
||||
if (hres) return hres;
|
||||
hres = _GetMarshaller(riid,pUnk,dwDestContext,pvDestContext,mshlflags,&pMarshal);
|
||||
if (hres) {
|
||||
FIXME("Failed to get marshaller, %lx?\n",hres);
|
||||
return hres;
|
||||
}
|
||||
hres = IMarshal_GetUnmarshalClass(pMarshal,riid,pUnk,dwDestContext,pvDestContext,mshlflags,&xclsid);
|
||||
if (hres) {
|
||||
FIXME("IMarshal:GetUnmarshalClass failed, %lx\n",hres);
|
||||
goto release_marshal;
|
||||
}
|
||||
hres = IStream_Write(pStm,&xclsid,sizeof(xclsid),&writeres);
|
||||
if (hres) {
|
||||
FIXME("Stream write failed, %lx\n",hres);
|
||||
goto release_marshal;
|
||||
}
|
||||
|
||||
TRACE("Calling IMarshal::MarshalInterace\n");
|
||||
hres = IMarshal_MarshalInterface(pMarshal,pStm,riid,pUnk,dwDestContext,pvDestContext,mshlflags);
|
||||
|
||||
if (hres) {
|
||||
if (IsEqualGUID(riid,&IID_IOleObject)) {
|
||||
ERR("WINE currently cannot marshal IOleObject interfaces. This means you cannot embed/link OLE objects between applications.\n");
|
||||
} else {
|
||||
FIXME("Failed to marshal the interface %s, %lx?\n",debugstr_guid(riid),hres);
|
||||
}
|
||||
}
|
||||
release_marshal:
|
||||
IMarshal_Release(pMarshal);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CoUnmarshalInterface [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoUnmarshalInterface(IStream *pStm, REFIID riid, LPVOID *ppv) {
|
||||
HRESULT hres;
|
||||
wine_marshal_id mid;
|
||||
wine_marshal_data md;
|
||||
ULONG res;
|
||||
LPMARSHAL pMarshal;
|
||||
LPUNKNOWN pUnk;
|
||||
CLSID xclsid;
|
||||
|
||||
TRACE("(%p,%s,%p)\n",pStm,debugstr_guid(riid),ppv);
|
||||
|
||||
hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
|
||||
if (hres) {
|
||||
FIXME("Stream read 1 failed, %lx, (%ld of %d)\n",hres,res,sizeof(mid));
|
||||
return hres;
|
||||
}
|
||||
hres = IStream_Read(pStm,&md,sizeof(md),&res);
|
||||
if (hres) {
|
||||
FIXME("Stream read 2 failed, %lx, (%ld of %d)\n",hres,res,sizeof(md));
|
||||
return hres;
|
||||
}
|
||||
hres = IStream_Read(pStm,&xclsid,sizeof(xclsid),&res);
|
||||
if (hres) {
|
||||
FIXME("Stream read 3 failed, %lx, (%ld of %d)\n",hres,res,sizeof(xclsid));
|
||||
return hres;
|
||||
}
|
||||
hres=CoCreateInstance(&xclsid,NULL,CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER,&IID_IMarshal,(void**)&pUnk);
|
||||
if (hres) {
|
||||
FIXME("Failed to create instance of unmarshaller %s.\n",debugstr_guid(&xclsid));
|
||||
return hres;
|
||||
}
|
||||
hres = _GetMarshaller(riid,pUnk,md.dwDestContext,NULL,md.mshlflags,&pMarshal);
|
||||
if (hres) {
|
||||
FIXME("Failed to get unmarshaller, %lx?\n",hres);
|
||||
return hres;
|
||||
}
|
||||
hres = IMarshal_UnmarshalInterface(pMarshal,pStm,riid,ppv);
|
||||
if (hres) {
|
||||
FIXME("Failed to Unmarshal the interface, %lx?\n",hres);
|
||||
goto release_marshal;
|
||||
}
|
||||
release_marshal:
|
||||
IMarshal_Release(pMarshal);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoReleaseMarshalData [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoReleaseMarshalData(IStream *pStm) {
|
||||
HRESULT hres;
|
||||
wine_marshal_id mid;
|
||||
wine_marshal_data md;
|
||||
ULONG res;
|
||||
LPMARSHAL pMarshal;
|
||||
LPUNKNOWN pUnk;
|
||||
CLSID xclsid;
|
||||
|
||||
TRACE("(%p)\n",pStm);
|
||||
|
||||
hres = IStream_Read(pStm,&mid,sizeof(mid),&res);
|
||||
if (hres) {
|
||||
FIXME("Stream read 1 failed, %lx, (%ld of %d)\n",hres,res,sizeof(mid));
|
||||
return hres;
|
||||
}
|
||||
hres = IStream_Read(pStm,&md,sizeof(md),&res);
|
||||
if (hres) {
|
||||
FIXME("Stream read 2 failed, %lx, (%ld of %d)\n",hres,res,sizeof(md));
|
||||
return hres;
|
||||
}
|
||||
hres = IStream_Read(pStm,&xclsid,sizeof(xclsid),&res);
|
||||
if (hres) {
|
||||
FIXME("Stream read 3 failed, %lx, (%ld of %d)\n",hres,res,sizeof(xclsid));
|
||||
return hres;
|
||||
}
|
||||
hres=CoCreateInstance(&xclsid,NULL,CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER,&IID_IMarshal,(void**)(char*)&pUnk);
|
||||
if (hres) {
|
||||
FIXME("Failed to create instance of unmarshaller %s.\n",debugstr_guid(&xclsid));
|
||||
return hres;
|
||||
}
|
||||
hres = IUnknown_QueryInterface(pUnk,&IID_IMarshal,(LPVOID*)(char*)&pMarshal);
|
||||
if (hres) {
|
||||
FIXME("Failed to get IMarshal iface, %lx?\n",hres);
|
||||
return hres;
|
||||
}
|
||||
hres = IMarshal_ReleaseMarshalData(pMarshal,pStm);
|
||||
if (hres) {
|
||||
FIXME("Failed to releasemarshaldata the interface, %lx?\n",hres);
|
||||
}
|
||||
IMarshal_Release(pMarshal);
|
||||
IUnknown_Release(pUnk);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CoMarshalInterThreadInterfaceInStream [OLE32.@]
|
||||
*
|
||||
* Marshal an interface across threads in the same process.
|
||||
*
|
||||
* PARAMS
|
||||
* riid [I] Identifier of the interface to be marshalled.
|
||||
* pUnk [I] Pointer to IUnknown-derived interface that will be marshalled.
|
||||
* ppStm [O] Pointer to IStream object that is created and then used to store the marshalled inteface.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: E_OUTOFMEMORY and other COM error codes
|
||||
*
|
||||
* SEE
|
||||
* CoMarshalInterface(), CoUnmarshalInterface() and CoGetInterfaceAndReleaseStream()
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoMarshalInterThreadInterfaceInStream(
|
||||
REFIID riid, LPUNKNOWN pUnk, LPSTREAM * ppStm)
|
||||
{
|
||||
ULARGE_INTEGER xpos;
|
||||
LARGE_INTEGER seekto;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s, %p, %p)\n",debugstr_guid(riid), pUnk, ppStm);
|
||||
|
||||
hres = CreateStreamOnHGlobal(0, TRUE, ppStm);
|
||||
if (FAILED(hres)) return hres;
|
||||
hres = CoMarshalInterface(*ppStm, riid, pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
|
||||
|
||||
/* FIXME: is this needed? */
|
||||
memset(&seekto,0,sizeof(seekto));
|
||||
IStream_Seek(*ppStm,seekto,SEEK_SET,&xpos);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoGetInterfaceAndReleaseStream [OLE32.@]
|
||||
*
|
||||
* Unmarshalls an inteface from a stream and then releases the stream.
|
||||
*
|
||||
* PARAMS
|
||||
* pStm [I] Stream that contains the marshalled inteface.
|
||||
* riid [I] Interface identifier of the object to unmarshall.
|
||||
* ppv [O] Address of pointer where the requested interface object will be stored.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: A COM error code
|
||||
*
|
||||
* SEE
|
||||
* CoMarshalInterThreadInterfaceInStream() and CoUnmarshalInteface()
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoGetInterfaceAndReleaseStream(LPSTREAM pStm,REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
|
||||
|
||||
hres = CoUnmarshalInterface(pStm, riid, ppv);
|
||||
IStream_Release(pStm);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
SMCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) {
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IClassFactory)) {
|
||||
*ppv = (LPVOID)iface;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
static ULONG WINAPI SMCF_AddRef(LPCLASSFACTORY iface) { return 2; }
|
||||
static ULONG WINAPI SMCF_Release(LPCLASSFACTORY iface) { return 1; }
|
||||
|
||||
static HRESULT WINAPI
|
||||
SMCF_CreateInstance(
|
||||
LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv
|
||||
) {
|
||||
if (IsEqualIID(riid,&IID_IMarshal)) {
|
||||
StdMarshalImpl *dm;
|
||||
dm=(StdMarshalImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
|
||||
if (!dm)
|
||||
return E_FAIL;
|
||||
dm->lpvtbl = &stdmvtbl;
|
||||
dm->ref = 1;
|
||||
*ppv = (LPVOID)dm;
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("(%s), not supported.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
SMCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) {
|
||||
FIXME("(%d), stub!\n",fLock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IClassFactoryVtbl dfmarshalcfvtbl = {
|
||||
SMCF_QueryInterface,
|
||||
SMCF_AddRef,
|
||||
SMCF_Release,
|
||||
SMCF_CreateInstance,
|
||||
SMCF_LockServer
|
||||
};
|
||||
static IClassFactoryVtbl *pdfmarshalcfvtbl = &dfmarshalcfvtbl;
|
||||
|
||||
HRESULT
|
||||
MARSHAL_GetStandardMarshalCF(LPVOID *ppv) {
|
||||
*ppv = &pdfmarshalcfvtbl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoMarshalHresult [OLE32.@]
|
||||
*
|
||||
* Marshals an HRESULT value into a stream.
|
||||
*
|
||||
* PARAMS
|
||||
* pStm [I] Stream that hresult will be marshaled into.
|
||||
* hresult [I] HRESULT to be marshaled.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: A COM error code
|
||||
*
|
||||
* SEE
|
||||
* CoUnmarshalHresult().
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoMarshalHresult(LPSTREAM pStm, HRESULT hresult)
|
||||
{
|
||||
return IStream_Write(pStm, &hresult, sizeof(hresult), NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoUnmarshalHresult [OLE32.@]
|
||||
*
|
||||
* Unmarshals an HRESULT value from a stream.
|
||||
*
|
||||
* PARAMS
|
||||
* pStm [I] Stream that hresult will be unmarshaled from.
|
||||
* phresult [I] Pointer to HRESULT where the value will be unmarshaled to.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: A COM error code
|
||||
*
|
||||
* SEE
|
||||
* CoMarshalHresult().
|
||||
*/
|
||||
HRESULT WINAPI
|
||||
CoUnmarshalHresult(LPSTREAM pStm, HRESULT * phresult)
|
||||
{
|
||||
return IStream_Read(pStm, phresult, sizeof(*phresult), NULL);
|
||||
}
|
||||
@@ -1,622 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Global memory implementation of ILockBytes.
|
||||
*
|
||||
* Copyright 1999 Thuy Nguyen
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "ifs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/******************************************************************************
|
||||
* HGLOBALLockBytesImpl definition.
|
||||
*
|
||||
* This class imlements the ILockBytes inteface and represents a byte array
|
||||
* object supported by an HGLOBAL pointer.
|
||||
*/
|
||||
struct HGLOBALLockBytesImpl
|
||||
{
|
||||
/*
|
||||
* Needs to be the first item in the stuct
|
||||
* since we want to cast this in an ILockBytes pointer
|
||||
*/
|
||||
ILockBytesVtbl *lpVtbl;
|
||||
|
||||
/*
|
||||
* Reference count
|
||||
*/
|
||||
ULONG ref;
|
||||
|
||||
/*
|
||||
* Support for the LockBytes object
|
||||
*/
|
||||
HGLOBAL supportHandle;
|
||||
|
||||
/*
|
||||
* This flag is TRUE if the HGLOBAL is destroyed when the object
|
||||
* is finally released.
|
||||
*/
|
||||
BOOL deleteOnRelease;
|
||||
|
||||
/*
|
||||
* Helper variable that contains the size of the byte array
|
||||
*/
|
||||
ULARGE_INTEGER byteArraySize;
|
||||
};
|
||||
|
||||
typedef struct HGLOBALLockBytesImpl HGLOBALLockBytesImpl;
|
||||
|
||||
/*
|
||||
* Method definition for the HGLOBALLockBytesImpl class.
|
||||
*/
|
||||
HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease);
|
||||
|
||||
void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This);
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
|
||||
ILockBytes* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject); /* [iid_is][out] */
|
||||
|
||||
ULONG WINAPI HGLOBALLockBytesImpl_AddRef(
|
||||
ILockBytes* iface);
|
||||
|
||||
ULONG WINAPI HGLOBALLockBytesImpl_Release(
|
||||
ILockBytes* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_Flush(
|
||||
ILockBytes* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER libNewSize); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
|
||||
ILockBytes* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag); /* [in] */
|
||||
|
||||
/*
|
||||
* Virtual function table for the HGLOBALLockBytesImpl class.
|
||||
*/
|
||||
static ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl =
|
||||
{
|
||||
HGLOBALLockBytesImpl_QueryInterface,
|
||||
HGLOBALLockBytesImpl_AddRef,
|
||||
HGLOBALLockBytesImpl_Release,
|
||||
HGLOBALLockBytesImpl_ReadAt,
|
||||
HGLOBALLockBytesImpl_WriteAt,
|
||||
HGLOBALLockBytesImpl_Flush,
|
||||
HGLOBALLockBytesImpl_SetSize,
|
||||
HGLOBALLockBytesImpl_LockRegion,
|
||||
HGLOBALLockBytesImpl_UnlockRegion,
|
||||
HGLOBALLockBytesImpl_Stat,
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* CreateILockBytesOnHGlobal [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease,
|
||||
LPLOCKBYTES* ppLkbyt)
|
||||
{
|
||||
HGLOBALLockBytesImpl* newLockBytes;
|
||||
|
||||
newLockBytes = HGLOBALLockBytesImpl_Construct(hGlobal, fDeleteOnRelease);
|
||||
|
||||
if (newLockBytes != NULL)
|
||||
{
|
||||
return IUnknown_QueryInterface((IUnknown*)newLockBytes,
|
||||
&IID_ILockBytes,
|
||||
(void**)ppLkbyt);
|
||||
}
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetHGlobalFromILockBytes [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
|
||||
{
|
||||
HGLOBALLockBytesImpl* const pMemLockBytes = (HGLOBALLockBytesImpl*)plkbyt;
|
||||
STATSTG stbuf;
|
||||
HRESULT hres;
|
||||
ULARGE_INTEGER start;
|
||||
ULONG xread;
|
||||
|
||||
*phglobal = 0;
|
||||
if (pMemLockBytes->lpVtbl == &HGLOBALLockBytesImpl_Vtbl) {
|
||||
*phglobal = pMemLockBytes->supportHandle;
|
||||
if (*phglobal == 0)
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
/* It is not our lockbytes implementation, so use a more generic way */
|
||||
hres = ILockBytes_Stat(plkbyt,&stbuf,0);
|
||||
if (hres != S_OK) {
|
||||
ERR("Cannot ILockBytes_Stat, %lx\n",hres);
|
||||
return hres;
|
||||
}
|
||||
FIXME("cbSize is %ld\n",stbuf.cbSize.u.LowPart);
|
||||
*phglobal = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, stbuf.cbSize.u.LowPart);
|
||||
if (!*phglobal)
|
||||
return E_INVALIDARG;
|
||||
memset(&start,0,sizeof(start));
|
||||
hres = ILockBytes_ReadAt(plkbyt, start, GlobalLock(*phglobal), stbuf.cbSize.u.LowPart, &xread);
|
||||
GlobalUnlock(*phglobal);
|
||||
if (hres != S_OK) {
|
||||
FIXME("%p->ReadAt failed with %lx\n",plkbyt,hres);
|
||||
return hres;
|
||||
}
|
||||
if (stbuf.cbSize.u.LowPart != xread) {
|
||||
FIXME("Read size is not requested size %ld vs %ld?\n",stbuf.cbSize.u.LowPart, xread);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* HGLOBALLockBytesImpl implementation
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* This is the constructor for the HGLOBALLockBytesImpl class.
|
||||
*
|
||||
* Params:
|
||||
* hGlobal - Handle that will support the stream. can be NULL.
|
||||
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
|
||||
* when the IStream object is destroyed.
|
||||
*/
|
||||
HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease)
|
||||
{
|
||||
HGLOBALLockBytesImpl* newLockBytes;
|
||||
newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl));
|
||||
|
||||
if (newLockBytes!=0)
|
||||
{
|
||||
/*
|
||||
* Set up the virtual function table and reference count.
|
||||
*/
|
||||
newLockBytes->lpVtbl = &HGLOBALLockBytesImpl_Vtbl;
|
||||
newLockBytes->ref = 0;
|
||||
|
||||
/*
|
||||
* Initialize the support.
|
||||
*/
|
||||
newLockBytes->supportHandle = hGlobal;
|
||||
newLockBytes->deleteOnRelease = fDeleteOnRelease;
|
||||
|
||||
/*
|
||||
* This method will allocate a handle if one is not supplied.
|
||||
*/
|
||||
if (newLockBytes->supportHandle == 0)
|
||||
{
|
||||
newLockBytes->supportHandle = GlobalAlloc(GMEM_MOVEABLE |
|
||||
GMEM_NODISCARD,
|
||||
0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the size of the array to the size of the handle.
|
||||
*/
|
||||
newLockBytes->byteArraySize.u.HighPart = 0;
|
||||
newLockBytes->byteArraySize.u.LowPart = GlobalSize(
|
||||
newLockBytes->supportHandle);
|
||||
}
|
||||
|
||||
return newLockBytes;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This is the destructor of the HGLOBALStreamImpl class.
|
||||
*
|
||||
* This method will clean-up all the resources used-up by the given
|
||||
* HGLOBALLockBytesImpl class. The pointer passed-in to this function will be
|
||||
* freed and will not be valid anymore.
|
||||
*/
|
||||
void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
|
||||
{
|
||||
/*
|
||||
* Release the HGlobal if the constructor asked for that.
|
||||
*/
|
||||
if (This->deleteOnRelease)
|
||||
{
|
||||
GlobalFree(This->supportHandle);
|
||||
This->supportHandle = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, free the memory used-up by the class.
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This implements the IUnknown method QueryInterface for this
|
||||
* class
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
|
||||
ILockBytes* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject) /* [iid_is][out] */
|
||||
{
|
||||
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
|
||||
|
||||
/*
|
||||
* Perform a sanity check on the parameters.
|
||||
*/
|
||||
if (ppvObject==0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/*
|
||||
* Initialize the return parameter.
|
||||
*/
|
||||
*ppvObject = 0;
|
||||
|
||||
/*
|
||||
* Compare the riid with the interface IDs implemented by this object.
|
||||
*/
|
||||
if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
|
||||
{
|
||||
*ppvObject = (ILockBytes*)This;
|
||||
}
|
||||
else if (memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) == 0)
|
||||
{
|
||||
*ppvObject = (ILockBytes*)This;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we obtained an interface.
|
||||
*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/*
|
||||
* Query Interface always increases the reference count by one when it is
|
||||
* successful
|
||||
*/
|
||||
HGLOBALLockBytesImpl_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This implements the IUnknown method AddRef for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
|
||||
{
|
||||
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This implements the IUnknown method Release for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
|
||||
{
|
||||
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
|
||||
ULONG ref;
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
/*
|
||||
* If the reference count goes down to 0, perform suicide.
|
||||
*/
|
||||
if (ref==0)
|
||||
{
|
||||
HGLOBALLockBytesImpl_Destroy(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* It reads a block of information from the byte array at the specified
|
||||
* offset.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead) /* [out] */
|
||||
{
|
||||
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
|
||||
|
||||
void* supportBuffer;
|
||||
ULONG bytesReadBuffer = 0;
|
||||
ULONG bytesToReadFromBuffer;
|
||||
|
||||
/*
|
||||
* If the caller is not interested in the number of bytes read,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbRead == 0)
|
||||
pcbRead = &bytesReadBuffer;
|
||||
|
||||
/*
|
||||
* Make sure the offset is valid.
|
||||
*/
|
||||
if (ulOffset.u.LowPart > This->byteArraySize.u.LowPart)
|
||||
return E_FAIL;
|
||||
|
||||
/*
|
||||
* Using the known size of the array, calculate the number of bytes
|
||||
* to read.
|
||||
*/
|
||||
bytesToReadFromBuffer = min(This->byteArraySize.u.LowPart -
|
||||
ulOffset.u.LowPart, cb);
|
||||
|
||||
/*
|
||||
* Lock the buffer in position and copy the data.
|
||||
*/
|
||||
supportBuffer = GlobalLock(This->supportHandle);
|
||||
|
||||
memcpy(pv,
|
||||
(char *) supportBuffer + ulOffset.u.LowPart,
|
||||
bytesToReadFromBuffer);
|
||||
|
||||
/*
|
||||
* Return the number of bytes read.
|
||||
*/
|
||||
*pcbRead = bytesToReadFromBuffer;
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
GlobalUnlock(This->supportHandle);
|
||||
|
||||
/*
|
||||
* The function returns S_OK if the specified number of bytes were read
|
||||
* or the end of the array was reached.
|
||||
* It returns STG_E_READFAULT if the number of bytes to read does not equal
|
||||
* the number of bytes actually read.
|
||||
*/
|
||||
if(*pcbRead == cb)
|
||||
return S_OK;
|
||||
|
||||
return STG_E_READFAULT;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* It writes the specified bytes at the specified offset.
|
||||
* position. If the array is too small, it will be resized.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten) /* [out] */
|
||||
{
|
||||
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
|
||||
|
||||
void* supportBuffer;
|
||||
ULARGE_INTEGER newSize;
|
||||
ULONG bytesWritten = 0;
|
||||
|
||||
/*
|
||||
* If the caller is not interested in the number of bytes written,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbWritten == 0)
|
||||
pcbWritten = &bytesWritten;
|
||||
|
||||
if (cb == 0)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSize.u.HighPart = 0;
|
||||
newSize.u.LowPart = ulOffset.u.LowPart + cb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify if we need to grow the stream
|
||||
*/
|
||||
if (newSize.u.LowPart > This->byteArraySize.u.LowPart)
|
||||
{
|
||||
/* grow stream */
|
||||
if (HGLOBALLockBytesImpl_SetSize(iface, newSize) == STG_E_MEDIUMFULL)
|
||||
return STG_E_MEDIUMFULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock the buffer in position and copy the data.
|
||||
*/
|
||||
supportBuffer = GlobalLock(This->supportHandle);
|
||||
|
||||
memcpy((char *) supportBuffer + ulOffset.u.LowPart, pv, cb);
|
||||
|
||||
/*
|
||||
* Return the number of bytes written.
|
||||
*/
|
||||
*pcbWritten = cb;
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
GlobalUnlock(This->supportHandle);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* It will change the size of the byte array.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER libNewSize) /* [in] */
|
||||
{
|
||||
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
|
||||
HGLOBAL supportHandle;
|
||||
|
||||
/*
|
||||
* As documented.
|
||||
*/
|
||||
if (libNewSize.u.HighPart != 0)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
if (This->byteArraySize.u.LowPart == libNewSize.u.LowPart)
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
* Re allocate the HGlobal to fit the new size of the stream.
|
||||
*/
|
||||
supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
|
||||
|
||||
if (supportHandle == 0)
|
||||
return STG_E_MEDIUMFULL;
|
||||
|
||||
This->supportHandle = supportHandle;
|
||||
This->byteArraySize.u.LowPart = libNewSize.u.LowPart;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* The global memory implementation of ILockBytes does not support locking.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* The global memory implementation of ILockBytes does not support locking.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
|
||||
ILockBytes* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* This method returns information about the current
|
||||
* byte array object.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
|
||||
ILockBytes* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag) /* [in] */
|
||||
{
|
||||
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
|
||||
|
||||
memset(pstatstg, 0, sizeof(STATSTG));
|
||||
|
||||
pstatstg->pwcsName = NULL;
|
||||
pstatstg->type = STGTY_LOCKBYTES;
|
||||
pstatstg->cbSize = This->byteArraySize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,578 +0,0 @@
|
||||
/*
|
||||
* Global memory implementation of ILockBytes.
|
||||
*
|
||||
* Copyright 1999 Thuy Nguyen
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "ifs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/******************************************************************************
|
||||
* HGLOBALLockBytesImpl16 definition.
|
||||
*
|
||||
* This class imlements the ILockBytes inteface and represents a byte array
|
||||
* object supported by an HGLOBAL pointer.
|
||||
*/
|
||||
struct HGLOBALLockBytesImpl16
|
||||
{
|
||||
/*
|
||||
* Needs to be the first item in the stuct
|
||||
* since we want to cast this in an ILockBytes pointer
|
||||
*/
|
||||
ILockBytes16Vtbl *lpVtbl;
|
||||
ULONG ref;
|
||||
|
||||
/*
|
||||
* Support for the LockBytes object
|
||||
*/
|
||||
HGLOBAL16 supportHandle;
|
||||
|
||||
/*
|
||||
* This flag is TRUE if the HGLOBAL is destroyed when the object
|
||||
* is finally released.
|
||||
*/
|
||||
BOOL deleteOnRelease;
|
||||
/*
|
||||
* Helper variable that contains the size of the byte array
|
||||
*/
|
||||
ULARGE_INTEGER byteArraySize;
|
||||
};
|
||||
|
||||
typedef struct HGLOBALLockBytesImpl16 HGLOBALLockBytesImpl16;
|
||||
|
||||
HGLOBALLockBytesImpl16* HGLOBALLockBytesImpl16_Construct(
|
||||
HGLOBAL16 hGlobal,
|
||||
BOOL16 fDeleteOnRelease);
|
||||
|
||||
void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This);
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface(
|
||||
ILockBytes16* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject); /* [out][iid_is] */
|
||||
|
||||
ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(
|
||||
ILockBytes16* iface);
|
||||
|
||||
ULONG WINAPI HGLOBALLockBytesImpl16_Release(
|
||||
ILockBytes16* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
void* pv, /* [out][length_is][size_is] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
const void* pv, /* [in][size_is] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_Flush(
|
||||
ILockBytes16* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER libNewSize); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_Stat(
|
||||
ILockBytes16* iface,
|
||||
STATSTG16* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag); /* [in] */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* HGLOBALLockBytesImpl16 implementation
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* This is the constructor for the HGLOBALLockBytesImpl16 class.
|
||||
*
|
||||
* Params:
|
||||
* hGlobal - Handle that will support the stream. can be NULL.
|
||||
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL16 will be released
|
||||
* when the IStream object is destroyed.
|
||||
*/
|
||||
HGLOBALLockBytesImpl16*
|
||||
HGLOBALLockBytesImpl16_Construct(HGLOBAL16 hGlobal,
|
||||
BOOL16 fDeleteOnRelease)
|
||||
{
|
||||
HGLOBALLockBytesImpl16* newLockBytes;
|
||||
|
||||
static ILockBytes16Vtbl vt16;
|
||||
static SEGPTR msegvt16;
|
||||
HMODULE16 hcomp = GetModuleHandle16("OLE2");
|
||||
|
||||
|
||||
TRACE("(%x,%d)\n",hGlobal,fDeleteOnRelease);
|
||||
newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl16));
|
||||
if (newLockBytes == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Set up the virtual function table and reference count.
|
||||
*/
|
||||
if (!msegvt16)
|
||||
{
|
||||
#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"HGLOBALLockBytesImpl16_"#x);assert(vt16.x)
|
||||
VTENT(QueryInterface);
|
||||
VTENT(AddRef);
|
||||
VTENT(Release);
|
||||
VTENT(ReadAt);
|
||||
VTENT(WriteAt);
|
||||
VTENT(Flush);
|
||||
VTENT(SetSize);
|
||||
VTENT(LockRegion);
|
||||
VTENT(UnlockRegion);
|
||||
#undef VTENT
|
||||
msegvt16 = MapLS( &vt16 );
|
||||
}
|
||||
newLockBytes->lpVtbl = (ILockBytes16Vtbl*)msegvt16;
|
||||
newLockBytes->ref = 0;
|
||||
/*
|
||||
* Initialize the support.
|
||||
*/
|
||||
newLockBytes->supportHandle = hGlobal;
|
||||
newLockBytes->deleteOnRelease = fDeleteOnRelease;
|
||||
|
||||
/*
|
||||
* This method will allocate a handle if one is not supplied.
|
||||
*/
|
||||
if (newLockBytes->supportHandle == 0)
|
||||
newLockBytes->supportHandle = GlobalAlloc16(GMEM_MOVEABLE | GMEM_NODISCARD, 0);
|
||||
|
||||
/*
|
||||
* Initialize the size of the array to the size of the handle.
|
||||
*/
|
||||
newLockBytes->byteArraySize.u.HighPart = 0;
|
||||
newLockBytes->byteArraySize.u.LowPart = GlobalSize16(
|
||||
newLockBytes->supportHandle);
|
||||
|
||||
return (HGLOBALLockBytesImpl16*)MapLS(newLockBytes);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This is the destructor of the HGLOBALStreamImpl class.
|
||||
*
|
||||
* This method will clean-up all the resources used-up by the given
|
||||
* HGLOBALLockBytesImpl16 class. The pointer passed-in to this function will be
|
||||
* freed and will not be valid anymore.
|
||||
*/
|
||||
void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This)
|
||||
{
|
||||
TRACE("()\n");
|
||||
/*
|
||||
* Release the HGlobal if the constructor asked for that.
|
||||
*/
|
||||
if (This->deleteOnRelease)
|
||||
{
|
||||
GlobalFree16(This->supportHandle);
|
||||
This->supportHandle = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, free the memory used-up by the class.
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This implements the IUnknown method QueryInterface for this
|
||||
* class
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_QueryInterface(
|
||||
ILockBytes16* iface, /* [in] SEGPTR */
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject) /* [out][iid_is] (ptr to SEGPTR!) */
|
||||
{
|
||||
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)MapSL((SEGPTR)iface);
|
||||
|
||||
TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject);
|
||||
/*
|
||||
* Perform a sanity check on the parameters.
|
||||
*/
|
||||
if (ppvObject==0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/*
|
||||
* Initialize the return parameter.
|
||||
*/
|
||||
*ppvObject = 0;
|
||||
/*
|
||||
* Compare the riid with the interface IDs implemented by this object.
|
||||
*/
|
||||
if ( !memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) ||
|
||||
!memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes))
|
||||
)
|
||||
*ppvObject = (void*)iface;
|
||||
|
||||
/*
|
||||
* Check that we obtained an interface.
|
||||
*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/*
|
||||
* Query Interface always increases the reference count by one when it is
|
||||
* successful
|
||||
*/
|
||||
HGLOBALLockBytesImpl16_AddRef((ILockBytes16*)This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This implements the IUnknown method AddRef for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
|
||||
{
|
||||
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This implements the IUnknown method Release for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
|
||||
{
|
||||
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
|
||||
ULONG ref;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
/*
|
||||
* If the reference count goes down to 0, perform suicide.
|
||||
*/
|
||||
if (ref==0)
|
||||
HGLOBALLockBytesImpl16_Destroy(This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* It reads a block of information from the byte array at the specified
|
||||
* offset.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_ReadAt(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
void* pv, /* [out][length_is][size_is] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead) /* [out] */
|
||||
{
|
||||
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
|
||||
|
||||
void* supportBuffer;
|
||||
ULONG bytesReadBuffer = 0;
|
||||
ULONG bytesToReadFromBuffer;
|
||||
|
||||
TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbRead);
|
||||
/*
|
||||
* If the caller is not interested in the number of bytes read,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbRead == 0)
|
||||
pcbRead = &bytesReadBuffer;
|
||||
|
||||
/*
|
||||
* Make sure the offset is valid.
|
||||
*/
|
||||
if (ulOffset.u.LowPart > This->byteArraySize.u.LowPart)
|
||||
return E_FAIL;
|
||||
|
||||
/*
|
||||
* Using the known size of the array, calculate the number of bytes
|
||||
* to read.
|
||||
*/
|
||||
bytesToReadFromBuffer = min(This->byteArraySize.u.LowPart -
|
||||
ulOffset.u.LowPart, cb);
|
||||
|
||||
/*
|
||||
* Lock the buffer in position and copy the data.
|
||||
*/
|
||||
supportBuffer = GlobalLock16(This->supportHandle);
|
||||
|
||||
memcpy(pv,
|
||||
(char *) supportBuffer + ulOffset.u.LowPart,
|
||||
bytesToReadFromBuffer);
|
||||
|
||||
/*
|
||||
* Return the number of bytes read.
|
||||
*/
|
||||
*pcbRead = bytesToReadFromBuffer;
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
GlobalUnlock16(This->supportHandle);
|
||||
|
||||
/*
|
||||
* The function returns S_OK if the specified number of bytes were read
|
||||
* or the end of the array was reached.
|
||||
* It returns STG_E_READFAULT if the number of bytes to read does not equal
|
||||
* the number of bytes actually read.
|
||||
*/
|
||||
if(*pcbRead == cb)
|
||||
return S_OK;
|
||||
|
||||
return STG_E_READFAULT;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* It writes the specified bytes at the specified offset.
|
||||
* position. If the array is too small, it will be resized.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_WriteAt(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER ulOffset, /* [in] */
|
||||
const void* pv, /* [in][size_is] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten) /* [out] */
|
||||
{
|
||||
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
|
||||
|
||||
void* supportBuffer;
|
||||
ULARGE_INTEGER newSize;
|
||||
ULONG bytesWritten = 0;
|
||||
|
||||
TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbWritten);
|
||||
/*
|
||||
* If the caller is not interested in the number of bytes written,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbWritten == 0)
|
||||
pcbWritten = &bytesWritten;
|
||||
|
||||
if (cb == 0)
|
||||
return S_OK;
|
||||
|
||||
newSize.u.HighPart = 0;
|
||||
newSize.u.LowPart = ulOffset.u.LowPart + cb;
|
||||
|
||||
/*
|
||||
* Verify if we need to grow the stream
|
||||
*/
|
||||
if (newSize.u.LowPart > This->byteArraySize.u.LowPart)
|
||||
{
|
||||
/* grow stream */
|
||||
if (HGLOBALLockBytesImpl16_SetSize(iface, newSize) == STG_E_MEDIUMFULL)
|
||||
return STG_E_MEDIUMFULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock the buffer in position and copy the data.
|
||||
*/
|
||||
supportBuffer = GlobalLock16(This->supportHandle);
|
||||
|
||||
memcpy((char *) supportBuffer + ulOffset.u.LowPart, pv, cb);
|
||||
|
||||
/*
|
||||
* Return the number of bytes written.
|
||||
*/
|
||||
*pcbWritten = cb;
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
GlobalUnlock16(This->supportHandle);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
|
||||
{
|
||||
TRACE("(%p)\n",iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* It will change the size of the byte array.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_SetSize(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER libNewSize) /* [in] */
|
||||
{
|
||||
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
|
||||
HGLOBAL16 supportHandle;
|
||||
|
||||
TRACE("(%p,%ld)\n",This,libNewSize.u.LowPart);
|
||||
/*
|
||||
* As documented.
|
||||
*/
|
||||
if (libNewSize.u.HighPart != 0)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
if (This->byteArraySize.u.LowPart == libNewSize.u.LowPart)
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
* Re allocate the HGlobal to fit the new size of the stream.
|
||||
*/
|
||||
supportHandle = GlobalReAlloc16(This->supportHandle, libNewSize.u.LowPart, 0);
|
||||
|
||||
if (supportHandle == 0)
|
||||
return STG_E_MEDIUMFULL;
|
||||
|
||||
This->supportHandle = supportHandle;
|
||||
This->byteArraySize.u.LowPart = libNewSize.u.LowPart;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* The global memory implementation of ILockBytes does not support locking.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_LockRegion(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* The global memory implementation of ILockBytes does not support locking.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_UnlockRegion(
|
||||
ILockBytes16* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This method is part of the ILockBytes interface.
|
||||
*
|
||||
* This method returns information about the current
|
||||
* byte array object.
|
||||
*
|
||||
* See the documentation of ILockBytes for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALLockBytesImpl16_Stat(
|
||||
ILockBytes16*iface,
|
||||
STATSTG16* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag) /* [in] */
|
||||
{
|
||||
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
|
||||
|
||||
memset(pstatstg, 0, sizeof(STATSTG16));
|
||||
|
||||
pstatstg->pwcsName = NULL;
|
||||
pstatstg->type = STGTY_LOCKBYTES;
|
||||
pstatstg->cbSize = This->byteArraySize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateILockBytesOnHGlobal [OLE2.54]
|
||||
*
|
||||
* Creates an ILockBytes interface for a HGLOBAL handle.
|
||||
*
|
||||
* Params:
|
||||
* hGlobal the global handle (16bit)
|
||||
* fDeleteOnRelease delete handle on release.
|
||||
* ppLkbyt pointer to ILockBytes interface.
|
||||
*
|
||||
* Returns:
|
||||
* Staddard OLE error return codes.
|
||||
*
|
||||
*/
|
||||
HRESULT WINAPI CreateILockBytesOnHGlobal16(
|
||||
HGLOBAL16 hGlobal, /* [in] */
|
||||
BOOL16 fDeleteOnRelease, /* [in] */
|
||||
LPLOCKBYTES16 *ppLkbyt) /* [out] (ptr to SEGPTR!) */
|
||||
{
|
||||
HGLOBALLockBytesImpl16* newLockBytes; /* SEGPTR */
|
||||
|
||||
newLockBytes = HGLOBALLockBytesImpl16_Construct(hGlobal, fDeleteOnRelease);
|
||||
|
||||
if (newLockBytes != NULL)
|
||||
return HGLOBALLockBytesImpl16_QueryInterface((ILockBytes16*)newLockBytes,
|
||||
&IID_ILockBytes,
|
||||
(void**)ppLkbyt);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
@@ -1,554 +0,0 @@
|
||||
/*
|
||||
* Monikers
|
||||
*
|
||||
* Copyright 1998 Marcus Meissner
|
||||
* Copyright 1999 Noomen Hamza
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* - IRunningObjectTable should work interprocess, but currently doesn't.
|
||||
* Native (on Win2k at least) uses an undocumented RPC interface, IROT, to
|
||||
* communicate with RPCSS which contains the table of marshalled data.
|
||||
* - IRunningObjectTable should use marshalling instead of simple ref
|
||||
* counting as there is the possibility of using the running object table
|
||||
* to access objects in other apartments.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "winerror.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "wtypes.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "compobj_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
#define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
|
||||
|
||||
/* define the structure of the running object table elements */
|
||||
typedef struct RunObject{
|
||||
|
||||
IUnknown* pObj; /* points on a running object*/
|
||||
IMoniker* pmkObj; /* points on a moniker who identifies this object */
|
||||
FILETIME lastModifObj;
|
||||
DWORD identRegObj; /* registration key relative to this object */
|
||||
DWORD regTypeObj; /* registration type : strong or weak */
|
||||
}RunObject;
|
||||
|
||||
/* define the RunningObjectTableImpl structure */
|
||||
typedef struct RunningObjectTableImpl{
|
||||
|
||||
IRunningObjectTableVtbl *lpVtbl;
|
||||
ULONG ref;
|
||||
|
||||
RunObject* runObjTab; /* pointer to the first object in the table */
|
||||
DWORD runObjTabSize; /* current table size */
|
||||
DWORD runObjTabLastIndx; /* first free index element in the table. */
|
||||
DWORD runObjTabRegister; /* registration key of the next registered object */
|
||||
|
||||
} RunningObjectTableImpl;
|
||||
|
||||
RunningObjectTableImpl* runningObjectTableInstance=0;
|
||||
|
||||
/* IRunningObjectTable prototype functions : */
|
||||
/* IUnknown functions*/
|
||||
static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
|
||||
static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
|
||||
static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
|
||||
/* IRunningObjectTable functions */
|
||||
static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
|
||||
static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
|
||||
static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
|
||||
static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
|
||||
static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
|
||||
static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
|
||||
static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
|
||||
/* Local functions*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_Initialize();
|
||||
HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
|
||||
HRESULT WINAPI RunningObjectTableImpl_Destroy();
|
||||
HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
|
||||
|
||||
/* Virtual function table for the IRunningObjectTable class. */
|
||||
static IRunningObjectTableVtbl VT_RunningObjectTableImpl =
|
||||
{
|
||||
RunningObjectTableImpl_QueryInterface,
|
||||
RunningObjectTableImpl_AddRef,
|
||||
RunningObjectTableImpl_Release,
|
||||
RunningObjectTableImpl_Register,
|
||||
RunningObjectTableImpl_Revoke,
|
||||
RunningObjectTableImpl_IsRunning,
|
||||
RunningObjectTableImpl_GetObject,
|
||||
RunningObjectTableImpl_NoteChangeTime,
|
||||
RunningObjectTableImpl_GetTimeOfLastChange,
|
||||
RunningObjectTableImpl_EnumRunning
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_QueryInterface
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
|
||||
{
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
|
||||
|
||||
/* validate arguments */
|
||||
if (This==0)
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
||||
if (ppvObject==0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppvObject = 0;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, riid))
|
||||
*ppvObject = (IRunningObjectTable*)This;
|
||||
else
|
||||
if (IsEqualIID(&IID_IRunningObjectTable, riid))
|
||||
*ppvObject = (IRunningObjectTable*)This;
|
||||
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
RunningObjectTableImpl_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_AddRef
|
||||
*/
|
||||
ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
|
||||
{
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_Initialize
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_Destroy()
|
||||
{
|
||||
TRACE("()\n");
|
||||
|
||||
if (runningObjectTableInstance==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* free the ROT table memory */
|
||||
HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
|
||||
|
||||
/* free the ROT structure memory */
|
||||
HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_Release
|
||||
*/
|
||||
ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
|
||||
{
|
||||
DWORD i;
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
ULONG ref;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
/* unitialize ROT structure if there's no more reference to it*/
|
||||
if (ref == 0) {
|
||||
|
||||
/* release all registered objects */
|
||||
for(i=0;i<This->runObjTabLastIndx;i++)
|
||||
{
|
||||
if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
|
||||
IUnknown_Release(This->runObjTab[i].pObj);
|
||||
|
||||
IMoniker_Release(This->runObjTab[i].pmkObj);
|
||||
}
|
||||
/* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
|
||||
* when RunningObjectTableImpl_UnInitialize function is called
|
||||
*/
|
||||
|
||||
/* there's no more elements in the table */
|
||||
This->runObjTabRegister=0;
|
||||
This->runObjTabLastIndx=0;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_Initialize
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_Initialize()
|
||||
{
|
||||
TRACE("()\n");
|
||||
|
||||
/* create the unique instance of the RunningObjectTableImpl structure */
|
||||
runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
|
||||
|
||||
if (runningObjectTableInstance == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* initialize the virtual table function */
|
||||
runningObjectTableInstance->lpVtbl = &VT_RunningObjectTableImpl;
|
||||
|
||||
/* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
|
||||
/* the ROT referred many times not in the same time (all the objects in the ROT will */
|
||||
/* be removed every time the ROT is removed ) */
|
||||
runningObjectTableInstance->ref = 1;
|
||||
|
||||
/* allocate space memory for the table which contains all the running objects */
|
||||
runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
|
||||
|
||||
if (runningObjectTableInstance->runObjTab == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
|
||||
runningObjectTableInstance->runObjTabRegister=1;
|
||||
runningObjectTableInstance->runObjTabLastIndx=0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_UnInitialize
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
|
||||
{
|
||||
TRACE("()\n");
|
||||
|
||||
if (runningObjectTableInstance==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
|
||||
|
||||
RunningObjectTableImpl_Destroy();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_Register
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
|
||||
DWORD grfFlags, /* Registration options */
|
||||
IUnknown *punkObject, /* Pointer to the object being registered */
|
||||
IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
|
||||
DWORD *pdwRegister) /* Pointer to the value identifying the registration */
|
||||
{
|
||||
HRESULT res=S_OK;
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
|
||||
|
||||
/* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
|
||||
if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
|
||||
(!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
|
||||
(grfFlags) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* verify if the object to be registered was registered before */
|
||||
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
|
||||
res = MK_S_MONIKERALREADYREGISTERED;
|
||||
|
||||
/* put the new registered object in the first free element in the table */
|
||||
This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
|
||||
This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
|
||||
This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
|
||||
This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
|
||||
CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
|
||||
|
||||
/* gives a registration identifier to the registered object*/
|
||||
(*pdwRegister)= This->runObjTabRegister;
|
||||
|
||||
if (This->runObjTabRegister == 0xFFFFFFFF){
|
||||
|
||||
FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
|
||||
return E_FAIL;
|
||||
}
|
||||
This->runObjTabRegister++;
|
||||
This->runObjTabLastIndx++;
|
||||
|
||||
if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
|
||||
|
||||
This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
|
||||
This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
|
||||
This->runObjTabSize * sizeof(RunObject));
|
||||
if (!This->runObjTab)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
/* add a reference to the object in the strong registration case */
|
||||
if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 ) {
|
||||
TRACE("strong registration, reffing %p\n", punkObject);
|
||||
/* this is wrong; we should always add a reference to the object */
|
||||
IUnknown_AddRef(punkObject);
|
||||
}
|
||||
|
||||
IMoniker_AddRef(pmkObjectName);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_Revoke
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
|
||||
DWORD dwRegister) /* Value identifying registration to be revoked*/
|
||||
{
|
||||
|
||||
DWORD index,j;
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p,%ld)\n",This,dwRegister);
|
||||
|
||||
/* verify if the object to be revoked was registered before or not */
|
||||
if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
|
||||
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* release the object if it was registered with a strong registrantion option */
|
||||
if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0) {
|
||||
TRACE("releasing %p\n", This->runObjTab[index].pObj);
|
||||
/* this is also wrong; we should always release the object (see above) */
|
||||
IUnknown_Release(This->runObjTab[index].pObj);
|
||||
}
|
||||
|
||||
IMoniker_Release(This->runObjTab[index].pmkObj);
|
||||
|
||||
/* remove the object from the table */
|
||||
for(j=index; j<This->runObjTabLastIndx-1; j++)
|
||||
This->runObjTab[j]= This->runObjTab[j+1];
|
||||
|
||||
This->runObjTabLastIndx--;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_IsRunning
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
|
||||
IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
|
||||
{
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p)\n",This,pmkObjectName);
|
||||
|
||||
return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_GetObject
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
|
||||
IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
|
||||
IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
|
||||
{
|
||||
DWORD index;
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
|
||||
|
||||
if (ppunkObject==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppunkObject=0;
|
||||
|
||||
/* verify if the object was registered before or not */
|
||||
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE) {
|
||||
WARN("Moniker unavailable - needs to work interprocess?\n");
|
||||
return MK_E_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* add a reference to the object then set output object argument */
|
||||
IUnknown_AddRef(This->runObjTab[index].pObj);
|
||||
*ppunkObject=This->runObjTab[index].pObj;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_NoteChangeTime
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
|
||||
DWORD dwRegister, /* Value identifying registration being updated */
|
||||
FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
|
||||
{
|
||||
DWORD index=-1;
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
|
||||
|
||||
/* verify if the object to be changed was registered before or not */
|
||||
if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* set the new value of the last time change */
|
||||
This->runObjTab[index].lastModifObj= (*pfiletime);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_GetTimeOfLastChange
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
|
||||
IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
|
||||
FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
|
||||
{
|
||||
DWORD index=-1;
|
||||
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
|
||||
|
||||
if (pmkObjectName==NULL || pfiletime==NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* verify if the object was registered before or not */
|
||||
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
|
||||
return MK_E_UNAVAILABLE;
|
||||
|
||||
(*pfiletime)= This->runObjTab[index].lastModifObj;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RunningObjectTable_EnumRunning
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
|
||||
IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
|
||||
{
|
||||
FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetObjectIndex
|
||||
*/
|
||||
HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
|
||||
DWORD identReg,
|
||||
IMoniker* pmk,
|
||||
DWORD *indx)
|
||||
{
|
||||
|
||||
DWORD i;
|
||||
|
||||
TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
|
||||
|
||||
if (pmk!=NULL)
|
||||
/* search object identified by a moniker */
|
||||
for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
|
||||
else
|
||||
/* search object identified by a register identifier */
|
||||
for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
|
||||
|
||||
if (i==This->runObjTabLastIndx) return S_FALSE;
|
||||
|
||||
if (indx != NULL) *indx=i;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetRunningObjectTable (OLE2.30)
|
||||
*/
|
||||
HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
|
||||
{
|
||||
FIXME("(%ld,%p),stub!\n",reserved,pprot);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetRunningObjectTable (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
|
||||
{
|
||||
IID riid=IID_IRunningObjectTable;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
if (reserved!=0)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if(runningObjectTableInstance==NULL)
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
||||
res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleRun [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
|
||||
{
|
||||
IRunnableObject *runable;
|
||||
IRunnableObject *This = (IRunnableObject *)pUnknown;
|
||||
LRESULT ret;
|
||||
|
||||
ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
|
||||
if (ret)
|
||||
return 0; /* Appears to return no error. */
|
||||
ret = IRunnableObject_Run(runable,NULL);
|
||||
IRunnableObject_Release(runable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* MkParseDisplayName [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
|
||||
LPDWORD pchEaten, LPMONIKER *ppmk)
|
||||
{
|
||||
FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
|
||||
if (!(IsValidInterface((LPUNKNOWN) pbc)))
|
||||
return E_INVALIDARG;
|
||||
|
||||
return MK_E_SYNTAX;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateClassMoniker [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker ** ppmk)
|
||||
{
|
||||
FIXME("%s\n", debugstr_guid( rclsid ));
|
||||
if( ppmk )
|
||||
*ppmk = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef __WINE_MONIKER_H__
|
||||
#define __WINE_MONIKER_H__
|
||||
|
||||
#define ICOM_THIS_From_IROTData(class, name) class* This = (class*)(((char*)name)-sizeof(void*))
|
||||
|
||||
extern const CLSID CLSID_FileMoniker;
|
||||
extern const CLSID CLSID_ItemMoniker;
|
||||
extern const CLSID CLSID_AntiMoniker;
|
||||
extern const CLSID CLSID_CompositeMoniker;
|
||||
|
||||
#endif /* __WINE_MONIKER_H__ */
|
||||
@@ -1,527 +0,0 @@
|
||||
/*
|
||||
* 16 bit ole functions
|
||||
*
|
||||
* Copyright 1995 Martin von Loewis
|
||||
* Copyright 1998 Justin Bradford
|
||||
* Copyright 1999 Francis Beaudet
|
||||
* Copyright 1999 Sylvain St-Germain
|
||||
* Copyright 2002 Marcus Meissner
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "ole2ver.h"
|
||||
#include "rpc.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "wownt32.h"
|
||||
#include "wtypes.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "compobj_private.h"
|
||||
#include "ifs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
HINSTANCE16 COMPOBJ_hInstance = 0;
|
||||
static int COMPOBJ_Attach = 0;
|
||||
|
||||
HTASK16 hETask = 0;
|
||||
WORD Table_ETask[62];
|
||||
|
||||
LPMALLOC16 currentMalloc16=NULL;
|
||||
|
||||
/* --- IMalloc16 implementation */
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* IUnknown fields */
|
||||
IMalloc16Vtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
/* IMalloc16 fields */
|
||||
} IMalloc16Impl;
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_QueryInterface [COMPOBJ.500]
|
||||
*/
|
||||
HRESULT WINAPI IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
|
||||
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
|
||||
if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
|
||||
!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
|
||||
) {
|
||||
*obj = This;
|
||||
return 0;
|
||||
}
|
||||
return OLE_E_ENUM_NOMORE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_AddRef [COMPOBJ.501]
|
||||
*/
|
||||
ULONG WINAPI IMalloc16_fnAddRef(IMalloc16* iface) {
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
TRACE("(%p)->AddRef()\n",This);
|
||||
return 1; /* cannot be freed */
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_Release [COMPOBJ.502]
|
||||
*/
|
||||
ULONG WINAPI IMalloc16_fnRelease(IMalloc16* iface) {
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
TRACE("(%p)->Release()\n",This);
|
||||
return 1; /* cannot be freed */
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_Alloc [COMPOBJ.503]
|
||||
*/
|
||||
SEGPTR WINAPI IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
TRACE("(%p)->Alloc(%ld)\n",This,cb);
|
||||
return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_Free [COMPOBJ.505]
|
||||
*/
|
||||
VOID WINAPI IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
|
||||
{
|
||||
void *ptr = MapSL(pv);
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
TRACE("(%p)->Free(%08lx)\n",This,pv);
|
||||
UnMapLS(pv);
|
||||
HeapFree( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_Realloc [COMPOBJ.504]
|
||||
*/
|
||||
SEGPTR WINAPI IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
|
||||
{
|
||||
SEGPTR ret;
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
|
||||
if (!pv)
|
||||
ret = IMalloc16_fnAlloc(iface, cb);
|
||||
else if (cb) {
|
||||
ret = MapLS( HeapReAlloc( GetProcessHeap(), 0, MapSL(pv), cb ) );
|
||||
UnMapLS(pv);
|
||||
} else {
|
||||
IMalloc16_fnFree(iface, pv);
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_GetSize [COMPOBJ.506]
|
||||
*/
|
||||
DWORD WINAPI IMalloc16_fnGetSize(const IMalloc16* iface,SEGPTR pv)
|
||||
{
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
TRACE("(%p)->GetSize(%08lx)\n",This,pv);
|
||||
return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_DidAlloc [COMPOBJ.507]
|
||||
*/
|
||||
INT16 WINAPI IMalloc16_fnDidAlloc(const IMalloc16* iface,LPVOID pv) {
|
||||
IMalloc16 *This = (IMalloc16 *)iface;
|
||||
TRACE("(%p)->DidAlloc(%p)\n",This,pv);
|
||||
return (INT16)-1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_HeapMinimize [COMPOBJ.508]
|
||||
*/
|
||||
LPVOID WINAPI IMalloc16_fnHeapMinimize(IMalloc16* iface) {
|
||||
IMalloc16Impl *This = (IMalloc16Impl *)iface;
|
||||
TRACE("(%p)->HeapMinimize()\n",This);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IMalloc16_Constructor [VTABLE]
|
||||
*/
|
||||
LPMALLOC16
|
||||
IMalloc16_Constructor()
|
||||
{
|
||||
static IMalloc16Vtbl vt16;
|
||||
static SEGPTR msegvt16;
|
||||
IMalloc16Impl* This;
|
||||
HMODULE16 hcomp = GetModuleHandle16("COMPOBJ");
|
||||
|
||||
This = HeapAlloc( GetProcessHeap(), 0, sizeof(IMalloc16Impl) );
|
||||
if (!msegvt16)
|
||||
{
|
||||
#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"IMalloc16_"#x);assert(vt16.x)
|
||||
VTENT(QueryInterface);
|
||||
VTENT(AddRef);
|
||||
VTENT(Release);
|
||||
VTENT(Alloc);
|
||||
VTENT(Realloc);
|
||||
VTENT(Free);
|
||||
VTENT(GetSize);
|
||||
VTENT(DidAlloc);
|
||||
VTENT(HeapMinimize);
|
||||
#undef VTENT
|
||||
msegvt16 = MapLS( &vt16 );
|
||||
}
|
||||
This->lpVtbl = (IMalloc16Vtbl*)msegvt16;
|
||||
This->ref = 1;
|
||||
return (LPMALLOC16)MapLS( This );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CoGetMalloc [COMPOBJ.4]
|
||||
* RETURNS
|
||||
* The current win16 IMalloc
|
||||
*/
|
||||
HRESULT WINAPI CoGetMalloc16(
|
||||
DWORD dwMemContext, /* [in] unknown */
|
||||
LPMALLOC16 * lpMalloc /* [out] current win16 malloc interface */
|
||||
) {
|
||||
if(!currentMalloc16)
|
||||
currentMalloc16 = IMalloc16_Constructor();
|
||||
*lpMalloc = currentMalloc16;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoCreateStandardMalloc [COMPOBJ.71]
|
||||
*/
|
||||
HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
|
||||
LPMALLOC16 *lpMalloc)
|
||||
{
|
||||
/* FIXME: docu says we shouldn't return the same allocator as in
|
||||
* CoGetMalloc16 */
|
||||
*lpMalloc = IMalloc16_Constructor();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoInitialize [COMPOBJ.2]
|
||||
* Set the win16 IMalloc used for memory management
|
||||
*/
|
||||
HRESULT WINAPI CoInitialize16(
|
||||
LPVOID lpReserved /* [in] pointer to win16 malloc interface */
|
||||
) {
|
||||
currentMalloc16 = (LPMALLOC16)lpReserved;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoUninitialize [COMPOBJ.3]
|
||||
* Don't know what it does.
|
||||
* 3-Nov-98 -- this was originally misspelled, I changed it to what I
|
||||
* believe is the correct spelling
|
||||
*/
|
||||
void WINAPI CoUninitialize16(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
CoFreeAllLibraries();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* IsEqualGUID [COMPOBJ.18]
|
||||
*
|
||||
* Compares two Unique Identifiers.
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE if equal
|
||||
*/
|
||||
BOOL16 WINAPI IsEqualGUID16(
|
||||
GUID* g1, /* [in] unique id 1 */
|
||||
GUID* g2) /* [in] unique id 2 */
|
||||
{
|
||||
return !memcmp( g1, g2, sizeof(GUID) );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CLSIDFromString [COMPOBJ.20]
|
||||
* Converts a unique identifier from its string representation into
|
||||
* the GUID struct.
|
||||
*
|
||||
* Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
|
||||
*
|
||||
* RETURNS
|
||||
* the converted GUID
|
||||
*/
|
||||
HRESULT WINAPI CLSIDFromString16(
|
||||
LPCOLESTR16 idstr, /* [in] string representation of guid */
|
||||
CLSID *id) /* [out] GUID converted from string */
|
||||
{
|
||||
|
||||
return __CLSIDFromStringA(idstr,id);
|
||||
}
|
||||
|
||||
extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
||||
DWORD cbArgs, LPVOID pArgs,
|
||||
LPDWORD pdwRetCode );
|
||||
|
||||
/******************************************************************************
|
||||
* _xmalloc16 [internal]
|
||||
* Allocates size bytes from the standard ole16 allocator.
|
||||
*
|
||||
* RETURNS
|
||||
* the allocated segmented pointer and a HRESULT
|
||||
*/
|
||||
HRESULT
|
||||
_xmalloc16(DWORD size, SEGPTR *ptr) {
|
||||
LPMALLOC16 mllc;
|
||||
DWORD args[2];
|
||||
|
||||
if (CoGetMalloc16(0,&mllc))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
args[0] = (DWORD)mllc;
|
||||
args[1] = size;
|
||||
/* No need for a Callback entry, we have WOWCallback16Ex which does
|
||||
* everything we need.
|
||||
*/
|
||||
if (!K32WOWCallback16Ex(
|
||||
(DWORD)((IMalloc16Vtbl*)MapSL(
|
||||
(SEGPTR)((LPMALLOC16)MapSL((SEGPTR)mllc))->lpVtbl )
|
||||
)->Alloc,
|
||||
WCB16_CDECL,
|
||||
2*sizeof(DWORD),
|
||||
(LPVOID)args,
|
||||
(LPDWORD)ptr
|
||||
)) {
|
||||
ERR("CallTo16 IMalloc16 (%ld) failed\n",size);
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* StringFromCLSID [COMPOBJ.19]
|
||||
* Converts a GUID into the respective string representation.
|
||||
* The target string is allocated using the OLE IMalloc.
|
||||
*
|
||||
* RETURNS
|
||||
* the string representation and HRESULT
|
||||
*/
|
||||
|
||||
HRESULT WINAPI StringFromCLSID16(
|
||||
REFCLSID id, /* [in] the GUID to be converted */
|
||||
LPOLESTR16 *idstr /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
|
||||
|
||||
) {
|
||||
HRESULT ret;
|
||||
|
||||
ret = _xmalloc16(40,(SEGPTR*)idstr);
|
||||
if (ret != S_OK)
|
||||
return ret;
|
||||
return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ProgIDFromCLSID [COMPOBJ.62]
|
||||
* Converts a class id into the respective Program ID. (By using a registry lookup)
|
||||
* RETURNS S_OK on success
|
||||
* riid associated with the progid
|
||||
*/
|
||||
HRESULT WINAPI ProgIDFromCLSID16(
|
||||
REFCLSID clsid, /* [in] class id as found in registry */
|
||||
LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */
|
||||
) {
|
||||
char strCLSID[50], *buf, *buf2;
|
||||
DWORD buf2len;
|
||||
HKEY xhkey;
|
||||
HRESULT ret = S_OK;
|
||||
|
||||
WINE_StringFromCLSID(clsid, strCLSID);
|
||||
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, strlen(strCLSID)+14);
|
||||
sprintf(buf,"CLSID\\%s\\ProgID", strCLSID);
|
||||
if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey))
|
||||
ret = REGDB_E_CLASSNOTREG;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
|
||||
if (ret == S_OK)
|
||||
{
|
||||
buf2 = HeapAlloc(GetProcessHeap(), 0, 255);
|
||||
buf2len = 255;
|
||||
if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
|
||||
ret = REGDB_E_CLASSNOTREG;
|
||||
|
||||
if (ret == S_OK)
|
||||
{
|
||||
ret = _xmalloc16(buf2len+1, (SEGPTR*)lplpszProgID);
|
||||
if (ret == S_OK)
|
||||
strcpy(MapSL((SEGPTR)*lplpszProgID),buf2);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, buf2);
|
||||
}
|
||||
RegCloseKey(xhkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LookupETask (COMPOBJ.94)
|
||||
*/
|
||||
HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
|
||||
FIXME("(%p,%p),stub!\n",hTask,p);
|
||||
if ((*hTask = GetCurrentTask()) == hETask) {
|
||||
memcpy(p, Table_ETask, sizeof(Table_ETask));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetETask (COMPOBJ.95)
|
||||
*/
|
||||
HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
|
||||
FIXME("(%04x,%p),stub!\n",hTask,p);
|
||||
hETask = hTask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CALLOBJECTINWOW (COMPOBJ.201)
|
||||
*/
|
||||
HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
|
||||
FIXME("(%p,%p),stub!\n",p1,p2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoRegisterClassObject [COMPOBJ.5]
|
||||
*
|
||||
* Don't know where it registers it ...
|
||||
*/
|
||||
HRESULT WINAPI CoRegisterClassObject16(
|
||||
REFCLSID rclsid,
|
||||
LPUNKNOWN pUnk,
|
||||
DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
|
||||
DWORD flags, /* [in] REGCLS flags indicating how connections are made */
|
||||
LPDWORD lpdwRegister
|
||||
) {
|
||||
char buf[80];
|
||||
|
||||
WINE_StringFromCLSID(rclsid,buf);
|
||||
|
||||
FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
|
||||
buf,pUnk,dwClsContext,flags,lpdwRegister
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoRevokeClassObject [COMPOBJ.6]
|
||||
*
|
||||
*/
|
||||
HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
|
||||
{
|
||||
FIXME("(0x%08lx),stub!\n", dwRegister);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoFileTimeToDosDateTime [COMPOBJ.30]
|
||||
*/
|
||||
BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
|
||||
{
|
||||
return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoDosDateTimeToFileTime [COMPOBJ.31]
|
||||
*/
|
||||
BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
|
||||
{
|
||||
return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoRegisterMessageFilter [COMPOBJ.27]
|
||||
*/
|
||||
HRESULT WINAPI CoRegisterMessageFilter16(
|
||||
LPMESSAGEFILTER lpMessageFilter,
|
||||
LPMESSAGEFILTER *lplpMessageFilter
|
||||
) {
|
||||
FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoLockObjectExternal [COMPOBJ.63]
|
||||
*/
|
||||
HRESULT WINAPI CoLockObjectExternal16(
|
||||
LPUNKNOWN pUnk, /* [in] object to be locked */
|
||||
BOOL16 fLock, /* [in] do lock */
|
||||
BOOL16 fLastUnlockReleases /* [in] ? */
|
||||
) {
|
||||
FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoGetState [COMPOBJ.115]
|
||||
*/
|
||||
HRESULT WINAPI CoGetState16(LPDWORD state)
|
||||
{
|
||||
FIXME("(%p),stub!\n", state);
|
||||
|
||||
*state = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllEntryPoint [COMPOBJ.116]
|
||||
*
|
||||
* Initialization code for the COMPOBJ DLL
|
||||
*
|
||||
* RETURNS:
|
||||
*/
|
||||
BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
|
||||
{
|
||||
TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
|
||||
switch(Reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst;
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if(!--COMPOBJ_Attach)
|
||||
COMPOBJ_hInstance = 0;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,158 +0,0 @@
|
||||
1 pascal OleBuildVersion() OleBuildVersion
|
||||
2 pascal OleInitialize(ptr) OleInitialize
|
||||
3 pascal OleUninitialize() OleUninitialize
|
||||
4 pascal DllGetClassObject(ptr ptr ptr) DllGetClassObject16
|
||||
#5 WEP
|
||||
6 stub OLEQUERYLINKFROMDATA
|
||||
7 stub OLEQUERYCREATEFROMDATA
|
||||
8 stub OLECREATEFROMDATA
|
||||
9 stub OLECREATELINKFROMDATA
|
||||
10 stub OLECREATE
|
||||
11 stub OLECREATELINK
|
||||
12 stub OLELOAD
|
||||
13 stub OLESAVE
|
||||
14 stub OLERUN
|
||||
#15 ___EXPORTEDSTUB
|
||||
16 stub OLEISRUNNING
|
||||
17 stub OLELOCKRUNNING
|
||||
18 stub READCLASSSTG
|
||||
19 stub WRITECLASSSTG
|
||||
20 stub READCLASSSTM
|
||||
21 stub WRITECLASSSTM
|
||||
22 stub BINDMONIKER
|
||||
23 stub MKPARSEDISPLAYNAME
|
||||
24 stub OLESAVETOSTREAM
|
||||
25 stub OLELOADFROMSTREAM
|
||||
26 stub CREATEBINDCTX
|
||||
27 pascal CreateItemMoniker(str str ptr) CreateItemMoniker16
|
||||
28 pascal CreateFileMoniker(str ptr) CreateFileMoniker16
|
||||
29 stub CREATEGENERICCOMPOSITE
|
||||
30 pascal GetRunningObjectTable(long ptr) GetRunningObjectTable16
|
||||
31 stub OLEGETMALLOC
|
||||
32 stub RELEASESTGMEDIUM
|
||||
33 stub READSTRINGSTREAM
|
||||
34 stub WRITESTRINGSTREAM
|
||||
35 pascal RegisterDragDrop(word segptr) RegisterDragDrop16
|
||||
36 pascal RevokeDragDrop(word) RevokeDragDrop16
|
||||
37 stub DODRAGDROP
|
||||
38 stub CREATEOLEADVISEHOLDER
|
||||
39 stub CREATEDATAADVISEHOLDER
|
||||
40 stub OLECREATEMENUDESCRIPTOR
|
||||
41 stub OLESETMENUDESCRIPTOR
|
||||
42 stub OLEDESTROYMENUDESCRIPTOR
|
||||
43 stub OPENORCREATESTREAM
|
||||
44 stub CREATEANTIMONIKER
|
||||
45 stub CREATEPOINTERMONIKER
|
||||
46 stub MONIKERRELATIVEPATHTO
|
||||
47 stub MONIKERCOMMONPREFIXWITH
|
||||
48 stub ISACCELERATOR
|
||||
49 pascal OleSetClipboard(ptr) OleSetClipboard16
|
||||
50 pascal OleGetClipboard(ptr) OleGetClipboard16
|
||||
51 stub OLEDUPLICATEDATA
|
||||
52 stub OLEGETICONOFFILE
|
||||
53 stub OLEGETICONOFCLASS
|
||||
54 pascal CreateILockBytesOnHGlobal(word word ptr) CreateILockBytesOnHGlobal16
|
||||
55 stub GETHGLOBALFROMILOCKBYTES
|
||||
56 pascal -ret16 OleMetaFilePictFromIconAndLabel(word str str word) OleMetaFilePictFromIconAndLabel16
|
||||
57 stub GETCLASSFILE
|
||||
58 stub OLEDRAW
|
||||
59 stub OLECREATEDEFAULTHANDLER
|
||||
60 stub OLECREATEEMBEDDINGHELPER
|
||||
61 stub OLECONVERTISTORAGETOOLESTREAMEX
|
||||
62 stub OLECONVERTOLESTREAMTOISTORAGEEX
|
||||
63 stub SETDOCUMENTBITSTG
|
||||
64 stub GETDOCUMENTBITSTG
|
||||
65 stub WRITEOLESTG
|
||||
66 stub READOLESTG
|
||||
67 stub OLECREATEFROMFILE
|
||||
68 stub OLECREATELINKTOFILE
|
||||
69 stub CREATEDATACACHE
|
||||
70 stub OLECONVERTISTORAGETOOLESTREAM
|
||||
71 stub OLECONVERTOLESTREAMTOISTORAGE
|
||||
74 stub READFMTUSERTYPESTG
|
||||
75 stub WRITEFMTUSERTYPESTG
|
||||
76 pascal -ret16 OleFlushClipboard() OleFlushClipboard16
|
||||
77 stub OLEISCURRENTCLIPBOARD
|
||||
78 stub OLETRANSLATEACCELERATOR
|
||||
79 stub OLEDOAUTOCONVERT
|
||||
80 stub OLEGETAUTOCONVERT
|
||||
81 stub OLESETAUTOCONVERT
|
||||
82 stub GETCONVERTSTG
|
||||
83 stub SETCONVERTSTG
|
||||
84 stub CREATESTREAMONHGLOBAL
|
||||
85 stub GETHGLOBALFROMSTREAM
|
||||
86 stub OLESETCONTAINEDOBJECT
|
||||
87 stub OLENOTEOBJECTVISIBLE
|
||||
88 stub OLECREATESTATICFROMDATA
|
||||
89 stub OLEREGGETUSERTYPE
|
||||
90 stub OLEREGGETMISCSTATUS
|
||||
91 stub OLEREGENUMFORMATETC
|
||||
92 stub OLEREGENUMVERBS
|
||||
93 stub OLEGETENUMFORMATETC
|
||||
100 stub MAKEDEBUGSTREAM
|
||||
104 stub DBGLOGOPEN
|
||||
105 stub DBGLOGCLOSE
|
||||
106 stub DBGLOGOUTPUTDEBUGSTRING
|
||||
107 stub DBGLOGWRITE
|
||||
108 stub DBGLOGTIMESTAMP
|
||||
109 stub DBGLOGWRITEBANNER
|
||||
110 stub DBGDUMPOBJECT
|
||||
111 stub DBGISOBJECTVALID
|
||||
112 stub DUMPALLOBJECTS
|
||||
113 stub VALIDATEALLOBJECTS
|
||||
114 stub DBGDUMPCLASSNAME
|
||||
115 stub DBGDUMPEXTERNALOBJECT
|
||||
120 stub _IID_IENUMUNKNOWN
|
||||
121 stub _IID_IENUMSTRING
|
||||
122 stub _IID_IENUMMONIKER
|
||||
123 stub _IID_IENUMFORMATETC
|
||||
124 stub _IID_IENUMOLEVERB
|
||||
125 stub _IID_IENUMSTATDATA
|
||||
126 stub _IID_IENUMGENERIC
|
||||
127 stub _IID_IENUMHOLDER
|
||||
128 stub _IID_IENUMCALLBACK
|
||||
129 stub _IID_IPERSISTSTREAM
|
||||
130 stub _IID_IPERSISTSTORAGE
|
||||
131 stub _IID_IPERSISTFILE
|
||||
132 stub _IID_IPERSIST
|
||||
133 stub _IID_IVIEWOBJECT
|
||||
134 stub _IID_IDATAOBJECT
|
||||
135 stub _IID_IADVISESINK
|
||||
136 stub _IID_IDATAADVISEHOLDER
|
||||
137 stub _IID_IOLEADVISEHOLDER
|
||||
138 stub _IID_IOLEOBJECT
|
||||
139 stub _IID_IOLEINPLACEOBJECT
|
||||
140 stub _IID_IOLEWINDOW
|
||||
141 stub _IID_IOLEINPLACEUIWINDOW
|
||||
142 stub _IID_IOLEINPLACEFRAME
|
||||
143 stub _IID_IOLEINPLACEACTIVEOBJECT
|
||||
144 stub _IID_IOLECLIENTSITE
|
||||
145 stub _IID_IOLEINPLACESITE
|
||||
146 stub _IID_IPARSEDISPLAYNAME
|
||||
147 stub _IID_IOLECONTAINER
|
||||
148 stub _IID_IOLEITEMCONTAINER
|
||||
149 stub _IID_IOLELINK
|
||||
150 stub _IID_IOLECACHE
|
||||
151 stub _IID_IOLEMANAGER
|
||||
152 stub _IID_IOLEPRESOBJ
|
||||
153 stub _IID_IDROPSOURCE
|
||||
154 stub _IID_IDROPTARGET
|
||||
155 stub _IID_IDEBUG
|
||||
156 stub _IID_IDEBUGSTREAM
|
||||
157 stub _IID_IADVISESINK2
|
||||
158 stub _IID_IVIEWOBJECT2
|
||||
159 stub _IID_IOLECACHE2
|
||||
160 stub _IID_IOLECACHECONTROL
|
||||
161 stub _IID_IRUNNABLEOBJECT
|
||||
|
||||
# WINE MemLockBytes implementation.
|
||||
500 cdecl HGLOBALLockBytesImpl16_QueryInterface(segptr ptr ptr) HGLOBALLockBytesImpl16_QueryInterface
|
||||
501 cdecl HGLOBALLockBytesImpl16_AddRef(ptr) HGLOBALLockBytesImpl16_AddRef
|
||||
502 cdecl HGLOBALLockBytesImpl16_Release(ptr) HGLOBALLockBytesImpl16_Release
|
||||
503 cdecl HGLOBALLockBytesImpl16_ReadAt(ptr long long ptr long ptr) HGLOBALLockBytesImpl16_ReadAt
|
||||
504 cdecl HGLOBALLockBytesImpl16_WriteAt(ptr long long ptr long ptr) HGLOBALLockBytesImpl16_WriteAt
|
||||
505 cdecl HGLOBALLockBytesImpl16_Flush(ptr) HGLOBALLockBytesImpl16_Flush
|
||||
506 cdecl HGLOBALLockBytesImpl16_SetSize(ptr long long) HGLOBALLockBytesImpl16_SetSize
|
||||
507 cdecl HGLOBALLockBytesImpl16_LockRegion(ptr long long long long long) HGLOBALLockBytesImpl16_LockRegion
|
||||
508 cdecl HGLOBALLockBytesImpl16_UnlockRegion(ptr long long long long long) HGLOBALLockBytesImpl16_UnlockRegion
|
||||
509 cdecl HGLOBALLockBytesImpl16_Stat(ptr ptr long) HGLOBALLockBytesImpl16_Stat
|
||||
@@ -1,144 +0,0 @@
|
||||
|
||||
/*
|
||||
* OLE2 library - 16 bit only interfaces
|
||||
*
|
||||
* Copyright 1995 Martin von Loewis
|
||||
* Copyright 1999 Francis Beaudet
|
||||
* Copyright 1999 Noel Borthwick
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "commctrl.h"
|
||||
#include "ole2.h"
|
||||
#include "ole2ver.h"
|
||||
#include "winerror.h"
|
||||
#include "wownt32.h"
|
||||
|
||||
#include "wine/winbase16.h"
|
||||
#include "wine/wingdi16.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "ole32_main.h"
|
||||
#include "ifs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(accel);
|
||||
|
||||
#define HICON_16(h32) (LOWORD(h32))
|
||||
#define HICON_32(h16) ((HICON)(ULONG_PTR)(h16))
|
||||
#define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16))
|
||||
|
||||
/***********************************************************************
|
||||
* RegisterDragDrop (OLE2.35)
|
||||
*/
|
||||
HRESULT WINAPI RegisterDragDrop16(
|
||||
HWND16 hwnd,
|
||||
LPDROPTARGET pDropTarget
|
||||
) {
|
||||
FIXME("(0x%04x,%p),stub!\n",hwnd,pDropTarget);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RevokeDragDrop (OLE2.36)
|
||||
*/
|
||||
HRESULT WINAPI RevokeDragDrop16(
|
||||
HWND16 hwnd
|
||||
) {
|
||||
FIXME("(0x%04x),stub!\n",hwnd);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleMetaFilePictFromIconAndLabel (OLE2.56)
|
||||
*
|
||||
* Returns a global memory handle to a metafile which contains the icon and
|
||||
* label given.
|
||||
* I guess the result of that should look somehow like desktop icons.
|
||||
* If no hIcon is given, we load the icon via lpszSourceFile and iIconIndex.
|
||||
* This code might be wrong at some places.
|
||||
*/
|
||||
HGLOBAL16 WINAPI OleMetaFilePictFromIconAndLabel16(
|
||||
HICON16 hIcon,
|
||||
LPCOLESTR16 lpszLabel,
|
||||
LPCOLESTR16 lpszSourceFile,
|
||||
UINT16 iIconIndex
|
||||
) {
|
||||
METAFILEPICT16 *mf;
|
||||
HGLOBAL16 hmf;
|
||||
HDC hdc;
|
||||
|
||||
FIXME("(%04x, '%s', '%s', %d): incorrect metrics, please try to correct them !\n\n\n", hIcon, lpszLabel, lpszSourceFile, iIconIndex);
|
||||
|
||||
if (!hIcon) {
|
||||
if (lpszSourceFile) {
|
||||
HINSTANCE16 hInstance = LoadLibrary16(lpszSourceFile);
|
||||
|
||||
/* load the icon at index from lpszSourceFile */
|
||||
hIcon = HICON_16(LoadIconA(HINSTANCE_32(hInstance), (LPCSTR)(DWORD)iIconIndex));
|
||||
FreeLibrary16(hInstance);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdc = CreateMetaFileA(NULL);
|
||||
DrawIcon(hdc, 0, 0, HICON_32(hIcon)); /* FIXME */
|
||||
TextOutA(hdc, 0, 0, lpszLabel, 1); /* FIXME */
|
||||
hmf = GlobalAlloc16(0, sizeof(METAFILEPICT16));
|
||||
mf = (METAFILEPICT16 *)GlobalLock16(hmf);
|
||||
mf->mm = MM_ANISOTROPIC;
|
||||
mf->xExt = 20; /* FIXME: bogus */
|
||||
mf->yExt = 20; /* dito */
|
||||
mf->hMF = CloseMetaFile16(HDC_16(hdc));
|
||||
return hmf;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* CreateItemMoniker (OLE2.27)
|
||||
*/
|
||||
HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR16 lpszItem,LPMONIKER* ppmk)
|
||||
{
|
||||
FIXME("(%s,%p),stub!\n",lpszDelim,ppmk);
|
||||
*ppmk = NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* CreateFileMoniker (OLE2.28)
|
||||
*/
|
||||
HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName,LPMONIKER* ppmk)
|
||||
{
|
||||
FIXME("(%s,%p),stub!\n",lpszPathName,ppmk);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
1 stub GETFILTERINFO
|
||||
2 stub IMPORTGR
|
||||
3 stub GETFILTERPREF
|
||||
4 stub IMPORTEMBEDDEDGR
|
||||
5 stub QD2GDI
|
||||
6 stub STATUSPROC
|
||||
7 stub ENUMFONTFUNC
|
||||
#8 WEP
|
||||
#9 ___EXPORTEDSTUB
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Ole 2 Create functions implementation
|
||||
*
|
||||
* Copyright (C) 1999-2000 Abey George
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ole2.h"
|
||||
#include "olestd.h"
|
||||
#include "winreg.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
#define MAX_CLIPFORMAT_NAME 80
|
||||
|
||||
/******************************************************************************
|
||||
* OleQueryCreateFromData [OLE32.@]
|
||||
*
|
||||
* Author : Abey George
|
||||
* Checks whether an object can become an embedded object.
|
||||
* the clipboard or OLE drag and drop.
|
||||
* Returns : S_OK - Format that supports Embedded object creation are present.
|
||||
* OLE_E_STATIC - Format that supports static object creation are present.
|
||||
* S_FALSE - No acceptable format is available.
|
||||
*/
|
||||
|
||||
HRESULT WINAPI OleQueryCreateFromData(LPDATAOBJECT pSrcDataObject)
|
||||
{
|
||||
IEnumFORMATETC *pfmt;
|
||||
FORMATETC fmt;
|
||||
CHAR szFmtName[MAX_CLIPFORMAT_NAME];
|
||||
BOOL bFoundStatic = FALSE;
|
||||
|
||||
HRESULT hr = IDataObject_EnumFormatEtc(pSrcDataObject, DATADIR_GET, &pfmt);
|
||||
|
||||
if (hr == S_OK)
|
||||
hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
|
||||
|
||||
while (hr == S_OK)
|
||||
{
|
||||
GetClipboardFormatNameA(fmt.cfFormat, szFmtName, MAX_CLIPFORMAT_NAME-1);
|
||||
|
||||
/* first, Check for Embedded Object, Embed Source or Filename */
|
||||
|
||||
if (!strcmp(szFmtName, CF_EMBEDDEDOBJECT) || !strcmp(szFmtName, CF_EMBEDSOURCE) || !strcmp(szFmtName, CF_FILENAME))
|
||||
return S_OK;
|
||||
|
||||
/* Check for Metafile, Bitmap or DIB */
|
||||
|
||||
if (fmt.cfFormat == CF_METAFILEPICT || fmt.cfFormat == CF_BITMAP || fmt.cfFormat == CF_DIB)
|
||||
bFoundStatic = TRUE;
|
||||
|
||||
hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
|
||||
}
|
||||
|
||||
/* Found a static format, but no embed format */
|
||||
|
||||
if (bFoundStatic)
|
||||
return OLE_S_STATIC;
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleCreateFromData [OLE32.@]
|
||||
*
|
||||
* Author : Abey George
|
||||
* Creates an embedded object from data transfer object retrieved from
|
||||
* the clipboard or OLE drag and drop.
|
||||
* Returns : S_OK - Embedded object was created successfully.
|
||||
* OLE_E_STATIC - OLE can create only a static object
|
||||
* DV_E_FORMATETC - No acceptable format is available (only error return code)
|
||||
* TODO : CF_FILENAME, CF_EMBEDEDOBJECT formats. Parameter renderopt is currently ignored.
|
||||
*/
|
||||
|
||||
HRESULT WINAPI OleCreateFromData(LPDATAOBJECT pSrcDataObject, REFIID riid,
|
||||
DWORD renderopt, LPFORMATETC pFormatEtc,
|
||||
LPOLECLIENTSITE pClientSite, LPSTORAGE pStg,
|
||||
LPVOID* ppvObj)
|
||||
{
|
||||
IEnumFORMATETC *pfmt;
|
||||
FORMATETC fmt;
|
||||
CHAR szFmtName[MAX_CLIPFORMAT_NAME];
|
||||
STGMEDIUM std;
|
||||
HRESULT hr;
|
||||
HRESULT hr1;
|
||||
|
||||
hr = IDataObject_EnumFormatEtc(pSrcDataObject, DATADIR_GET, &pfmt);
|
||||
|
||||
if (hr == S_OK)
|
||||
{
|
||||
memset(&std, 0, sizeof(STGMEDIUM));
|
||||
|
||||
hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
|
||||
while (hr == S_OK)
|
||||
{
|
||||
GetClipboardFormatNameA(fmt.cfFormat, szFmtName, MAX_CLIPFORMAT_NAME-1);
|
||||
|
||||
/* first, Check for Embedded Object, Embed Source or Filename */
|
||||
/* TODO: Currently checks only for Embed Source. */
|
||||
|
||||
if (!strcmp(szFmtName, CF_EMBEDSOURCE))
|
||||
{
|
||||
std.tymed = TYMED_HGLOBAL;
|
||||
|
||||
if ((hr1 = IDataObject_GetData(pSrcDataObject, &fmt, &std)) == S_OK)
|
||||
{
|
||||
ILockBytes *ptrILockBytes = 0;
|
||||
IStorage *pStorage = 0;
|
||||
IOleObject *pOleObject = 0;
|
||||
IPersistStorage *pPersistStorage = 0;
|
||||
CLSID clsID;
|
||||
|
||||
/* Create ILock bytes */
|
||||
|
||||
hr1 = CreateILockBytesOnHGlobal(std.u.hGlobal, FALSE, &ptrILockBytes);
|
||||
|
||||
/* Open storage on the ILock bytes */
|
||||
|
||||
if (hr1 == S_OK)
|
||||
hr1 = StgOpenStorageOnILockBytes(ptrILockBytes, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);
|
||||
|
||||
/* Get Class ID from the opened storage */
|
||||
|
||||
if (hr1 == S_OK)
|
||||
hr1 = ReadClassStg(pStorage, &clsID);
|
||||
|
||||
/* Create default handler for Persist storage */
|
||||
|
||||
if (hr1 == S_OK)
|
||||
hr1 = OleCreateDefaultHandler(&clsID, NULL, &IID_IPersistStorage, (LPVOID*)&pPersistStorage);
|
||||
|
||||
/* Load the storage to Persist storage */
|
||||
|
||||
if (hr1 == S_OK)
|
||||
hr1 = IPersistStorage_Load(pPersistStorage, pStorage);
|
||||
|
||||
/* Query for IOleObject */
|
||||
|
||||
if (hr1 == S_OK)
|
||||
hr1 = IPersistStorage_QueryInterface(pPersistStorage, &IID_IOleObject, (LPVOID*)&pOleObject);
|
||||
|
||||
/* Set client site with the IOleObject */
|
||||
|
||||
if (hr1 == S_OK)
|
||||
hr1 = IOleObject_SetClientSite(pOleObject, pClientSite);
|
||||
|
||||
IPersistStorage_Release(pPersistStorage);
|
||||
/* Query for the requested interface */
|
||||
|
||||
if (hr1 == S_OK)
|
||||
hr1 = IPersistStorage_QueryInterface(pPersistStorage, riid, ppvObj);
|
||||
|
||||
IPersistStorage_Release(pPersistStorage);
|
||||
|
||||
IStorage_Release(pStorage);
|
||||
|
||||
if (hr1 == S_OK)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Return error */
|
||||
|
||||
return DV_E_FORMATETC;
|
||||
}
|
||||
|
||||
hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return DV_E_FORMATETC;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* OleDuplicateData [OLE32.@]
|
||||
*
|
||||
* Duplicates clipboard data.
|
||||
*
|
||||
* PARAMS
|
||||
* hSrc [I] Handle of the source clipboard data.
|
||||
* cfFormat [I] The clipboard format of hSrc.
|
||||
* uiFlags [I] Flags to pass to GlobalAlloc.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: handle to the duplicated data.
|
||||
* Failure: NULL.
|
||||
*/
|
||||
HANDLE WINAPI OleDuplicateData(HANDLE hSrc, CLIPFORMAT cfFormat,
|
||||
UINT uiFlags)
|
||||
{
|
||||
HANDLE hDst = NULL;
|
||||
|
||||
TRACE("(%p,%x,%x)\n", hSrc, cfFormat, uiFlags);
|
||||
|
||||
if (!uiFlags) uiFlags = GMEM_MOVEABLE;
|
||||
|
||||
switch (cfFormat)
|
||||
{
|
||||
case CF_ENHMETAFILE:
|
||||
hDst = CopyEnhMetaFileW(hSrc, NULL);
|
||||
break;
|
||||
case CF_METAFILEPICT:
|
||||
hDst = CopyMetaFileW(hSrc, NULL);
|
||||
break;
|
||||
case CF_PALETTE:
|
||||
{
|
||||
LOGPALETTE * logpalette;
|
||||
UINT nEntries = GetPaletteEntries(hSrc, 0, 0, NULL);
|
||||
if (!nEntries) return NULL;
|
||||
logpalette = HeapAlloc(GetProcessHeap(), 0,
|
||||
FIELD_OFFSET(LOGPALETTE, palPalEntry[nEntries]));
|
||||
if (!logpalette) return NULL;
|
||||
if (!GetPaletteEntries(hSrc, 0, nEntries, logpalette->palPalEntry))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, logpalette);
|
||||
return NULL;
|
||||
}
|
||||
logpalette->palVersion = 0x300;
|
||||
logpalette->palNumEntries = (WORD)nEntries;
|
||||
|
||||
hDst = CreatePalette(logpalette);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, logpalette);
|
||||
break;
|
||||
}
|
||||
case CF_BITMAP:
|
||||
{
|
||||
LONG size;
|
||||
BITMAP bm;
|
||||
if (!GetObjectW(hSrc, sizeof(bm), &bm))
|
||||
return NULL;
|
||||
size = GetBitmapBits(hSrc, 0, NULL);
|
||||
if (!size) return NULL;
|
||||
bm.bmBits = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
if (!bm.bmBits) return NULL;
|
||||
if (!GetBitmapBits(hSrc, size, bm.bmBits))
|
||||
return NULL;
|
||||
hDst = CreateBitmapIndirect(&bm);
|
||||
HeapFree(GetProcessHeap(), 0, bm.bmBits);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
SIZE_T size = GlobalSize(hSrc);
|
||||
LPVOID pvSrc = NULL;
|
||||
LPVOID pvDst = NULL;
|
||||
|
||||
/* allocate space for object */
|
||||
if (!size) return NULL;
|
||||
hDst = GlobalAlloc(uiFlags, size);
|
||||
if (!hDst) return NULL;
|
||||
|
||||
/* lock pointers */
|
||||
pvSrc = GlobalLock(hSrc);
|
||||
if (!pvSrc)
|
||||
{
|
||||
GlobalFree(hDst);
|
||||
return NULL;
|
||||
}
|
||||
pvDst = GlobalLock(hDst);
|
||||
if (!pvDst)
|
||||
{
|
||||
GlobalUnlock(hSrc);
|
||||
GlobalFree(hDst);
|
||||
return NULL;
|
||||
}
|
||||
/* copy data */
|
||||
memcpy(pvDst, pvSrc, size);
|
||||
|
||||
/* cleanup */
|
||||
GlobalUnlock(hDst);
|
||||
GlobalUnlock(hSrc);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("returning %p\n", hDst);
|
||||
return hDst;
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* OLE2NLS library
|
||||
*
|
||||
* Copyright 1995 Martin von Loewis
|
||||
* Copyright 1998 David Lee Lambert
|
||||
* Copyright 2000 Julio César Gázquez
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "winuser.h"
|
||||
#include "winver.h"
|
||||
|
||||
#include "wine/winbase16.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
static LPVOID lpNLSInfo = NULL;
|
||||
|
||||
/******************************************************************************
|
||||
* GetLocaleInfoA [OLE2NLS.5]
|
||||
* Is the last parameter really WORD for Win16?
|
||||
*/
|
||||
INT16 WINAPI GetLocaleInfo16(LCID lcid,LCTYPE LCType,LPSTR buf,INT16 len)
|
||||
{
|
||||
return GetLocaleInfoA(lcid,LCType,buf,len);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetStringTypeA [OLE2NLS.7]
|
||||
*/
|
||||
BOOL16 WINAPI GetStringType16(LCID locale,DWORD dwInfoType,LPCSTR src,
|
||||
INT16 cchSrc,LPWORD chartype)
|
||||
{
|
||||
return GetStringTypeExA(locale,dwInfoType,src,cchSrc,chartype);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetUserDefaultLCID [OLE2NLS.1]
|
||||
*/
|
||||
LCID WINAPI GetUserDefaultLCID16(void)
|
||||
{
|
||||
return GetUserDefaultLCID();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetSystemDefaultLCID [OLE2NLS.2]
|
||||
*/
|
||||
LCID WINAPI GetSystemDefaultLCID16(void)
|
||||
{
|
||||
return GetSystemDefaultLCID();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetUserDefaultLangID [OLE2NLS.3]
|
||||
*/
|
||||
LANGID WINAPI GetUserDefaultLangID16(void)
|
||||
{
|
||||
return GetUserDefaultLangID();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetSystemDefaultLangID [OLE2NLS.4]
|
||||
*/
|
||||
LANGID WINAPI GetSystemDefaultLangID16(void)
|
||||
{
|
||||
return GetSystemDefaultLangID();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* LCMapStringA [OLE2NLS.6]
|
||||
*/
|
||||
INT16 LCMapString16(LCID lcid, DWORD mapflags, LPCSTR srcstr, INT16 srclen,
|
||||
LPSTR dststr, INT16 dstlen)
|
||||
{
|
||||
return LCMapStringA(lcid, mapflags, srcstr, srclen, dststr, dstlen);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CompareStringA (OLE2NLS.8)
|
||||
*/
|
||||
UINT16 WINAPI CompareString16(DWORD lcid,DWORD fdwStyle,
|
||||
LPCSTR s1,DWORD l1,LPCSTR s2,DWORD l2)
|
||||
{
|
||||
return (UINT16)CompareStringA(lcid,fdwStyle,s1,l1,s2,l2);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RegisterNLSInfoChanged [OLE2NLS.9]
|
||||
*/
|
||||
BOOL16 WINAPI RegisterNLSInfoChanged16(LPVOID lpNewNLSInfo) /* [???] FIXME */
|
||||
{
|
||||
FIXME("Fully implemented, but doesn't effect anything.\n");
|
||||
|
||||
if (!lpNewNLSInfo) {
|
||||
lpNLSInfo = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
if (!lpNLSInfo) {
|
||||
lpNLSInfo = lpNewNLSInfo;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; /* ptr not set */
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
1 pascal GetUserDefaultLCID() GetUserDefaultLCID16
|
||||
2 pascal GetSystemDefaultLCID() GetSystemDefaultLCID16
|
||||
3 pascal -ret16 GetUserDefaultLangID() GetUserDefaultLangID16
|
||||
4 pascal -ret16 GetSystemDefaultLangID() GetSystemDefaultLangID16
|
||||
5 pascal GetLocaleInfoA(long long ptr word) GetLocaleInfo16
|
||||
6 pascal -ret16 LCMapStringA(word long ptr word ptr word) LCMapString16
|
||||
7 pascal -ret16 GetStringTypeA(long long str word ptr) GetStringType16
|
||||
8 pascal -ret16 CompareStringA(long long str word str word) CompareString16
|
||||
9 pascal -ret16 RegisterNLSInfoChanged(ptr) RegisterNLSInfoChanged16
|
||||
#10 stub WEP
|
||||
11 stub LIBMAIN
|
||||
12 stub NOTIFYWINDOWPROC
|
||||
@@ -1,3 +0,0 @@
|
||||
1 stub DLLGETCLASSOBJECT
|
||||
#2 WEP
|
||||
#3 ___EXPORTEDSTUB
|
||||
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Temporary place for ole2 stubs.
|
||||
*
|
||||
* Copyright (C) 1999 Corel Corporation
|
||||
* Move these functions to dlls/ole32/ole2impl.c when you implement them.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
#include "objidl.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/******************************************************************************
|
||||
* OleCreateLinkToFile [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OleCreateLinkToFile(LPCOLESTR lpszFileName, REFIID riid,
|
||||
DWORD renderopt, LPFORMATETC lpFormatEtc,
|
||||
LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj)
|
||||
{
|
||||
FIXME("(%p,%p,%li,%p,%p,%p,%p), stub!\n",lpszFileName, riid, renderopt, lpFormatEtc, pClientSite, pStg, ppvObj);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SetConvertStg [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI SetConvertStg(LPSTORAGE pStg, BOOL fConvert)
|
||||
{
|
||||
FIXME("(%p,%x), stub!\n", pStg, fConvert);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleCreateLink [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OleCreateLink(LPMONIKER pmkLinkSrc, REFIID riid, DWORD renderopt, LPFORMATETC lpFormatEtc,
|
||||
LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj)
|
||||
{
|
||||
FIXME("(not shown), stub!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleCreateFromFile [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OleCreateFromFile(REFCLSID rclsid, LPCOLESTR lpszFileName, REFIID riid,
|
||||
DWORD renderopt, LPFORMATETC lpFormatEtc, LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj)
|
||||
{
|
||||
FIXME("(not shown), stub!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* OleGetIconOfClass [OLE32.@]
|
||||
*/
|
||||
HGLOBAL WINAPI OleGetIconOfClass(REFCLSID rclsid, LPOLESTR lpszLabel, BOOL fUseTypeAsLabel)
|
||||
{
|
||||
FIXME("(%p,%p,%x), stub!\n", rclsid, lpszLabel, fUseTypeAsLabel);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* OleCreateStaticFromData [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OleCreateStaticFromData(LPDATAOBJECT pSrcDataObj, REFIID iid,
|
||||
DWORD renderopt, LPFORMATETC pFormatEtc, LPOLECLIENTSITE pClientSite,
|
||||
LPSTORAGE pStg, LPVOID* ppvObj)
|
||||
{
|
||||
FIXME("(not shown), stub!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleCreateLinkFromData [OLE32.@]
|
||||
*/
|
||||
|
||||
HRESULT WINAPI OleCreateLinkFromData(LPDATAOBJECT pSrcDataObj, REFIID riid,
|
||||
DWORD renderopt, LPFORMATETC pFormatEtc,
|
||||
LPOLECLIENTSITE pClientSite, LPSTORAGE pStg,
|
||||
LPVOID* ppvObj)
|
||||
{
|
||||
FIXME("(not shown), stub!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleIsRunning [OLE32.@]
|
||||
*/
|
||||
BOOL WINAPI OleIsRunning(LPOLEOBJECT pObject)
|
||||
{
|
||||
FIXME("(%p), stub!\n", pObject);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleRegEnumVerbs [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum)
|
||||
{
|
||||
FIXME("(%p,%p), stub!\n", clsid, ppenum);
|
||||
return OLEOBJ_E_NOVERBS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleRegEnumFormatEtc [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OleRegEnumFormatEtc (
|
||||
REFCLSID clsid,
|
||||
DWORD dwDirection,
|
||||
LPENUMFORMATETC* ppenumFormatetc)
|
||||
{
|
||||
FIXME("(%p, %ld, %p), stub!\n", clsid, dwDirection, ppenumFormatetc);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoIsOle1Class [OLE32.@]
|
||||
*/
|
||||
BOOL WINAPI CoIsOle1Class(REFCLSID clsid)
|
||||
{
|
||||
FIXME("%s\n", debugstr_guid(clsid));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllGetClassObject [OLE2.4]
|
||||
*/
|
||||
HRESULT WINAPI DllGetClassObject16(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
||||
{
|
||||
FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleSetClipboard [OLE2.49]
|
||||
*/
|
||||
HRESULT WINAPI OleSetClipboard16(IDataObject* pDataObj)
|
||||
{
|
||||
FIXME("(%p): stub\n", pDataObj);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleGetClipboard [OLE2.50]
|
||||
*/
|
||||
HRESULT WINAPI OleGetClipboard16(IDataObject** ppDataObj)
|
||||
{
|
||||
FIXME("(%p): stub\n", ppDataObj);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
1 stub WEP
|
||||
2 stub ROT16_ISRUNNING16
|
||||
3 stub ISWIN32SHANDLE
|
||||
4 stub ___EXPORTEDSTUB
|
||||
5 stub COTHKCOMMON
|
||||
6 stub ROT16_GETTIMEOFLASTCHANGE16
|
||||
7 stub ROT16_GETOBJECT16
|
||||
@@ -1,266 +0,0 @@
|
||||
@ stdcall BindMoniker(ptr long ptr ptr)
|
||||
@ stub CLIPFORMAT_UserFree
|
||||
@ stub CLIPFORMAT_UserMarshal
|
||||
@ stub CLIPFORMAT_UserSize
|
||||
@ stub CLIPFORMAT_UserUnmarshal
|
||||
@ stdcall CLSIDFromProgID(wstr ptr)
|
||||
@ stdcall CLSIDFromString(wstr ptr)
|
||||
@ stdcall CoAddRefServerProcess()
|
||||
@ stdcall CoBuildVersion()
|
||||
@ stub CoCopyProxy #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr)
|
||||
@ stdcall CoCreateGuid(ptr)
|
||||
@ stdcall CoCreateInstance(ptr ptr long ptr ptr)
|
||||
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr)
|
||||
@ stdcall CoDisconnectObject(ptr long)
|
||||
@ stdcall CoDosDateTimeToFileTime(long long ptr) kernel32.DosDateTimeToFileTime
|
||||
@ stdcall CoFileTimeNow(ptr)
|
||||
@ stdcall CoFileTimeToDosDateTime(ptr ptr ptr) kernel32.FileTimeToDosDateTime
|
||||
@ stdcall CoFreeAllLibraries()
|
||||
@ stdcall CoFreeLibrary(long)
|
||||
@ stdcall CoFreeUnusedLibraries()
|
||||
@ stub CoGetCallContext #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stub CoGetCallerTID
|
||||
@ stdcall CoGetClassObject(ptr long ptr ptr ptr)
|
||||
@ stub CoGetCurrentLogicalThreadId
|
||||
@ stdcall CoGetCurrentProcess()
|
||||
@ stub CoGetInstanceFromFile #@ stdcall (ptr ptr ptr long wstr long ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stub CoGetInstanceFromIStorage #@ stdcall (ptr ptr ptr long ptr long ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr)
|
||||
@ stdcall CoGetMalloc(long ptr)
|
||||
@ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long)
|
||||
@ stub CoGetObject
|
||||
@ stdcall CoGetPSClsid(ptr ptr)
|
||||
@ stdcall CoGetStandardMarshal(ptr ptr long ptr long ptr)
|
||||
@ stdcall CoGetState(ptr)
|
||||
@ stub CoGetTIDFromIPID
|
||||
@ stdcall CoGetTreatAsClass(ptr ptr)
|
||||
@ stub CoImpersonateClient
|
||||
@ stdcall CoInitialize(ptr)
|
||||
@ stdcall CoInitializeEx(ptr long)
|
||||
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
|
||||
@ stdcall CoInitializeWOW(long long)
|
||||
@ stub CoIsHandlerConnected #@ stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CoIsOle1Class (ptr)
|
||||
@ stdcall CoLoadLibrary(wstr long)
|
||||
@ stdcall CoLockObjectExternal(ptr long long)
|
||||
@ stdcall CoMarshalHresult(ptr long)
|
||||
@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr)
|
||||
@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long)
|
||||
@ stub CoQueryAuthenticationServices
|
||||
@ stub CoQueryClientBlanket
|
||||
@ stub CoQueryProxyBlanket
|
||||
@ stub CoQueryReleaseObject
|
||||
@ stub CoRegisterChannelHook
|
||||
@ stdcall CoRegisterClassObject(ptr ptr long long ptr)
|
||||
@ stdcall CoRegisterMallocSpy (ptr)
|
||||
@ stdcall CoRegisterMessageFilter(ptr ptr)
|
||||
@ stub CoRegisterPSClsid #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stub CoRegisterSurrogate
|
||||
@ stdcall CoReleaseMarshalData(ptr)
|
||||
@ stdcall CoReleaseServerProcess()
|
||||
@ stdcall CoResumeClassObjects()
|
||||
@ stub CoRevertToSelf #@ stdcall () return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CoRevokeClassObject(long)
|
||||
@ stdcall CoRevokeMallocSpy()
|
||||
@ stub CoSetProxyBlanket #@ stdcall (ptr long long wstr long long ptr long) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CoSetState(ptr)
|
||||
@ stub CoSwitchCallContext
|
||||
@ stdcall CoSuspendClassObjects()
|
||||
@ stdcall CoTaskMemAlloc(long)
|
||||
@ stdcall CoTaskMemFree(ptr)
|
||||
@ stdcall CoTaskMemRealloc(ptr long)
|
||||
@ stdcall CoTreatAsClass(ptr ptr)
|
||||
@ stdcall CoUninitialize()
|
||||
@ stub CoUnloadingWOW
|
||||
@ stdcall CoUnmarshalHresult(ptr ptr)
|
||||
@ stdcall CoUnmarshalInterface(ptr ptr ptr)
|
||||
@ stdcall CreateAntiMoniker(ptr)
|
||||
@ stdcall CreateBindCtx(long ptr)
|
||||
@ stdcall CreateClassMoniker(ptr ptr)
|
||||
@ stdcall CreateDataAdviseHolder(ptr)
|
||||
@ stdcall CreateDataCache(ptr ptr ptr ptr)
|
||||
@ stdcall CreateErrorInfo(ptr)
|
||||
@ stdcall CreateFileMoniker(wstr ptr)
|
||||
@ stdcall CreateGenericComposite(ptr ptr ptr)
|
||||
@ stdcall CreateILockBytesOnHGlobal(ptr long ptr)
|
||||
@ stdcall CreateItemMoniker(wstr wstr ptr)
|
||||
@ stub CreateObjrefMoniker
|
||||
@ stdcall CreateOleAdviseHolder(ptr)
|
||||
@ stub CreatePointerMoniker #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CreateStreamOnHGlobal(ptr long ptr)
|
||||
@ stdcall DllDebugObjectRPCHook(long ptr)
|
||||
@ stdcall -private DllGetClassObject (ptr ptr ptr) OLE32_DllGetClassObject
|
||||
@ stub DllGetClassObjectWOW
|
||||
@ stdcall -private DllRegisterServer() OLE32_DllRegisterServer
|
||||
@ stdcall -private DllUnregisterServer() OLE32_DllUnregisterServer
|
||||
@ stdcall DoDragDrop(ptr ptr long ptr)
|
||||
@ stub EnableHookObject
|
||||
@ stdcall FreePropVariantArray(long ptr)
|
||||
@ stdcall GetClassFile(wstr ptr)
|
||||
@ stdcall GetConvertStg(ptr)
|
||||
@ stub GetDocumentBitStg
|
||||
@ stdcall GetErrorInfo(long ptr)
|
||||
@ stdcall GetHGlobalFromILockBytes(ptr ptr)
|
||||
@ stdcall GetHGlobalFromStream(ptr ptr)
|
||||
@ stub GetHookInterface
|
||||
@ stdcall GetRunningObjectTable(long ptr)
|
||||
@ stub HACCEL_UserFree
|
||||
@ stub HACCEL_UserMarshal
|
||||
@ stub HACCEL_UserSize
|
||||
@ stub HACCEL_UserUnmarshal
|
||||
@ stub HBITMAP_UserFree
|
||||
@ stub HBITMAP_UserMarshal
|
||||
@ stub HBITMAP_UserSize
|
||||
@ stub HBITMAP_UserUnmarshal
|
||||
@ stub HBRUSH_UserFree
|
||||
@ stub HBRUSH_UserMarshal
|
||||
@ stub HBRUSH_UserSize
|
||||
@ stub HBRUSH_UserUnmarshal
|
||||
@ stub HENHMETAFILE_UserFree
|
||||
@ stub HENHMETAFILE_UserMarshal
|
||||
@ stub HENHMETAFILE_UserSize
|
||||
@ stub HENHMETAFILE_UserUnmarshal
|
||||
@ stub HGLOBAL_UserFree
|
||||
@ stub HGLOBAL_UserMarshal
|
||||
@ stub HGLOBAL_UserSize
|
||||
@ stub HGLOBAL_UserUnmarshal
|
||||
@ stub HMENU_UserFree
|
||||
@ stub HMENU_UserMarshal
|
||||
@ stub HMENU_UserSize
|
||||
@ stub HMENU_UserUnmarshal
|
||||
@ stub HMETAFILEPICT_UserFree
|
||||
@ stub HMETAFILEPICT_UserMarshal
|
||||
@ stub HMETAFILEPICT_UserSize
|
||||
@ stub HMETAFILEPICT_UserUnmarshal
|
||||
@ stub HMETAFILE_UserFree
|
||||
@ stub HMETAFILE_UserMarshal
|
||||
@ stub HMETAFILE_UserSize
|
||||
@ stub HMETAFILE_UserUnmarshal
|
||||
@ stub HPALETTE_UserFree
|
||||
@ stub HPALETTE_UserMarshal
|
||||
@ stub HPALETTE_UserSize
|
||||
@ stub HPALETTE_UserUnmarshal
|
||||
@ stub HWND_UserFree
|
||||
@ stub HWND_UserMarshal
|
||||
@ stub HWND_UserSize
|
||||
@ stub HWND_UserUnmarshal
|
||||
@ stub I_RemoteMain
|
||||
@ stdcall IIDFromString(wstr ptr) CLSIDFromString
|
||||
@ stdcall IsAccelerator(long long ptr long)
|
||||
@ stdcall IsEqualGUID(ptr ptr)
|
||||
@ stub IsValidIid
|
||||
@ stdcall IsValidInterface(ptr)
|
||||
@ stub IsValidPtrIn
|
||||
@ stub IsValidPtrOut
|
||||
@ stdcall MkParseDisplayName(ptr ptr ptr ptr)
|
||||
@ stdcall MonikerCommonPrefixWith(ptr ptr ptr)
|
||||
@ stub MonikerRelativePathTo
|
||||
@ stdcall OleBuildVersion()
|
||||
@ stdcall OleConvertIStorageToOLESTREAM(ptr ptr)
|
||||
@ stub OleConvertIStorageToOLESTREAMEx
|
||||
@ stdcall OleConvertOLESTREAMToIStorage(ptr ptr ptr)
|
||||
@ stub OleConvertOLESTREAMToIStorageEx
|
||||
@ stdcall OleCreate(ptr ptr long ptr ptr ptr ptr)
|
||||
@ stdcall OleCreateDefaultHandler(ptr ptr ptr ptr)
|
||||
@ stub OleCreateEmbeddingHelper
|
||||
@ stub OleCreateEx
|
||||
@ stdcall OleCreateFromData(ptr ptr long ptr ptr ptr ptr)
|
||||
@ stub OleCreateFromDataEx
|
||||
@ stdcall OleCreateFromFile(ptr ptr ptr long ptr ptr ptr ptr)
|
||||
@ stub OleCreateFromFileEx
|
||||
@ stdcall OleCreateLink(ptr ptr long ptr ptr ptr ptr)
|
||||
@ stub OleCreateLinkEx
|
||||
@ stdcall OleCreateLinkFromData(ptr ptr long ptr ptr ptr ptr)
|
||||
@ stub OleCreateLinkFromDataEx
|
||||
@ stdcall OleCreateLinkToFile(ptr ptr long ptr ptr ptr ptr)
|
||||
@ stub OleCreateLinkToFileEx
|
||||
@ stdcall OleCreateMenuDescriptor(long ptr)
|
||||
@ stdcall OleCreateStaticFromData(ptr ptr long ptr ptr ptr ptr)
|
||||
@ stdcall OleDestroyMenuDescriptor(long)
|
||||
@ stdcall OleDoAutoConvert(ptr ptr)
|
||||
@ stdcall OleDraw(ptr long long ptr)
|
||||
@ stdcall OleDuplicateData(long long long)
|
||||
@ stdcall OleFlushClipboard()
|
||||
@ stdcall OleGetAutoConvert(ptr ptr)
|
||||
@ stdcall OleGetClipboard(ptr)
|
||||
@ stdcall OleGetIconOfClass(ptr ptr long)
|
||||
@ stub OleGetIconOfFile
|
||||
@ stdcall OleInitialize(ptr)
|
||||
@ stdcall OleInitializeWOW(long)
|
||||
@ stdcall OleIsCurrentClipboard(ptr)
|
||||
@ stdcall OleIsRunning(ptr)
|
||||
@ stdcall OleLoad(ptr ptr ptr ptr)
|
||||
@ stdcall OleLoadFromStream(ptr ptr ptr)
|
||||
@ stdcall OleLockRunning(ptr long long)
|
||||
@ stdcall OleMetafilePictFromIconAndLabel(long ptr ptr long)
|
||||
@ stub OleNoteObjectVisible
|
||||
@ stdcall OleQueryCreateFromData(ptr)
|
||||
@ stdcall OleQueryLinkFromData(ptr)
|
||||
@ stdcall OleRegEnumFormatEtc(ptr long ptr)
|
||||
@ stdcall OleRegEnumVerbs(long ptr)
|
||||
@ stdcall OleRegGetMiscStatus(ptr long ptr)
|
||||
@ stdcall OleRegGetUserType(long long ptr)
|
||||
@ stdcall OleRun(ptr)
|
||||
@ stdcall OleSave(ptr ptr long)
|
||||
@ stdcall OleSaveToStream(ptr ptr)
|
||||
@ stdcall OleSetAutoConvert(ptr ptr)
|
||||
@ stdcall OleSetClipboard(ptr)
|
||||
@ stdcall OleSetContainedObject(ptr long)
|
||||
@ stdcall OleSetMenuDescriptor(long long long ptr ptr)
|
||||
@ stdcall OleTranslateAccelerator(ptr ptr ptr)
|
||||
@ stdcall OleUninitialize()
|
||||
@ stub OpenOrCreateStream
|
||||
@ stdcall ProgIDFromCLSID(ptr ptr)
|
||||
@ stub PropSysAllocString
|
||||
@ stub PropSysFreeString
|
||||
@ stdcall PropVariantClear(ptr)
|
||||
@ stdcall PropVariantCopy(ptr ptr)
|
||||
@ stdcall ReadClassStg(ptr ptr)
|
||||
@ stdcall ReadClassStm(ptr ptr)
|
||||
@ stdcall ReadFmtUserTypeStg(ptr ptr ptr)
|
||||
@ stub ReadOleStg
|
||||
@ stub ReadStringStream
|
||||
@ stdcall RegisterDragDrop(long ptr)
|
||||
@ stdcall ReleaseStgMedium(ptr)
|
||||
@ stdcall RevokeDragDrop(long)
|
||||
@ stdcall SetConvertStg(ptr long)
|
||||
@ stub SetDocumentBitStg
|
||||
@ stdcall SetErrorInfo(long ptr)
|
||||
@ stub SNB_UserFree
|
||||
@ stub SNB_UserMarshal
|
||||
@ stub SNB_UserSize
|
||||
@ stub SNB_UserUnmarshal
|
||||
@ stdcall StgCreateDocfile(wstr long long ptr)
|
||||
@ stdcall StgCreateDocfileOnILockBytes(ptr long long ptr)
|
||||
@ stdcall StgCreateStorageEx(wstr long long long ptr ptr ptr ptr)
|
||||
@ stub StgGetIFillLockBytesOnFile
|
||||
@ stub StgGetIFillLockBytesOnILockBytes
|
||||
@ stdcall StgIsStorageFile(wstr)
|
||||
@ stdcall StgIsStorageILockBytes(ptr)
|
||||
@ stub STGMEDIUM_UserFree
|
||||
@ stub STGMEDIUM_UserMarshal
|
||||
@ stub STGMEDIUM_UserSize
|
||||
@ stub STGMEDIUM_UserUnmarshal
|
||||
@ stub StgOpenAsyncDocfileOnIFillLockBytes
|
||||
@ stdcall StgOpenStorage(wstr ptr long ptr long ptr)
|
||||
@ stub StgOpenStorageEx
|
||||
@ stdcall StgOpenStorageOnILockBytes(ptr ptr long long long ptr)
|
||||
@ stdcall StgSetTimes(wstr ptr ptr ptr )
|
||||
@ stdcall StringFromCLSID(ptr ptr)
|
||||
@ stdcall StringFromGUID2(ptr ptr long)
|
||||
@ stdcall StringFromIID(ptr ptr) StringFromCLSID
|
||||
@ stub UpdateDCOMSettings
|
||||
@ stub UtConvertDvtd16toDvtd32
|
||||
@ stub UtConvertDvtd32toDvtd16
|
||||
@ stub UtGetDvtd16Info
|
||||
@ stub UtGetDvtd32Info
|
||||
@ stub WdtpInterfacePointer_UserFree
|
||||
@ stub WdtpInterfacePointer_UserMarshal
|
||||
@ stub WdtpInterfacePointer_UserSize
|
||||
@ stub WdtpInterfacePointer_UserUnmarshal
|
||||
@ stdcall WriteClassStg(ptr ptr)
|
||||
@ stdcall WriteClassStm(ptr ptr)
|
||||
@ stdcall WriteFmtUserTypeStg(ptr long ptr)
|
||||
@ stub WriteOleStg
|
||||
@ stub WriteStringStream
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* OLE32 Initialization
|
||||
*
|
||||
* Copyright 2000 Huw D M Davies for CodeWeavers
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winerror.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "ole32_main.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
HINSTANCE OLE32_hInstance = 0;
|
||||
|
||||
/***********************************************************************
|
||||
* OleMetafilePictFromIconAndLabel (OLE32.@)
|
||||
*/
|
||||
HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
|
||||
LPOLESTR lpszSourceFile, UINT iIconIndex)
|
||||
{
|
||||
METAFILEPICT mfp;
|
||||
HDC hdc;
|
||||
UINT dy;
|
||||
HGLOBAL hmem = NULL;
|
||||
LPVOID mfdata;
|
||||
static const char szIconOnly[] = "IconOnly";
|
||||
|
||||
TRACE("%p %p %s %d\n", hIcon, lpszLabel, debugstr_w(lpszSourceFile), iIconIndex);
|
||||
|
||||
if( !hIcon )
|
||||
return NULL;
|
||||
|
||||
hdc = CreateMetaFileW(NULL);
|
||||
if( !hdc )
|
||||
return NULL;
|
||||
|
||||
ExtEscape(hdc, MFCOMMENT, sizeof(szIconOnly), szIconOnly, 0, NULL);
|
||||
|
||||
/* FIXME: things are drawn in the wrong place */
|
||||
DrawIcon(hdc, 0, 0, hIcon);
|
||||
dy = GetSystemMetrics(SM_CXICON);
|
||||
if(lpszLabel)
|
||||
TextOutW(hdc, 0, dy, lpszLabel, lstrlenW(lpszLabel));
|
||||
|
||||
if (lpszSourceFile)
|
||||
{
|
||||
char szIconIndex[10];
|
||||
int path_length = WideCharToMultiByte(CP_ACP,0,lpszSourceFile,-1,NULL,0,NULL,NULL);
|
||||
if (path_length > 1)
|
||||
{
|
||||
char * szPath = CoTaskMemAlloc(path_length * sizeof(CHAR));
|
||||
if (szPath)
|
||||
{
|
||||
WideCharToMultiByte(CP_ACP,0,lpszSourceFile,-1,szPath,path_length,NULL,NULL);
|
||||
ExtEscape(hdc, MFCOMMENT, path_length, szPath, 0, NULL);
|
||||
CoTaskMemFree(szPath);
|
||||
}
|
||||
}
|
||||
snprintf(szIconIndex, 10, "%u", iIconIndex);
|
||||
ExtEscape(hdc, MFCOMMENT, strlen(szIconIndex)+1, szIconIndex, 0, NULL);
|
||||
}
|
||||
|
||||
mfp.mm = MM_ISOTROPIC;
|
||||
mfp.xExt = mfp.yExt = 0; /* FIXME ? */
|
||||
mfp.hMF = CloseMetaFile(hdc);
|
||||
if( !mfp.hMF )
|
||||
return NULL;
|
||||
|
||||
hmem = GlobalAlloc( GMEM_MOVEABLE, sizeof(mfp) );
|
||||
if( !hmem )
|
||||
{
|
||||
DeleteMetaFile(mfp.hMF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mfdata = GlobalLock( hmem );
|
||||
if( !mfdata )
|
||||
{
|
||||
GlobalFree( hmem );
|
||||
DeleteMetaFile(mfp.hMF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(mfdata,&mfp,sizeof(mfp));
|
||||
GlobalUnlock( hmem );
|
||||
|
||||
TRACE("returning %p\n",hmem);
|
||||
|
||||
return hmem;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (OLE32.@)
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||
{
|
||||
TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
|
||||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
OLE32_hInstance = hinstDLL;
|
||||
COMPOBJ_InitProcess();
|
||||
if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (TRACE_ON(ole)) CoRevokeMallocSpy();
|
||||
COMPOBJ_UninitProcess();
|
||||
OLE32_hInstance = 0;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* NOTE: DllRegisterServer and DllUnregisterServer are in regsvr.c */
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000 Huw D M Davies for CodeWeavers
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_OLE32_MAIN_H
|
||||
#define __WINE_OLE32_MAIN_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
extern HINSTANCE OLE32_hInstance;
|
||||
|
||||
void COMPOBJ_InitProcess( void );
|
||||
void COMPOBJ_UninitProcess( void );
|
||||
|
||||
#endif /* __WINE_OLE32_MAIN_H */
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Top level resource file for OLE32
|
||||
*
|
||||
* Copyright 2000 Huw D M Davies for CodeWeavers
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
|
||||
#include "version.rc"
|
||||
|
||||
/*
|
||||
* Everything that does not depend on language,
|
||||
* like textless bitmaps etc, go into the
|
||||
* neutral language. This will prevent them from
|
||||
* being duplicated for each language.
|
||||
*/
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
/* BINRES nodrop.cur */
|
||||
0 CURSOR nodrop.cur
|
||||
/* {
|
||||
'00 00 02 00 01 00 20 20 00 00 0F 00 0F 00 30 01'
|
||||
'00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
|
||||
'00 00 01 00 01 00 00 00 00 00 80 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07'
|
||||
'E0 00 00 18 18 00 00 20 04 00 00 43 E2 00 00 8C'
|
||||
'11 00 01 10 20 80 01 20 44 80 02 20 8C 40 02 41'
|
||||
'12 40 02 42 22 40 02 44 42 40 02 48 82 40 02 31'
|
||||
'04 40 01 22 04 80 01 04 08 80 00 8C 31 00 00 43'
|
||||
'C2 00 00 20 04 00 00 18 18 00 00 07 E0 00 00 00'
|
||||
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
|
||||
'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F8'
|
||||
'1F FF FF E0 07 FF FF C0 03 FF FF 80 01 FF FF 03'
|
||||
'E0 FF FE 0F C0 7F FE 1F 80 7F FC 1F 00 3F FC 3E'
|
||||
'0C 3F FC 3C 1C 3F FC 38 3C 3F FC 30 7C 3F FC 00'
|
||||
'F8 3F FE 01 F8 7F FE 03 F0 7F FF 03 C0 FF FF 80'
|
||||
'01 FF FF C0 03 FF FF E0 07 FF FF F8 1F FF FF FF'
|
||||
'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
|
||||
'FF FF FF FF FF FF'
|
||||
} */
|
||||
|
||||
/* BINRES drag_move.cur */
|
||||
1 CURSOR drag_move.cur
|
||||
/* {
|
||||
'00 00 02 00 01 00 20 20 00 00 12 00 16 00 30 01'
|
||||
'00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
|
||||
'00 00 01 00 01 00 00 00 00 00 00 01 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 05 55 00 00 0A AA 80 00 04 01 00 00 08 00'
|
||||
'80 00 04 01 00 00 08 00 80 00 05 55 00 00 0A EA'
|
||||
'80 00 00 C0 00 00 01 80 00 00 01 80 00 00 03 00'
|
||||
'00 00 23 00 00 00 36 00 00 00 3E 00 00 00 3F C0'
|
||||
'00 00 3F 80 00 00 3F 00 00 00 3E 00 00 00 3C 00'
|
||||
'00 00 38 00 00 00 30 00 00 00 20 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
|
||||
'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
|
||||
'FF FF FA AA FF FF F5 55 7F FF FB FE FF FF F7 FF'
|
||||
'7F FF FB FE FF FF F7 FF 7F FF FA AA FF FF F5 15'
|
||||
'7F FF FE 1F FF FF FC 3F FF FF BC 3F FF FF 98 7F'
|
||||
'FF FF 88 7F FF FF 80 FF FF FF 80 0F FF FF 80 1F'
|
||||
'FF FF 80 3F FF FF 80 7F FF FF 80 FF FF FF 81 FF'
|
||||
'FF FF 83 FF FF FF 87 FF FF FF 8F FF FF FF 9F FF'
|
||||
'FF FF FF FF FF FF'
|
||||
} */
|
||||
|
||||
/* BINRES drag_copy.cur */
|
||||
2 CURSOR drag_copy.cur
|
||||
/* {
|
||||
'00 00 02 00 01 00 20 20 00 00 01 00 01 00 30 01'
|
||||
'00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
|
||||
'00 00 01 00 01 00 00 00 00 00 00 01 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 07 F0 00 00 07 70 00 00 07'
|
||||
'70 00 05 54 10 00 0A A7 70 00 04 07 70 00 08 07'
|
||||
'F0 00 04 00 00 00 08 00 80 00 05 55 00 00 0A EA'
|
||||
'80 00 00 C0 00 00 01 80 00 00 01 80 00 00 03 00'
|
||||
'00 00 23 00 00 00 36 00 00 00 3E 00 00 00 3F C0'
|
||||
'00 00 3F 80 00 00 3F 00 00 00 3E 00 00 00 3C 00'
|
||||
'00 00 38 00 00 00 30 00 00 00 20 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
|
||||
'FF FF FF F0 07 FF FF F0 07 FF FF F0 07 FF FF F0'
|
||||
'07 FF FA A0 07 FF F5 50 07 FF FB F0 07 FF F7 F0'
|
||||
'07 FF FB F0 07 FF F7 FF 7F FF FA AA FF FF F5 15'
|
||||
'7F FF FE 1F FF FF FC 3F FF FF BC 3F FF FF 98 7F'
|
||||
'FF FF 88 7F FF FF 80 FF FF FF 80 0F FF FF 80 1F'
|
||||
'FF FF 80 3F FF FF 80 7F FF FF 80 FF FF FF 81 FF'
|
||||
'FF FF 83 FF FF FF 87 FF FF FF 8F FF FF FF 9F FF'
|
||||
'FF FF FF FF FF FF'
|
||||
} */
|
||||
|
||||
/* BINRES drag_link.cur */
|
||||
3 CURSOR drag_link.cur
|
||||
/* {
|
||||
'00 00 02 00 01 00 20 20 00 00 12 00 16 00 30 01'
|
||||
'00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
|
||||
'00 00 01 00 01 00 00 00 00 00 00 01 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 00 07 F0 00 00 06 F0 00 00 06'
|
||||
'F0 00 05 57 50 00 0A A7 90 00 04 07 10 00 08 07'
|
||||
'F0 00 04 00 00 00 08 00 80 00 05 55 00 00 0A EA'
|
||||
'80 00 00 C0 00 00 01 80 00 00 01 80 00 00 03 00'
|
||||
'00 00 23 00 00 00 36 00 00 00 3E 00 00 00 3F C0'
|
||||
'00 00 3F 80 00 00 3F 00 00 00 3E 00 00 00 3C 00'
|
||||
'00 00 38 00 00 00 30 00 00 00 20 00 00 00 00 00'
|
||||
'00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
|
||||
'FF FF FF F0 07 FF FF F0 07 FF FF F0 07 FF FF F0'
|
||||
'07 FF FA A0 07 FF F5 50 07 FF FB F0 07 FF F7 F0'
|
||||
'07 FF FB F0 07 FF F7 FF 7F FF FA AA FF FF F5 15'
|
||||
'7F FF FE 1F FF FF FC 3F FF FF BC 3F FF FF 98 7F'
|
||||
'FF FF 88 7F FF FF 80 FF FF FF 80 0F FF FF 80 1F'
|
||||
'FF FF 80 3F FF FF 80 7F FF FF 80 FF FF FF 81 FF'
|
||||
'FF FF 83 FF FF FF 87 FF FF FF 8F FF FF FF 9F FF'
|
||||
'FF FF FF FF FF FF'
|
||||
} */
|
||||
|
||||
|
||||
/*
|
||||
* Everything specific to any language goes
|
||||
* in one of the specific files.
|
||||
* Note that you can and may override resources
|
||||
* which also have a neutral version. This is to
|
||||
* get localized bitmaps for example.
|
||||
*/
|
||||
@@ -1,752 +0,0 @@
|
||||
/*
|
||||
* OLE2 COM objects
|
||||
*
|
||||
* Copyright 1998 Eric Kohl
|
||||
* Copyright 1999 Francis Beaudet
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ole2.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
#define INITIAL_SINKS 10
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl Implementation
|
||||
*/
|
||||
typedef struct OleAdviseHolderImpl
|
||||
{
|
||||
IOleAdviseHolderVtbl *lpVtbl;
|
||||
|
||||
DWORD ref;
|
||||
|
||||
DWORD maxSinks;
|
||||
IAdviseSink** arrayOfSinks;
|
||||
|
||||
} OleAdviseHolderImpl;
|
||||
|
||||
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor();
|
||||
static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
|
||||
static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
|
||||
static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_VTable
|
||||
*/
|
||||
static struct IOleAdviseHolderVtbl oahvt =
|
||||
{
|
||||
OleAdviseHolderImpl_QueryInterface,
|
||||
OleAdviseHolderImpl_AddRef,
|
||||
OleAdviseHolderImpl_Release,
|
||||
OleAdviseHolderImpl_Advise,
|
||||
OleAdviseHolderImpl_Unadvise,
|
||||
OleAdviseHolderImpl_EnumAdvise,
|
||||
OleAdviseHolderImpl_SendOnRename,
|
||||
OleAdviseHolderImpl_SendOnSave,
|
||||
OleAdviseHolderImpl_SendOnClose
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_Constructor
|
||||
*/
|
||||
|
||||
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
|
||||
{
|
||||
OleAdviseHolderImpl* lpoah;
|
||||
DWORD index;
|
||||
|
||||
lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
sizeof(OleAdviseHolderImpl));
|
||||
|
||||
lpoah->lpVtbl = &oahvt;
|
||||
lpoah->ref = 1;
|
||||
lpoah->maxSinks = INITIAL_SINKS;
|
||||
lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
lpoah->maxSinks * sizeof(IAdviseSink*));
|
||||
|
||||
for (index = 0; index < lpoah->maxSinks; index++)
|
||||
lpoah->arrayOfSinks[index]=0;
|
||||
|
||||
TRACE("returning %p\n", lpoah);
|
||||
return (LPOLEADVISEHOLDER)lpoah;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_Destructor
|
||||
*/
|
||||
static void OleAdviseHolderImpl_Destructor(
|
||||
OleAdviseHolderImpl* ptrToDestroy)
|
||||
{
|
||||
DWORD index;
|
||||
TRACE("%p\n", ptrToDestroy);
|
||||
|
||||
for (index = 0; index < ptrToDestroy->maxSinks; index++)
|
||||
{
|
||||
if (ptrToDestroy->arrayOfSinks[index]!=0)
|
||||
{
|
||||
IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
|
||||
ptrToDestroy->arrayOfSinks[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
ptrToDestroy->arrayOfSinks);
|
||||
|
||||
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
ptrToDestroy);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_QueryInterface
|
||||
*/
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
|
||||
LPOLEADVISEHOLDER iface,
|
||||
REFIID riid,
|
||||
LPVOID* ppvObj)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj);
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if (ppvObj==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppvObj = NULL;
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
/* IUnknown */
|
||||
*ppvObj = This;
|
||||
}
|
||||
else if(IsEqualIID(riid, &IID_IOleAdviseHolder))
|
||||
{
|
||||
/* IOleAdviseHolder */
|
||||
*ppvObj = (IOleAdviseHolder*) This;
|
||||
}
|
||||
|
||||
if(*ppvObj == NULL)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/*
|
||||
* A successful QI always increments the reference count.
|
||||
*/
|
||||
IUnknown_AddRef((IUnknown*)*ppvObj);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_AddRef
|
||||
*/
|
||||
static ULONG WINAPI OleAdviseHolderImpl_AddRef(
|
||||
LPOLEADVISEHOLDER iface)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
TRACE("(%p)->(ref=%ld)\n", This, This->ref);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_Release
|
||||
*/
|
||||
static ULONG WINAPI OleAdviseHolderImpl_Release(
|
||||
LPOLEADVISEHOLDER iface)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p)->(ref=%ld)\n", This, This->ref);
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0) OleAdviseHolderImpl_Destructor(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_Advise
|
||||
*/
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_Advise(
|
||||
LPOLEADVISEHOLDER iface,
|
||||
IAdviseSink* pAdvise,
|
||||
DWORD* pdwConnection)
|
||||
{
|
||||
DWORD index;
|
||||
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
|
||||
TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if (pdwConnection==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*pdwConnection = 0;
|
||||
|
||||
/*
|
||||
* Find a free spot in the array.
|
||||
*/
|
||||
for (index = 0; index < This->maxSinks; index++)
|
||||
{
|
||||
if (This->arrayOfSinks[index]==NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the array is full, we need to grow it.
|
||||
*/
|
||||
if (index == This->maxSinks)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
This->maxSinks+=INITIAL_SINKS;
|
||||
|
||||
This->arrayOfSinks = HeapReAlloc(GetProcessHeap(),
|
||||
0,
|
||||
This->arrayOfSinks,
|
||||
This->maxSinks*sizeof(IAdviseSink*));
|
||||
|
||||
for (i=index;i < This->maxSinks; i++)
|
||||
This->arrayOfSinks[i]=0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the new sink
|
||||
*/
|
||||
This->arrayOfSinks[index] = pAdvise;
|
||||
|
||||
if (This->arrayOfSinks[index]!=NULL)
|
||||
IAdviseSink_AddRef(This->arrayOfSinks[index]);
|
||||
|
||||
/*
|
||||
* Return the index as the cookie.
|
||||
* Since 0 is not a valid cookie, we will increment by
|
||||
* 1 the index in the table.
|
||||
*/
|
||||
*pdwConnection = index+1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_Unadvise
|
||||
*/
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
|
||||
LPOLEADVISEHOLDER iface,
|
||||
DWORD dwConnection)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
|
||||
TRACE("(%p)->(%lu)\n", This, dwConnection);
|
||||
|
||||
/*
|
||||
* So we don't return 0 as a cookie, the index was
|
||||
* incremented by 1 in OleAdviseHolderImpl_Advise
|
||||
* we have to compensate.
|
||||
*/
|
||||
dwConnection--;
|
||||
|
||||
/*
|
||||
* Check for invalid cookies.
|
||||
*/
|
||||
if (dwConnection >= This->maxSinks)
|
||||
return OLE_E_NOCONNECTION;
|
||||
|
||||
if (This->arrayOfSinks[dwConnection] == NULL)
|
||||
return OLE_E_NOCONNECTION;
|
||||
|
||||
/*
|
||||
* Release the sink and mark the spot in the list as free.
|
||||
*/
|
||||
IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
|
||||
This->arrayOfSinks[dwConnection] = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_EnumAdvise
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
FIXME("(%p)->(%p)\n", This, ppenumAdvise);
|
||||
|
||||
*ppenumAdvise = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_SendOnRename
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
FIXME("(%p)->(%p)\n", This, pmk);
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_SendOnSave
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
FIXME("(%p)\n", This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OleAdviseHolderImpl_SendOnClose
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
|
||||
{
|
||||
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
|
||||
FIXME("(%p)\n", This);
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DataAdviseHolder Implementation
|
||||
*/
|
||||
typedef struct DataAdviseConnection {
|
||||
IAdviseSink *sink;
|
||||
FORMATETC fmat;
|
||||
DWORD advf;
|
||||
} DataAdviseConnection;
|
||||
|
||||
typedef struct DataAdviseHolder
|
||||
{
|
||||
IDataAdviseHolderVtbl *lpVtbl;
|
||||
|
||||
DWORD ref;
|
||||
DWORD maxCons;
|
||||
DataAdviseConnection* Connections;
|
||||
} DataAdviseHolder;
|
||||
|
||||
/**************************************************************************
|
||||
* DataAdviseHolder method prototypes
|
||||
*/
|
||||
static IDataAdviseHolder* DataAdviseHolder_Constructor();
|
||||
static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
|
||||
static HRESULT WINAPI DataAdviseHolder_QueryInterface(
|
||||
IDataAdviseHolder* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
static ULONG WINAPI DataAdviseHolder_AddRef(
|
||||
IDataAdviseHolder* iface);
|
||||
static ULONG WINAPI DataAdviseHolder_Release(
|
||||
IDataAdviseHolder* iface);
|
||||
static HRESULT WINAPI DataAdviseHolder_Advise(
|
||||
IDataAdviseHolder* iface,
|
||||
IDataObject* pDataObject,
|
||||
FORMATETC* pFetc,
|
||||
DWORD advf,
|
||||
IAdviseSink* pAdvise,
|
||||
DWORD* pdwConnection);
|
||||
static HRESULT WINAPI DataAdviseHolder_Unadvise(
|
||||
IDataAdviseHolder* iface,
|
||||
DWORD dwConnection);
|
||||
static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
|
||||
IDataAdviseHolder* iface,
|
||||
IEnumSTATDATA** ppenumAdvise);
|
||||
static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
|
||||
IDataAdviseHolder* iface,
|
||||
IDataObject* pDataObject,
|
||||
DWORD dwReserved,
|
||||
DWORD advf);
|
||||
|
||||
/**************************************************************************
|
||||
* DataAdviseHolderImpl_VTable
|
||||
*/
|
||||
static struct IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
|
||||
{
|
||||
DataAdviseHolder_QueryInterface,
|
||||
DataAdviseHolder_AddRef,
|
||||
DataAdviseHolder_Release,
|
||||
DataAdviseHolder_Advise,
|
||||
DataAdviseHolder_Unadvise,
|
||||
DataAdviseHolder_EnumAdvise,
|
||||
DataAdviseHolder_SendOnDataChange
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* DataAdviseHolder_Constructor
|
||||
*/
|
||||
static IDataAdviseHolder* DataAdviseHolder_Constructor()
|
||||
{
|
||||
DataAdviseHolder* newHolder;
|
||||
|
||||
newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
sizeof(DataAdviseHolder));
|
||||
|
||||
newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
|
||||
newHolder->ref = 1;
|
||||
newHolder->maxCons = INITIAL_SINKS;
|
||||
newHolder->Connections = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
newHolder->maxCons *
|
||||
sizeof(DataAdviseConnection));
|
||||
|
||||
TRACE("returning %p\n", newHolder);
|
||||
return (IDataAdviseHolder*)newHolder;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DataAdviseHolder_Destructor
|
||||
*/
|
||||
static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
|
||||
{
|
||||
DWORD index;
|
||||
TRACE("%p\n", ptrToDestroy);
|
||||
|
||||
for (index = 0; index < ptrToDestroy->maxCons; index++)
|
||||
{
|
||||
if (ptrToDestroy->Connections[index].sink != NULL)
|
||||
{
|
||||
IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
|
||||
ptrToDestroy->Connections[index].sink = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections);
|
||||
HeapFree(GetProcessHeap(), 0, ptrToDestroy);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* DataAdviseHolder_QueryInterface (IUnknown)
|
||||
*
|
||||
* See Windows documentation for more details on IUnknown methods.
|
||||
*/
|
||||
static HRESULT WINAPI DataAdviseHolder_QueryInterface(
|
||||
IDataAdviseHolder* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
||||
/*
|
||||
* Perform a sanity check on the parameters.
|
||||
*/
|
||||
if ( (This==0) || (ppvObject==0) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
/*
|
||||
* Initialize the return parameter.
|
||||
*/
|
||||
*ppvObject = 0;
|
||||
|
||||
/*
|
||||
* Compare the riid with the interface IDs implemented by this object.
|
||||
*/
|
||||
if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
|
||||
(memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) )
|
||||
{
|
||||
*ppvObject = iface;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we obtained an interface.
|
||||
*/
|
||||
if ((*ppvObject)==0)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Query Interface always increases the reference count by one when it is
|
||||
* successful.
|
||||
*/
|
||||
IUnknown_AddRef((IUnknown*)*ppvObject);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* DataAdviseHolder_AddRef (IUnknown)
|
||||
*
|
||||
* See Windows documentation for more details on IUnknown methods.
|
||||
*/
|
||||
static ULONG WINAPI DataAdviseHolder_AddRef(
|
||||
IDataAdviseHolder* iface)
|
||||
{
|
||||
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
||||
TRACE("(%p) (ref=%ld)\n", This, This->ref);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* DataAdviseHolder_Release (IUnknown)
|
||||
*
|
||||
* See Windows documentation for more details on IUnknown methods.
|
||||
*/
|
||||
static ULONG WINAPI DataAdviseHolder_Release(
|
||||
IDataAdviseHolder* iface)
|
||||
{
|
||||
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) (ref=%ld)\n", This, This->ref);
|
||||
|
||||
/*
|
||||
* Decrease the reference count on this object.
|
||||
*/
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
/*
|
||||
* If the reference count goes down to 0, perform suicide.
|
||||
*/
|
||||
if (ref==0) DataAdviseHolder_Destructor(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* DataAdviseHolder_Advise
|
||||
*
|
||||
*/
|
||||
static HRESULT WINAPI DataAdviseHolder_Advise(
|
||||
IDataAdviseHolder* iface,
|
||||
IDataObject* pDataObject,
|
||||
FORMATETC* pFetc,
|
||||
DWORD advf,
|
||||
IAdviseSink* pAdvise,
|
||||
DWORD* pdwConnection)
|
||||
{
|
||||
DWORD index;
|
||||
|
||||
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
||||
|
||||
TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf,
|
||||
pAdvise, pdwConnection);
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if (pdwConnection==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*pdwConnection = 0;
|
||||
|
||||
/*
|
||||
* Find a free spot in the array.
|
||||
*/
|
||||
for (index = 0; index < This->maxCons; index++)
|
||||
{
|
||||
if (This->Connections[index].sink == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the array is full, we need to grow it.
|
||||
*/
|
||||
if (index == This->maxCons)
|
||||
{
|
||||
This->maxCons+=INITIAL_SINKS;
|
||||
This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
This->Connections,
|
||||
This->maxCons*sizeof(DataAdviseConnection));
|
||||
}
|
||||
/*
|
||||
* Store the new sink
|
||||
*/
|
||||
This->Connections[index].sink = pAdvise;
|
||||
memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
|
||||
This->Connections[index].advf = advf;
|
||||
|
||||
if (This->Connections[index].sink != NULL) {
|
||||
IAdviseSink_AddRef(This->Connections[index].sink);
|
||||
if(advf & ADVF_PRIMEFIRST) {
|
||||
DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Return the index as the cookie.
|
||||
* Since 0 is not a valid cookie, we will increment by
|
||||
* 1 the index in the table.
|
||||
*/
|
||||
*pdwConnection = index+1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DataAdviseHolder_Unadvise
|
||||
*/
|
||||
static HRESULT WINAPI DataAdviseHolder_Unadvise(
|
||||
IDataAdviseHolder* iface,
|
||||
DWORD dwConnection)
|
||||
{
|
||||
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
||||
|
||||
TRACE("(%p)->(%lu)\n", This, dwConnection);
|
||||
|
||||
/*
|
||||
* So we don't return 0 as a cookie, the index was
|
||||
* incremented by 1 in OleAdviseHolderImpl_Advise
|
||||
* we have to compensate.
|
||||
*/
|
||||
dwConnection--;
|
||||
|
||||
/*
|
||||
* Check for invalid cookies.
|
||||
*/
|
||||
if (dwConnection >= This->maxCons)
|
||||
return OLE_E_NOCONNECTION;
|
||||
|
||||
if (This->Connections[dwConnection].sink == NULL)
|
||||
return OLE_E_NOCONNECTION;
|
||||
|
||||
/*
|
||||
* Release the sink and mark the spot in the list as free.
|
||||
*/
|
||||
IAdviseSink_Release(This->Connections[dwConnection].sink);
|
||||
memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
|
||||
IDataAdviseHolder* iface,
|
||||
IEnumSTATDATA** ppenumAdvise)
|
||||
{
|
||||
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
||||
|
||||
FIXME("(%p)->(%p)\n", This, ppenumAdvise);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DataAdviseHolder_SendOnDataChange
|
||||
*/
|
||||
static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
|
||||
IDataAdviseHolder* iface,
|
||||
IDataObject* pDataObject,
|
||||
DWORD dwReserved,
|
||||
DWORD advf)
|
||||
{
|
||||
DataAdviseHolder *This = (DataAdviseHolder *)iface;
|
||||
DWORD index;
|
||||
STGMEDIUM stg;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf);
|
||||
|
||||
for(index = 0; index < This->maxCons; index++) {
|
||||
if(This->Connections[index].sink != NULL) {
|
||||
if(!(This->Connections[index].advf & ADVF_NODATA)) {
|
||||
TRACE("Calling IDataObject_GetData\n");
|
||||
res = IDataObject_GetData(pDataObject,
|
||||
&(This->Connections[index].fmat),
|
||||
&stg);
|
||||
TRACE("returns %08lx\n", res);
|
||||
}
|
||||
TRACE("Calling IAdviseSink_OnDataChange\n");
|
||||
IAdviseSink_OnDataChange(This->Connections[index].sink,
|
||||
&(This->Connections[index].fmat),
|
||||
&stg);
|
||||
TRACE("Done IAdviseSink_OnDataChange\n");
|
||||
if(This->Connections[index].advf & ADVF_ONLYONCE) {
|
||||
TRACE("Removing connection\n");
|
||||
DataAdviseHolder_Unadvise(iface, index+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* API functions
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* CreateOleAdviseHolder [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI CreateOleAdviseHolder(
|
||||
LPOLEADVISEHOLDER *ppOAHolder)
|
||||
{
|
||||
TRACE("(%p)\n", ppOAHolder);
|
||||
|
||||
/*
|
||||
* Sanity check,
|
||||
*/
|
||||
if (ppOAHolder==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppOAHolder = OleAdviseHolderImpl_Constructor ();
|
||||
|
||||
if (*ppOAHolder != NULL)
|
||||
return S_OK;
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateDataAdviseHolder [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI CreateDataAdviseHolder(
|
||||
LPDATAADVISEHOLDER* ppDAHolder)
|
||||
{
|
||||
TRACE("(%p)\n", ppDAHolder);
|
||||
|
||||
/*
|
||||
* Sanity check,
|
||||
*/
|
||||
if (ppDAHolder==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*ppDAHolder = DataAdviseHolder_Constructor();
|
||||
|
||||
if (*ppDAHolder != NULL)
|
||||
return S_OK;
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
@@ -1,526 +0,0 @@
|
||||
/*
|
||||
* OLE32 proxy/stub handler
|
||||
*
|
||||
* Copyright 2002 Marcus Meissner
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Documentation on MSDN:
|
||||
*
|
||||
* (Top level COM documentation)
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/componentdevelopmentank.asp
|
||||
*
|
||||
* (COM Proxy)
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/comext_1q0p.asp
|
||||
*
|
||||
* (COM Stub)
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/comext_1lia.asp
|
||||
*
|
||||
* (Marshal)
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/comext_1gfn.asp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "rpc.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "wtypes.h"
|
||||
|
||||
#include "compobj_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
const CLSID CLSID_DfMarshal = { 0x0000030b, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
|
||||
const CLSID CLSID_PSFactoryBuffer = { 0x00000320, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
|
||||
|
||||
/* From: http://msdn.microsoft.com/library/en-us/com/cmi_m_4lda.asp
|
||||
*
|
||||
* The first time a client requests a pointer to an interface on a
|
||||
* particular object, COM loads an IClassFactory stub in the server
|
||||
* process and uses it to marshal the first pointer back to the
|
||||
* client. In the client process, COM loads the generic proxy for the
|
||||
* class factory object and calls its implementation of IMarshal to
|
||||
* unmarshal that first pointer. COM then creates the first interface
|
||||
* proxy and hands it a pointer to the RPC channel. Finally, COM returns
|
||||
* the IClassFactory pointer to the client, which uses it to call
|
||||
* IClassFactory::CreateInstance, passing it a reference to the interface.
|
||||
*
|
||||
* Back in the server process, COM now creates a new instance of the
|
||||
* object, along with a stub for the requested interface. This stub marshals
|
||||
* the interface pointer back to the client process, where another object
|
||||
* proxy is created, this time for the object itself. Also created is a
|
||||
* proxy for the requested interface, a pointer to which is returned to
|
||||
* the client. With subsequent calls to other interfaces on the object,
|
||||
* COM will load the appropriate interface stubs and proxies as needed.
|
||||
*/
|
||||
typedef struct _CFStub {
|
||||
IRpcStubBufferVtbl *lpvtbl;
|
||||
DWORD ref;
|
||||
|
||||
LPUNKNOWN pUnkServer;
|
||||
} CFStub;
|
||||
|
||||
static HRESULT WINAPI
|
||||
CFStub_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv) {
|
||||
if (IsEqualIID(&IID_IUnknown,riid)||IsEqualIID(&IID_IRpcStubBuffer,riid)) {
|
||||
*ppv = (LPVOID)iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("(%s), interface not supported.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
CFStub_AddRef(LPRPCSTUBBUFFER iface) {
|
||||
CFStub *This = (CFStub *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
CFStub_Release(LPRPCSTUBBUFFER iface) {
|
||||
CFStub *This = (CFStub *)iface;
|
||||
ULONG ref;
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (!ref) HeapFree(GetProcessHeap(),0,This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CFStub_Connect(LPRPCSTUBBUFFER iface, IUnknown *pUnkServer) {
|
||||
CFStub *This = (CFStub *)iface;
|
||||
|
||||
This->pUnkServer = pUnkServer;
|
||||
IUnknown_AddRef(pUnkServer);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void WINAPI
|
||||
CFStub_Disconnect(LPRPCSTUBBUFFER iface) {
|
||||
CFStub *This = (CFStub *)iface;
|
||||
|
||||
IUnknown_Release(This->pUnkServer);
|
||||
This->pUnkServer = NULL;
|
||||
}
|
||||
static HRESULT WINAPI
|
||||
CFStub_Invoke(
|
||||
LPRPCSTUBBUFFER iface,RPCOLEMESSAGE* msg,IRpcChannelBuffer* chanbuf
|
||||
) {
|
||||
CFStub *This = (CFStub *)iface;
|
||||
HRESULT hres;
|
||||
|
||||
if (msg->iMethod == 3) { /* CreateInstance */
|
||||
IID iid;
|
||||
IClassFactory *classfac;
|
||||
IUnknown *ppv;
|
||||
IStream *pStm;
|
||||
STATSTG ststg;
|
||||
ULARGE_INTEGER newpos;
|
||||
LARGE_INTEGER seekto;
|
||||
ULONG res;
|
||||
|
||||
if (msg->cbBuffer < sizeof(IID)) {
|
||||
FIXME("Not enough bytes in buffer (%ld instead of %d)?\n",msg->cbBuffer,sizeof(IID));
|
||||
return E_FAIL;
|
||||
}
|
||||
memcpy(&iid,msg->Buffer,sizeof(iid));
|
||||
TRACE("->CreateInstance(%s)\n",debugstr_guid(&iid));
|
||||
hres = IUnknown_QueryInterface(This->pUnkServer,&IID_IClassFactory,(LPVOID*)&classfac);
|
||||
if (hres) {
|
||||
FIXME("Ole server does not provide a IClassFactory?\n");
|
||||
return hres;
|
||||
}
|
||||
hres = IClassFactory_CreateInstance(classfac,NULL,&iid,(LPVOID*)&ppv);
|
||||
IClassFactory_Release(classfac);
|
||||
if (hres) {
|
||||
msg->cbBuffer = 0;
|
||||
FIXME("Failed to create an instance of %s\n",debugstr_guid(&iid));
|
||||
return hres;
|
||||
}
|
||||
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
|
||||
if (hres) {
|
||||
FIXME("Failed to create stream on hglobal\n");
|
||||
return hres;
|
||||
}
|
||||
hres = CoMarshalInterface(pStm,&iid,ppv,0,NULL,0);
|
||||
if (hres) {
|
||||
FIXME("CoMarshalInterface failed, %lx!\n",hres);
|
||||
msg->cbBuffer = 0;
|
||||
return hres;
|
||||
}
|
||||
hres = IStream_Stat(pStm,&ststg,0);
|
||||
if (hres) {
|
||||
FIXME("Stat failed.\n");
|
||||
return hres;
|
||||
}
|
||||
|
||||
msg->cbBuffer = ststg.cbSize.u.LowPart;
|
||||
|
||||
if (msg->Buffer)
|
||||
msg->Buffer = HeapReAlloc(GetProcessHeap(),0,msg->Buffer,ststg.cbSize.u.LowPart);
|
||||
else
|
||||
msg->Buffer = HeapAlloc(GetProcessHeap(),0,ststg.cbSize.u.LowPart);
|
||||
|
||||
seekto.u.LowPart = 0;seekto.u.HighPart = 0;
|
||||
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
|
||||
if (hres) {
|
||||
FIXME("IStream_Seek failed, %lx\n",hres);
|
||||
return hres;
|
||||
}
|
||||
hres = IStream_Read(pStm,msg->Buffer,msg->cbBuffer,&res);
|
||||
if (hres) {
|
||||
FIXME("Stream Read failed, %lx\n",hres);
|
||||
return hres;
|
||||
}
|
||||
IStream_Release(pStm);
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("(%p,%p), stub!\n",msg,chanbuf);
|
||||
FIXME("iMethod is %ld\n",msg->iMethod);
|
||||
FIXME("cbBuffer is %ld\n",msg->cbBuffer);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static LPRPCSTUBBUFFER WINAPI
|
||||
CFStub_IsIIDSupported(LPRPCSTUBBUFFER iface,REFIID riid) {
|
||||
FIXME("(%s), stub!\n",debugstr_guid(riid));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
CFStub_CountRefs(LPRPCSTUBBUFFER iface) {
|
||||
FIXME("(), stub!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CFStub_DebugServerQueryInterface(LPRPCSTUBBUFFER iface,void** ppv) {
|
||||
FIXME("(%p), stub!\n",ppv);
|
||||
return E_FAIL;
|
||||
}
|
||||
static void WINAPI
|
||||
CFStub_DebugServerRelease(LPRPCSTUBBUFFER iface,void *pv) {
|
||||
FIXME("(%p), stub!\n",pv);
|
||||
}
|
||||
|
||||
static IRpcStubBufferVtbl cfstubvt = {
|
||||
CFStub_QueryInterface,
|
||||
CFStub_AddRef,
|
||||
CFStub_Release,
|
||||
CFStub_Connect,
|
||||
CFStub_Disconnect,
|
||||
CFStub_Invoke,
|
||||
CFStub_IsIIDSupported,
|
||||
CFStub_CountRefs,
|
||||
CFStub_DebugServerQueryInterface,
|
||||
CFStub_DebugServerRelease
|
||||
};
|
||||
|
||||
static HRESULT
|
||||
CFStub_Construct(LPRPCSTUBBUFFER *ppv) {
|
||||
CFStub *cfstub;
|
||||
cfstub = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CFStub));
|
||||
if (!cfstub)
|
||||
return E_OUTOFMEMORY;
|
||||
*ppv = (LPRPCSTUBBUFFER)cfstub;
|
||||
cfstub->lpvtbl = &cfstubvt;
|
||||
cfstub->ref = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Since we create proxy buffers and classfactory in a pair, there is
|
||||
* no need for 2 separate structs. Just put them in one, but remember
|
||||
* the refcount.
|
||||
*/
|
||||
typedef struct _CFProxy {
|
||||
IClassFactoryVtbl *lpvtbl_cf;
|
||||
IRpcProxyBufferVtbl *lpvtbl_proxy;
|
||||
DWORD ref;
|
||||
|
||||
IRpcChannelBuffer *chanbuf;
|
||||
} CFProxy;
|
||||
|
||||
static HRESULT WINAPI IRpcProxyBufferImpl_QueryInterface(LPRPCPROXYBUFFER iface,REFIID riid,LPVOID *ppv) {
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid,&IID_IRpcProxyBuffer)||IsEqualIID(riid,&IID_IUnknown)) {
|
||||
IRpcProxyBuffer_AddRef(iface);
|
||||
*ppv = (LPVOID)iface;
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("(%s), no interface.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IRpcProxyBufferImpl_AddRef(LPRPCPROXYBUFFER iface) {
|
||||
ICOM_THIS_MULTI(CFProxy,lpvtbl_proxy,iface);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IRpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface) {
|
||||
ICOM_THIS_MULTI(CFProxy,lpvtbl_proxy,iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (!ref) {
|
||||
IRpcChannelBuffer_Release(This->chanbuf);This->chanbuf = NULL;
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRpcProxyBufferImpl_Connect(LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer) {
|
||||
ICOM_THIS_MULTI(CFProxy,lpvtbl_proxy,iface);
|
||||
|
||||
This->chanbuf = pRpcChannelBuffer;
|
||||
IRpcChannelBuffer_AddRef(This->chanbuf);
|
||||
return S_OK;
|
||||
}
|
||||
static void WINAPI IRpcProxyBufferImpl_Disconnect(LPRPCPROXYBUFFER iface) {
|
||||
ICOM_THIS_MULTI(CFProxy,lpvtbl_proxy,iface);
|
||||
if (This->chanbuf) {
|
||||
IRpcChannelBuffer_Release(This->chanbuf);
|
||||
This->chanbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CFProxy_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) {
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(&IID_IClassFactory,riid) || IsEqualIID(&IID_IUnknown,riid)) {
|
||||
*ppv = (LPVOID)iface;
|
||||
IClassFactory_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
if (IsEqualIID(riid,&IID_IMarshal)) /* just to avoid debug output */
|
||||
return E_NOINTERFACE;
|
||||
FIXME("Unhandled interface: %s\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI CFProxy_AddRef(LPCLASSFACTORY iface) {
|
||||
ICOM_THIS_MULTI(CFProxy,lpvtbl_cf,iface);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI CFProxy_Release(LPCLASSFACTORY iface) {
|
||||
ULONG ref;
|
||||
ICOM_THIS_MULTI(CFProxy,lpvtbl_cf,iface);
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (!ref) HeapFree(GetProcessHeap(),0,This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CFProxy_CreateInstance(
|
||||
LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pUnkOuter,/* [in] */
|
||||
REFIID riid, /* [in] */
|
||||
LPVOID *ppv /* [out] */
|
||||
) {
|
||||
ICOM_THIS_MULTI(CFProxy,lpvtbl_cf,iface);
|
||||
HRESULT hres;
|
||||
LPSTREAM pStream;
|
||||
HGLOBAL hGlobal;
|
||||
ULONG srstatus;
|
||||
RPCOLEMESSAGE msg;
|
||||
|
||||
TRACE("(%p,%s,%p)\n",pUnkOuter,debugstr_guid(riid),ppv);
|
||||
|
||||
/* Send CreateInstance to the remote classfactory.
|
||||
*
|
||||
* Data: Only the 'IID'.
|
||||
*/
|
||||
msg.iMethod = 3;
|
||||
msg.cbBuffer = sizeof(*riid);
|
||||
msg.Buffer = NULL;
|
||||
hres = IRpcChannelBuffer_GetBuffer(This->chanbuf,&msg,&IID_IClassFactory);
|
||||
if (hres) {
|
||||
FIXME("IRpcChannelBuffer_GetBuffer failed with %lx?\n",hres);
|
||||
return hres;
|
||||
}
|
||||
memcpy(msg.Buffer,riid,sizeof(*riid));
|
||||
hres = IRpcChannelBuffer_SendReceive(This->chanbuf,&msg,&srstatus);
|
||||
if (hres) {
|
||||
FIXME("IRpcChannelBuffer_SendReceive failed with %lx?\n",hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if (!msg.cbBuffer) /* interface not found on remote */
|
||||
return srstatus;
|
||||
|
||||
/* We got back: [Marshalled Interface data] */
|
||||
TRACE("got %ld bytes data.\n",msg.cbBuffer);
|
||||
hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE,msg.cbBuffer);
|
||||
memcpy(GlobalLock(hGlobal),msg.Buffer,msg.cbBuffer);
|
||||
hres = CreateStreamOnHGlobal(hGlobal,TRUE,&pStream);
|
||||
if (hres) {
|
||||
FIXME("CreateStreamOnHGlobal failed with %lx\n",hres);
|
||||
return hres;
|
||||
}
|
||||
hres = CoUnmarshalInterface(
|
||||
pStream,
|
||||
riid,
|
||||
ppv
|
||||
);
|
||||
IStream_Release(pStream); /* Does GlobalFree hGlobal too. */
|
||||
if (hres) {
|
||||
FIXME("CoMarshalInterface failed, %lx\n",hres);
|
||||
return hres;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CFProxy_LockServer(LPCLASSFACTORY iface,BOOL fLock) {
|
||||
/*ICOM_THIS_MULTI(CFProxy,lpvtbl_cf,iface);*/
|
||||
FIXME("(%d), stub!\n",fLock);
|
||||
/* basically: write BOOL, read empty */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IRpcProxyBufferVtbl pspbvtbl = {
|
||||
IRpcProxyBufferImpl_QueryInterface,
|
||||
IRpcProxyBufferImpl_AddRef,
|
||||
IRpcProxyBufferImpl_Release,
|
||||
IRpcProxyBufferImpl_Connect,
|
||||
IRpcProxyBufferImpl_Disconnect
|
||||
};
|
||||
static IClassFactoryVtbl cfproxyvt = {
|
||||
CFProxy_QueryInterface,
|
||||
CFProxy_AddRef,
|
||||
CFProxy_Release,
|
||||
CFProxy_CreateInstance,
|
||||
CFProxy_LockServer
|
||||
};
|
||||
|
||||
static HRESULT
|
||||
CFProxy_Construct(LPVOID *ppv,LPVOID *ppProxy) {
|
||||
CFProxy *cf;
|
||||
|
||||
cf = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CFProxy));
|
||||
if (!cf)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
cf->lpvtbl_cf = &cfproxyvt;
|
||||
cf->lpvtbl_proxy = &pspbvtbl;
|
||||
/* 1 reference for the proxy and 1 for the object */
|
||||
cf->ref = 2;
|
||||
*ppv = &(cf->lpvtbl_cf);
|
||||
*ppProxy = &(cf->lpvtbl_proxy);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/********************* OLE Proxy/Stub Factory ********************************/
|
||||
static HRESULT WINAPI
|
||||
PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) {
|
||||
if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) {
|
||||
*ppv = (LPVOID)iface;
|
||||
/* No ref counting, static class */
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("(%s) unknown IID?\n",debugstr_guid(iid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; }
|
||||
static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; }
|
||||
|
||||
static HRESULT WINAPI
|
||||
PSFacBuf_CreateProxy(
|
||||
LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid,
|
||||
IRpcProxyBuffer **ppProxy, LPVOID *ppv
|
||||
) {
|
||||
if (IsEqualIID(&IID_IClassFactory,riid) ||
|
||||
IsEqualIID(&IID_IUnknown,riid)
|
||||
)
|
||||
return CFProxy_Construct(ppv,(LPVOID*)ppProxy);
|
||||
FIXME("proxying not implemented for (%s) yet!\n",debugstr_guid(riid));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PSFacBuf_CreateStub(
|
||||
LPPSFACTORYBUFFER iface, REFIID riid,IUnknown *pUnkServer,
|
||||
IRpcStubBuffer** ppStub
|
||||
) {
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub);
|
||||
|
||||
if (IsEqualIID(&IID_IClassFactory,riid) ||
|
||||
IsEqualIID(&IID_IUnknown,riid)
|
||||
) {
|
||||
hres = CFStub_Construct(ppStub);
|
||||
if (!hres)
|
||||
IRpcStubBuffer_Connect((*ppStub),pUnkServer);
|
||||
return hres;
|
||||
}
|
||||
FIXME("stubbing not implemented for (%s) yet!\n",debugstr_guid(riid));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static IPSFactoryBufferVtbl psfacbufvtbl = {
|
||||
PSFacBuf_QueryInterface,
|
||||
PSFacBuf_AddRef,
|
||||
PSFacBuf_Release,
|
||||
PSFacBuf_CreateProxy,
|
||||
PSFacBuf_CreateStub
|
||||
};
|
||||
|
||||
/* This is the whole PSFactoryBuffer object, just the vtableptr */
|
||||
static IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl;
|
||||
|
||||
/***********************************************************************
|
||||
* DllGetClassObject [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(rclsid,&CLSID_PSFactoryBuffer)) {
|
||||
*ppv = &lppsfac;
|
||||
return S_OK;
|
||||
}
|
||||
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
|
||||
IsEqualIID(iid,&IID_IClassFactory) ||
|
||||
IsEqualIID(iid,&IID_IUnknown)
|
||||
)
|
||||
)
|
||||
return MARSHAL_GetStandardMarshalCF(ppv);
|
||||
if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown)))
|
||||
return StdGlobalInterfaceTable_GetFactory(ppv);
|
||||
|
||||
FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000 Abey George
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined( __WINE_OLESTD_H_ )
|
||||
#define __WINE_OLESTD_H_
|
||||
|
||||
#if !defined(__cplusplus) && !defined( __TURBOC__)
|
||||
#define NONAMELESSUNION /* use strict ANSI standard (for DVOBJ.H) */
|
||||
#endif
|
||||
|
||||
/* Clipboard format strings */
|
||||
#define CF_EMBEDSOURCE "Embed Source"
|
||||
#define CF_EMBEDDEDOBJECT "Embedded Object"
|
||||
#define CF_LINKSOURCE "Link Source"
|
||||
#define CF_CUSTOMLINKSOURCE "Custom Link Source"
|
||||
#define CF_OBJECTDESCRIPTOR "Object Descriptor"
|
||||
#define CF_LINKSRCDESCRIPTOR "Link Source Descriptor"
|
||||
#define CF_OWNERLINK "OwnerLink"
|
||||
#define CF_FILENAME "FileName"
|
||||
|
||||
#define OleStdQueryOleObjectData(lpformatetc) \
|
||||
(((lpformatetc)->tymed & TYMED_ISTORAGE) ? \
|
||||
NOERROR : ResultFromScode(DV_E_FORMATETC))
|
||||
|
||||
#define OleStdQueryLinkSourceData(lpformatetc) \
|
||||
(((lpformatetc)->tymed & TYMED_ISTREAM) ? \
|
||||
NOERROR : ResultFromScode(DV_E_FORMATETC))
|
||||
|
||||
#define OleStdQueryObjectDescriptorData(lpformatetc) \
|
||||
(((lpformatetc)->tymed & TYMED_HGLOBAL) ? \
|
||||
NOERROR : ResultFromScode(DV_E_FORMATETC))
|
||||
|
||||
#define OleStdQueryFormatMedium(lpformatetc, tymd) \
|
||||
(((lpformatetc)->tymed & tymd) ? \
|
||||
NOERROR : ResultFromScode(DV_E_FORMATETC))
|
||||
|
||||
/* Make an independent copy of a MetafilePict */
|
||||
#define OleStdCopyMetafilePict(hpictin, phpictout) \
|
||||
(*(phpictout) = OleDuplicateData(hpictin,CF_METAFILEPICT,GHND|GMEM_SHARE))
|
||||
|
||||
#endif /* __WINE_OLESTD_H_ */
|
||||
@@ -1,865 +0,0 @@
|
||||
/*
|
||||
* self-registerable dll functions for ole32.dll
|
||||
*
|
||||
* Copyright (C) 2003 John K. Hohm
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "ole2.h"
|
||||
#include "olectl.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/*
|
||||
* Near the bottom of this file are the exported DllRegisterServer and
|
||||
* DllUnregisterServer, which make all this worthwhile.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* interface for self-registering
|
||||
*/
|
||||
struct regsvr_interface
|
||||
{
|
||||
IID const *iid; /* NULL for end of list */
|
||||
LPCSTR name; /* can be NULL to omit */
|
||||
IID const *base_iid; /* can be NULL to omit */
|
||||
int num_methods; /* can be <0 to omit */
|
||||
CLSID const *ps_clsid; /* can be NULL to omit */
|
||||
CLSID const *ps_clsid32; /* can be NULL to omit */
|
||||
};
|
||||
|
||||
static HRESULT register_interfaces(struct regsvr_interface const *list);
|
||||
static HRESULT unregister_interfaces(struct regsvr_interface const *list);
|
||||
|
||||
struct regsvr_coclass
|
||||
{
|
||||
CLSID const *clsid; /* NULL for end of list */
|
||||
LPCSTR name; /* can be NULL to omit */
|
||||
LPCSTR ips; /* can be NULL to omit */
|
||||
LPCSTR ips32; /* can be NULL to omit */
|
||||
LPCSTR ips32_tmodel; /* can be NULL to omit */
|
||||
};
|
||||
|
||||
static HRESULT register_coclasses(struct regsvr_coclass const *list);
|
||||
static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
|
||||
|
||||
/***********************************************************************
|
||||
* static string constants
|
||||
*/
|
||||
static WCHAR const interface_keyname[10] = {
|
||||
'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
|
||||
static WCHAR const base_ifa_keyname[14] = {
|
||||
'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
|
||||
'e', 0 };
|
||||
static WCHAR const num_methods_keyname[11] = {
|
||||
'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
|
||||
static WCHAR const ps_clsid_keyname[15] = {
|
||||
'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
|
||||
'i', 'd', 0 };
|
||||
static WCHAR const ps_clsid32_keyname[17] = {
|
||||
'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
|
||||
'i', 'd', '3', '2', 0 };
|
||||
static WCHAR const clsid_keyname[6] = {
|
||||
'C', 'L', 'S', 'I', 'D', 0 };
|
||||
static WCHAR const ips_keyname[13] = {
|
||||
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
|
||||
0 };
|
||||
static WCHAR const ips32_keyname[15] = {
|
||||
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
|
||||
'3', '2', 0 };
|
||||
static char const tmodel_valuename[] = "ThreadingModel";
|
||||
|
||||
/***********************************************************************
|
||||
* static helper functions
|
||||
*/
|
||||
static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
|
||||
static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
|
||||
WCHAR const *value);
|
||||
static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
|
||||
char const *value);
|
||||
static LONG recursive_delete_key(HKEY key);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* register_interfaces
|
||||
*/
|
||||
static HRESULT register_interfaces(struct regsvr_interface const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY interface_key;
|
||||
|
||||
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->iid; ++list) {
|
||||
WCHAR buf[39];
|
||||
HKEY iid_key;
|
||||
|
||||
StringFromGUID2(list->iid, buf, 39);
|
||||
res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_interface_key;
|
||||
|
||||
if (list->name) {
|
||||
res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)(list->name),
|
||||
strlen(list->name) + 1);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->base_iid) {
|
||||
register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (0 <= list->num_methods) {
|
||||
static WCHAR const fmt[3] = { '%', 'd', 0 };
|
||||
HKEY key;
|
||||
|
||||
res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
|
||||
wsprintfW(buf, fmt, list->num_methods);
|
||||
res = RegSetValueExW(key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)buf,
|
||||
(lstrlenW(buf) + 1) * sizeof(WCHAR));
|
||||
RegCloseKey(key);
|
||||
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->ps_clsid) {
|
||||
register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->ps_clsid32) {
|
||||
register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
error_close_iid_key:
|
||||
RegCloseKey(iid_key);
|
||||
}
|
||||
|
||||
error_close_interface_key:
|
||||
RegCloseKey(interface_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* unregister_interfaces
|
||||
*/
|
||||
static HRESULT unregister_interfaces(struct regsvr_interface const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY interface_key;
|
||||
|
||||
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
|
||||
KEY_READ | KEY_WRITE, &interface_key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->iid; ++list) {
|
||||
WCHAR buf[39];
|
||||
HKEY iid_key;
|
||||
|
||||
StringFromGUID2(list->iid, buf, 39);
|
||||
res = RegOpenKeyExW(interface_key, buf, 0,
|
||||
KEY_READ | KEY_WRITE, &iid_key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) {
|
||||
res = ERROR_SUCCESS;
|
||||
continue;
|
||||
}
|
||||
if (res != ERROR_SUCCESS) goto error_close_interface_key;
|
||||
res = recursive_delete_key(iid_key);
|
||||
RegCloseKey(iid_key);
|
||||
if (res != ERROR_SUCCESS) goto error_close_interface_key;
|
||||
}
|
||||
|
||||
error_close_interface_key:
|
||||
RegCloseKey(interface_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* register_coclasses
|
||||
*/
|
||||
static HRESULT register_coclasses(struct regsvr_coclass const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY coclass_key;
|
||||
|
||||
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
|
||||
WCHAR buf[39];
|
||||
HKEY clsid_key;
|
||||
|
||||
StringFromGUID2(list->clsid, buf, 39);
|
||||
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
|
||||
if (list->name) {
|
||||
res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)(list->name),
|
||||
strlen(list->name) + 1);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
if (list->ips) {
|
||||
res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
if (list->ips32) {
|
||||
HKEY ips32_key;
|
||||
|
||||
res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL,
|
||||
&ips32_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
|
||||
res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)list->ips32,
|
||||
lstrlenA(list->ips32) + 1);
|
||||
if (res == ERROR_SUCCESS && list->ips32_tmodel)
|
||||
res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
|
||||
(CONST BYTE*)list->ips32_tmodel,
|
||||
strlen(list->ips32_tmodel) + 1);
|
||||
RegCloseKey(ips32_key);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
error_close_clsid_key:
|
||||
RegCloseKey(clsid_key);
|
||||
}
|
||||
|
||||
error_close_coclass_key:
|
||||
RegCloseKey(coclass_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* unregister_coclasses
|
||||
*/
|
||||
static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY coclass_key;
|
||||
|
||||
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
|
||||
KEY_READ | KEY_WRITE, &coclass_key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
|
||||
WCHAR buf[39];
|
||||
HKEY clsid_key;
|
||||
|
||||
StringFromGUID2(list->clsid, buf, 39);
|
||||
res = RegOpenKeyExW(coclass_key, buf, 0,
|
||||
KEY_READ | KEY_WRITE, &clsid_key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) {
|
||||
res = ERROR_SUCCESS;
|
||||
continue;
|
||||
}
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
res = recursive_delete_key(clsid_key);
|
||||
RegCloseKey(clsid_key);
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
}
|
||||
|
||||
error_close_coclass_key:
|
||||
RegCloseKey(coclass_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* regsvr_key_guid
|
||||
*/
|
||||
static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
|
||||
{
|
||||
WCHAR buf[39];
|
||||
|
||||
StringFromGUID2(guid, buf, 39);
|
||||
return register_key_defvalueW(base, name, buf);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* regsvr_key_defvalueW
|
||||
*/
|
||||
static LONG register_key_defvalueW(
|
||||
HKEY base,
|
||||
WCHAR const *name,
|
||||
WCHAR const *value)
|
||||
{
|
||||
LONG res;
|
||||
HKEY key;
|
||||
|
||||
res = RegCreateKeyExW(base, name, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
if (res != ERROR_SUCCESS) return res;
|
||||
res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
|
||||
(lstrlenW(value) + 1) * sizeof(WCHAR));
|
||||
RegCloseKey(key);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* regsvr_key_defvalueA
|
||||
*/
|
||||
static LONG register_key_defvalueA(
|
||||
HKEY base,
|
||||
WCHAR const *name,
|
||||
char const *value)
|
||||
{
|
||||
LONG res;
|
||||
HKEY key;
|
||||
|
||||
res = RegCreateKeyExW(base, name, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
if (res != ERROR_SUCCESS) return res;
|
||||
res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
|
||||
lstrlenA(value) + 1);
|
||||
RegCloseKey(key);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* recursive_delete_key
|
||||
*/
|
||||
static LONG recursive_delete_key(HKEY key)
|
||||
{
|
||||
LONG res;
|
||||
WCHAR subkey_name[MAX_PATH];
|
||||
DWORD cName;
|
||||
HKEY subkey;
|
||||
|
||||
for (;;) {
|
||||
cName = sizeof(subkey_name) / sizeof(WCHAR);
|
||||
res = RegEnumKeyExW(key, 0, subkey_name, &cName,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
|
||||
res = ERROR_SUCCESS; /* presumably we're done enumerating */
|
||||
break;
|
||||
}
|
||||
res = RegOpenKeyExW(key, subkey_name, 0,
|
||||
KEY_READ | KEY_WRITE, &subkey);
|
||||
if (res == ERROR_FILE_NOT_FOUND) continue;
|
||||
if (res != ERROR_SUCCESS) break;
|
||||
|
||||
res = recursive_delete_key(subkey);
|
||||
RegCloseKey(subkey);
|
||||
if (res != ERROR_SUCCESS) break;
|
||||
}
|
||||
|
||||
if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* coclass list
|
||||
*/
|
||||
static GUID const CLSID_FileMoniker = {
|
||||
0x00000303, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
|
||||
|
||||
static GUID const CLSID_ItemMoniker = {
|
||||
0x00000304, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
|
||||
|
||||
/* FIXME: DfMarshal and PSFactoryBuffer are defined elsewhere too */
|
||||
|
||||
static GUID const CLSID_DfMarshal = {
|
||||
0x0000030B, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
|
||||
|
||||
static GUID const CLSID_PSFactoryBuffer = {
|
||||
0x00000320, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
|
||||
|
||||
static struct regsvr_coclass const coclass_list[] = {
|
||||
{ &CLSID_FileMoniker,
|
||||
"FileMoniker",
|
||||
NULL,
|
||||
"ole32.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_ItemMoniker,
|
||||
"ItemMoniker",
|
||||
NULL,
|
||||
"ole32.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_DfMarshal,
|
||||
"DfMarshal",
|
||||
NULL,
|
||||
"ole32.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_PSFactoryBuffer,
|
||||
"PSFactoryBuffer",
|
||||
NULL,
|
||||
"ole32.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_StdGlobalInterfaceTable,
|
||||
"StdGlobalInterfaceTable",
|
||||
NULL,
|
||||
"ole32.dll",
|
||||
"Apartment"
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* interface list
|
||||
*/
|
||||
|
||||
/* FIXME: perhaps the interfaces that are proxied by another dll
|
||||
* should be registered in that dll? Or maybe the choice of proxy is
|
||||
* arbitrary at this point? */
|
||||
|
||||
static GUID const CLSID_PSFactoryBuffer_ole2disp = {
|
||||
0x00020420, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
|
||||
|
||||
static GUID const CLSID_PSFactoryBuffer_oleaut32 = {
|
||||
0xB196B286, 0xBAB4, 0x101A, {0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07} };
|
||||
|
||||
/* FIXME: these interfaces should be defined in ocidl.idl */
|
||||
|
||||
static IID const IID_IFontEventsDisp = {
|
||||
0x4EF6100A, 0xAF88, 0x11D0, {0x98,0x46,0x00,0xC0,0x4F,0xC2,0x99,0x93} };
|
||||
|
||||
static IID const IID_IProvideMultipleClassInfo = {
|
||||
0xA7ABA9C1, 0x8983, 0x11CF, {0x8F,0x20,0x00,0x80,0x5F,0x2C,0xD0,0x64} };
|
||||
|
||||
static struct regsvr_interface const interface_list[] = {
|
||||
{ &IID_IUnknown,
|
||||
"IUnknown",
|
||||
NULL,
|
||||
3,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IClassFactory,
|
||||
"IClassFactory",
|
||||
NULL,
|
||||
5,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IStorage,
|
||||
"IStorage",
|
||||
NULL,
|
||||
18,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IStream,
|
||||
"IStream",
|
||||
NULL,
|
||||
14,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IPersistStorage,
|
||||
"IPersistStorage",
|
||||
&IID_IPersist,
|
||||
10,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IDataObject,
|
||||
"IDataObject",
|
||||
NULL,
|
||||
12,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IAdviseSink,
|
||||
"IAdviseSink",
|
||||
NULL,
|
||||
8,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IOleObject,
|
||||
"IOleObject",
|
||||
NULL,
|
||||
24,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IOleClientSite,
|
||||
"IOleClientSite",
|
||||
NULL,
|
||||
9,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer
|
||||
},
|
||||
{ &IID_IDispatch,
|
||||
"IDispatch",
|
||||
NULL,
|
||||
7,
|
||||
&CLSID_PSFactoryBuffer_ole2disp,
|
||||
&CLSID_PSFactoryBuffer_ole2disp
|
||||
},
|
||||
{ &IID_ITypeLib2,
|
||||
"ITypeLib2",
|
||||
NULL,
|
||||
16,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_ole2disp
|
||||
},
|
||||
{ &IID_ITypeInfo2,
|
||||
"ITypeInfo2",
|
||||
NULL,
|
||||
32,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_ole2disp
|
||||
},
|
||||
{ &IID_IPropertyPage2,
|
||||
"IPropertyPage2",
|
||||
NULL,
|
||||
15,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IErrorInfo,
|
||||
"IErrorInfo",
|
||||
NULL,
|
||||
8,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_ICreateErrorInfo,
|
||||
"ICreateErrorInfo",
|
||||
NULL,
|
||||
8,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPersistPropertyBag2,
|
||||
"IPersistPropertyBag2",
|
||||
NULL,
|
||||
8,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPropertyBag2,
|
||||
"IPropertyBag2",
|
||||
NULL,
|
||||
8,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IErrorLog,
|
||||
"IErrorLog",
|
||||
NULL,
|
||||
4,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPerPropertyBrowsing,
|
||||
"IPerPropertyBrowsing",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPersistPropertyBag,
|
||||
"IPersistPropertyBag",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IAdviseSinkEx,
|
||||
"IAdviseSinkEx",
|
||||
NULL,
|
||||
9,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IFontEventsDisp,
|
||||
"IFontEventsDisp",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPropertyBag,
|
||||
"IPropertyBag",
|
||||
NULL,
|
||||
5,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPointerInactive,
|
||||
"IPointerInactive",
|
||||
NULL,
|
||||
6,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_ISimpleFrameSite,
|
||||
"ISimpleFrameSite",
|
||||
NULL,
|
||||
5,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPicture,
|
||||
"IPicture",
|
||||
NULL,
|
||||
17,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPictureDisp,
|
||||
"IPictureDisp",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPersistStreamInit,
|
||||
"IPersistStreamInit",
|
||||
NULL,
|
||||
9,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IOleUndoUnit,
|
||||
"IOleUndoUnit",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPropertyNotifySink,
|
||||
"IPropertyNotifySink",
|
||||
NULL,
|
||||
5,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IOleInPlaceSiteEx,
|
||||
"IOleInPlaceSiteEx",
|
||||
NULL,
|
||||
18,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IOleParentUndoUnit,
|
||||
"IOleParentUndoUnit",
|
||||
NULL,
|
||||
12,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IProvideClassInfo2,
|
||||
"IProvideClassInfo2",
|
||||
NULL,
|
||||
5,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IProvideMultipleClassInfo,
|
||||
"IProvideMultipleClassInfo",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IProvideClassInfo,
|
||||
"IProvideClassInfo",
|
||||
NULL,
|
||||
4,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IConnectionPointContainer,
|
||||
"IConnectionPointContainer",
|
||||
NULL,
|
||||
5,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IEnumConnectionPoints,
|
||||
"IEnumConnectionPoints",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IConnectionPoint,
|
||||
"IConnectionPoint",
|
||||
NULL,
|
||||
8,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IEnumConnections,
|
||||
"IEnumConnections",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IOleControl,
|
||||
"IOleControl",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IOleControlSite,
|
||||
"IOleControlSite",
|
||||
NULL,
|
||||
10,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_ISpecifyPropertyPages,
|
||||
"ISpecifyPropertyPages",
|
||||
NULL,
|
||||
4,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPropertyPageSite,
|
||||
"IPropertyPageSite",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPropertyPage,
|
||||
"IPropertyPage",
|
||||
NULL,
|
||||
14,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IClassFactory2,
|
||||
"IClassFactory2",
|
||||
NULL,
|
||||
8,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IEnumOleUndoUnits,
|
||||
"IEnumOleUndoUnits",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IPersistMemory,
|
||||
"IPersistMemory",
|
||||
NULL,
|
||||
9,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IFont,
|
||||
"IFont",
|
||||
NULL,
|
||||
27,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IFontDisp,
|
||||
"IFontDisp",
|
||||
NULL,
|
||||
7,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IQuickActivate,
|
||||
"IQuickActivate",
|
||||
NULL,
|
||||
6,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IOleUndoManager,
|
||||
"IOleUndoManager",
|
||||
NULL,
|
||||
15,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ &IID_IObjectWithSite,
|
||||
"IObjectWithSite",
|
||||
NULL,
|
||||
5,
|
||||
NULL,
|
||||
&CLSID_PSFactoryBuffer_oleaut32
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* DllRegisterServer (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI OLE32_DllRegisterServer()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hr = register_coclasses(coclass_list);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = register_interfaces(interface_list);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllUnregisterServer (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI OLE32_DllUnregisterServer()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hr = unregister_coclasses(coclass_list);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = unregister_interfaces(interface_list);
|
||||
return hr;
|
||||
}
|
||||
@@ -1,805 +0,0 @@
|
||||
/*
|
||||
* (Local) RPC Stuff
|
||||
*
|
||||
* Copyright 2002 Marcus Meissner
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
#include "ole2ver.h"
|
||||
#include "rpc.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "wownt32.h"
|
||||
#include "wtypes.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "compobj_private.h"
|
||||
#include "ifs.h"
|
||||
|
||||
#include "compobj_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
#define REQTYPE_REQUEST 0
|
||||
typedef struct _wine_rpc_request_header {
|
||||
DWORD reqid;
|
||||
wine_marshal_id mid;
|
||||
DWORD iMethod;
|
||||
DWORD cbBuffer;
|
||||
} wine_rpc_request_header;
|
||||
|
||||
#define REQTYPE_RESPONSE 1
|
||||
typedef struct _wine_rpc_response_header {
|
||||
DWORD reqid;
|
||||
DWORD cbBuffer;
|
||||
DWORD retval;
|
||||
} wine_rpc_response_header;
|
||||
|
||||
/* used when shutting down a pipe, e.g. at the end of a process */
|
||||
#define REQTYPE_DISCONNECT 2
|
||||
typedef struct _wine_rpc_disconnect_header {
|
||||
DWORD reqid;
|
||||
wine_marshal_id mid; /* mid of stub to delete */
|
||||
} wine_rpc_disconnect_header;
|
||||
|
||||
|
||||
#define REQSTATE_START 0
|
||||
#define REQSTATE_REQ_QUEUED 1
|
||||
#define REQSTATE_REQ_WAITING_FOR_REPLY 2
|
||||
#define REQSTATE_REQ_GOT 3
|
||||
#define REQSTATE_INVOKING 4
|
||||
#define REQSTATE_RESP_QUEUED 5
|
||||
#define REQSTATE_RESP_GOT 6
|
||||
#define REQSTATE_DONE 6
|
||||
|
||||
typedef struct _wine_rpc_request {
|
||||
int state;
|
||||
HANDLE hPipe; /* temp copy of handle */
|
||||
wine_rpc_request_header reqh;
|
||||
wine_rpc_response_header resph;
|
||||
LPBYTE Buffer;
|
||||
} wine_rpc_request;
|
||||
|
||||
static wine_rpc_request **reqs = NULL;
|
||||
static int nrofreqs = 0;
|
||||
|
||||
/* This pipe is _thread_ based, each thread which talks to a remote
|
||||
* apartment (mid) has its own pipe */
|
||||
typedef struct _wine_pipe {
|
||||
wine_marshal_id mid; /* target mid */
|
||||
DWORD tid; /* thread which owns this outgoing pipe */
|
||||
HANDLE hPipe;
|
||||
|
||||
int pending;
|
||||
HANDLE hThread;
|
||||
CRITICAL_SECTION crit;
|
||||
} wine_pipe;
|
||||
|
||||
static wine_pipe *pipes = NULL;
|
||||
static int nrofpipes = 0;
|
||||
|
||||
typedef struct _PipeBuf {
|
||||
IRpcChannelBufferVtbl *lpVtbl;
|
||||
DWORD ref;
|
||||
|
||||
wine_marshal_id mid;
|
||||
wine_pipe *pipe;
|
||||
} PipeBuf;
|
||||
|
||||
static HRESULT WINAPI
|
||||
read_pipe(HANDLE hf, LPVOID ptr, DWORD size) {
|
||||
DWORD res;
|
||||
if (!ReadFile(hf,ptr,size,&res,NULL)) {
|
||||
FIXME("Failed to read from %p, le is %lx\n",hf,GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
if (res!=size) {
|
||||
FIXME("Read only %ld of %ld bytes from %p.\n",res,size,hf);
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
drs(LPCSTR where) {
|
||||
#if 0
|
||||
static int nrofreaders = 0;
|
||||
|
||||
int i, states[10];
|
||||
|
||||
memset(states,0,sizeof(states));
|
||||
for (i=nrofreqs;i--;)
|
||||
states[reqs[i]->state]++;
|
||||
FIXME("%lx/%s/%d: rq %d, w %d, rg %d, rsq %d, rsg %d, d %d\n",
|
||||
GetCurrentProcessId(),
|
||||
where,
|
||||
nrofreaders,
|
||||
states[REQSTATE_REQ_QUEUED],
|
||||
states[REQSTATE_REQ_WAITING_FOR_REPLY],
|
||||
states[REQSTATE_REQ_GOT],
|
||||
states[REQSTATE_RESP_QUEUED],
|
||||
states[REQSTATE_RESP_GOT],
|
||||
states[REQSTATE_DONE]
|
||||
);
|
||||
#endif
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
write_pipe(HANDLE hf, LPVOID ptr, DWORD size) {
|
||||
DWORD res;
|
||||
if (!WriteFile(hf,ptr,size,&res,NULL)) {
|
||||
FIXME("Failed to write to %p, le is %lx\n",hf,GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
if (res!=size) {
|
||||
FIXME("Wrote only %ld of %ld bytes to %p.\n",res,size,hf);
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static DWORD WINAPI _StubReaderThread(LPVOID);
|
||||
|
||||
static HRESULT
|
||||
PIPE_RegisterPipe(wine_marshal_id *mid, HANDLE hPipe, BOOL startreader) {
|
||||
int i;
|
||||
char pipefn[100];
|
||||
wine_pipe *new_pipes;
|
||||
|
||||
for (i=0;i<nrofpipes;i++)
|
||||
if (pipes[i].mid.processid==mid->processid)
|
||||
return S_OK;
|
||||
if (pipes)
|
||||
new_pipes=(wine_pipe*)HeapReAlloc(GetProcessHeap(),0,pipes,sizeof(pipes[0])*(nrofpipes+1));
|
||||
else
|
||||
new_pipes=(wine_pipe*)HeapAlloc(GetProcessHeap(),0,sizeof(pipes[0]));
|
||||
if (!new_pipes) return E_OUTOFMEMORY;
|
||||
pipes = new_pipes;
|
||||
sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
|
||||
memcpy(&(pipes[nrofpipes].mid),mid,sizeof(*mid));
|
||||
pipes[nrofpipes].hPipe = hPipe;
|
||||
InitializeCriticalSection(&(pipes[nrofpipes].crit));
|
||||
nrofpipes++;
|
||||
if (startreader) {
|
||||
pipes[nrofpipes-1].hThread = CreateThread(NULL,0,_StubReaderThread,(LPVOID)(pipes+(nrofpipes-1)),0,&(pipes[nrofpipes-1].tid));
|
||||
} else {
|
||||
pipes[nrofpipes-1].tid = GetCurrentThreadId();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HANDLE
|
||||
PIPE_FindByMID(wine_marshal_id *mid) {
|
||||
int i;
|
||||
for (i=0;i<nrofpipes;i++)
|
||||
if ((pipes[i].mid.processid==mid->processid) &&
|
||||
(GetCurrentThreadId()==pipes[i].tid)
|
||||
)
|
||||
return pipes[i].hPipe;
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static wine_pipe*
|
||||
PIPE_GetFromMID(wine_marshal_id *mid) {
|
||||
int i;
|
||||
for (i=0;i<nrofpipes;i++) {
|
||||
if ((pipes[i].mid.processid==mid->processid) &&
|
||||
(GetCurrentThreadId()==pipes[i].tid)
|
||||
)
|
||||
return pipes+i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
RPC_GetRequest(wine_rpc_request **req) {
|
||||
static int reqid = 0xdeadbeef;
|
||||
int i;
|
||||
|
||||
for (i=0;i<nrofreqs;i++) { /* try to reuse */
|
||||
if (reqs[i]->state == REQSTATE_DONE) {
|
||||
reqs[i]->reqh.reqid = reqid++;
|
||||
reqs[i]->resph.reqid = reqs[i]->reqh.reqid;
|
||||
reqs[i]->hPipe = INVALID_HANDLE_VALUE;
|
||||
*req = reqs[i];
|
||||
reqs[i]->state = REQSTATE_START;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
/* create new */
|
||||
if (reqs)
|
||||
reqs = (wine_rpc_request**)HeapReAlloc(
|
||||
GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
reqs,
|
||||
sizeof(wine_rpc_request*)*(nrofreqs+1)
|
||||
);
|
||||
else
|
||||
reqs = (wine_rpc_request**)HeapAlloc(
|
||||
GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(wine_rpc_request*)
|
||||
);
|
||||
if (!reqs)
|
||||
return E_OUTOFMEMORY;
|
||||
reqs[nrofreqs] = (wine_rpc_request*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(wine_rpc_request));
|
||||
reqs[nrofreqs]->reqh.reqid = reqid++;
|
||||
reqs[nrofreqs]->resph.reqid = reqs[nrofreqs]->reqh.reqid;
|
||||
reqs[nrofreqs]->hPipe = INVALID_HANDLE_VALUE;
|
||||
*req = reqs[nrofreqs];
|
||||
reqs[nrofreqs]->state = REQSTATE_START;
|
||||
nrofreqs++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
RPC_FreeRequest(wine_rpc_request *req) {
|
||||
req->state = REQSTATE_DONE; /* Just reuse slot. */
|
||||
return;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_QueryInterface(
|
||||
LPRPCCHANNELBUFFER iface,REFIID riid,LPVOID *ppv
|
||||
) {
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown)) {
|
||||
*ppv = (LPVOID)iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) {
|
||||
PipeBuf *This = (PipeBuf *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
|
||||
PipeBuf *This = (PipeBuf *)iface;
|
||||
ULONG ref;
|
||||
wine_rpc_disconnect_header header;
|
||||
HANDLE pipe;
|
||||
DWORD reqtype = REQTYPE_DISCONNECT;
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (ref)
|
||||
return ref;
|
||||
|
||||
FIXME("Free all stuff\n");
|
||||
|
||||
memcpy(&header.mid, &This->mid, sizeof(wine_marshal_id));
|
||||
|
||||
pipe = PIPE_FindByMID(&This->mid);
|
||||
|
||||
write_pipe(pipe, &reqtype, sizeof(reqtype));
|
||||
write_pipe(pipe, &header, sizeof(wine_rpc_disconnect_header));
|
||||
|
||||
TRACE("written disconnect packet\n");
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_GetBuffer(
|
||||
LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,REFIID riid
|
||||
) {
|
||||
/*PipeBuf *This = (PipeBuf *)iface;*/
|
||||
|
||||
TRACE("(%p,%s)\n",msg,debugstr_guid(riid));
|
||||
/* probably reuses IID in real. */
|
||||
if (msg->cbBuffer && (msg->Buffer == NULL))
|
||||
msg->Buffer = HeapAlloc(GetProcessHeap(),0,msg->cbBuffer);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
COM_InvokeAndRpcSend(wine_rpc_request *req) {
|
||||
IRpcStubBuffer *stub;
|
||||
RPCOLEMESSAGE msg;
|
||||
HRESULT hres;
|
||||
DWORD reqtype;
|
||||
|
||||
hres = MARSHAL_Find_Stub_Buffer(&(req->reqh.mid),&stub);
|
||||
if (hres) {
|
||||
ERR("Stub not found?\n");
|
||||
return hres;
|
||||
}
|
||||
msg.Buffer = req->Buffer;
|
||||
msg.iMethod = req->reqh.iMethod;
|
||||
msg.cbBuffer = req->reqh.cbBuffer;
|
||||
msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
||||
req->state = REQSTATE_INVOKING;
|
||||
req->resph.retval = IRpcStubBuffer_Invoke(stub,&msg,NULL);
|
||||
IUnknown_Release(stub);
|
||||
req->Buffer = msg.Buffer;
|
||||
req->resph.cbBuffer = msg.cbBuffer;
|
||||
reqtype = REQTYPE_RESPONSE;
|
||||
hres = write_pipe(req->hPipe,&reqtype,sizeof(reqtype));
|
||||
if (hres) return hres;
|
||||
hres = write_pipe(req->hPipe,&(req->resph),sizeof(req->resph));
|
||||
if (hres) return hres;
|
||||
hres = write_pipe(req->hPipe,req->Buffer,req->resph.cbBuffer);
|
||||
if (hres) return hres;
|
||||
req->state = REQSTATE_DONE;
|
||||
drs("invoke");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT COM_RpcReceive(wine_pipe *xpipe);
|
||||
|
||||
static HRESULT
|
||||
RPC_QueueRequestAndWait(wine_rpc_request *req) {
|
||||
int i;
|
||||
wine_rpc_request *xreq;
|
||||
HRESULT hres;
|
||||
DWORD reqtype;
|
||||
wine_pipe *xpipe = PIPE_GetFromMID(&(req->reqh.mid));
|
||||
|
||||
if (!xpipe) {
|
||||
FIXME("no pipe found.\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
if (GetCurrentProcessId() == req->reqh.mid.processid) {
|
||||
ERR("In current process?\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
req->hPipe = xpipe->hPipe;
|
||||
req->state = REQSTATE_REQ_WAITING_FOR_REPLY;
|
||||
reqtype = REQTYPE_REQUEST;
|
||||
hres = write_pipe(req->hPipe,&reqtype,sizeof(reqtype));
|
||||
if (hres) return hres;
|
||||
hres = write_pipe(req->hPipe,&(req->reqh),sizeof(req->reqh));
|
||||
if (hres) return hres;
|
||||
hres = write_pipe(req->hPipe,req->Buffer,req->reqh.cbBuffer);
|
||||
if (hres) return hres;
|
||||
|
||||
/* This loop is about allowing re-entrancy. While waiting for the
|
||||
* response to one RPC we may receive a request starting another. */
|
||||
while (!hres) {
|
||||
hres = COM_RpcReceive(xpipe);
|
||||
if (hres) break;
|
||||
|
||||
for (i=0;i<nrofreqs;i++) {
|
||||
xreq = reqs[i];
|
||||
if ((xreq->state==REQSTATE_REQ_GOT) && (xreq->hPipe==req->hPipe)) {
|
||||
hres = COM_InvokeAndRpcSend(xreq);
|
||||
if (hres) break;
|
||||
}
|
||||
}
|
||||
if (req->state == REQSTATE_RESP_GOT)
|
||||
return S_OK;
|
||||
}
|
||||
if (FAILED(hres))
|
||||
WARN("-- 0x%08lx\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_SendReceive(
|
||||
LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,ULONG *status
|
||||
) {
|
||||
PipeBuf *This = (PipeBuf *)iface;
|
||||
wine_rpc_request *req;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
if (This->mid.processid == GetCurrentProcessId()) {
|
||||
ERR("Need to call directly!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hres = RPC_GetRequest(&req);
|
||||
if (hres) return hres;
|
||||
req->reqh.iMethod = msg->iMethod;
|
||||
req->reqh.cbBuffer = msg->cbBuffer;
|
||||
memcpy(&(req->reqh.mid),&(This->mid),sizeof(This->mid));
|
||||
req->Buffer = msg->Buffer;
|
||||
hres = RPC_QueueRequestAndWait(req);
|
||||
if (hres) {
|
||||
RPC_FreeRequest(req);
|
||||
return hres;
|
||||
}
|
||||
msg->cbBuffer = req->resph.cbBuffer;
|
||||
msg->Buffer = req->Buffer;
|
||||
*status = req->resph.retval;
|
||||
RPC_FreeRequest(req);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_FreeBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg) {
|
||||
FIXME("(%p), stub!\n",msg);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_GetDestCtx(
|
||||
LPRPCCHANNELBUFFER iface,DWORD* pdwDestContext,void** ppvDestContext
|
||||
) {
|
||||
FIXME("(%p,%p), stub!\n",pdwDestContext,ppvDestContext);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
PipeBuf_IsConnected(LPRPCCHANNELBUFFER iface) {
|
||||
FIXME("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IRpcChannelBufferVtbl pipebufvt = {
|
||||
PipeBuf_QueryInterface,
|
||||
PipeBuf_AddRef,
|
||||
PipeBuf_Release,
|
||||
PipeBuf_GetBuffer,
|
||||
PipeBuf_SendReceive,
|
||||
PipeBuf_FreeBuffer,
|
||||
PipeBuf_GetDestCtx,
|
||||
PipeBuf_IsConnected
|
||||
};
|
||||
|
||||
HRESULT
|
||||
PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf) {
|
||||
wine_marshal_id ourid;
|
||||
DWORD res;
|
||||
HANDLE hPipe;
|
||||
HRESULT hres;
|
||||
PipeBuf *pbuf;
|
||||
|
||||
hPipe = PIPE_FindByMID(mid);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
char pipefn[200];
|
||||
sprintf(pipefn,OLESTUBMGR"_%08lx",mid->processid);
|
||||
hPipe = CreateFileA(
|
||||
pipefn,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
0
|
||||
);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
FIXME("Could not open named pipe %s, le is %lx\n",pipefn,GetLastError());
|
||||
return E_FAIL;
|
||||
}
|
||||
hres = PIPE_RegisterPipe(mid, hPipe, FALSE);
|
||||
if (hres) return hres;
|
||||
memset(&ourid,0,sizeof(ourid));
|
||||
ourid.processid = GetCurrentProcessId();
|
||||
if (!WriteFile(hPipe,&ourid,sizeof(ourid),&res,NULL)||(res!=sizeof(ourid))) {
|
||||
ERR("Failed writing startup mid!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
pbuf = (PipeBuf*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PipeBuf));
|
||||
pbuf->lpVtbl = &pipebufvt;
|
||||
pbuf->ref = 1;
|
||||
memcpy(&(pbuf->mid),mid,sizeof(*mid));
|
||||
*pipebuf = (IRpcChannelBuffer*)pbuf;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
create_server(REFCLSID rclsid) {
|
||||
static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
|
||||
HKEY key;
|
||||
char buf[200];
|
||||
HRESULT hres = E_UNEXPECTED;
|
||||
char xclsid[80];
|
||||
WCHAR exe[MAX_PATH+1];
|
||||
DWORD exelen = sizeof(exe);
|
||||
WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
|
||||
STARTUPINFOW sinfo;
|
||||
PROCESS_INFORMATION pinfo;
|
||||
|
||||
WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
|
||||
|
||||
sprintf(buf,"CLSID\\%s\\LocalServer32",xclsid);
|
||||
hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key);
|
||||
|
||||
if (hres != ERROR_SUCCESS) {
|
||||
WARN("CLSID %s not registered as LocalServer32\n", xclsid);
|
||||
return REGDB_E_READREGDB; /* Probably */
|
||||
}
|
||||
|
||||
memset(exe,0,sizeof(exe));
|
||||
hres= RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)exe, &exelen);
|
||||
RegCloseKey(key);
|
||||
if (hres) {
|
||||
WARN("No default value for LocalServer32 key\n");
|
||||
return REGDB_E_CLASSNOTREG; /* FIXME: check retval */
|
||||
}
|
||||
|
||||
memset(&sinfo,0,sizeof(sinfo));
|
||||
sinfo.cb = sizeof(sinfo);
|
||||
|
||||
/* EXE servers are started with the -Embedding switch. MSDN also claims /Embedding is used,
|
||||
9x does -Embedding, perhaps an 9x/NT difference? */
|
||||
|
||||
strcpyW(command, exe);
|
||||
strcatW(command, embedding);
|
||||
|
||||
TRACE("activating local server '%s' for %s\n", debugstr_w(command), xclsid);
|
||||
|
||||
if (!CreateProcessW(exe, command, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) {
|
||||
WARN("failed to run local server %s\n", debugstr_w(exe));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
/* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, Figure 4 */
|
||||
HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) {
|
||||
HRESULT hres;
|
||||
HANDLE hPipe;
|
||||
char pipefn[200];
|
||||
DWORD res,bufferlen;
|
||||
char marshalbuffer[200];
|
||||
IStream *pStm;
|
||||
LARGE_INTEGER seekto;
|
||||
ULARGE_INTEGER newpos;
|
||||
int tries = 0;
|
||||
#define MAXTRIES 10000
|
||||
|
||||
TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
|
||||
|
||||
strcpy(pipefn,PIPEPREF);
|
||||
WINE_StringFromCLSID(rclsid,pipefn+strlen(PIPEPREF));
|
||||
|
||||
while (tries++<MAXTRIES) {
|
||||
WaitNamedPipeA( pipefn, NMPWAIT_WAIT_FOREVER );
|
||||
hPipe = CreateFileA(
|
||||
pipefn,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
0
|
||||
);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
if (tries == 1) {
|
||||
if ((hres = create_server(rclsid)))
|
||||
return hres;
|
||||
Sleep(1000);
|
||||
} else {
|
||||
WARN("Could not open named pipe to broker %s, le is %lx\n",pipefn,GetLastError());
|
||||
Sleep(1000);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
bufferlen = 0;
|
||||
if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) {
|
||||
FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid));
|
||||
Sleep(1000);
|
||||
continue;
|
||||
}
|
||||
CloseHandle(hPipe);
|
||||
break;
|
||||
}
|
||||
if (tries>=MAXTRIES)
|
||||
return E_NOINTERFACE;
|
||||
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
|
||||
if (hres) return hres;
|
||||
hres = IStream_Write(pStm,marshalbuffer,bufferlen,&res);
|
||||
if (hres) goto out;
|
||||
seekto.u.LowPart = 0;seekto.u.HighPart = 0;
|
||||
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
|
||||
hres = CoUnmarshalInterface(pStm,&IID_IClassFactory,ppv);
|
||||
out:
|
||||
IStream_Release(pStm);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
static void WINAPI
|
||||
PIPE_StartRequestThread(HANDLE xhPipe) {
|
||||
wine_marshal_id remoteid;
|
||||
HRESULT hres;
|
||||
|
||||
hres = read_pipe(xhPipe,&remoteid,sizeof(remoteid));
|
||||
if (hres) {
|
||||
ERR("Failed to read remote mid!\n");
|
||||
return;
|
||||
}
|
||||
PIPE_RegisterPipe(&remoteid,xhPipe, TRUE);
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
COM_RpcReceive(wine_pipe *xpipe) {
|
||||
DWORD reqtype;
|
||||
HRESULT hres = S_OK;
|
||||
HANDLE xhPipe = xpipe->hPipe;
|
||||
|
||||
/*FIXME("%lx %d reading reqtype\n",GetCurrentProcessId(),xhPipe);*/
|
||||
hres = read_pipe(xhPipe,&reqtype,sizeof(reqtype));
|
||||
if (hres) goto end;
|
||||
EnterCriticalSection(&(xpipe->crit));
|
||||
/*FIXME("%lx got reqtype %ld\n",GetCurrentProcessId(),reqtype);*/
|
||||
|
||||
if (reqtype == REQTYPE_DISCONNECT) { /* only received by servers */
|
||||
wine_rpc_disconnect_header header;
|
||||
IRpcStubBuffer *stub;
|
||||
ULONG ret;
|
||||
|
||||
hres = read_pipe(xhPipe, &header, sizeof(header));
|
||||
if (hres) {
|
||||
ERR("could not read disconnect header\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
TRACE("read disconnect header\n");
|
||||
|
||||
hres = MARSHAL_Find_Stub_Buffer(&header.mid, &stub);
|
||||
if (hres) {
|
||||
ERR("could not locate stub to disconnect, mid.objectid=%p\n", (void*)header.mid.objectid);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
/* release reference added by MARSHAL_Find_Stub_Buffer call */
|
||||
IRpcStubBuffer_Release(stub);
|
||||
/* release it for real */
|
||||
ret = IRpcStubBuffer_Release(stub);
|
||||
/* FIXME: race */
|
||||
if (ret == 0)
|
||||
MARSHAL_Invalidate_Stub_From_MID(&header.mid);
|
||||
goto end;
|
||||
} else if (reqtype == REQTYPE_REQUEST) {
|
||||
wine_rpc_request *xreq;
|
||||
RPC_GetRequest(&xreq);
|
||||
xreq->hPipe = xhPipe;
|
||||
hres = read_pipe(xhPipe,&(xreq->reqh),sizeof(xreq->reqh));
|
||||
if (hres) goto end;
|
||||
xreq->resph.reqid = xreq->reqh.reqid;
|
||||
xreq->Buffer = HeapAlloc(GetProcessHeap(),0, xreq->reqh.cbBuffer);
|
||||
hres = read_pipe(xhPipe,xreq->Buffer,xreq->reqh.cbBuffer);
|
||||
if (hres) goto end;
|
||||
xreq->state = REQSTATE_REQ_GOT;
|
||||
goto end;
|
||||
} else if (reqtype == REQTYPE_RESPONSE) {
|
||||
wine_rpc_response_header resph;
|
||||
int i;
|
||||
|
||||
hres = read_pipe(xhPipe,&resph,sizeof(resph));
|
||||
if (hres) goto end;
|
||||
for (i=nrofreqs;i--;) {
|
||||
wine_rpc_request *xreq = reqs[i];
|
||||
if (xreq->state != REQSTATE_REQ_WAITING_FOR_REPLY)
|
||||
continue;
|
||||
if (xreq->reqh.reqid == resph.reqid) {
|
||||
memcpy(&(xreq->resph),&resph,sizeof(resph));
|
||||
|
||||
if (xreq->Buffer)
|
||||
xreq->Buffer = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,xreq->Buffer,xreq->resph.cbBuffer);
|
||||
else
|
||||
xreq->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,xreq->resph.cbBuffer);
|
||||
|
||||
hres = read_pipe(xhPipe,xreq->Buffer,xreq->resph.cbBuffer);
|
||||
if (hres) goto end;
|
||||
xreq->state = REQSTATE_RESP_GOT;
|
||||
/*PulseEvent(hRpcChanged);*/
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ERR("Did not find request for id %lx\n",resph.reqid);
|
||||
hres = S_OK;
|
||||
goto end;
|
||||
}
|
||||
ERR("Unknown reqtype %ld\n",reqtype);
|
||||
hres = E_FAIL;
|
||||
end:
|
||||
LeaveCriticalSection(&(xpipe->crit));
|
||||
return hres;
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
_StubReaderThread(LPVOID param) {
|
||||
wine_pipe *xpipe = (wine_pipe*)param;
|
||||
HANDLE xhPipe = xpipe->hPipe;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("STUB reader thread %lx\n",GetCurrentProcessId());
|
||||
while (!hres) {
|
||||
int i;
|
||||
hres = COM_RpcReceive(xpipe);
|
||||
if (hres) break;
|
||||
|
||||
for (i=nrofreqs;i--;) {
|
||||
wine_rpc_request *xreq = reqs[i];
|
||||
if ((xreq->state == REQSTATE_REQ_GOT) && (xreq->hPipe == xhPipe)) {
|
||||
hres = COM_InvokeAndRpcSend(xreq);
|
||||
if (!hres) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
FIXME("Failed with hres %lx\n",hres);
|
||||
CloseHandle(xhPipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
_StubMgrThread(LPVOID param) {
|
||||
char pipefn[200];
|
||||
HANDLE listenPipe;
|
||||
|
||||
sprintf(pipefn,OLESTUBMGR"_%08lx",GetCurrentProcessId());
|
||||
TRACE("Stub Manager Thread starting on (%s)\n",pipefn);
|
||||
|
||||
while (1) {
|
||||
listenPipe = CreateNamedPipeA(
|
||||
pipefn,
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_BYTE|PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
4096,
|
||||
4096,
|
||||
NMPWAIT_USE_DEFAULT_WAIT,
|
||||
NULL
|
||||
);
|
||||
if (listenPipe == INVALID_HANDLE_VALUE) {
|
||||
FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError());
|
||||
return 1; /* permanent failure, so quit stubmgr thread */
|
||||
}
|
||||
if (!ConnectNamedPipe(listenPipe,NULL)) {
|
||||
ERR("Failure during ConnectNamedPipe %lx!\n",GetLastError());
|
||||
CloseHandle(listenPipe);
|
||||
continue;
|
||||
}
|
||||
PIPE_StartRequestThread(listenPipe);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
STUBMGR_Start() {
|
||||
static BOOL stubMgrRunning = FALSE;
|
||||
DWORD tid;
|
||||
|
||||
if (!stubMgrRunning) {
|
||||
stubMgrRunning = TRUE;
|
||||
CreateThread(NULL,0,_StubMgrThread,NULL,0,&tid);
|
||||
Sleep(2000); /* actually we just try opening the pipe until it succeeds */
|
||||
}
|
||||
}
|
||||
@@ -1,872 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* BigBlockFile
|
||||
*
|
||||
* This is the implementation of a file that consists of blocks of
|
||||
* a predetermined size.
|
||||
* This class is used in the Compound File implementation of the
|
||||
* IStorage and IStream interfaces. It provides the functionality
|
||||
* to read and write any blocks in the file as well as setting and
|
||||
* obtaining the size of the file.
|
||||
* The blocks are indexed sequentially from the start of the file
|
||||
* starting with -1.
|
||||
*
|
||||
* TODO:
|
||||
* - Support for a transacted mode
|
||||
*
|
||||
* Copyright 1999 Thuy Nguyen
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "objbase.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "storage32.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(storage);
|
||||
|
||||
/***********************************************************
|
||||
* Data structures used internally by the BigBlockFile
|
||||
* class.
|
||||
*/
|
||||
|
||||
/* We map in PAGE_SIZE-sized chunks. Must be a multiple of 4096. */
|
||||
#define PAGE_SIZE 131072
|
||||
|
||||
#define BLOCKS_PER_PAGE (PAGE_SIZE / BIG_BLOCK_SIZE)
|
||||
|
||||
/* We keep a list of recently-discarded pages. This controls the
|
||||
* size of that list. */
|
||||
#define MAX_VICTIM_PAGES 16
|
||||
|
||||
/* This structure provides one bit for each block in a page.
|
||||
* Use BIGBLOCKFILE_{Test,Set,Clear}Bit to manipulate it. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned int bits[BLOCKS_PER_PAGE / (CHAR_BIT * sizeof(unsigned int))];
|
||||
} BlockBits;
|
||||
|
||||
/***
|
||||
* This structure identifies the paged that are mapped
|
||||
* from the file and their position in memory. It is
|
||||
* also used to hold a reference count to those pages.
|
||||
*
|
||||
* page_index identifies which PAGE_SIZE chunk from the
|
||||
* file this mapping represents. (The mappings are always
|
||||
* PAGE_SIZE-aligned.)
|
||||
*/
|
||||
struct MappedPage
|
||||
{
|
||||
MappedPage *next;
|
||||
MappedPage *prev;
|
||||
|
||||
DWORD page_index;
|
||||
LPVOID lpBytes;
|
||||
LONG refcnt;
|
||||
|
||||
BlockBits readable_blocks;
|
||||
BlockBits writable_blocks;
|
||||
};
|
||||
|
||||
/***********************************************************
|
||||
* Prototypes for private methods
|
||||
*/
|
||||
static void* BIGBLOCKFILE_GetMappedView(LPBIGBLOCKFILE This,
|
||||
DWORD page_index);
|
||||
static void BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This,
|
||||
MappedPage *page);
|
||||
static void BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This);
|
||||
static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This);
|
||||
static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This);
|
||||
static void* BIGBLOCKFILE_GetBigBlockPointer(LPBIGBLOCKFILE This,
|
||||
ULONG index,
|
||||
DWORD desired_access);
|
||||
static MappedPage* BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
|
||||
void* pBlock);
|
||||
static MappedPage* BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
|
||||
ULONG page_index);
|
||||
static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
|
||||
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile);
|
||||
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt);
|
||||
|
||||
/* Note that this evaluates a and b multiple times, so don't
|
||||
* pass expressions with side effects. */
|
||||
#define ROUND_UP(a, b) ((((a) + (b) - 1)/(b))*(b))
|
||||
|
||||
/***********************************************************
|
||||
* Blockbits functions.
|
||||
*/
|
||||
static inline BOOL BIGBLOCKFILE_TestBit(const BlockBits *bb,
|
||||
unsigned int index)
|
||||
{
|
||||
unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
|
||||
unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
|
||||
|
||||
return bb->bits[array_index] & (1 << bit_index);
|
||||
}
|
||||
|
||||
static inline void BIGBLOCKFILE_SetBit(BlockBits *bb, unsigned int index)
|
||||
{
|
||||
unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
|
||||
unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
|
||||
|
||||
bb->bits[array_index] |= (1 << bit_index);
|
||||
}
|
||||
|
||||
static inline void BIGBLOCKFILE_ClearBit(BlockBits *bb, unsigned int index)
|
||||
{
|
||||
unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
|
||||
unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
|
||||
|
||||
bb->bits[array_index] &= ~(1 << bit_index);
|
||||
}
|
||||
|
||||
static inline void BIGBLOCKFILE_Zero(BlockBits *bb)
|
||||
{
|
||||
memset(bb->bits, 0, sizeof(bb->bits));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_Construct
|
||||
*
|
||||
* Construct a big block file. Create the file mapping object.
|
||||
* Create the read only mapped pages list, the writable mapped page list
|
||||
* and the blocks in use list.
|
||||
*/
|
||||
BigBlockFile * BIGBLOCKFILE_Construct(
|
||||
HANDLE hFile,
|
||||
ILockBytes* pLkByt,
|
||||
DWORD openFlags,
|
||||
ULONG blocksize,
|
||||
BOOL fileBased)
|
||||
{
|
||||
LPBIGBLOCKFILE This;
|
||||
|
||||
This = (LPBIGBLOCKFILE)HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlockFile));
|
||||
|
||||
if (This == NULL)
|
||||
return NULL;
|
||||
|
||||
This->fileBased = fileBased;
|
||||
|
||||
This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);
|
||||
|
||||
This->blocksize = blocksize;
|
||||
|
||||
This->maplist = NULL;
|
||||
This->victimhead = NULL;
|
||||
This->victimtail = NULL;
|
||||
This->num_victim_pages = 0;
|
||||
|
||||
if (This->fileBased)
|
||||
{
|
||||
if (!BIGBLOCKFILE_FileInit(This, hFile))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BIGBLOCKFILE_MemInit(This, pLkByt))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return This;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_FileInit
|
||||
*
|
||||
* Initialize a big block object supported by a file.
|
||||
*/
|
||||
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
|
||||
{
|
||||
This->pLkbyt = NULL;
|
||||
This->hbytearray = 0;
|
||||
This->pbytearray = NULL;
|
||||
|
||||
This->hfile = hFile;
|
||||
|
||||
if (This->hfile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
This->filesize.u.LowPart = GetFileSize(This->hfile,
|
||||
&This->filesize.u.HighPart);
|
||||
|
||||
if( This->filesize.u.LowPart || This->filesize.u.HighPart )
|
||||
{
|
||||
/* create the file mapping object
|
||||
*/
|
||||
This->hfilemap = CreateFileMappingA(This->hfile,
|
||||
NULL,
|
||||
This->flProtect,
|
||||
0, 0,
|
||||
NULL);
|
||||
|
||||
if (!This->hfilemap)
|
||||
{
|
||||
CloseHandle(This->hfile);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
This->hfilemap = NULL;
|
||||
|
||||
This->maplist = NULL;
|
||||
|
||||
TRACE("file len %lu\n", This->filesize.u.LowPart);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_MemInit
|
||||
*
|
||||
* Initialize a big block object supported by an ILockBytes on HGLOABL.
|
||||
*/
|
||||
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
|
||||
{
|
||||
This->hfile = 0;
|
||||
This->hfilemap = 0;
|
||||
|
||||
/*
|
||||
* Retrieve the handle to the byte array from the LockByte object.
|
||||
*/
|
||||
if (GetHGlobalFromILockBytes(plkbyt, &(This->hbytearray)) != S_OK)
|
||||
{
|
||||
FIXME("May not be an ILockBytes on HGLOBAL\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
This->pLkbyt = plkbyt;
|
||||
|
||||
/*
|
||||
* Increment the reference count of the ILockByte object since
|
||||
* we're keeping a reference to it.
|
||||
*/
|
||||
ILockBytes_AddRef(This->pLkbyt);
|
||||
|
||||
This->filesize.u.LowPart = GlobalSize(This->hbytearray);
|
||||
This->filesize.u.HighPart = 0;
|
||||
|
||||
This->pbytearray = GlobalLock(This->hbytearray);
|
||||
|
||||
TRACE("mem on %p len %lu\n", This->pbytearray, This->filesize.u.LowPart);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_Destructor
|
||||
*
|
||||
* Destructor. Clean up, free memory.
|
||||
*/
|
||||
void BIGBLOCKFILE_Destructor(
|
||||
LPBIGBLOCKFILE This)
|
||||
{
|
||||
BIGBLOCKFILE_FreeAllMappedPages(This);
|
||||
|
||||
if (This->fileBased)
|
||||
{
|
||||
CloseHandle(This->hfilemap);
|
||||
CloseHandle(This->hfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalUnlock(This->hbytearray);
|
||||
ILockBytes_Release(This->pLkbyt);
|
||||
}
|
||||
|
||||
/* destroy this
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_GetROBigBlock
|
||||
*
|
||||
* Returns the specified block in read only mode.
|
||||
* Will return NULL if the block doesn't exists.
|
||||
*/
|
||||
void* BIGBLOCKFILE_GetROBigBlock(
|
||||
LPBIGBLOCKFILE This,
|
||||
ULONG index)
|
||||
{
|
||||
/*
|
||||
* block index starts at -1
|
||||
* translate to zero based index
|
||||
*/
|
||||
if (index == 0xffffffff)
|
||||
index = 0;
|
||||
else
|
||||
index++;
|
||||
|
||||
/*
|
||||
* validate the block index
|
||||
*
|
||||
*/
|
||||
if (This->blocksize * (index + 1)
|
||||
> ROUND_UP(This->filesize.u.LowPart, This->blocksize))
|
||||
{
|
||||
TRACE("out of range %lu vs %lu\n", This->blocksize * (index + 1),
|
||||
This->filesize.u.LowPart);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_READ);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_GetBigBlock
|
||||
*
|
||||
* Returns the specified block.
|
||||
* Will grow the file if necessary.
|
||||
*/
|
||||
void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
|
||||
{
|
||||
/*
|
||||
* block index starts at -1
|
||||
* translate to zero based index
|
||||
*/
|
||||
if (index == 0xffffffff)
|
||||
index = 0;
|
||||
else
|
||||
index++;
|
||||
|
||||
/*
|
||||
* make sure that the block physically exists
|
||||
*/
|
||||
if ((This->blocksize * (index + 1)) > This->filesize.u.LowPart)
|
||||
{
|
||||
ULARGE_INTEGER newSize;
|
||||
|
||||
newSize.u.HighPart = 0;
|
||||
newSize.u.LowPart = This->blocksize * (index + 1);
|
||||
|
||||
BIGBLOCKFILE_SetSize(This, newSize);
|
||||
}
|
||||
|
||||
return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_WRITE);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_ReleaseBigBlock
|
||||
*
|
||||
* Releases the specified block.
|
||||
*/
|
||||
void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
|
||||
{
|
||||
MappedPage *page;
|
||||
|
||||
if (pBlock == NULL)
|
||||
return;
|
||||
|
||||
page = BIGBLOCKFILE_GetPageFromPointer(This, pBlock);
|
||||
|
||||
if (page == NULL)
|
||||
return;
|
||||
|
||||
BIGBLOCKFILE_ReleaseMappedPage(This, page);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_SetSize
|
||||
*
|
||||
* Sets the size of the file.
|
||||
*
|
||||
*/
|
||||
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
|
||||
{
|
||||
if (This->filesize.u.LowPart == newSize.u.LowPart)
|
||||
return;
|
||||
|
||||
TRACE("from %lu to %lu\n", This->filesize.u.LowPart, newSize.u.LowPart);
|
||||
/*
|
||||
* unmap all views, must be done before call to SetEndFile
|
||||
*/
|
||||
BIGBLOCKFILE_UnmapAllMappedPages(This);
|
||||
|
||||
if (This->fileBased)
|
||||
{
|
||||
char buf[10];
|
||||
|
||||
/*
|
||||
* close file-mapping object, must be done before call to SetEndFile
|
||||
*/
|
||||
if( This->hfilemap )
|
||||
CloseHandle(This->hfilemap);
|
||||
This->hfilemap = 0;
|
||||
|
||||
/*
|
||||
* BEGIN HACK
|
||||
* This fixes a bug when saving through smbfs.
|
||||
* smbmount a Windows shared directory, save a structured storage file
|
||||
* to that dir: crash.
|
||||
*
|
||||
* The problem is that the SetFilePointer-SetEndOfFile combo below
|
||||
* doesn't always succeed. The file is not grown. It seems like the
|
||||
* operation is cached. By doing the WriteFile, the file is actually
|
||||
* grown on disk.
|
||||
* This hack is only needed when saving to smbfs.
|
||||
*/
|
||||
memset(buf, '0', 10);
|
||||
SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN);
|
||||
WriteFile(This->hfile, buf, 10, NULL, NULL);
|
||||
/*
|
||||
* END HACK
|
||||
*/
|
||||
|
||||
/*
|
||||
* set the new end of file
|
||||
*/
|
||||
SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN);
|
||||
SetEndOfFile(This->hfile);
|
||||
|
||||
/*
|
||||
* re-create the file mapping object
|
||||
*/
|
||||
This->hfilemap = CreateFileMappingA(This->hfile,
|
||||
NULL,
|
||||
This->flProtect,
|
||||
0, 0,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalUnlock(This->hbytearray);
|
||||
|
||||
/*
|
||||
* Resize the byte array object.
|
||||
*/
|
||||
ILockBytes_SetSize(This->pLkbyt, newSize);
|
||||
|
||||
/*
|
||||
* Re-acquire the handle, it may have changed.
|
||||
*/
|
||||
GetHGlobalFromILockBytes(This->pLkbyt, &This->hbytearray);
|
||||
This->pbytearray = GlobalLock(This->hbytearray);
|
||||
}
|
||||
|
||||
This->filesize.u.LowPart = newSize.u.LowPart;
|
||||
This->filesize.u.HighPart = newSize.u.HighPart;
|
||||
|
||||
BIGBLOCKFILE_RemapAllMappedPages(This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_GetSize
|
||||
*
|
||||
* Returns the size of the file.
|
||||
*
|
||||
*/
|
||||
ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This)
|
||||
{
|
||||
return This->filesize;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_AccessCheck [PRIVATE]
|
||||
*
|
||||
* block_index is the index within the page.
|
||||
*/
|
||||
static BOOL BIGBLOCKFILE_AccessCheck(MappedPage *page, ULONG block_index,
|
||||
DWORD desired_access)
|
||||
{
|
||||
assert(block_index < BLOCKS_PER_PAGE);
|
||||
|
||||
if (desired_access == FILE_MAP_READ)
|
||||
{
|
||||
if (BIGBLOCKFILE_TestBit(&page->writable_blocks, block_index))
|
||||
return FALSE;
|
||||
|
||||
BIGBLOCKFILE_SetBit(&page->readable_blocks, block_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(desired_access == FILE_MAP_WRITE);
|
||||
|
||||
if (BIGBLOCKFILE_TestBit(&page->readable_blocks, block_index))
|
||||
return FALSE;
|
||||
|
||||
BIGBLOCKFILE_SetBit(&page->writable_blocks, block_index);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_GetBigBlockPointer [PRIVATE]
|
||||
*
|
||||
* Returns a pointer to the specified block.
|
||||
*/
|
||||
static void* BIGBLOCKFILE_GetBigBlockPointer(
|
||||
LPBIGBLOCKFILE This,
|
||||
ULONG block_index,
|
||||
DWORD desired_access)
|
||||
{
|
||||
DWORD page_index = block_index / BLOCKS_PER_PAGE;
|
||||
DWORD block_on_page = block_index % BLOCKS_PER_PAGE;
|
||||
|
||||
MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index);
|
||||
if (!page || !page->lpBytes) return NULL;
|
||||
|
||||
if (!BIGBLOCKFILE_AccessCheck(page, block_on_page, desired_access))
|
||||
{
|
||||
BIGBLOCKFILE_ReleaseMappedPage(This, page);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (LPBYTE)page->lpBytes + (block_on_page * This->blocksize);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_GetMappedPageFromPointer [PRIVATE]
|
||||
*
|
||||
* pBlock is a pointer to a block on a page.
|
||||
* The page has to be on the in-use list. (As oppsed to the victim list.)
|
||||
*
|
||||
* Does not increment the usage count.
|
||||
*/
|
||||
static MappedPage *BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
|
||||
void *pBlock)
|
||||
{
|
||||
MappedPage *page;
|
||||
|
||||
for (page = This->maplist; page != NULL; page = page->next)
|
||||
{
|
||||
if ((LPBYTE)pBlock >= (LPBYTE)page->lpBytes
|
||||
&& (LPBYTE)pBlock <= (LPBYTE)page->lpBytes + PAGE_SIZE)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_FindPageInList [PRIVATE]
|
||||
*
|
||||
*/
|
||||
static MappedPage *BIGBLOCKFILE_FindPageInList(MappedPage *head,
|
||||
ULONG page_index)
|
||||
{
|
||||
for (; head != NULL; head = head->next)
|
||||
{
|
||||
if (head->page_index == page_index)
|
||||
{
|
||||
InterlockedIncrement(&head->refcnt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return head;
|
||||
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_UnlinkPage(MappedPage *page)
|
||||
{
|
||||
if (page->next) page->next->prev = page->prev;
|
||||
if (page->prev) page->prev->next = page->next;
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_LinkHeadPage(MappedPage **head, MappedPage *page)
|
||||
{
|
||||
if (*head) (*head)->prev = page;
|
||||
page->next = *head;
|
||||
page->prev = NULL;
|
||||
*head = page;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_GetMappedView [PRIVATE]
|
||||
*
|
||||
* Gets the page requested if it is already mapped.
|
||||
* If it's not already mapped, this method will map it
|
||||
*/
|
||||
static void * BIGBLOCKFILE_GetMappedView(
|
||||
LPBIGBLOCKFILE This,
|
||||
DWORD page_index)
|
||||
{
|
||||
MappedPage *page;
|
||||
|
||||
page = BIGBLOCKFILE_FindPageInList(This->maplist, page_index);
|
||||
if (!page)
|
||||
{
|
||||
page = BIGBLOCKFILE_FindPageInList(This->victimhead, page_index);
|
||||
if (page)
|
||||
{
|
||||
This->num_victim_pages--;
|
||||
|
||||
BIGBLOCKFILE_Zero(&page->readable_blocks);
|
||||
BIGBLOCKFILE_Zero(&page->writable_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
if (page)
|
||||
{
|
||||
/* If the page is not already at the head of the list, move
|
||||
* it there. (Also moves pages from victim to main list.) */
|
||||
if (This->maplist != page)
|
||||
{
|
||||
if (This->victimhead == page) This->victimhead = page->next;
|
||||
if (This->victimtail == page) This->victimtail = page->prev;
|
||||
|
||||
BIGBLOCKFILE_UnlinkPage(page);
|
||||
|
||||
BIGBLOCKFILE_LinkHeadPage(&This->maplist, page);
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
page = BIGBLOCKFILE_CreatePage(This, page_index);
|
||||
if (!page) return NULL;
|
||||
|
||||
BIGBLOCKFILE_LinkHeadPage(&This->maplist, page);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
static BOOL BIGBLOCKFILE_MapPage(LPBIGBLOCKFILE This, MappedPage *page)
|
||||
{
|
||||
DWORD lowoffset = PAGE_SIZE * page->page_index;
|
||||
|
||||
if (This->fileBased)
|
||||
{
|
||||
DWORD numBytesToMap;
|
||||
DWORD desired_access;
|
||||
|
||||
if( !This->hfilemap )
|
||||
return FALSE;
|
||||
|
||||
if (lowoffset + PAGE_SIZE > This->filesize.u.LowPart)
|
||||
numBytesToMap = This->filesize.u.LowPart - lowoffset;
|
||||
else
|
||||
numBytesToMap = PAGE_SIZE;
|
||||
|
||||
if (This->flProtect == PAGE_READONLY)
|
||||
desired_access = FILE_MAP_READ;
|
||||
else
|
||||
desired_access = FILE_MAP_WRITE;
|
||||
|
||||
page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
|
||||
lowoffset, numBytesToMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
page->lpBytes = (LPBYTE)This->pbytearray + lowoffset;
|
||||
}
|
||||
|
||||
TRACE("mapped page %lu to %p\n", page->page_index, page->lpBytes);
|
||||
|
||||
return page->lpBytes != NULL;
|
||||
}
|
||||
|
||||
static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
|
||||
ULONG page_index)
|
||||
{
|
||||
MappedPage *page;
|
||||
|
||||
page = HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
|
||||
if (page == NULL)
|
||||
return NULL;
|
||||
|
||||
page->page_index = page_index;
|
||||
page->refcnt = 1;
|
||||
|
||||
page->next = NULL;
|
||||
page->prev = NULL;
|
||||
|
||||
BIGBLOCKFILE_MapPage(This, page);
|
||||
|
||||
BIGBLOCKFILE_Zero(&page->readable_blocks);
|
||||
BIGBLOCKFILE_Zero(&page->writable_blocks);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page)
|
||||
{
|
||||
TRACE("%ld at %p\n", page->page_index, page->lpBytes);
|
||||
if (page->refcnt > 0)
|
||||
ERR("unmapping inuse page %p\n", page->lpBytes);
|
||||
|
||||
if (This->fileBased && page->lpBytes)
|
||||
UnmapViewOfFile(page->lpBytes);
|
||||
|
||||
page->lpBytes = NULL;
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_DeletePage(LPBIGBLOCKFILE This, MappedPage *page)
|
||||
{
|
||||
BIGBLOCKFILE_UnmapPage(This, page);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, page);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_ReleaseMappedPage [PRIVATE]
|
||||
*
|
||||
* Decrements the reference count of the mapped page.
|
||||
*/
|
||||
static void BIGBLOCKFILE_ReleaseMappedPage(
|
||||
LPBIGBLOCKFILE This,
|
||||
MappedPage *page)
|
||||
{
|
||||
assert(This != NULL);
|
||||
assert(page != NULL);
|
||||
|
||||
/* If the page is no longer refenced, move it to the victim list.
|
||||
* If the victim list is too long, kick somebody off. */
|
||||
if (!InterlockedDecrement(&page->refcnt))
|
||||
{
|
||||
if (This->maplist == page) This->maplist = page->next;
|
||||
|
||||
BIGBLOCKFILE_UnlinkPage(page);
|
||||
|
||||
if (MAX_VICTIM_PAGES > 0)
|
||||
{
|
||||
if (This->num_victim_pages >= MAX_VICTIM_PAGES)
|
||||
{
|
||||
MappedPage *victim = This->victimtail;
|
||||
if (victim)
|
||||
{
|
||||
This->victimtail = victim->prev;
|
||||
if (This->victimhead == victim)
|
||||
This->victimhead = victim->next;
|
||||
|
||||
BIGBLOCKFILE_UnlinkPage(victim);
|
||||
BIGBLOCKFILE_DeletePage(This, victim);
|
||||
}
|
||||
}
|
||||
else This->num_victim_pages++;
|
||||
|
||||
BIGBLOCKFILE_LinkHeadPage(&This->victimhead, page);
|
||||
if (This->victimtail == NULL) This->victimtail = page;
|
||||
}
|
||||
else
|
||||
BIGBLOCKFILE_DeletePage(This, page);
|
||||
}
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_DeleteList(LPBIGBLOCKFILE This, MappedPage *list)
|
||||
{
|
||||
while (list != NULL)
|
||||
{
|
||||
MappedPage *next = list->next;
|
||||
|
||||
BIGBLOCKFILE_DeletePage(This, list);
|
||||
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BIGBLOCKFILE_FreeAllMappedPages [PRIVATE]
|
||||
*
|
||||
* Unmap all currently mapped pages.
|
||||
* Empty mapped pages list.
|
||||
*/
|
||||
static void BIGBLOCKFILE_FreeAllMappedPages(
|
||||
LPBIGBLOCKFILE This)
|
||||
{
|
||||
BIGBLOCKFILE_DeleteList(This, This->maplist);
|
||||
BIGBLOCKFILE_DeleteList(This, This->victimhead);
|
||||
|
||||
This->maplist = NULL;
|
||||
This->victimhead = NULL;
|
||||
This->victimtail = NULL;
|
||||
This->num_victim_pages = 0;
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_UnmapList(LPBIGBLOCKFILE This, MappedPage *list)
|
||||
{
|
||||
for (; list != NULL; list = list->next)
|
||||
{
|
||||
BIGBLOCKFILE_UnmapPage(This, list);
|
||||
}
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This)
|
||||
{
|
||||
BIGBLOCKFILE_UnmapList(This, This->maplist);
|
||||
BIGBLOCKFILE_UnmapList(This, This->victimhead);
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_RemapList(LPBIGBLOCKFILE This, MappedPage *list)
|
||||
{
|
||||
while (list != NULL)
|
||||
{
|
||||
MappedPage *next = list->next;
|
||||
|
||||
if (list->page_index * PAGE_SIZE > This->filesize.u.LowPart)
|
||||
{
|
||||
TRACE("discarding %lu\n", list->page_index);
|
||||
|
||||
/* page is entirely outside of the file, delete it */
|
||||
BIGBLOCKFILE_UnlinkPage(list);
|
||||
BIGBLOCKFILE_DeletePage(This, list);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise, remap it */
|
||||
BIGBLOCKFILE_MapPage(This, list);
|
||||
}
|
||||
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This)
|
||||
{
|
||||
BIGBLOCKFILE_RemapList(This, This->maplist);
|
||||
BIGBLOCKFILE_RemapList(This, This->victimhead);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* BIGBLOCKFILE_GetProtectMode
|
||||
*
|
||||
* This function will return a protection mode flag for a file-mapping object
|
||||
* from the open flags of a file.
|
||||
*/
|
||||
static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
|
||||
{
|
||||
if (openFlags & (STGM_WRITE | STGM_READWRITE))
|
||||
return PAGE_READWRITE;
|
||||
else
|
||||
return PAGE_READONLY;
|
||||
}
|
||||
@@ -1,895 +0,0 @@
|
||||
/*
|
||||
* Compound Storage (32 bit version)
|
||||
* Stream implementation
|
||||
*
|
||||
* This file contains the implementation of the stream interface
|
||||
* for streams contained in a compound storage.
|
||||
*
|
||||
* Copyright 1999 Francis Beaudet
|
||||
* Copyright 1999 Thuy Nguyen
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "storage32.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(storage);
|
||||
|
||||
|
||||
/*
|
||||
* Virtual function table for the StgStreamImpl class.
|
||||
*/
|
||||
static IStreamVtbl StgStreamImpl_Vtbl =
|
||||
{
|
||||
StgStreamImpl_QueryInterface,
|
||||
StgStreamImpl_AddRef,
|
||||
StgStreamImpl_Release,
|
||||
StgStreamImpl_Read,
|
||||
StgStreamImpl_Write,
|
||||
StgStreamImpl_Seek,
|
||||
StgStreamImpl_SetSize,
|
||||
StgStreamImpl_CopyTo,
|
||||
StgStreamImpl_Commit,
|
||||
StgStreamImpl_Revert,
|
||||
StgStreamImpl_LockRegion,
|
||||
StgStreamImpl_UnlockRegion,
|
||||
StgStreamImpl_Stat,
|
||||
StgStreamImpl_Clone
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
** StgStreamImpl implementation
|
||||
*/
|
||||
|
||||
/***
|
||||
* This is the constructor for the StgStreamImpl class.
|
||||
*
|
||||
* Params:
|
||||
* parentStorage - Pointer to the storage that contains the stream to open
|
||||
* ownerProperty - Index of the property that points to this stream.
|
||||
*/
|
||||
StgStreamImpl* StgStreamImpl_Construct(
|
||||
StorageBaseImpl* parentStorage,
|
||||
DWORD grfMode,
|
||||
ULONG ownerProperty)
|
||||
{
|
||||
StgStreamImpl* newStream;
|
||||
|
||||
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(StgStreamImpl));
|
||||
|
||||
if (newStream!=0)
|
||||
{
|
||||
/*
|
||||
* Set-up the virtual function table and reference count.
|
||||
*/
|
||||
newStream->lpVtbl = &StgStreamImpl_Vtbl;
|
||||
newStream->ref = 0;
|
||||
|
||||
/*
|
||||
* We want to nail-down the reference to the storage in case the
|
||||
* stream out-lives the storage in the client application.
|
||||
*/
|
||||
newStream->parentStorage = parentStorage;
|
||||
IStorage_AddRef((IStorage*)newStream->parentStorage);
|
||||
|
||||
newStream->grfMode = grfMode;
|
||||
newStream->ownerProperty = ownerProperty;
|
||||
|
||||
/*
|
||||
* Start the stream at the beginning.
|
||||
*/
|
||||
newStream->currentPosition.u.HighPart = 0;
|
||||
newStream->currentPosition.u.LowPart = 0;
|
||||
|
||||
/*
|
||||
* Initialize the rest of the data.
|
||||
*/
|
||||
newStream->streamSize.u.HighPart = 0;
|
||||
newStream->streamSize.u.LowPart = 0;
|
||||
newStream->bigBlockChain = 0;
|
||||
newStream->smallBlockChain = 0;
|
||||
|
||||
/*
|
||||
* Read the size from the property and determine if the blocks forming
|
||||
* this stream are large or small.
|
||||
*/
|
||||
StgStreamImpl_OpenBlockChain(newStream);
|
||||
}
|
||||
|
||||
return newStream;
|
||||
}
|
||||
|
||||
/***
|
||||
* This is the destructor of the StgStreamImpl class.
|
||||
*
|
||||
* This method will clean-up all the resources used-up by the given StgStreamImpl
|
||||
* class. The pointer passed-in to this function will be freed and will not
|
||||
* be valid anymore.
|
||||
*/
|
||||
void StgStreamImpl_Destroy(StgStreamImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
/*
|
||||
* Release the reference we are holding on the parent storage.
|
||||
*/
|
||||
IStorage_Release((IStorage*)This->parentStorage);
|
||||
This->parentStorage = 0;
|
||||
|
||||
/*
|
||||
* Make sure we clean-up the block chain stream objects that we were using.
|
||||
*/
|
||||
if (This->bigBlockChain != 0)
|
||||
{
|
||||
BlockChainStream_Destroy(This->bigBlockChain);
|
||||
This->bigBlockChain = 0;
|
||||
}
|
||||
|
||||
if (This->smallBlockChain != 0)
|
||||
{
|
||||
SmallBlockChainStream_Destroy(This->smallBlockChain);
|
||||
This->smallBlockChain = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, free the memory used-up by the class.
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method QueryInterface for this
|
||||
* class
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_QueryInterface(
|
||||
IStream* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject) /* [iid_is][out] */
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
|
||||
/*
|
||||
* Perform a sanity check on the parameters.
|
||||
*/
|
||||
if (ppvObject==0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/*
|
||||
* Initialize the return parameter.
|
||||
*/
|
||||
*ppvObject = 0;
|
||||
|
||||
/*
|
||||
* Compare the riid with the interface IDs implemented by this object.
|
||||
*/
|
||||
if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
|
||||
{
|
||||
*ppvObject = (IStream*)This;
|
||||
}
|
||||
else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
|
||||
{
|
||||
*ppvObject = (IStream*)This;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we obtained an interface.
|
||||
*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/*
|
||||
* Query Interface always increases the reference count by one when it is
|
||||
* successful
|
||||
*/
|
||||
StgStreamImpl_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method AddRef for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI StgStreamImpl_AddRef(
|
||||
IStream* iface)
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method Release for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI StgStreamImpl_Release(
|
||||
IStream* iface)
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
|
||||
ULONG ref;
|
||||
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
/*
|
||||
* If the reference count goes down to 0, perform suicide.
|
||||
*/
|
||||
if (ref==0)
|
||||
{
|
||||
StgStreamImpl_Destroy(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method will open the block chain pointed by the property
|
||||
* that describes the stream.
|
||||
* If the stream's size is null, no chain is opened.
|
||||
*/
|
||||
void StgStreamImpl_OpenBlockChain(
|
||||
StgStreamImpl* This)
|
||||
{
|
||||
StgProperty curProperty;
|
||||
BOOL readSucessful;
|
||||
|
||||
/*
|
||||
* Make sure no old object is left over.
|
||||
*/
|
||||
if (This->smallBlockChain != 0)
|
||||
{
|
||||
SmallBlockChainStream_Destroy(This->smallBlockChain);
|
||||
This->smallBlockChain = 0;
|
||||
}
|
||||
|
||||
if (This->bigBlockChain != 0)
|
||||
{
|
||||
BlockChainStream_Destroy(This->bigBlockChain);
|
||||
This->bigBlockChain = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the information from the property.
|
||||
*/
|
||||
readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
|
||||
This->ownerProperty,
|
||||
&curProperty);
|
||||
|
||||
if (readSucessful)
|
||||
{
|
||||
This->streamSize = curProperty.size;
|
||||
|
||||
/*
|
||||
* This code supports only streams that are <32 bits in size.
|
||||
*/
|
||||
assert(This->streamSize.u.HighPart == 0);
|
||||
|
||||
if(curProperty.startingBlock == BLOCK_END_OF_CHAIN)
|
||||
{
|
||||
assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (This->streamSize.u.HighPart == 0) &&
|
||||
(This->streamSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )
|
||||
{
|
||||
This->smallBlockChain = SmallBlockChainStream_Construct(
|
||||
This->parentStorage->ancestorStorage,
|
||||
This->ownerProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
This->bigBlockChain = BlockChainStream_Construct(
|
||||
This->parentStorage->ancestorStorage,
|
||||
NULL,
|
||||
This->ownerProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the ISequentialStream interface.
|
||||
*
|
||||
* It reads a block of information from the stream at the current
|
||||
* position. It then moves the current position at the end of the
|
||||
* read block
|
||||
*
|
||||
* See the documentation of ISequentialStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_Read(
|
||||
IStream* iface,
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead) /* [out] */
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
|
||||
ULONG bytesReadBuffer;
|
||||
ULONG bytesToReadFromBuffer;
|
||||
HRESULT res = S_FALSE;
|
||||
|
||||
TRACE("(%p, %p, %ld, %p)\n",
|
||||
iface, pv, cb, pcbRead);
|
||||
|
||||
/*
|
||||
* If the caller is not interested in the number of bytes read,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbRead==0)
|
||||
pcbRead = &bytesReadBuffer;
|
||||
|
||||
/*
|
||||
* Using the known size of the stream, calculate the number of bytes
|
||||
* to read from the block chain
|
||||
*/
|
||||
bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
|
||||
|
||||
/*
|
||||
* Depending on the type of chain that was opened when the stream was constructed,
|
||||
* we delegate the work to the method that reads the block chains.
|
||||
*/
|
||||
if (This->smallBlockChain!=0)
|
||||
{
|
||||
SmallBlockChainStream_ReadAt(This->smallBlockChain,
|
||||
This->currentPosition,
|
||||
bytesToReadFromBuffer,
|
||||
pv,
|
||||
pcbRead);
|
||||
|
||||
}
|
||||
else if (This->bigBlockChain!=0)
|
||||
{
|
||||
BlockChainStream_ReadAt(This->bigBlockChain,
|
||||
This->currentPosition,
|
||||
bytesToReadFromBuffer,
|
||||
pv,
|
||||
pcbRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Small and big block chains are both NULL. This case will happen
|
||||
* when a stream starts with BLOCK_END_OF_CHAIN and has size zero.
|
||||
*/
|
||||
|
||||
*pcbRead = 0;
|
||||
res = S_OK;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* We should always be able to read the proper amount of data from the
|
||||
* chain.
|
||||
*/
|
||||
assert(bytesToReadFromBuffer == *pcbRead);
|
||||
|
||||
/*
|
||||
* Advance the pointer for the number of positions read.
|
||||
*/
|
||||
This->currentPosition.u.LowPart += *pcbRead;
|
||||
|
||||
if(*pcbRead != cb)
|
||||
{
|
||||
WARN("read %ld instead of the required %ld bytes !\n", *pcbRead, cb);
|
||||
/*
|
||||
* this used to return S_FALSE, however MSDN docu says that an app should
|
||||
* be prepared to handle error in case of stream end reached, as *some*
|
||||
* implementations *might* return an error (IOW: most do *not*).
|
||||
* As some program fails on returning S_FALSE, I better use S_OK here.
|
||||
*/
|
||||
res = S_OK;
|
||||
}
|
||||
else
|
||||
res = S_OK;
|
||||
|
||||
end:
|
||||
TRACE("<-- %08lx\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the ISequentialStream interface.
|
||||
*
|
||||
* It writes a block of information to the stream at the current
|
||||
* position. It then moves the current position at the end of the
|
||||
* written block. If the stream is too small to fit the block,
|
||||
* the stream is grown to fit.
|
||||
*
|
||||
* See the documentation of ISequentialStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_Write(
|
||||
IStream* iface,
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten) /* [out] */
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
|
||||
ULARGE_INTEGER newSize;
|
||||
ULONG bytesWritten = 0;
|
||||
|
||||
TRACE("(%p, %p, %ld, %p)\n",
|
||||
iface, pv, cb, pcbWritten);
|
||||
|
||||
/*
|
||||
* Do we have permission to write to this stream?
|
||||
*/
|
||||
if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE))) {
|
||||
return STG_E_ACCESSDENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the caller is not interested in the number of bytes written,
|
||||
* we use another buffer to avoid "if" statements in the code.
|
||||
*/
|
||||
if (pcbWritten == 0)
|
||||
pcbWritten = &bytesWritten;
|
||||
|
||||
/*
|
||||
* Initialize the out parameter
|
||||
*/
|
||||
*pcbWritten = 0;
|
||||
|
||||
if (cb == 0)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSize.u.HighPart = 0;
|
||||
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify if we need to grow the stream
|
||||
*/
|
||||
if (newSize.u.LowPart > This->streamSize.u.LowPart)
|
||||
{
|
||||
/* grow stream */
|
||||
IStream_SetSize(iface, newSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Depending on the type of chain that was opened when the stream was constructed,
|
||||
* we delegate the work to the method that readwrites to the block chains.
|
||||
*/
|
||||
if (This->smallBlockChain!=0)
|
||||
{
|
||||
SmallBlockChainStream_WriteAt(This->smallBlockChain,
|
||||
This->currentPosition,
|
||||
cb,
|
||||
pv,
|
||||
pcbWritten);
|
||||
|
||||
}
|
||||
else if (This->bigBlockChain!=0)
|
||||
{
|
||||
BlockChainStream_WriteAt(This->bigBlockChain,
|
||||
This->currentPosition,
|
||||
cb,
|
||||
pv,
|
||||
pcbWritten);
|
||||
}
|
||||
else
|
||||
assert(FALSE);
|
||||
|
||||
/*
|
||||
* Advance the position pointer for the number of positions written.
|
||||
*/
|
||||
This->currentPosition.u.LowPart += *pcbWritten;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* It will move the current stream pointer according to the parameters
|
||||
* given.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_Seek(
|
||||
IStream* iface,
|
||||
LARGE_INTEGER dlibMove, /* [in] */
|
||||
DWORD dwOrigin, /* [in] */
|
||||
ULARGE_INTEGER* plibNewPosition) /* [out] */
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
|
||||
ULARGE_INTEGER newPosition;
|
||||
|
||||
TRACE("(%p, %ld, %ld, %p)\n",
|
||||
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
|
||||
/*
|
||||
* The caller is allowed to pass in NULL as the new position return value.
|
||||
* If it happens, we assign it to a dynamic variable to avoid special cases
|
||||
* in the code below.
|
||||
*/
|
||||
if (plibNewPosition == 0)
|
||||
{
|
||||
plibNewPosition = &newPosition;
|
||||
}
|
||||
|
||||
/*
|
||||
* The file pointer is moved depending on the given "function"
|
||||
* parameter.
|
||||
*/
|
||||
switch (dwOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET:
|
||||
plibNewPosition->u.HighPart = 0;
|
||||
plibNewPosition->u.LowPart = 0;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
*plibNewPosition = This->currentPosition;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
*plibNewPosition = This->streamSize;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
|
||||
plibNewPosition->QuadPart = RtlLargeIntegerAdd( plibNewPosition->QuadPart, dlibMove.QuadPart );
|
||||
|
||||
/*
|
||||
* tell the caller what we calculated
|
||||
*/
|
||||
This->currentPosition = *plibNewPosition;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* It will change the size of a stream.
|
||||
*
|
||||
* TODO: Switch from small blocks to big blocks and vice versa.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_SetSize(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libNewSize) /* [in] */
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
|
||||
StgProperty curProperty;
|
||||
BOOL Success;
|
||||
|
||||
TRACE("(%p, %ld)\n", iface, libNewSize.u.LowPart);
|
||||
|
||||
/*
|
||||
* As documented.
|
||||
*/
|
||||
if (libNewSize.u.HighPart != 0)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
/*
|
||||
* Do we have permission?
|
||||
*/
|
||||
if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
|
||||
return STG_E_ACCESSDENIED;
|
||||
|
||||
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
* This will happen if we're creating a stream
|
||||
*/
|
||||
if ((This->smallBlockChain == 0) && (This->bigBlockChain == 0))
|
||||
{
|
||||
if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK)
|
||||
{
|
||||
This->smallBlockChain = SmallBlockChainStream_Construct(
|
||||
This->parentStorage->ancestorStorage,
|
||||
This->ownerProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
This->bigBlockChain = BlockChainStream_Construct(
|
||||
This->parentStorage->ancestorStorage,
|
||||
NULL,
|
||||
This->ownerProperty);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read this stream's property to see if it's small blocks or big blocks
|
||||
*/
|
||||
Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
|
||||
This->ownerProperty,
|
||||
&curProperty);
|
||||
/*
|
||||
* Determine if we have to switch from small to big blocks or vice versa
|
||||
*/
|
||||
if ( (This->smallBlockChain!=0) &&
|
||||
(curProperty.size.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )
|
||||
{
|
||||
if (libNewSize.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK)
|
||||
{
|
||||
/*
|
||||
* Transform the small block chain into a big block chain
|
||||
*/
|
||||
This->bigBlockChain = Storage32Impl_SmallBlocksToBigBlocks(
|
||||
This->parentStorage->ancestorStorage,
|
||||
&This->smallBlockChain);
|
||||
}
|
||||
}
|
||||
|
||||
if (This->smallBlockChain!=0)
|
||||
{
|
||||
Success = SmallBlockChainStream_SetSize(This->smallBlockChain, libNewSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
Success = BlockChainStream_SetSize(This->bigBlockChain, libNewSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the new information about this stream to the property
|
||||
*/
|
||||
Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
|
||||
This->ownerProperty,
|
||||
&curProperty);
|
||||
|
||||
curProperty.size.u.HighPart = libNewSize.u.HighPart;
|
||||
curProperty.size.u.LowPart = libNewSize.u.LowPart;
|
||||
|
||||
if (Success)
|
||||
{
|
||||
StorageImpl_WriteProperty(This->parentStorage->ancestorStorage,
|
||||
This->ownerProperty,
|
||||
&curProperty);
|
||||
}
|
||||
|
||||
This->streamSize = libNewSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* It will copy the 'cb' Bytes to 'pstm' IStream.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_CopyTo(
|
||||
IStream* iface,
|
||||
IStream* pstm, /* [unique][in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
ULARGE_INTEGER* pcbRead, /* [out] */
|
||||
ULARGE_INTEGER* pcbWritten) /* [out] */
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
BYTE tmpBuffer[128];
|
||||
ULONG bytesRead, bytesWritten, copySize;
|
||||
ULARGE_INTEGER totalBytesRead;
|
||||
ULARGE_INTEGER totalBytesWritten;
|
||||
|
||||
TRACE("(%p, %p, %ld, %p, %p)\n",
|
||||
iface, pstm, cb.u.LowPart, pcbRead, pcbWritten);
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if ( pstm == 0 )
|
||||
return STG_E_INVALIDPOINTER;
|
||||
|
||||
totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
|
||||
totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
|
||||
|
||||
/*
|
||||
* use stack to store data temporarily
|
||||
* there is surely a more performant way of doing it, for now this basic
|
||||
* implementation will do the job
|
||||
*/
|
||||
while ( cb.u.LowPart > 0 )
|
||||
{
|
||||
if ( cb.u.LowPart >= 128 )
|
||||
copySize = 128;
|
||||
else
|
||||
copySize = cb.u.LowPart;
|
||||
|
||||
IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
|
||||
|
||||
totalBytesRead.u.LowPart += bytesRead;
|
||||
|
||||
IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
|
||||
|
||||
totalBytesWritten.u.LowPart += bytesWritten;
|
||||
|
||||
/*
|
||||
* Check that read & write operations were successful
|
||||
*/
|
||||
if (bytesRead != bytesWritten)
|
||||
{
|
||||
hr = STG_E_MEDIUMFULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytesRead!=copySize)
|
||||
cb.u.LowPart = 0;
|
||||
else
|
||||
cb.u.LowPart -= bytesRead;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update number of bytes read and written
|
||||
*/
|
||||
if (pcbRead)
|
||||
{
|
||||
pcbRead->u.LowPart = totalBytesRead.u.LowPart;
|
||||
pcbRead->u.HighPart = totalBytesRead.u.HighPart;
|
||||
}
|
||||
|
||||
if (pcbWritten)
|
||||
{
|
||||
pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
|
||||
pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* For streams contained in structured storages, this method
|
||||
* does nothing. This is what the documentation tells us.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_Commit(
|
||||
IStream* iface,
|
||||
DWORD grfCommitFlags) /* [in] */
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* For streams contained in structured storages, this method
|
||||
* does nothing. This is what the documentation tells us.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_Revert(
|
||||
IStream* iface)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_LockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
FIXME("not implemented!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_UnlockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType) /* [in] */
|
||||
{
|
||||
FIXME("not implemented!\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* This method returns information about the current
|
||||
* stream.
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_Stat(
|
||||
IStream* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag) /* [in] */
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
|
||||
StgProperty curProperty;
|
||||
BOOL readSucessful;
|
||||
|
||||
/*
|
||||
* Read the information from the property.
|
||||
*/
|
||||
readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
|
||||
This->ownerProperty,
|
||||
&curProperty);
|
||||
|
||||
if (readSucessful)
|
||||
{
|
||||
StorageUtl_CopyPropertyToSTATSTG(pstatstg,
|
||||
&curProperty,
|
||||
grfStatFlag);
|
||||
|
||||
pstatstg->grfMode = This->grfMode;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/***
|
||||
* This method is part of the IStream interface.
|
||||
*
|
||||
* This method returns a clone of the interface that allows for
|
||||
* another seek pointer
|
||||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*
|
||||
* I am not totally sure what I am doing here but I presume that this
|
||||
* should be basically as simple as creating a new stream with the same
|
||||
* parent etc and positioning its seek cursor.
|
||||
*/
|
||||
HRESULT WINAPI StgStreamImpl_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm) /* [out] */
|
||||
{
|
||||
StgStreamImpl* const This=(StgStreamImpl*)iface;
|
||||
HRESULT hres;
|
||||
StgStreamImpl* new_stream;
|
||||
LARGE_INTEGER seek_pos;
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if ( ppstm == 0 )
|
||||
return STG_E_INVALIDPOINTER;
|
||||
|
||||
new_stream = StgStreamImpl_Construct (This->parentStorage, This->grfMode, This->ownerProperty);
|
||||
|
||||
if (!new_stream)
|
||||
return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */
|
||||
|
||||
*ppstm = (IStream*) new_stream;
|
||||
seek_pos.QuadPart = This->currentPosition.QuadPart;
|
||||
|
||||
hres=StgStreamImpl_Seek (*ppstm, seek_pos, STREAM_SEEK_SET, NULL);
|
||||
|
||||
assert (SUCCEEDED(hres));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,59 +0,0 @@
|
||||
# Compound Storage DLL.
|
||||
# (FIXME: some methods are commented out. Commenting them in _WILL_
|
||||
# result in dataloss. Do it at your own risk.)
|
||||
|
||||
1 pascal StgCreateDocFileA(str long long ptr) StgCreateDocFile16
|
||||
2 stub StgCreateDocFileOnILockBytes
|
||||
# 2 pascal StgCreateDocFileOnILockBytes(ptr long long ptr) StgCreateDocFileOnILockBytes16
|
||||
3 pascal StgOpenStorage(str ptr long ptr long ptr) StgOpenStorage16
|
||||
4 pascal StgOpenStorageOnILockBytes(ptr ptr long long long ptr) StgOpenStorageOnILockBytes16
|
||||
5 pascal StgIsStorageFile(str) StgIsStorageFile16
|
||||
6 pascal StgIsStorageILockBytes(segptr) StgIsStorageILockBytes16
|
||||
7 stub StgSetTimes
|
||||
#8 WEP
|
||||
#9 ___EXPORTEDSTUB
|
||||
103 stub DllGetClassObject
|
||||
|
||||
# Storage Interface functions. Starting at 500
|
||||
# these are not exported in the real storage.dll, we use them
|
||||
# as 16->32 relays. They use the cdecl calling convention.
|
||||
|
||||
# IStorage
|
||||
500 cdecl IStorage16_QueryInterface(ptr ptr ptr) IStorage16_fnQueryInterface
|
||||
501 cdecl IStorage16_AddRef(ptr) IStorage16_fnAddRef
|
||||
502 cdecl IStorage16_Release(ptr) IStorage16_fnRelease
|
||||
#503 cdecl IStorage16_CreateStream(ptr str long long long ptr) IStorage16_fnCreateStream
|
||||
503 stub IStorage16_CreateStream
|
||||
|
||||
504 cdecl IStorage16_OpenStream(ptr str ptr long long ptr) IStorage16_fnOpenStream
|
||||
#505 cdecl IStorage16_CreateStorage(ptr str long long long ptr) IStorage16_fnCreateStorage
|
||||
505 stub IStorage16_CreateStorage
|
||||
506 cdecl IStorage16_OpenStorage(ptr str ptr long ptr long ptr) IStorage16_fnOpenStorage
|
||||
507 cdecl IStorage16_CopyTo(ptr long ptr ptr ptr) IStorage16_fnCopyTo
|
||||
508 stub IStorage16_MoveElementTo
|
||||
509 cdecl IStorage16_Commit(ptr long) IStorage16_fnCommit
|
||||
510 stub IStorage16_Revert
|
||||
511 stub IStorage16_EnumElements
|
||||
512 stub IStorage16_DestroyElement
|
||||
513 stub IStorage16_RenameElement
|
||||
514 stub IStorage16_SetElementTimes
|
||||
515 stub IStorage16_SetClass
|
||||
516 stub IStorage16_SetStateBits
|
||||
517 cdecl IStorage16_Stat(ptr ptr long) IStorage16_fnStat
|
||||
|
||||
# IStream
|
||||
518 cdecl IStream16_QueryInterface(ptr ptr ptr) IStream16_fnQueryInterface
|
||||
519 cdecl IStream16_AddRef(ptr) IStream16_fnAddRef
|
||||
520 cdecl IStream16_Release(ptr) IStream16_fnRelease
|
||||
521 cdecl IStream16_Read(ptr ptr long ptr) IStream16_fnRead
|
||||
#522 cdecl IStream16_Write(ptr ptr long ptr) IStream16_fnWrite
|
||||
522 stub IStream16_Write
|
||||
523 cdecl IStream16_Seek(ptr long long long ptr) IStream16_fnSeek
|
||||
524 stub IStream16_SetSize
|
||||
525 stub IStream16_CopyTo
|
||||
526 stub IStream16_Commit
|
||||
527 stub IStream16_Revert
|
||||
528 stub IStream16_LockRegion
|
||||
529 stub IStream16_UnlockRegion
|
||||
530 stub IStream16_Stat
|
||||
531 stub IStream16_Clone
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,892 +0,0 @@
|
||||
/*
|
||||
* Compound Storage (32 bit version)
|
||||
*
|
||||
* Implemented using the documentation of the LAOLA project at
|
||||
* <URL:http://wwwwbs.cs.tu-berlin.de/~schwartz/pmh/index.html>
|
||||
* (Thanks to Martin Schwartz <schwartz@cs.tu-berlin.de>)
|
||||
*
|
||||
* This include file contains definitions of types and function
|
||||
* prototypes that are used in the many files implementing the
|
||||
* storage functionality
|
||||
*
|
||||
* Copyright 1998,1999 Francis Beaudet
|
||||
* Copyright 1998,1999 Thuy Nguyen
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __STORAGE32_H__
|
||||
#define __STORAGE32_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnt.h"
|
||||
#include "objbase.h"
|
||||
|
||||
/*
|
||||
* Definitions for the file format offsets.
|
||||
*/
|
||||
static const ULONG OFFSET_BIGBLOCKSIZEBITS = 0x0000001e;
|
||||
static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020;
|
||||
static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C;
|
||||
static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030;
|
||||
static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C;
|
||||
static const ULONG OFFSET_SBDEPOTCOUNT = 0x00000040;
|
||||
static const ULONG OFFSET_EXTBBDEPOTSTART = 0x00000044;
|
||||
static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048;
|
||||
static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C;
|
||||
static const ULONG OFFSET_PS_NAME = 0x00000000;
|
||||
static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040;
|
||||
static const ULONG OFFSET_PS_PROPERTYTYPE = 0x00000042;
|
||||
static const ULONG OFFSET_PS_PREVIOUSPROP = 0x00000044;
|
||||
static const ULONG OFFSET_PS_NEXTPROP = 0x00000048;
|
||||
static const ULONG OFFSET_PS_DIRPROP = 0x0000004C;
|
||||
static const ULONG OFFSET_PS_GUID = 0x00000050;
|
||||
static const ULONG OFFSET_PS_TSS1 = 0x00000064;
|
||||
static const ULONG OFFSET_PS_TSD1 = 0x00000068;
|
||||
static const ULONG OFFSET_PS_TSS2 = 0x0000006C;
|
||||
static const ULONG OFFSET_PS_TSD2 = 0x00000070;
|
||||
static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074;
|
||||
static const ULONG OFFSET_PS_SIZE = 0x00000078;
|
||||
static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009;
|
||||
static const WORD DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
|
||||
static const WORD DEF_BIG_BLOCK_SIZE = 0x0200;
|
||||
static const WORD DEF_SMALL_BLOCK_SIZE = 0x0040;
|
||||
static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC;
|
||||
static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD;
|
||||
static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
|
||||
static const ULONG BLOCK_UNUSED = 0xFFFFFFFF;
|
||||
static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
|
||||
|
||||
#define PROPERTY_NAME_MAX_LEN 0x20
|
||||
#define PROPERTY_NAME_BUFFER_LEN 0x40
|
||||
|
||||
#define PROPSET_BLOCK_SIZE 0x00000080
|
||||
|
||||
/*
|
||||
* Property type of relation
|
||||
*/
|
||||
#define PROPERTY_RELATION_PREVIOUS 0
|
||||
#define PROPERTY_RELATION_NEXT 1
|
||||
#define PROPERTY_RELATION_DIR 2
|
||||
|
||||
/*
|
||||
* Property type constants
|
||||
*/
|
||||
#define PROPTYPE_STORAGE 0x01
|
||||
#define PROPTYPE_STREAM 0x02
|
||||
#define PROPTYPE_ROOT 0x05
|
||||
|
||||
/*
|
||||
* These defines assume a hardcoded blocksize. The code will assert
|
||||
* if the blocksize is different. Some changes will have to be done if it
|
||||
* becomes the case.
|
||||
*/
|
||||
#define BIG_BLOCK_SIZE 0x200
|
||||
#define COUNT_BBDEPOTINHEADER 109
|
||||
#define LIMIT_TO_USE_SMALL_BLOCK 0x1000
|
||||
#define NUM_BLOCKS_PER_DEPOT_BLOCK 128
|
||||
|
||||
/*
|
||||
* These are signatures to detect the type of Document file.
|
||||
*/
|
||||
static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1};
|
||||
static const BYTE STORAGE_oldmagic[8] ={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d};
|
||||
|
||||
/*
|
||||
* Forward declarations of all the structures used by the storage
|
||||
* module.
|
||||
*/
|
||||
typedef struct StorageBaseImpl StorageBaseImpl;
|
||||
typedef struct StorageImpl StorageImpl;
|
||||
typedef struct StorageInternalImpl StorageInternalImpl;
|
||||
typedef struct BlockChainStream BlockChainStream;
|
||||
typedef struct SmallBlockChainStream SmallBlockChainStream;
|
||||
typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
|
||||
typedef struct StgProperty StgProperty;
|
||||
typedef struct StgStreamImpl StgStreamImpl;
|
||||
|
||||
/*
|
||||
* This utility structure is used to read/write the information in a storage
|
||||
* property.
|
||||
*/
|
||||
struct StgProperty
|
||||
{
|
||||
WCHAR name[PROPERTY_NAME_MAX_LEN];
|
||||
WORD sizeOfNameString;
|
||||
BYTE propertyType;
|
||||
ULONG previousProperty;
|
||||
ULONG nextProperty;
|
||||
ULONG dirProperty;
|
||||
GUID propertyUniqueID;
|
||||
ULONG timeStampS1;
|
||||
ULONG timeStampD1;
|
||||
ULONG timeStampS2;
|
||||
ULONG timeStampD2;
|
||||
ULONG startingBlock;
|
||||
ULARGE_INTEGER size;
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
* Big Block File support
|
||||
*
|
||||
* The big block file is an abstraction of a flat file separated in
|
||||
* same sized blocks. The implementation for the methods described in
|
||||
* this section appear in stg_bigblockfile.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* Declaration of the data structures
|
||||
*/
|
||||
typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
|
||||
typedef struct MappedPage MappedPage,*LPMAPPEDPAGE;
|
||||
|
||||
struct BigBlockFile
|
||||
{
|
||||
BOOL fileBased;
|
||||
ULARGE_INTEGER filesize;
|
||||
ULONG blocksize;
|
||||
HANDLE hfile;
|
||||
HANDLE hfilemap;
|
||||
DWORD flProtect;
|
||||
MappedPage *maplist;
|
||||
MappedPage *victimhead, *victimtail;
|
||||
ULONG num_victim_pages;
|
||||
ILockBytes *pLkbyt;
|
||||
HGLOBAL hbytearray;
|
||||
LPVOID pbytearray;
|
||||
};
|
||||
|
||||
/*
|
||||
* Declaration of the functions used to manipulate the BigBlockFile
|
||||
* data structure.
|
||||
*/
|
||||
BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
|
||||
ILockBytes* pLkByt,
|
||||
DWORD openFlags,
|
||||
ULONG blocksize,
|
||||
BOOL fileBased);
|
||||
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
|
||||
void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
|
||||
void* BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
|
||||
void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock);
|
||||
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
|
||||
ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This);
|
||||
|
||||
/*************************************************************************
|
||||
* Ole Convert support
|
||||
*/
|
||||
|
||||
void OLECONVERT_CreateOleStream(LPSTORAGE pStorage);
|
||||
HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName);
|
||||
|
||||
/****************************************************************************
|
||||
* Storage32BaseImpl definitions.
|
||||
*
|
||||
* This structure defines the base information contained in all implementations
|
||||
* of IStorage32 contained in this file storage implementation.
|
||||
*
|
||||
* In OOP terms, this is the base class for all the IStorage32 implementations
|
||||
* contained in this file.
|
||||
*/
|
||||
struct StorageBaseImpl
|
||||
{
|
||||
IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct
|
||||
* since we want to cast this in a Storage32 pointer */
|
||||
|
||||
/*
|
||||
* Reference count of this object
|
||||
*/
|
||||
ULONG ref;
|
||||
|
||||
/*
|
||||
* Ancestor storage (top level)
|
||||
*/
|
||||
StorageImpl* ancestorStorage;
|
||||
|
||||
/*
|
||||
* Index of the property for the root of
|
||||
* this storage
|
||||
*/
|
||||
ULONG rootPropertySetIndex;
|
||||
|
||||
/*
|
||||
* virtual Destructor method.
|
||||
*/
|
||||
void (*v_destructor)(StorageBaseImpl*);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes for the methods of the Storage32BaseImpl class.
|
||||
*/
|
||||
HRESULT WINAPI StorageBaseImpl_QueryInterface(
|
||||
IStorage* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
ULONG WINAPI StorageBaseImpl_AddRef(
|
||||
IStorage* iface);
|
||||
|
||||
ULONG WINAPI StorageBaseImpl_Release(
|
||||
IStorage* iface);
|
||||
|
||||
HRESULT WINAPI StorageBaseImpl_OpenStream(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsName, /* [string][in] */
|
||||
void* reserved1, /* [unique][in] */
|
||||
DWORD grfMode, /* [in] */
|
||||
DWORD reserved2, /* [in] */
|
||||
IStream** ppstm); /* [out] */
|
||||
|
||||
HRESULT WINAPI StorageBaseImpl_OpenStorage(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsName, /* [string][unique][in] */
|
||||
IStorage* pstgPriority, /* [unique][in] */
|
||||
DWORD grfMode, /* [in] */
|
||||
SNB snbExclude, /* [unique][in] */
|
||||
DWORD reserved, /* [in] */
|
||||
IStorage** ppstg); /* [out] */
|
||||
|
||||
HRESULT WINAPI StorageBaseImpl_EnumElements(
|
||||
IStorage* iface,
|
||||
DWORD reserved1, /* [in] */
|
||||
void* reserved2, /* [size_is][unique][in] */
|
||||
DWORD reserved3, /* [in] */
|
||||
IEnumSTATSTG** ppenum); /* [out] */
|
||||
|
||||
HRESULT WINAPI StorageBaseImpl_Stat(
|
||||
IStorage* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag); /* [in] */
|
||||
|
||||
HRESULT WINAPI StorageBaseImpl_RenameElement(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsOldName, /* [string][in] */
|
||||
const OLECHAR* pwcsNewName); /* [string][in] */
|
||||
|
||||
HRESULT WINAPI StorageBaseImpl_CreateStream(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsName, /* [string][in] */
|
||||
DWORD grfMode, /* [in] */
|
||||
DWORD reserved1, /* [in] */
|
||||
DWORD reserved2, /* [in] */
|
||||
IStream** ppstm); /* [out] */
|
||||
|
||||
HRESULT WINAPI StorageBaseImpl_SetClass(
|
||||
IStorage* iface,
|
||||
REFCLSID clsid); /* [in] */
|
||||
|
||||
/****************************************************************************
|
||||
* Storage32Impl definitions.
|
||||
*
|
||||
* This implementation of the IStorage32 interface represents a root
|
||||
* storage. Basically, a document file.
|
||||
*/
|
||||
struct StorageImpl
|
||||
{
|
||||
IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct
|
||||
* since we want to cast this in a Storage32 pointer */
|
||||
|
||||
/*
|
||||
* Declare the member of the Storage32BaseImpl class to allow
|
||||
* casting as a Storage32BaseImpl
|
||||
*/
|
||||
ULONG ref;
|
||||
struct StorageImpl* ancestorStorage;
|
||||
ULONG rootPropertySetIndex;
|
||||
void (*v_destructor)(struct StorageImpl*);
|
||||
|
||||
/*
|
||||
* The following data members are specific to the Storage32Impl
|
||||
* class
|
||||
*/
|
||||
HANDLE hFile; /* Physical support for the Docfile */
|
||||
LPOLESTR pwcsName; /* Full path of the document file */
|
||||
|
||||
/* FIXME: should this be in Storage32BaseImpl ? */
|
||||
WCHAR filename[PROPERTY_NAME_BUFFER_LEN];
|
||||
|
||||
/*
|
||||
* File header
|
||||
*/
|
||||
WORD bigBlockSizeBits;
|
||||
WORD smallBlockSizeBits;
|
||||
ULONG bigBlockSize;
|
||||
ULONG smallBlockSize;
|
||||
ULONG bigBlockDepotCount;
|
||||
ULONG rootStartBlock;
|
||||
ULONG smallBlockDepotStart;
|
||||
ULONG extBigBlockDepotStart;
|
||||
ULONG extBigBlockDepotCount;
|
||||
ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
|
||||
|
||||
ULONG blockDepotCached[NUM_BLOCKS_PER_DEPOT_BLOCK];
|
||||
ULONG indexBlockDepotCached;
|
||||
ULONG prevFreeBlock;
|
||||
|
||||
/*
|
||||
* Abstraction of the big block chains for the chains of the header.
|
||||
*/
|
||||
BlockChainStream* rootBlockChain;
|
||||
BlockChainStream* smallBlockDepotChain;
|
||||
BlockChainStream* smallBlockRootChain;
|
||||
|
||||
/*
|
||||
* Pointer to the big block file abstraction
|
||||
*/
|
||||
BigBlockFile* bigBlockFile;
|
||||
};
|
||||
|
||||
/*
|
||||
* Method declaration for the Storage32Impl class
|
||||
*/
|
||||
|
||||
HRESULT WINAPI StorageImpl_CreateStorage(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsName, /* [string][in] */
|
||||
DWORD grfMode, /* [in] */
|
||||
DWORD dwStgFmt, /* [in] */
|
||||
DWORD reserved2, /* [in] */
|
||||
IStorage** ppstg); /* [out] */
|
||||
|
||||
HRESULT WINAPI StorageImpl_CopyTo(
|
||||
IStorage* iface,
|
||||
DWORD ciidExclude, /* [in] */
|
||||
const IID* rgiidExclude, /* [size_is][unique][in] */
|
||||
SNB snbExclude, /* [unique][in] */
|
||||
IStorage* pstgDest); /* [unique][in] */
|
||||
|
||||
HRESULT WINAPI StorageImpl_MoveElementTo(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsName, /* [string][in] */
|
||||
IStorage* pstgDest, /* [unique][in] */
|
||||
const OLECHAR* pwcsNewName, /* [string][in] */
|
||||
DWORD grfFlags); /* [in] */
|
||||
|
||||
HRESULT WINAPI StorageImpl_Commit(
|
||||
IStorage* iface,
|
||||
DWORD grfCommitFlags); /* [in] */
|
||||
|
||||
HRESULT WINAPI StorageImpl_Revert(
|
||||
IStorage* iface);
|
||||
|
||||
HRESULT WINAPI StorageImpl_DestroyElement(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsName); /* [string][in] */
|
||||
|
||||
HRESULT WINAPI StorageImpl_SetElementTimes(
|
||||
IStorage* iface,
|
||||
const OLECHAR* pwcsName, /* [string][in] */
|
||||
const FILETIME* pctime, /* [in] */
|
||||
const FILETIME* patime, /* [in] */
|
||||
const FILETIME* pmtime); /* [in] */
|
||||
|
||||
HRESULT WINAPI StorageImpl_SetStateBits(
|
||||
IStorage* iface,
|
||||
DWORD grfStateBits, /* [in] */
|
||||
DWORD grfMask); /* [in] */
|
||||
|
||||
HRESULT WINAPI StorageImpl_Stat(IStorage* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag); /* [in] */
|
||||
|
||||
void StorageImpl_Destroy(
|
||||
StorageImpl* This);
|
||||
|
||||
HRESULT StorageImpl_Construct(
|
||||
StorageImpl* This,
|
||||
HANDLE hFile,
|
||||
LPCOLESTR pwcsName,
|
||||
ILockBytes* pLkbyt,
|
||||
DWORD openFlags,
|
||||
BOOL fileBased,
|
||||
BOOL fileCreate);
|
||||
|
||||
BOOL StorageImpl_ReadBigBlock(
|
||||
StorageImpl* This,
|
||||
ULONG blockIndex,
|
||||
void* buffer);
|
||||
|
||||
BOOL StorageImpl_WriteBigBlock(
|
||||
StorageImpl* This,
|
||||
ULONG blockIndex,
|
||||
void* buffer);
|
||||
|
||||
void* StorageImpl_GetROBigBlock(
|
||||
StorageImpl* This,
|
||||
ULONG blockIndex);
|
||||
|
||||
void* StorageImpl_GetBigBlock(
|
||||
StorageImpl* This,
|
||||
ULONG blockIndex);
|
||||
|
||||
void StorageImpl_ReleaseBigBlock(
|
||||
StorageImpl* This,
|
||||
void* pBigBlock);
|
||||
|
||||
ULONG StorageImpl_GetNextFreeBigBlock(
|
||||
StorageImpl* This);
|
||||
|
||||
void StorageImpl_FreeBigBlock(
|
||||
StorageImpl* This,
|
||||
ULONG blockIndex);
|
||||
|
||||
HRESULT StorageImpl_GetNextBlockInChain(
|
||||
StorageImpl* This,
|
||||
ULONG blockIndex,
|
||||
ULONG* nextBlockIndex);
|
||||
|
||||
void StorageImpl_SetNextBlockInChain(
|
||||
StorageImpl* This,
|
||||
ULONG blockIndex,
|
||||
ULONG nextBlock);
|
||||
|
||||
HRESULT StorageImpl_LoadFileHeader(
|
||||
StorageImpl* This);
|
||||
|
||||
void StorageImpl_SaveFileHeader(
|
||||
StorageImpl* This);
|
||||
|
||||
BOOL StorageImpl_ReadProperty(
|
||||
StorageImpl* This,
|
||||
ULONG index,
|
||||
StgProperty* buffer);
|
||||
|
||||
BOOL StorageImpl_WriteProperty(
|
||||
StorageImpl* This,
|
||||
ULONG index,
|
||||
StgProperty* buffer);
|
||||
|
||||
BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
|
||||
StorageImpl* This,
|
||||
SmallBlockChainStream** ppsbChain);
|
||||
|
||||
ULONG Storage32Impl_GetNextExtendedBlock(StorageImpl* This,
|
||||
ULONG blockIndex);
|
||||
|
||||
void Storage32Impl_AddBlockDepot(StorageImpl* This,
|
||||
ULONG blockIndex);
|
||||
|
||||
ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This);
|
||||
|
||||
ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This,
|
||||
ULONG depotIndex);
|
||||
|
||||
void Storage32Impl_SetExtDepotBlock(StorageImpl* This,
|
||||
ULONG depotIndex,
|
||||
ULONG blockIndex);
|
||||
/****************************************************************************
|
||||
* Storage32InternalImpl definitions.
|
||||
*
|
||||
* Definition of the implementation structure for the IStorage32 interface.
|
||||
* This one implements the IStorage32 interface for storage that are
|
||||
* inside another storage.
|
||||
*/
|
||||
struct StorageInternalImpl
|
||||
{
|
||||
IStorageVtbl *lpVtbl; /* Needs to be the first item in the struct
|
||||
* since we want to cast this in a Storage32 pointer */
|
||||
|
||||
/*
|
||||
* Declare the member of the Storage32BaseImpl class to allow
|
||||
* casting as a Storage32BaseImpl
|
||||
*/
|
||||
ULONG ref;
|
||||
struct StorageImpl* ancestorStorage;
|
||||
ULONG rootPropertySetIndex;
|
||||
void (*v_destructor)(struct StorageInternalImpl*);
|
||||
|
||||
/*
|
||||
* There is no specific data for this class.
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* Method definitions for the Storage32InternalImpl class.
|
||||
*/
|
||||
StorageInternalImpl* StorageInternalImpl_Construct(
|
||||
StorageImpl* ancestorStorage,
|
||||
ULONG rootTropertyIndex);
|
||||
|
||||
void StorageInternalImpl_Destroy(
|
||||
StorageInternalImpl* This);
|
||||
|
||||
HRESULT WINAPI StorageInternalImpl_Commit(
|
||||
IStorage* iface,
|
||||
DWORD grfCommitFlags); /* [in] */
|
||||
|
||||
HRESULT WINAPI StorageInternalImpl_Revert(
|
||||
IStorage* iface);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* IEnumSTATSTGImpl definitions.
|
||||
*
|
||||
* Definition of the implementation structure for the IEnumSTATSTGImpl interface.
|
||||
* This class allows iterating through the content of a storage and to find
|
||||
* specific items inside it.
|
||||
*/
|
||||
struct IEnumSTATSTGImpl
|
||||
{
|
||||
IEnumSTATSTGVtbl *lpVtbl; /* Needs to be the first item in the struct
|
||||
* since we want to cast this in a IEnumSTATSTG pointer */
|
||||
|
||||
ULONG ref; /* Reference count */
|
||||
StorageImpl* parentStorage; /* Reference to the parent storage */
|
||||
ULONG firstPropertyNode; /* Index of the root of the storage to enumerate */
|
||||
|
||||
/*
|
||||
* The current implementation of the IEnumSTATSTGImpl class uses a stack
|
||||
* to walk the property sets to get the content of a storage. This stack
|
||||
* is implemented by the following 3 data members
|
||||
*/
|
||||
ULONG stackSize;
|
||||
ULONG stackMaxSize;
|
||||
ULONG* stackToVisit;
|
||||
|
||||
#define ENUMSTATSGT_SIZE_INCREMENT 10
|
||||
};
|
||||
|
||||
/*
|
||||
* Method definitions for the IEnumSTATSTGImpl class.
|
||||
*/
|
||||
HRESULT WINAPI IEnumSTATSTGImpl_QueryInterface(
|
||||
IEnumSTATSTG* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
ULONG WINAPI IEnumSTATSTGImpl_AddRef(
|
||||
IEnumSTATSTG* iface);
|
||||
|
||||
ULONG WINAPI IEnumSTATSTGImpl_Release(
|
||||
IEnumSTATSTG* iface);
|
||||
|
||||
HRESULT WINAPI IEnumSTATSTGImpl_Next(
|
||||
IEnumSTATSTG* iface,
|
||||
ULONG celt,
|
||||
STATSTG* rgelt,
|
||||
ULONG* pceltFetched);
|
||||
|
||||
HRESULT WINAPI IEnumSTATSTGImpl_Skip(
|
||||
IEnumSTATSTG* iface,
|
||||
ULONG celt);
|
||||
|
||||
HRESULT WINAPI IEnumSTATSTGImpl_Reset(
|
||||
IEnumSTATSTG* iface);
|
||||
|
||||
HRESULT WINAPI IEnumSTATSTGImpl_Clone(
|
||||
IEnumSTATSTG* iface,
|
||||
IEnumSTATSTG** ppenum);
|
||||
|
||||
IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
|
||||
StorageImpl* This,
|
||||
ULONG firstPropertyNode);
|
||||
|
||||
void IEnumSTATSTGImpl_Destroy(
|
||||
IEnumSTATSTGImpl* This);
|
||||
|
||||
void IEnumSTATSTGImpl_PushSearchNode(
|
||||
IEnumSTATSTGImpl* This,
|
||||
ULONG nodeToPush);
|
||||
|
||||
ULONG IEnumSTATSTGImpl_PopSearchNode(
|
||||
IEnumSTATSTGImpl* This,
|
||||
BOOL remove);
|
||||
|
||||
ULONG IEnumSTATSTGImpl_FindProperty(
|
||||
IEnumSTATSTGImpl* This,
|
||||
const OLECHAR* lpszPropName,
|
||||
StgProperty* buffer);
|
||||
|
||||
INT IEnumSTATSTGImpl_FindParentProperty(
|
||||
IEnumSTATSTGImpl *This,
|
||||
ULONG childProperty,
|
||||
StgProperty *currentProperty,
|
||||
ULONG *propertyId);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* StgStreamImpl definitions.
|
||||
*
|
||||
* This class imlements the IStream32 inteface and represents a stream
|
||||
* located inside a storage object.
|
||||
*/
|
||||
struct StgStreamImpl
|
||||
{
|
||||
IStreamVtbl *lpVtbl; /* Needs to be the first item in the struct
|
||||
* since we want to cast this in a IStream pointer */
|
||||
|
||||
/*
|
||||
* Reference count
|
||||
*/
|
||||
ULONG ref;
|
||||
|
||||
/*
|
||||
* Storage that is the parent(owner) of the stream
|
||||
*/
|
||||
StorageBaseImpl* parentStorage;
|
||||
|
||||
/*
|
||||
* Access mode of this stream.
|
||||
*/
|
||||
DWORD grfMode;
|
||||
|
||||
/*
|
||||
* Index of the property that owns (points to) this stream.
|
||||
*/
|
||||
ULONG ownerProperty;
|
||||
|
||||
/*
|
||||
* Helper variable that contains the size of the stream
|
||||
*/
|
||||
ULARGE_INTEGER streamSize;
|
||||
|
||||
/*
|
||||
* This is the current position of the cursor in the stream
|
||||
*/
|
||||
ULARGE_INTEGER currentPosition;
|
||||
|
||||
/*
|
||||
* The information in the stream is represented by a chain of small blocks
|
||||
* or a chain of large blocks. Depending on the case, one of the two
|
||||
* following variabled points to that information.
|
||||
*/
|
||||
BlockChainStream* bigBlockChain;
|
||||
SmallBlockChainStream* smallBlockChain;
|
||||
};
|
||||
|
||||
/*
|
||||
* Method definition for the StgStreamImpl class.
|
||||
*/
|
||||
StgStreamImpl* StgStreamImpl_Construct(
|
||||
StorageBaseImpl* parentStorage,
|
||||
DWORD grfMode,
|
||||
ULONG ownerProperty);
|
||||
|
||||
void StgStreamImpl_Destroy(
|
||||
StgStreamImpl* This);
|
||||
|
||||
void StgStreamImpl_OpenBlockChain(
|
||||
StgStreamImpl* This);
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_QueryInterface(
|
||||
IStream* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject); /* [iid_is][out] */
|
||||
|
||||
ULONG WINAPI StgStreamImpl_AddRef(
|
||||
IStream* iface);
|
||||
|
||||
ULONG WINAPI StgStreamImpl_Release(
|
||||
IStream* iface);
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_Read(
|
||||
IStream* iface,
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead); /* [out] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_Write(
|
||||
IStream* iface,
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_Seek(
|
||||
IStream* iface,
|
||||
LARGE_INTEGER dlibMove, /* [in] */
|
||||
DWORD dwOrigin, /* [in] */
|
||||
ULARGE_INTEGER* plibNewPosition); /* [out] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_SetSize(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libNewSize); /* [in] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_CopyTo(
|
||||
IStream* iface,
|
||||
IStream* pstm, /* [unique][in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
ULARGE_INTEGER* pcbRead, /* [out] */
|
||||
ULARGE_INTEGER* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_Commit(
|
||||
IStream* iface,
|
||||
DWORD grfCommitFlags); /* [in] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_Revert(
|
||||
IStream* iface);
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_LockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_UnlockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_Stat(
|
||||
IStream* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag); /* [in] */
|
||||
|
||||
HRESULT WINAPI StgStreamImpl_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm); /* [out] */
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* The StorageUtl_ functions are miscelaneous utility functions. Most of which are
|
||||
* abstractions used to read values from file buffers without having to worry
|
||||
* about bit order
|
||||
*/
|
||||
void StorageUtl_ReadWord(void* buffer, ULONG offset, WORD* value);
|
||||
void StorageUtl_WriteWord(void* buffer, ULONG offset, WORD value);
|
||||
void StorageUtl_ReadDWord(void* buffer, ULONG offset, DWORD* value);
|
||||
void StorageUtl_WriteDWord(void* buffer, ULONG offset, DWORD value);
|
||||
void StorageUtl_ReadGUID(void* buffer, ULONG offset, GUID* value);
|
||||
void StorageUtl_WriteGUID(void* buffer, ULONG offset, GUID* value);
|
||||
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination,
|
||||
StgProperty* source,
|
||||
int statFlags);
|
||||
|
||||
/****************************************************************************
|
||||
* BlockChainStream definitions.
|
||||
*
|
||||
* The BlockChainStream class is a utility class that is used to create an
|
||||
* abstraction of the big block chains in the storage file.
|
||||
*/
|
||||
struct BlockChainStream
|
||||
{
|
||||
StorageImpl* parentStorage;
|
||||
ULONG* headOfStreamPlaceHolder;
|
||||
ULONG ownerPropertyIndex;
|
||||
ULONG lastBlockNoInSequence;
|
||||
ULONG lastBlockNoInSequenceIndex;
|
||||
ULONG tailIndex;
|
||||
ULONG numBlocks;
|
||||
};
|
||||
|
||||
/*
|
||||
* Methods for the BlockChainStream class.
|
||||
*/
|
||||
BlockChainStream* BlockChainStream_Construct(
|
||||
StorageImpl* parentStorage,
|
||||
ULONG* headOfStreamPlaceHolder,
|
||||
ULONG propertyIndex);
|
||||
|
||||
void BlockChainStream_Destroy(
|
||||
BlockChainStream* This);
|
||||
|
||||
ULONG BlockChainStream_GetHeadOfChain(
|
||||
BlockChainStream* This);
|
||||
|
||||
BOOL BlockChainStream_ReadAt(
|
||||
BlockChainStream* This,
|
||||
ULARGE_INTEGER offset,
|
||||
ULONG size,
|
||||
void* buffer,
|
||||
ULONG* bytesRead);
|
||||
|
||||
BOOL BlockChainStream_WriteAt(
|
||||
BlockChainStream* This,
|
||||
ULARGE_INTEGER offset,
|
||||
ULONG size,
|
||||
const void* buffer,
|
||||
ULONG* bytesWritten);
|
||||
|
||||
BOOL BlockChainStream_SetSize(
|
||||
BlockChainStream* This,
|
||||
ULARGE_INTEGER newSize);
|
||||
|
||||
ULARGE_INTEGER BlockChainStream_GetSize(
|
||||
BlockChainStream* This);
|
||||
|
||||
ULONG BlockChainStream_GetCount(
|
||||
BlockChainStream* This);
|
||||
|
||||
/****************************************************************************
|
||||
* SmallBlockChainStream definitions.
|
||||
*
|
||||
* The SmallBlockChainStream class is a utility class that is used to create an
|
||||
* abstraction of the small block chains in the storage file.
|
||||
*/
|
||||
struct SmallBlockChainStream
|
||||
{
|
||||
StorageImpl* parentStorage;
|
||||
ULONG ownerPropertyIndex;
|
||||
};
|
||||
|
||||
/*
|
||||
* Methods of the SmallBlockChainStream class.
|
||||
*/
|
||||
SmallBlockChainStream* SmallBlockChainStream_Construct(
|
||||
StorageImpl* parentStorage,
|
||||
ULONG propertyIndex);
|
||||
|
||||
void SmallBlockChainStream_Destroy(
|
||||
SmallBlockChainStream* This);
|
||||
|
||||
ULONG SmallBlockChainStream_GetHeadOfChain(
|
||||
SmallBlockChainStream* This);
|
||||
|
||||
HRESULT SmallBlockChainStream_GetNextBlockInChain(
|
||||
SmallBlockChainStream* This,
|
||||
ULONG blockIndex,
|
||||
ULONG* nextBlockIndex);
|
||||
|
||||
void SmallBlockChainStream_SetNextBlockInChain(
|
||||
SmallBlockChainStream* This,
|
||||
ULONG blockIndex,
|
||||
ULONG nextBlock);
|
||||
|
||||
void SmallBlockChainStream_FreeBlock(
|
||||
SmallBlockChainStream* This,
|
||||
ULONG blockIndex);
|
||||
|
||||
ULONG SmallBlockChainStream_GetNextFreeBlock(
|
||||
SmallBlockChainStream* This);
|
||||
|
||||
BOOL SmallBlockChainStream_ReadAt(
|
||||
SmallBlockChainStream* This,
|
||||
ULARGE_INTEGER offset,
|
||||
ULONG size,
|
||||
void* buffer,
|
||||
ULONG* bytesRead);
|
||||
|
||||
BOOL SmallBlockChainStream_WriteAt(
|
||||
SmallBlockChainStream* This,
|
||||
ULARGE_INTEGER offset,
|
||||
ULONG size,
|
||||
const void* buffer,
|
||||
ULONG* bytesWritten);
|
||||
|
||||
BOOL SmallBlockChainStream_SetSize(
|
||||
SmallBlockChainStream* This,
|
||||
ULARGE_INTEGER newSize);
|
||||
|
||||
ULARGE_INTEGER SmallBlockChainStream_GetSize(
|
||||
SmallBlockChainStream* This);
|
||||
|
||||
ULONG SmallBlockChainStream_GetCount(
|
||||
SmallBlockChainStream* This);
|
||||
|
||||
|
||||
#endif /* __STORAGE32_H__ */
|
||||
@@ -1,28 +0,0 @@
|
||||
# $Id: Makefile,v 1.1 2004/11/07 22:19:07 sedwards Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_NORC = yes
|
||||
|
||||
TARGET_TYPE = program
|
||||
|
||||
TARGET_APPTYPE = console
|
||||
|
||||
# require os code to explicitly request A/W version of structs/functions
|
||||
TARGET_CFLAGS += -D_DISABLE_TIDENTS -D__USE_W32API -D_WIN32_IE=0x0600 \
|
||||
-D_WIN32_WINNT=0x0501 -D__REACTOS__
|
||||
|
||||
TARGET_NAME = ole32_test
|
||||
|
||||
TARGET_SDKLIBS = oleaut32.a ole32.a ntdll.a
|
||||
|
||||
TARGET_OBJECTS = \
|
||||
testlist.o \
|
||||
propvariant.o \
|
||||
storage32.o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
# EOF
|
||||
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
* PropVariant Tests
|
||||
*
|
||||
* Copyright 2004 Robert Shearman
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
HRESULT WINAPI PropVariantCopy(PROPVARIANT*,const PROPVARIANT*);
|
||||
HRESULT WINAPI PropVariantClear(PROPVARIANT*);
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#ifdef NONAMELESSUNION
|
||||
# define U(x) (x).u
|
||||
#else
|
||||
# define U(x) (x)
|
||||
#endif
|
||||
|
||||
struct valid_mapping
|
||||
{
|
||||
BOOL simple;
|
||||
BOOL with_array;
|
||||
BOOL with_vector;
|
||||
BOOL byref;
|
||||
} valid_types[] =
|
||||
{
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_EMPTY */
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_NULL */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_I2 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_I4 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_R4 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_R8 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_CY */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_DATE */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_BSTR */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_DISPATCH */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_ERROR */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_BOOL */
|
||||
{ FALSE, FALSE, TRUE , FALSE }, /* VT_VARIANT */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_UNKNOWN */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_DECIMAL */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 15 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_I1 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_UI1 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_UI2 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_UI4 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_I8 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_UI8 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_INT */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_UINT */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_VOID */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_HRESULT */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_PTR */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_SAFEARRAY */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_CARRAY */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_USERDEFINED */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_LPSTR */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_LPWSTR */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 32 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 33 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 34 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 35 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_RECORD */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_INT_PTR */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* VT_UINT_PTR */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 39 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 40 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 41 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 42 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 43 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 44 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 45 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 46 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 47 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 48 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 49 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 50 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 51 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 52 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 53 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 54 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 55 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 56 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 57 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 58 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 59 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 60 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 61 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 62 */
|
||||
{ FALSE, FALSE, FALSE, FALSE }, /* 63 */
|
||||
{ TRUE , FALSE, TRUE , FALSE }, /* VT_FILETIME */
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_BLOB */
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_STREAM */
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_STORAGE */
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_STREAMED_OBJECT */
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_STORED_OBJECT */
|
||||
{ TRUE , FALSE, FALSE, FALSE }, /* VT_BLOB_OBJECT */
|
||||
{ TRUE , FALSE, TRUE , FALSE } /* VT_CF */
|
||||
};
|
||||
|
||||
static const char* wine_vtypes[VT_CLSID+1] =
|
||||
{
|
||||
"VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE",
|
||||
"VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN",
|
||||
"VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8",
|
||||
"VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY",
|
||||
"VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR","32","33","34","35",
|
||||
"VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45",
|
||||
"46","47","48","49","50","51","52","53","54","55","56","57","58","59","60",
|
||||
"61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE",
|
||||
"VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID"
|
||||
};
|
||||
|
||||
static void test_validtypes()
|
||||
{
|
||||
PROPVARIANT propvar;
|
||||
HRESULT hr;
|
||||
unsigned int i;
|
||||
|
||||
memset(&propvar, 0, sizeof(propvar));
|
||||
|
||||
for (i = 0; i < sizeof(valid_types)/sizeof(valid_types[0]); i++)
|
||||
{
|
||||
propvar.vt = i;
|
||||
hr = PropVariantClear(&propvar);
|
||||
ok(valid_types[i].simple == !(hr == STG_E_INVALIDPARAMETER),
|
||||
"PropVariantClear(%s) should have returned 0x%08lx, but returned 0x%08lx\n",
|
||||
wine_vtypes[i],
|
||||
valid_types[i].simple ? S_OK : STG_E_INVALIDPARAMETER, hr);
|
||||
|
||||
propvar.vt = i | VT_ARRAY;
|
||||
hr = PropVariantClear(&propvar);
|
||||
ok(valid_types[i].with_array == !(hr == STG_E_INVALIDPARAMETER),
|
||||
"PropVariantClear(%s|VT_ARRAY) should have returned 0x%08lx, but returned 0x%08lx\n",
|
||||
wine_vtypes[i],
|
||||
valid_types[i].with_array ? S_OK : STG_E_INVALIDPARAMETER, hr);
|
||||
|
||||
propvar.vt = i | VT_VECTOR;
|
||||
hr = PropVariantClear(&propvar);
|
||||
ok(valid_types[i].with_vector == !(hr == STG_E_INVALIDPARAMETER),
|
||||
"PropVariantClear(%s|VT_VECTOR) should have returned 0x%08lx, but returned 0x%08lx\n",
|
||||
wine_vtypes[i],
|
||||
valid_types[i].with_vector ? S_OK : STG_E_INVALIDPARAMETER, hr);
|
||||
|
||||
propvar.vt = i | VT_BYREF;
|
||||
hr = PropVariantClear(&propvar);
|
||||
ok(valid_types[i].byref == !(hr == STG_E_INVALIDPARAMETER),
|
||||
"PropVariantClear(%s|VT_BYREF) should have returned 0x%08lx, but returned 0x%08lx\n",
|
||||
wine_vtypes[i],
|
||||
valid_types[i].byref ? S_OK : STG_E_INVALIDPARAMETER, hr);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_copy()
|
||||
{
|
||||
static const char szTestString[] = "Test String";
|
||||
static const WCHAR wszTestString[] = {'T','e','s','t',' ','S','t','r','i','n','g',0};
|
||||
PROPVARIANT propvarSrc;
|
||||
PROPVARIANT propvarDst;
|
||||
HRESULT hr;
|
||||
|
||||
propvarSrc.vt = VT_BSTR;
|
||||
U(propvarSrc).bstrVal = SysAllocString(wszTestString);
|
||||
|
||||
hr = PropVariantCopy(&propvarDst, &propvarSrc);
|
||||
ok(hr == S_OK, "PropVariantCopy(...VT_BSTR...) failed\n");
|
||||
ok(!lstrcmpW(U(propvarSrc).bstrVal, U(propvarDst).bstrVal), "BSTR not copied properly\n");
|
||||
hr = PropVariantClear(&propvarSrc);
|
||||
ok(hr == S_OK, "PropVariantClear(...VT_BSTR...) failed\n");
|
||||
hr = PropVariantClear(&propvarDst);
|
||||
ok(hr == S_OK, "PropVariantClear(...VT_BSTR...) failed\n");
|
||||
|
||||
propvarSrc.vt = VT_LPWSTR;
|
||||
U(propvarSrc).pwszVal = (LPWSTR)wszTestString;
|
||||
hr = PropVariantCopy(&propvarDst, &propvarSrc);
|
||||
ok(hr == S_OK, "PropVariantCopy(...VT_LPWSTR...) failed\n");
|
||||
ok(!lstrcmpW(U(propvarSrc).pwszVal, U(propvarDst).pwszVal), "Wide string not copied properly\n");
|
||||
hr = PropVariantClear(&propvarDst);
|
||||
ok(hr == S_OK, "PropVariantClear(...VT_LPWSTR...) failed\n");
|
||||
memset(&propvarSrc, 0, sizeof(propvarSrc));
|
||||
|
||||
propvarSrc.vt = VT_LPSTR;
|
||||
U(propvarSrc).pszVal = (LPSTR)szTestString;
|
||||
hr = PropVariantCopy(&propvarDst, &propvarSrc);
|
||||
ok(hr == S_OK, "PropVariantCopy(...VT_LPSTR...) failed\n");
|
||||
ok(!strcmp(U(propvarSrc).pszVal, U(propvarDst).pszVal), "String not copied properly\n");
|
||||
hr = PropVariantClear(&propvarDst);
|
||||
ok(hr == S_OK, "PropVariantClear(...VT_LPSTR...) failed\n");
|
||||
memset(&propvarSrc, 0, sizeof(propvarSrc));
|
||||
}
|
||||
|
||||
START_TEST(propvariant)
|
||||
{
|
||||
test_validtypes();
|
||||
test_copy();
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Unit tests for OLE storage
|
||||
*
|
||||
* Copyright (c) 2004 Mike McCormack
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "ole2.h"
|
||||
#include "objidl.h"
|
||||
#include "initguid.h"
|
||||
|
||||
DEFINE_GUID( test_stg_cls, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0);
|
||||
|
||||
void test_hglobal_storage_stat(void)
|
||||
{
|
||||
ILockBytes *ilb = NULL;
|
||||
IStorage *stg = NULL;
|
||||
HRESULT r;
|
||||
STATSTG stat;
|
||||
DWORD mode, refcount;
|
||||
|
||||
r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
|
||||
ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
|
||||
|
||||
mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
|
||||
r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg );
|
||||
ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
|
||||
|
||||
r = WriteClassStg( stg, &test_stg_cls );
|
||||
ok( r == S_OK, "WriteClassStg failed\n");
|
||||
|
||||
memset( &stat, 0, sizeof stat );
|
||||
r = IStorage_Stat( stg, &stat, 0 );
|
||||
|
||||
ok( stat.pwcsName == NULL, "storage name not null\n");
|
||||
ok( stat.type == 1, "type is wrong\n");
|
||||
#ifndef __REACTOS__
|
||||
todo_wine {
|
||||
ok( stat.grfMode == 0x12, "grf mode is incorrect\n");
|
||||
}
|
||||
#endif
|
||||
ok( !memcmp(&stat.clsid, &test_stg_cls, sizeof test_stg_cls), "CLSID is wrong\n");
|
||||
|
||||
refcount = IStorage_Release( stg );
|
||||
ok( refcount == 0, "IStorage refcount is wrong\n");
|
||||
refcount = ILockBytes_Release( ilb );
|
||||
ok( refcount == 0, "ILockBytes refcount is wrong\n");
|
||||
}
|
||||
|
||||
START_TEST(storage32)
|
||||
{
|
||||
test_hglobal_storage_stat();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/* Automatically generated file; DO NOT EDIT!! */
|
||||
|
||||
/* stdarg.h is needed for Winelib */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
||||
extern void func_propvariant(void);
|
||||
extern void func_storage32(void);
|
||||
|
||||
struct test
|
||||
{
|
||||
const char *name;
|
||||
void (*func)(void);
|
||||
};
|
||||
|
||||
static const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "propvariant", func_propvariant },
|
||||
{ "storage32", func_storage32 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#define WINETEST_WANT_MAIN
|
||||
#include "wine/test.h"
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* version information for ole32.dll
|
||||
*
|
||||
* Copyright (C) 2003 John K. Hohm
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define WINE_OLESELFREGISTER
|
||||
#define WINE_FILENAME_STR "ole32.dll"
|
||||
|
||||
#include <wine/wine_common_ver.rc>
|
||||
@@ -1,67 +0,0 @@
|
||||
Index: ifs.h
|
||||
===================================================================
|
||||
RCS file: /home/wine/wine/dlls/ole32/ifs.h,v
|
||||
retrieving revision 1.13
|
||||
diff -u -r1.13 ifs.h
|
||||
--- ifs.h 5 Oct 2004 04:16:21 -0000 1.13
|
||||
+++ ifs.h 6 Dec 2004 10:15:06 -0000
|
||||
@@ -33,8 +33,7 @@
|
||||
* IMalloc16 interface
|
||||
*/
|
||||
|
||||
-typedef struct IMalloc16 IMalloc16, *LPMALLOC16;
|
||||
-
|
||||
+#undef INTERFACE
|
||||
#define INTERFACE IMalloc16
|
||||
DECLARE_INTERFACE_(IMalloc16,IUnknown)
|
||||
{
|
||||
@@ -52,14 +51,14 @@
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
+typedef struct IMalloc16 *LPMALLOC16;
|
||||
+
|
||||
/**********************************************************************/
|
||||
|
||||
extern LPMALLOC16 IMalloc16_Constructor();
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
-typedef struct ILockBytes16 *LPLOCKBYTES16, ILockBytes16;
|
||||
-
|
||||
#define INTERFACE ILockBytes16
|
||||
DECLARE_INTERFACE_(ILockBytes16,IUnknown)
|
||||
{
|
||||
@@ -95,8 +94,6 @@
|
||||
DWORD reserved;
|
||||
} STATSTG16;
|
||||
|
||||
-typedef struct IStream16 IStream16, *LPSTREAM16;
|
||||
-
|
||||
#define INTERFACE IStream16
|
||||
DECLARE_INTERFACE_(IStream16,ISequentialStream)
|
||||
{
|
||||
@@ -123,8 +120,6 @@
|
||||
/**********************************************************************/
|
||||
|
||||
typedef OLECHAR16 **SNB16;
|
||||
-
|
||||
-typedef struct IStorage16 IStorage16, *LPSTORAGE16;
|
||||
|
||||
#define INTERFACE IStorage16
|
||||
DECLARE_INTERFACE_(IStorage16,IUnknown)
|
||||
Index: oleproxy.c
|
||||
===================================================================
|
||||
RCS file: /home/wine/wine/dlls/ole32/oleproxy.c,v
|
||||
retrieving revision 1.23
|
||||
diff -u -r1.23 oleproxy.c
|
||||
--- oleproxy.c 7 Oct 2004 03:06:49 -0000 1.23
|
||||
+++ oleproxy.c 6 Dec 2004 10:15:06 -0000
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
+#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
Reference in New Issue
Block a user