Need to remove existing files before doing vendor import

svn path=/trunk/; revision=12574
This commit is contained in:
Gé van Geldorp
2004-12-31 15:19:40 +00:00
parent da5c413758
commit 53af5ece75
59 changed files with 0 additions and 40107 deletions
-74
View File
@@ -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)
-21
View File
@@ -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
-666
View File
@@ -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;
}
-590
View File
@@ -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
-218
View File
@@ -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
-192
View File
@@ -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
-515
View File
@@ -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 */
-292
View File
@@ -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
-523
View File
@@ -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
-240
View File
@@ -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;
}
-366
View File
@@ -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;
}
-837
View File
@@ -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;
}
-642
View File
@@ -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)
);
}
-150
View File
@@ -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 */
-982
View File
@@ -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);
}
-9
View File
@@ -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
-809
View File
@@ -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);
}
-622
View File
@@ -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;
}
-578
View File
@@ -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;
}
-554
View File
@@ -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;
}
-11
View File
@@ -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__ */
-527
View File
@@ -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
-158
View File
@@ -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
-144
View File
@@ -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;
}
-9
View File
@@ -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
-304
View File
@@ -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;
}
-136
View File
@@ -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 */
}
-12
View File
@@ -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
-3
View File
@@ -1,3 +0,0 @@
1 stub DLLGETCLASSOBJECT
#2 WEP
#3 ___EXPORTEDSTUB
-175
View File
@@ -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;
}
-7
View File
@@ -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
-266
View File
@@ -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
-139
View File
@@ -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 */
-33
View File
@@ -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 */
-147
View File
@@ -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.
*/
-752
View File
@@ -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;
}
-526
View File
@@ -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;
}
-56
View File
@@ -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_ */
-865
View File
@@ -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;
}
-805
View File
@@ -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 */
}
}
-872
View File
@@ -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;
}
-895
View File
@@ -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
-59
View File
@@ -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
-892
View File
@@ -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__ */
-28
View File
@@ -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
-211
View File
@@ -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();
}
-74
View File
@@ -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();
}
-27
View File
@@ -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"
-24
View File
@@ -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>
-67
View File
@@ -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>