Autosyncing with Wine HEAD

svn path=/trunk/; revision=26436
This commit is contained in:
The Wine Synchronizer
2007-04-20 12:23:52 +00:00
parent c3111bb5ce
commit f662eaa548
54 changed files with 10012 additions and 3853 deletions
+107 -17
View File
@@ -1,4 +1,4 @@
/***************************************************************************************
/*
* AntiMonikers implementation
*
* Copyright 1999 Noomen Hamza
@@ -15,8 +15,8 @@
*
* 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
***************************************************************************************/
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
@@ -35,10 +35,6 @@
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{
@@ -51,6 +47,7 @@ typedef struct AntiMonikerImpl{
LONG ref; /* reference counter for this object */
IUnknown *pMarshal; /* custom marshaler */
} AntiMonikerImpl;
static inline IMoniker *impl_from_IROTData( IROTData *iface )
@@ -84,6 +81,15 @@ AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
*ppvObject = iface;
else if (IsEqualIID(&IID_IROTData, riid))
*ppvObject = (IROTData*)&(This->lpvtbl2);
else if (IsEqualIID(&IID_IMarshal, riid))
{
HRESULT hr = S_OK;
if (!This->pMarshal)
hr = MonikerMarshal_Create(iface, &This->pMarshal);
if (hr != S_OK)
return hr;
return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
}
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
@@ -122,7 +128,11 @@ AntiMonikerImpl_Release(IMoniker* iface)
ref = InterlockedDecrement(&This->ref);
/* destroy the object if there's no more reference on it */
if (ref == 0) HeapFree(GetProcessHeap(),0,This);
if (ref == 0)
{
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This);
}
return ref;
}
@@ -133,7 +143,7 @@ AntiMonikerImpl_Release(IMoniker* iface)
static HRESULT WINAPI
AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
TRACE("(%p,%p),stub!\n",iface,pClassID);
TRACE("(%p,%p)\n",iface,pClassID);
if (pClassID==NULL)
return E_POINTER;
@@ -202,7 +212,7 @@ AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
{
TRACE("(%p,%p)\n",iface,pcbSize);
if (pcbSize!=NULL)
if (!pcbSize)
return E_POINTER;
/* for more details see AntiMonikerImpl_Save coments */
@@ -248,7 +258,7 @@ static 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);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@@ -325,7 +335,7 @@ static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
if (pdwHash==NULL)
return E_POINTER;
*pdwHash=0;
*pdwHash = 0x80000001;
return S_OK;
}
@@ -395,7 +405,7 @@ AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** p
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
if(mkSys==MKSYS_ITEMMONIKER){
if(mkSys==MKSYS_ANTIMONIKER){
IMoniker_AddRef(iface);
@@ -525,11 +535,21 @@ static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
* AntiMonikerIROTData_GetComparaisonData
******************************************************************************/
static HRESULT WINAPI
AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface, BYTE* pbData,
AntiMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
ULONG cbMax, ULONG* pcbData)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
DWORD constant = 1;
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + sizeof(DWORD);
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
memcpy(pbData, &CLSID_AntiMoniker, sizeof(CLSID));
memcpy(pbData+sizeof(CLSID), &constant, sizeof(DWORD));
return S_OK;
}
/********************************************************************************/
@@ -569,7 +589,7 @@ static const IROTDataVtbl VT_ROTDataImpl =
AntiMonikerROTDataImpl_QueryInterface,
AntiMonikerROTDataImpl_AddRef,
AntiMonikerROTDataImpl_Release,
AntiMonikerROTDataImpl_GetComparaisonData
AntiMonikerROTDataImpl_GetComparisonData
};
/******************************************************************************
@@ -584,6 +604,7 @@ static HRESULT AntiMonikerImpl_Construct(AntiMonikerImpl* This)
This->lpvtbl1 = &VT_AntiMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->pMarshal = NULL;
return S_OK;
}
@@ -615,3 +636,72 @@ HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk)
return hr;
}
static HRESULT WINAPI AntiMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI AntiMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI AntiMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI AntiMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
IMoniker *pMoniker;
HRESULT hr;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
hr = CreateAntiMoniker(&pMoniker);
if (FAILED(hr))
return hr;
hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
if (FAILED(hr))
IMoniker_Release(pMoniker);
return hr;
}
static HRESULT WINAPI AntiMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl AntiMonikerCFVtbl =
{
AntiMonikerCF_QueryInterface,
AntiMonikerCF_AddRef,
AntiMonikerCF_Release,
AntiMonikerCF_CreateInstance,
AntiMonikerCF_LockServer
};
static const IClassFactoryVtbl *AntiMonikerCF = &AntiMonikerCFVtbl;
HRESULT AntiMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&AntiMonikerCF, riid, ppv);
}
+104 -54
View File
@@ -1,4 +1,4 @@
/***************************************************************************************
/*
* BindCtx implementation
*
* Copyright 1999 Noomen Hamza
@@ -15,26 +15,25 @@
*
* 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
***************************************************************************************/
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#define COBJMACROS
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winnls.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
#define BINDCTX_FIRST_TABLE_SIZE 4
/* data structure of the BindCtx table elements */
typedef struct BindCtxObject{
@@ -65,6 +64,7 @@ typedef struct BindCtxImpl{
/* IBindCtx prototype functions : */
static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx*);
static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl*, IUnknown*, LPOLESTR, DWORD *);
static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *);
/*******************************************************************************
* BindCtx_QueryInterface
@@ -157,7 +157,14 @@ BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
TRACE("(%p,%p)\n",This,punk);
if (punk==NULL)
return E_POINTER;
return S_OK;
if (lastIndex == This->bindCtxTableSize)
{
HRESULT hr = BindCtxImpl_ExpandTable(This);
if (FAILED(hr))
return hr;
}
IUnknown_AddRef(punk);
@@ -167,20 +174,6 @@ BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
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;
}
@@ -196,6 +189,9 @@ BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
TRACE("(%p,%p)\n",This,punk);
if (!punk)
return E_INVALIDARG;
/* check if the object was registered or not */
if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
return MK_E_NOTBOUND;
@@ -266,18 +262,20 @@ static HRESULT WINAPI
BindCtxImpl_GetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
{
BindCtxImpl *This = (BindCtxImpl *)iface;
ULONG cbStruct;
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);
cbStruct = pbindopts->cbStruct;
if (cbStruct > sizeof(BIND_OPTS2))
cbStruct = sizeof(BIND_OPTS2);
memcpy(pbindopts, &This->bindOption2, cbStruct);
pbindopts->cbStruct = cbStruct;
return S_OK;
}
@@ -324,6 +322,14 @@ BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
IUnknown_AddRef(punk);
return S_OK;
}
if (This->bindCtxTableLastIndex == This->bindCtxTableSize)
{
HRESULT hr = BindCtxImpl_ExpandTable(This);
if (FAILED(hr))
return hr;
}
This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
@@ -344,21 +350,6 @@ BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
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;
}
@@ -424,7 +415,11 @@ BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
static HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
{
FIXME("(%p,%p),stub!\n",iface,pszkey);
TRACE("(%p,%p)\n",iface,pszkey);
*pszkey = NULL;
/* not implemented in native either */
return E_NOTIMPL;
}
@@ -473,6 +468,29 @@ static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
return S_FALSE;
}
static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *This)
{
if (!This->bindCtxTableSize)
{
This->bindCtxTableSize = BINDCTX_FIRST_TABLE_SIZE;
This->bindCtxTable = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
This->bindCtxTableSize * sizeof(BindCtxObject));
}
else
{
This->bindCtxTableSize *= 2;
This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
This->bindCtxTableSize * sizeof(BindCtxObject));
}
if (!This->bindCtxTable)
return E_OUTOFMEMORY;
return S_OK;
}
/* Virtual function table for the BindCtx class. */
static const IBindCtxVtbl VT_BindCtxImpl =
{
@@ -510,31 +528,48 @@ static HRESULT BindCtxImpl_Construct(BindCtxImpl* This)
This->bindOption2.dwTrackFlags = 0;
This->bindOption2.dwClassContext = CLSCTX_SERVER;
This->bindOption2.locale = 1033;
This->bindOption2.locale = GetThreadLocale();
This->bindOption2.pServerInfo = 0;
/* Initialize the bindctx table */
This->bindCtxTableSize=BLOCK_TAB_SIZE;
This->bindCtxTableSize=0;
This->bindCtxTableLastIndex=0;
This->bindCtxTable = HeapAlloc(GetProcessHeap(), 0,
This->bindCtxTableSize*sizeof(BindCtxObject));
if (This->bindCtxTable==NULL)
return E_OUTOFMEMORY;
This->bindCtxTable = NULL;
return S_OK;
}
/******************************************************************************
* CreateBindCtx (OLE32.@)
******************************************************************************/
*
* Creates a bind context. A bind context encompasses information and options
* used when binding to a moniker.
*
* PARAMS
* reserved [I] Reserved. Set to 0.
* ppbc [O] Address that receives the bind context object.
*
* RETURNS
* Success: S_OK.
* Failure: Any HRESULT code.
*/
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
{
BindCtxImpl* newBindCtx = 0;
HRESULT hr;
IID riid=IID_IBindCtx;
TRACE("(%ld,%p)\n",reserved,ppbc);
TRACE("(%d,%p)\n",reserved,ppbc);
if (!ppbc) return E_INVALIDARG;
*ppbc = NULL;
if (reserved != 0)
{
ERR("reserved should be 0, not 0x%x\n", reserved);
return E_INVALIDARG;
}
newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
if (newBindCtx == 0)
@@ -552,12 +587,27 @@ HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
return hr;
}
/******************************************************************************
* BindMoniker [OLE32.@]
*
* Binds to a moniker.
*
* PARAMS
* pmk [I] Moniker to bind to.
* grfOpt [I] Reserved option flags. Set to 0.
* riid [I] ID of the interface to bind to.
* pvResult [O] Address that receives the interface of the object that was bound to.
*
* RETURNS
* Success: S_OK.
* Failure: Any HRESULT code.
*/
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);
TRACE("(%p, %x, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult);
res = CreateBindCtx(grfOpt, &pbc);
if (SUCCEEDED(res))
+882
View File
@@ -0,0 +1,882 @@
/*
* Class Monikers
*
* Copyright 1999 Noomen Hamza
* Copyright 2005-2007 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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);
#define CHARS_IN_GUID 39
/* ClassMoniker data structure */
typedef struct ClassMoniker
{
const IMonikerVtbl* lpVtbl; /* VTable relative to the IMoniker interface.*/
const IROTDataVtbl* lpVtblRotData; /* VTable relative to the IROTData interface.*/
LONG ref; /* reference counter for this object */
CLSID clsid; /* clsid identified by this moniker */
IUnknown *pMarshal; /* custom marshaler */
} ClassMoniker;
static inline IMoniker *impl_from_IROTData( IROTData *iface )
{
return (IMoniker *)((char*)iface - FIELD_OFFSET(ClassMoniker, lpVtblRotData));
}
/*******************************************************************************
* ClassMoniker_QueryInterface
*******************************************************************************/
static HRESULT WINAPI ClassMoniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
ClassMoniker *This = (ClassMoniker *)iface;
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
/* Perform a sanity check on the parameters.*/
if (!ppvObject)
return E_POINTER;
/* 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->lpVtblRotData);
else if (IsEqualIID(&IID_IMarshal, riid))
{
HRESULT hr = S_OK;
if (!This->pMarshal)
hr = MonikerMarshal_Create(iface, &This->pMarshal);
if (hr != S_OK)
return hr;
return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
}
/* Check that we obtained an interface.*/
if (!*ppvObject)
return E_NOINTERFACE;
/* Query Interface always increases the reference count by one when it is successful */
IMoniker_AddRef(iface);
return S_OK;
}
/******************************************************************************
* ClassMoniker_AddRef
******************************************************************************/
static ULONG WINAPI ClassMoniker_AddRef(IMoniker* iface)
{
ClassMoniker *This = (ClassMoniker *)iface;
TRACE("(%p)\n",This);
return InterlockedIncrement(&This->ref);
}
/******************************************************************************
* ClassMoniker_Destroy (local function)
*******************************************************************************/
static HRESULT WINAPI ClassMoniker_Destroy(ClassMoniker* This)
{
TRACE("(%p)\n",This);
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This);
return S_OK;
}
/******************************************************************************
* ClassMoniker_Release
******************************************************************************/
static ULONG WINAPI ClassMoniker_Release(IMoniker* iface)
{
ClassMoniker *This = (ClassMoniker *)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) ClassMoniker_Destroy(This);
return ref;
}
/******************************************************************************
* ClassMoniker_GetClassID
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetClassID(IMoniker* iface,CLSID *pClassID)
{
TRACE("(%p,%p),stub!\n",iface,pClassID);
if (pClassID==NULL)
return E_POINTER;
*pClassID = CLSID_ClassMoniker;
return S_OK;
}
/******************************************************************************
* ClassMoniker_IsDirty
******************************************************************************/
static HRESULT WINAPI ClassMoniker_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;
}
/******************************************************************************
* ClassMoniker_Load
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Load(IMoniker* iface,IStream* pStm)
{
ClassMoniker *This = (ClassMoniker *)iface;
HRESULT hr;
DWORD zero;
TRACE("(%p)\n", pStm);
hr = IStream_Read(pStm, &This->clsid, sizeof(This->clsid), NULL);
if (hr != S_OK) return STG_E_READFAULT;
hr = IStream_Read(pStm, &zero, sizeof(zero), NULL);
if ((hr != S_OK) || (zero != 0)) return STG_E_READFAULT;
return S_OK;
}
/******************************************************************************
* ClassMoniker_Save
******************************************************************************/
static HRESULT WINAPI ClassMoniker_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 */
{
ClassMoniker *This = (ClassMoniker *)iface;
HRESULT hr;
DWORD zero = 0;
TRACE("(%p, %s)\n", pStm, fClearDirty ? "TRUE" : "FALSE");
hr = IStream_Write(pStm, &This->clsid, sizeof(This->clsid), NULL);
if (FAILED(hr)) return hr;
hr = IStream_Write(pStm, &zero, sizeof(zero), NULL);
return hr;
}
/******************************************************************************
* ClassMoniker_GetSizeMax
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetSizeMax(IMoniker* iface,
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{
TRACE("(%p)\n", pcbSize);
pcbSize->QuadPart = sizeof(CLSID) + sizeof(DWORD);
return S_OK;
}
/******************************************************************************
* ClassMoniker_BindToObject
******************************************************************************/
static HRESULT WINAPI ClassMoniker_BindToObject(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
{
ClassMoniker *This = (ClassMoniker *)iface;
BIND_OPTS2 bindopts;
IClassActivator *pActivator;
HRESULT hr;
TRACE("(%p,%p,%p,%p)\n", pbc, pmkToLeft, riid, ppvResult);
bindopts.cbStruct = sizeof(bindopts);
IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts);
if (!pmkToLeft)
return CoGetClassObject(&This->clsid, bindopts.dwClassContext, NULL,
riid, ppvResult);
else
{
hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator,
(void **)&pActivator);
if (FAILED(hr)) return hr;
hr = IClassActivator_GetClassObject(pActivator, &This->clsid,
bindopts.dwClassContext,
bindopts.locale, riid, ppvResult);
IClassActivator_Release(pActivator);
return hr;
}
}
/******************************************************************************
* ClassMoniker_BindToStorage
******************************************************************************/
static HRESULT WINAPI ClassMoniker_BindToStorage(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
{
TRACE("(%p,%p,%p,%p)\n",pbc, pmkToLeft, riid, ppvResult);
return ClassMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult);
}
/******************************************************************************
* ClassMoniker_Reduce
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Reduce(IMoniker* iface,
IBindCtx* pbc,
DWORD dwReduceHowFar,
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (!ppmkReduced)
return E_POINTER;
ClassMoniker_AddRef(iface);
*ppmkReduced = iface;
return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
* ClassMoniker_ComposeWith
******************************************************************************/
static HRESULT WINAPI ClassMoniker_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,%d,%p)\n", 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;
}
/******************************************************************************
* ClassMoniker_Enum
******************************************************************************/
static HRESULT WINAPI ClassMoniker_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;
}
/******************************************************************************
* ClassMoniker_IsEqual
******************************************************************************/
static HRESULT WINAPI ClassMoniker_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 ClassMoniker */
if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
if(!IsEqualCLSID(&clsid,&CLSID_ClassMoniker)) 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;
}
/******************************************************************************
* ClassMoniker_Hash
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Hash(IMoniker* iface,DWORD* pdwHash)
{
ClassMoniker *This = (ClassMoniker *)iface;
TRACE("(%p)\n", pdwHash);
*pdwHash = This->clsid.Data1;
return S_OK;
}
/******************************************************************************
* ClassMoniker_IsRunning
******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsRunning(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
{
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pmkNewlyRunning);
/* as in native */
return E_NOTIMPL;
}
/******************************************************************************
* ClassMoniker_GetTimeOfLastChange
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetTimeOfLastChange(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
FILETIME* pItemTime)
{
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pItemTime);
return MK_E_UNAVAILABLE;
}
/******************************************************************************
* ClassMoniker_Inverse
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Inverse(IMoniker* iface,IMoniker** ppmk)
{
TRACE("(%p)\n",ppmk);
if (!ppmk)
return E_POINTER;
return CreateAntiMoniker(ppmk);
}
/******************************************************************************
* ClassMoniker_CommonPrefixWith
******************************************************************************/
static HRESULT WINAPI ClassMoniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
DWORD mkSys;
TRACE("(%p, %p)\n", pmkOther, ppmkPrefix);
*ppmkPrefix = NULL;
IMoniker_IsSystemMoniker(pmkOther, &mkSys);
/* If the other moniker is an class moniker that is equal to this moniker, this method sets *ppmkPrefix */
/* to this moniker and returns MK_S_US */
if (mkSys == MKSYS_CLASSMONIKER)
{
if (IMoniker_IsEqual(iface, pmkOther) == S_OK)
{
*ppmkPrefix = iface;
IMoniker_AddRef(iface);
return MK_S_US;
}
else
return MK_E_NOPREFIX;
}
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);
}
/******************************************************************************
* ClassMoniker_RelativePathTo
******************************************************************************/
static HRESULT WINAPI ClassMoniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
TRACE("(%p, %p)\n",pmOther,ppmkRelPath);
if (!ppmkRelPath)
return E_POINTER;
*ppmkRelPath = NULL;
return MK_E_NOTBINDABLE;
}
/******************************************************************************
* ClassMoniker_GetDisplayName
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
{
ClassMoniker *This = (ClassMoniker *)iface;
static const WCHAR wszClsidPrefix[] = {'c','l','s','i','d',':',0};
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, ppszDisplayName);
if (!ppszDisplayName)
return E_POINTER;
if (pmkToLeft)
return E_INVALIDARG;
*ppszDisplayName = CoTaskMemAlloc(sizeof(wszClsidPrefix) + (CHARS_IN_GUID-2) * sizeof(WCHAR));
StringFromGUID2(&This->clsid, *ppszDisplayName+sizeof(wszClsidPrefix)/sizeof(WCHAR)-2, CHARS_IN_GUID);
/* note: this overwrites the opening curly bracket of the CLSID string generated above */
memcpy(*ppszDisplayName, wszClsidPrefix, sizeof(wszClsidPrefix)-sizeof(WCHAR));
/* note: this overwrites the closing curly bracket of the CLSID string generated above */
(*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-2] = ':';
(*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-1] = '\0';
TRACE("string is %s\n", debugstr_w(*ppszDisplayName));
return S_OK;
}
/******************************************************************************
* ClassMoniker_ParseDisplayName
******************************************************************************/
static HRESULT WINAPI ClassMoniker_ParseDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR pszDisplayName,
ULONG* pchEaten,
IMoniker** ppmkOut)
{
FIXME("(%p, %p, %s, %p, %p)\n", pbc, pmkToLeft, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
return E_NOTIMPL;
}
/******************************************************************************
* ClassMoniker_IsSystemMoniker
******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
TRACE("(%p,%p)\n",iface,pwdMksys);
if (!pwdMksys)
return E_POINTER;
*pwdMksys = MKSYS_CLASSMONIKER;
return S_OK;
}
/*******************************************************************************
* ClassMonikerIROTData_QueryInterface
*******************************************************************************/
static HRESULT WINAPI ClassMonikerROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
{
IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
return ClassMoniker_QueryInterface(This, riid, ppvObject);
}
/***********************************************************************
* ClassMonikerIROTData_AddRef
*/
static ULONG WINAPI ClassMonikerROTData_AddRef(IROTData *iface)
{
IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p)\n",iface);
return ClassMoniker_AddRef(This);
}
/***********************************************************************
* ClassMonikerIROTData_Release
*/
static ULONG WINAPI ClassMonikerROTData_Release(IROTData* iface)
{
IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p)\n",iface);
return ClassMoniker_Release(This);
}
/******************************************************************************
* ClassMonikerIROTData_GetComparaisonData
******************************************************************************/
static HRESULT WINAPI ClassMonikerROTData_GetComparaisonData(IROTData* iface,
BYTE* pbData,
ULONG cbMax,
ULONG* pcbData)
{
ClassMoniker *This = (ClassMoniker *)impl_from_IROTData(iface);
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = 2*sizeof(CLSID);
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
/* write CLSID of the moniker */
memcpy(pbData, &CLSID_ClassMoniker, sizeof(CLSID));
/* write CLSID the moniker represents */
memcpy(pbData+sizeof(CLSID), &This->clsid, sizeof(CLSID));
return S_OK;
}
/********************************************************************************/
/* Virtual function table for the ClassMoniker class which include IPersist,*/
/* IPersistStream and IMoniker functions. */
static const IMonikerVtbl ClassMonikerVtbl =
{
ClassMoniker_QueryInterface,
ClassMoniker_AddRef,
ClassMoniker_Release,
ClassMoniker_GetClassID,
ClassMoniker_IsDirty,
ClassMoniker_Load,
ClassMoniker_Save,
ClassMoniker_GetSizeMax,
ClassMoniker_BindToObject,
ClassMoniker_BindToStorage,
ClassMoniker_Reduce,
ClassMoniker_ComposeWith,
ClassMoniker_Enum,
ClassMoniker_IsEqual,
ClassMoniker_Hash,
ClassMoniker_IsRunning,
ClassMoniker_GetTimeOfLastChange,
ClassMoniker_Inverse,
ClassMoniker_CommonPrefixWith,
ClassMoniker_RelativePathTo,
ClassMoniker_GetDisplayName,
ClassMoniker_ParseDisplayName,
ClassMoniker_IsSystemMoniker
};
/********************************************************************************/
/* Virtual function table for the IROTData class. */
static const IROTDataVtbl ROTDataVtbl =
{
ClassMonikerROTData_QueryInterface,
ClassMonikerROTData_AddRef,
ClassMonikerROTData_Release,
ClassMonikerROTData_GetComparaisonData
};
/******************************************************************************
* ClassMoniker_Construct (local function)
*******************************************************************************/
static HRESULT WINAPI ClassMoniker_Construct(ClassMoniker* This, REFCLSID rclsid)
{
TRACE("(%p,%s)\n",This,debugstr_guid(rclsid));
/* Initialize the virtual function table. */
This->lpVtbl = &ClassMonikerVtbl;
This->lpVtblRotData = &ROTDataVtbl;
This->ref = 0;
This->clsid = *rclsid;
This->pMarshal = NULL;
return S_OK;
}
/******************************************************************************
* CreateClassMoniker [OLE32.@]
******************************************************************************/
HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker **ppmk)
{
ClassMoniker* newClassMoniker;
HRESULT hr;
TRACE("(%s,%p)\n", debugstr_guid(rclsid), ppmk);
newClassMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassMoniker));
if (!newClassMoniker)
return STG_E_INSUFFICIENTMEMORY;
hr = ClassMoniker_Construct(newClassMoniker, rclsid);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, newClassMoniker);
return hr;
}
return ClassMoniker_QueryInterface((IMoniker *)newClassMoniker, &IID_IMoniker, (void**)ppmk);
}
HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
HRESULT hr;
LPCWSTR s = strchrW(szDisplayName, ':');
LPCWSTR end;
CLSID clsid;
BYTE table[256];
int i;
if (!s)
return MK_E_SYNTAX;
s++;
for (end = s; *end && (*end != ':'); end++)
;
TRACE("parsing %s\n", debugstr_wn(s, end - s));
/* validate the CLSID string */
if (s[0] == '{')
{
if ((end - s != 38) || (s[37] != '}'))
return MK_E_SYNTAX;
s++;
}
else
{
if (end - s != 36)
return MK_E_SYNTAX;
}
for (i=0; i<36; i++)
{
if ((i == 8)||(i == 13)||(i == 18)||(i == 23))
{
if (s[i] != '-')
return MK_E_SYNTAX;
continue;
}
if (!(((s[i] >= '0') && (s[i] <= '9')) ||
((s[i] >= 'a') && (s[i] <= 'f')) ||
((s[i] >= 'A') && (s[i] <= 'F'))))
return MK_E_SYNTAX;
}
/* quick lookup table */
memset(table, 0, 256);
for (i = 0; i < 10; i++)
table['0' + i] = i;
for (i = 0; i < 6; i++)
{
table['A' + i] = i+10;
table['a' + i] = i+10;
}
/* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
clsid.Data1 = (table[s[0]] << 28 | table[s[1]] << 24 | table[s[2]] << 20 | table[s[3]] << 16 |
table[s[4]] << 12 | table[s[5]] << 8 | table[s[6]] << 4 | table[s[7]]);
clsid.Data2 = table[s[9]] << 12 | table[s[10]] << 8 | table[s[11]] << 4 | table[s[12]];
clsid.Data3 = table[s[14]] << 12 | table[s[15]] << 8 | table[s[16]] << 4 | table[s[17]];
/* these are just sequential bytes */
clsid.Data4[0] = table[s[19]] << 4 | table[s[20]];
clsid.Data4[1] = table[s[21]] << 4 | table[s[22]];
clsid.Data4[2] = table[s[24]] << 4 | table[s[25]];
clsid.Data4[3] = table[s[26]] << 4 | table[s[27]];
clsid.Data4[4] = table[s[28]] << 4 | table[s[29]];
clsid.Data4[5] = table[s[30]] << 4 | table[s[31]];
clsid.Data4[6] = table[s[32]] << 4 | table[s[33]];
clsid.Data4[7] = table[s[34]] << 4 | table[s[35]];
hr = CreateClassMoniker(&clsid, ppmk);
if (SUCCEEDED(hr))
*pchEaten = (*end == ':' ? end + 1 : end) - szDisplayName;
return hr;
}
static HRESULT WINAPI ClassMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI ClassMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI ClassMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI ClassMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
HRESULT hr;
IMoniker *pmk;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
hr = CreateClassMoniker(&CLSID_NULL, &pmk);
if (FAILED(hr)) return hr;
hr = IMoniker_QueryInterface(pmk, riid, ppv);
IMoniker_Release(pmk);
return hr;
}
static HRESULT WINAPI ClassMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl ClassMonikerCFVtbl =
{
ClassMonikerCF_QueryInterface,
ClassMonikerCF_AddRef,
ClassMonikerCF_Release,
ClassMonikerCF_CreateInstance,
ClassMonikerCF_LockServer
};
static const IClassFactoryVtbl *ClassMonikerCF = &ClassMonikerCFVtbl;
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&ClassMonikerCF, riid, ppv);
}
+20 -24
View File
@@ -16,7 +16,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
* This file contains the implementation for the OLE Clipboard and its
@@ -78,12 +78,7 @@
#include "storage32.h"
#define HANDLE_ERROR(err) { hr = err; TRACE("(HRESULT=%lx)\n", (HRESULT)err); goto CLEANUP; }
/* For CoGetMalloc (MEMCTX_TASK is currently ignored) */
#ifndef MEMCTX_TASK
# define MEMCTX_TASK -1
#endif
#define HANDLE_ERROR(err) { hr = err; TRACE("(HRESULT=%x)\n", (HRESULT)err); goto CLEANUP; }
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -178,7 +173,7 @@ static OLEClipbrd* OLEClipbrd_Construct(void);
static void OLEClipbrd_Destroy(OLEClipbrd* ptrToDestroy);
static HWND OLEClipbrd_CreateWindow(void);
static void OLEClipbrd_DestroyWindow(HWND hwnd);
LRESULT CALLBACK OLEClipbrd_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK OLEClipbrd_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static HRESULT OLEClipbrd_RenderFormat( IDataObject *pIDataObject, LPFORMATETC pFormatetc );
static HGLOBAL OLEClipbrd_GlobalDupMem( HGLOBAL hGlobalSrc );
@@ -283,7 +278,7 @@ static const IEnumFORMATETCVtbl efvt =
/*
* Name of our registered OLE clipboard window class
*/
CHAR OLEClipbrd_WNDCLASS[] = "CLIPBRDWNDCLASS";
static const CHAR OLEClipbrd_WNDCLASS[] = "CLIPBRDWNDCLASS";
/*
* If we need to store state info we can store it here.
@@ -487,7 +482,7 @@ HRESULT WINAPI OleGetClipboard(IDataObject** ppDataObj)
* data object exposed through OleGetClipboard must convert this TYMED_HGLOBAL
* back to TYMED_IStorage.
*/
HRESULT WINAPI OleFlushClipboard()
HRESULT WINAPI OleFlushClipboard(void)
{
IEnumFORMATETC* penumFormatetc = NULL;
FORMATETC rgelt;
@@ -577,7 +572,7 @@ CLEANUP:
/***********************************************************************
* OleIsCurrentClipboard [OLE32.@]
*/
HRESULT WINAPI OleIsCurrentClipboard ( IDataObject *pDataObject)
HRESULT WINAPI OleIsCurrentClipboard(IDataObject *pDataObject)
{
TRACE("()\n");
/*
@@ -638,7 +633,7 @@ void OLEClipbrd_UnInitialize(void)
/*********************************************************
* Construct the OLEClipbrd class.
*/
static OLEClipbrd* OLEClipbrd_Construct()
static OLEClipbrd* OLEClipbrd_Construct(void)
{
OLEClipbrd* newObject = NULL;
HGLOBAL hNewObject = 0;
@@ -711,7 +706,7 @@ static void OLEClipbrd_Destroy(OLEClipbrd* ptrToDestroy)
* OLEClipbrd_CreateWindow()
* Create the clipboard window
*/
static HWND OLEClipbrd_CreateWindow()
static HWND OLEClipbrd_CreateWindow(void)
{
HWND hwnd = 0;
WNDCLASSEXA wcex;
@@ -776,7 +771,7 @@ static void OLEClipbrd_DestroyWindow(HWND hwnd)
* has been placed in the clipboard via OleSetClipboard().
* i.e. Only when OLE owns the windows clipboard.
*/
LRESULT CALLBACK OLEClipbrd_WndProc
static LRESULT CALLBACK OLEClipbrd_WndProc
(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
@@ -919,7 +914,8 @@ static HRESULT OLEClipbrd_RenderFormat(IDataObject *pIDataObject, LPFORMATETC pF
ILockBytes *ptrILockBytes = 0;
HGLOBAL hStorage = 0;
GetClipboardFormatNameA(pFormatetc->cfFormat, szFmtName, MAX_CLIPFORMAT_NAME);
if (!GetClipboardFormatNameA(pFormatetc->cfFormat, szFmtName, MAX_CLIPFORMAT_NAME))
szFmtName[0] = '\0';
/* If embed source */
if (!strcmp(szFmtName, CF_EMBEDSOURCE))
@@ -935,7 +931,7 @@ static HRESULT OLEClipbrd_RenderFormat(IDataObject *pIDataObject, LPFORMATETC pF
if (FAILED(hr = IDataObject_GetDataHere(theOleClipboard->pIDataObjectSrc, pFormatetc, &std)))
{
WARN("() : IDataObject_GetDataHere failed to render clipboard data! (%lx)\n", hr);
WARN("() : IDataObject_GetDataHere failed to render clipboard data! (%x)\n", hr);
GlobalFree(hStorage);
return hr;
}
@@ -1017,7 +1013,7 @@ static HRESULT OLEClipbrd_RenderFormat(IDataObject *pIDataObject, LPFORMATETC pF
{
if (FAILED(hr = IDataObject_GetData(pIDataObject, pFormatetc, &std)))
{
WARN("() : IDataObject_GetData failed to render clipboard data! (%lx)\n", hr);
WARN("() : IDataObject_GetData failed to render clipboard data! (%x)\n", hr);
GlobalFree(hStorage);
return hr;
}
@@ -1159,7 +1155,7 @@ static ULONG WINAPI OLEClipbrd_IDataObject_AddRef(
*/
OLEClipbrd *This = (OLEClipbrd *)iface;
TRACE("(%p)->(count=%lu)\n",This, This->ref);
TRACE("(%p)->(count=%u)\n",This, This->ref);
return InterlockedIncrement(&This->ref);
@@ -1179,7 +1175,7 @@ static ULONG WINAPI OLEClipbrd_IDataObject_Release(
OLEClipbrd *This = (OLEClipbrd *)iface;
ULONG ref;
TRACE("(%p)->(count=%lu)\n",This, This->ref);
TRACE("(%p)->(count=%u)\n",This, This->ref);
/*
* Decrease the reference count on this object.
@@ -1411,7 +1407,7 @@ static HRESULT WINAPI OLEClipbrd_IDataObject_EnumFormatEtc(
*/
OLEClipbrd *This = (OLEClipbrd *)iface;
TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
/*
* If we have a data source placed on the clipboard (via OleSetClipboard)
@@ -1559,7 +1555,7 @@ static HRESULT WINAPI OLEClipbrd_IDataObject_EnumDAdvise(
* NOTE: this does not AddRef the interface.
*/
LPENUMFORMATETC OLEClipbrd_IEnumFORMATETC_Construct(UINT cfmt, const FORMATETC afmt[],
static LPENUMFORMATETC OLEClipbrd_IEnumFORMATETC_Construct(UINT cfmt, const FORMATETC afmt[],
LPUNKNOWN pUnkDataObj)
{
IEnumFORMATETCImpl* ef;
@@ -1642,7 +1638,7 @@ static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_QueryInterface
static ULONG WINAPI OLEClipbrd_IEnumFORMATETC_AddRef(LPENUMFORMATETC iface)
{
IEnumFORMATETCImpl *This = (IEnumFORMATETCImpl *)iface;
TRACE("(%p)->(count=%lu)\n",This, This->ref);
TRACE("(%p)->(count=%u)\n",This, This->ref);
if (This->pUnkDataObj)
IUnknown_AddRef(This->pUnkDataObj);
@@ -1661,7 +1657,7 @@ static ULONG WINAPI OLEClipbrd_IEnumFORMATETC_Release(LPENUMFORMATETC iface)
LPMALLOC pIMalloc;
ULONG ref;
TRACE("(%p)->(count=%lu)\n",This, This->ref);
TRACE("(%p)->(count=%u)\n",This, This->ref);
if (This->pUnkDataObj)
IUnknown_Release(This->pUnkDataObj); /* Release parent data object */
@@ -1728,7 +1724,7 @@ static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Next
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Skip(LPENUMFORMATETC iface, ULONG celt)
{
IEnumFORMATETCImpl *This = (IEnumFORMATETCImpl *)iface;
TRACE("(%p)->(num=%lu)\n", This, celt);
TRACE("(%p)->(num=%u)\n", This, celt);
This->posFmt += celt;
if (This->posFmt > This->countFmt)
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -12,7 +12,7 @@
12 stub COFREEALLLIBRARIES
13 pascal CoCreateInstance(ptr ptr long ptr ptr) CoCreateInstance16
14 stub STRINGFROMIID
15 pascal CoDisconnectObject(ptr long) CoDisconnectObject
15 pascal CoDisconnectObject(ptr long) CoDisconnectObject16
16 stub CORELEASEMARSHALDATA
17 pascal -ret16 CoFreeUnusedLibraries() CoFreeUnusedLibraries
18 pascal -ret16 IsEqualGUID(ptr ptr) IsEqualGUID16
+58 -15
View File
@@ -19,7 +19,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_OLE_COMPOBJ_H
@@ -41,6 +41,13 @@
struct apartment;
typedef struct apartment APARTMENT;
DEFINE_OLEGUID( CLSID_DfMarshal, 0x0000030b, 0, 0 );
DEFINE_OLEGUID( CLSID_PSFactoryBuffer, 0x00000320, 0, 0 );
DEFINE_OLEGUID( CLSID_InProcFreeMarshaler, 0x0000033a, 0, 0 );
/* signal to stub manager that this is a rem unknown object */
#define MSHLFLAGSP_REMUNKNOWN 0x80000000
/* Thread-safety Annotation Legend:
*
* RO - The value is read only. It never changes after creation, so no
@@ -72,6 +79,7 @@ struct ifstub
IPID ipid; /* RO */
IUnknown *iface; /* RO */
MSHLFLAGS flags; /* so we can enforce process-local marshalling rules (RO) */
IRpcChannelBuffer*chan; /* channel passed to IRpcStubBuffer::Invoke (RO) */
};
@@ -88,6 +96,7 @@ struct stub_manager
OID oid; /* apartment-scoped unique identifier (RO) */
IUnknown *object; /* the object we are managing the stub for (RO) */
ULONG next_ipid; /* currently unused (LOCK) */
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
/* We need to keep a count of the outstanding marshals, so we can enforce the
* marshalling rules (ie, you can only unmarshal normal marshals once). Note
@@ -107,7 +116,7 @@ struct ifproxy
STDOBJREF stdobjref; /* marshal data that represents this object (RO) */
IID iid; /* interface ID (RO) */
LPRPCPROXYBUFFER proxy; /* interface proxy (RO) */
DWORD refs; /* imported (public) references (MUTEX parent->remoting_mutex) */
ULONG refs; /* imported (public) references (LOCK) */
IRpcChannelBuffer *chan; /* channel to object (CS parent->cs) */
};
@@ -116,9 +125,11 @@ struct proxy_manager
{
const IMultiQIVtbl *lpVtbl;
const IMarshalVtbl *lpVtblMarshal;
const IClientSecurityVtbl *lpVtblCliSec;
struct apartment *parent; /* owning apartment (RO) */
struct list entry; /* entry in apartment (CS parent->cs) */
OXID oxid; /* object exported ID (RO) */
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
OID oid; /* object ID (RO) */
struct list interfaces; /* imported interfaces (CS cs) */
LONG refs; /* proxy reference count (LOCK) */
@@ -126,28 +137,35 @@ struct proxy_manager
ULONG sorflags; /* STDOBJREF flags (RO) */
IRemUnknown *remunk; /* proxy to IRemUnknown used for lifecycle management (CS cs) */
HANDLE remoting_mutex; /* mutex used for synchronizing access to IRemUnknown */
MSHCTX dest_context; /* context used for activating optimisations (LOCK) */
void *dest_context_data; /* reserved context value (LOCK) */
};
/* this needs to become a COM object that implements IRemUnknown */
struct apartment
{
struct list entry;
struct list entry;
LONG refs; /* refcount of the apartment (LOCK) */
DWORD model; /* threading model (RO) */
BOOL multi_threaded; /* multi-threaded or single-threaded apartment? (RO) */
DWORD tid; /* thread id (RO) */
OXID oxid; /* object exporter ID (RO) */
LONG ipidc; /* interface pointer ID counter, starts at 1 (LOCK) */
HWND win; /* message window (RO) */
CRITICAL_SECTION cs; /* thread safety */
LPMESSAGEFILTER filter; /* message filter (CS cs) */
struct list proxies; /* imported objects (CS cs) */
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
struct list psclsids; /* list of registered PS CLSIDs (CS cs) */
struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
/* FIXME: OID's should be given out by RPCSS */
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
/* STA-only fields */
HWND win; /* message window (LOCK) */
LPMESSAGEFILTER filter; /* message filter (CS cs) */
BOOL main; /* is this a main-threaded-apartment? (RO) */
};
/* this is what is stored in TEB->ReservedForOle */
@@ -157,22 +175,26 @@ struct oletls
IErrorInfo *errorinfo; /* see errorinfo.c */
IUnknown *state; /* see CoSetState */
DWORD inits; /* number of times CoInitializeEx called */
DWORD ole_inits; /* number of times OleInitialize called */
GUID causality_id; /* unique identifier for each COM call */
LONG pending_call_count_client; /* number of client calls pending */
LONG pending_call_count_server; /* number of server calls pending */
};
/* Global Interface Table Functions */
extern void* StdGlobalInterfaceTable_Construct(void);
extern void StdGlobalInterfaceTable_Destroy(void* self);
extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);
extern void* StdGlobalInterfaceTableInstance;
/* FIXME: these shouldn't be needed, except for 16-bit functions */
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key);
HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey);
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv);
/* Stub Manager */
@@ -180,7 +202,7 @@ ULONG stub_manager_int_addref(struct stub_manager *This);
ULONG stub_manager_int_release(struct stub_manager *This);
struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object);
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs);
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs);
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL last_unlock_releases);
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags);
struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags);
struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid);
@@ -189,7 +211,7 @@ BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid);
BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid);
void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid);
HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret);
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface);
HRESULT start_apartment_remote_unknown(void);
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags);
@@ -199,12 +221,20 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
struct dispatch_params;
void RPC_StartRemoting(struct apartment *apt);
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
const OXID_INFO *oxid_info,
DWORD dest_context, void *dest_context_data,
IRpcChannelBuffer **chan);
HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan);
void RPC_ExecuteCall(struct dispatch_params *params);
HRESULT RPC_RegisterInterface(REFIID riid);
void RPC_UnregisterInterface(REFIID riid);
void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration);
void RPC_StopLocalServer(void *registration);
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook);
void RPC_UnregisterAllChannelHooks(void);
HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info);
/* This function initialize the Running Object Table */
HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
@@ -212,9 +242,8 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
/* This function uninitialize the Running Object Table */
HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void);
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
/* Drag and drop */
void OLEDD_UnInitialize(void);
/* Apartment Functions */
@@ -229,10 +258,14 @@ static inline HRESULT apartment_getoxid(struct apartment *apt, OXID *oxid)
*oxid = apt->oxid;
return S_OK;
}
HRESULT apartment_createwindowifneeded(struct apartment *apt);
HWND apartment_getwindow(struct apartment *apt);
void apartment_joinmta(void);
/* DCOM messages used by the apartment window (not compatible with native) */
#define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */
#define DM_HOSTOBJECT (WM_USER + 1) /* WPARAM = 0, LPARAM = (struct host_object_params *) */
/*
* Per-thread values are stored in the TEB on offset 0xF80,
@@ -253,6 +286,16 @@ static inline APARTMENT* COM_CurrentApt(void)
return COM_CurrentInfo()->apt;
}
static inline GUID COM_CurrentCausalityId(void)
{
struct oletls *info = COM_CurrentInfo();
if (!info)
return GUID_NULL;
if (IsEqualGUID(&info->causality_id, &GUID_NULL))
CoCreateGuid(&info->causality_id);
return info->causality_id;
}
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
/* helpers for debugging */
+483 -141
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@@ -37,10 +37,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
static const CLSID CLSID_CompositeMoniker = {
0x309, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
};
#define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */
/* CompositeMoniker data structure */
@@ -54,6 +50,8 @@ typedef struct CompositeMonikerImpl{
*/
const IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/
const IMarshalVtbl* lpvtblMarshal; /* VTable relative to the IMarshal interface.*/
LONG ref; /* reference counter for this object */
IMoniker** tabMoniker; /* dynamaic table containing all components (monikers) of this composite moniker */
@@ -85,6 +83,11 @@ static inline IMoniker *impl_from_IROTData( IROTData *iface )
return (IMoniker *)((char*)iface - FIELD_OFFSET(CompositeMonikerImpl, lpvtbl2));
}
static inline IMoniker *impl_from_IMarshal( IMarshal *iface )
{
return (IMoniker *)((char*)iface - FIELD_OFFSET(CompositeMonikerImpl, lpvtblMarshal));
}
static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRigth,IEnumMoniker ** ppmk);
/*******************************************************************************
@@ -113,6 +116,8 @@ CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject
*ppvObject = iface;
else if (IsEqualIID(&IID_IROTData, riid))
*ppvObject = (IROTData*)&(This->lpvtbl2);
else if (IsEqualIID(&IID_IMarshal, riid))
*ppvObject = (IROTData*)&(This->lpvtblMarshal);
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
@@ -137,6 +142,16 @@ CompositeMonikerImpl_AddRef(IMoniker* iface)
return InterlockedIncrement(&This->ref);
}
static void CompositeMonikerImpl_ReleaseMonikersInTable(CompositeMonikerImpl *This)
{
ULONG i;
for (i = 0; i < This->tabLastIndex; i++)
IMoniker_Release(This->tabMoniker[i]);
This->tabLastIndex = 0;
}
/******************************************************************************
* CompositeMoniker_Release
******************************************************************************/
@@ -144,7 +159,6 @@ static ULONG WINAPI
CompositeMonikerImpl_Release(IMoniker* iface)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
ULONG i;
ULONG ref;
TRACE("(%p)\n",This);
@@ -155,8 +169,7 @@ CompositeMonikerImpl_Release(IMoniker* iface)
if (ref == 0){
/* release all the components before destroying this object */
for (i=0;i<This->tabLastIndex;i++)
IMoniker_Release(This->tabMoniker[i]);
CompositeMonikerImpl_ReleaseMonikersInTable(This);
HeapFree(GetProcessHeap(),0,This->tabMoniker);
HeapFree(GetProcessHeap(),0,This);
@@ -170,7 +183,7 @@ CompositeMonikerImpl_Release(IMoniker* iface)
static HRESULT WINAPI
CompositeMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
TRACE("(%p,%p),stub!\n",iface,pClassID);
TRACE("(%p,%p)\n",iface,pClassID);
if (pClassID==NULL)
return E_POINTER;
@@ -202,9 +215,8 @@ static HRESULT WINAPI
CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
HRESULT res;
DWORD constant;
CLSID clsid;
WCHAR string[1]={0};
DWORD moniker_count;
DWORD i;
CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
@@ -212,54 +224,22 @@ CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
/* this function call OleLoadFromStream function for each moniker within this object */
/* read the a constant written by CompositeMonikerImpl_Save (see CompositeMonikerImpl_Save for more details)*/
res=IStream_Read(pStm,&constant,sizeof(DWORD),NULL);
if (SUCCEEDED(res)&& constant!=3)
res=IStream_Read(pStm,&moniker_count,sizeof(DWORD),NULL);
if (res != S_OK)
{
ERR("couldn't reading moniker count from stream\n");
return E_FAIL;
}
while(1){
#if 0
CompositeMonikerImpl_ReleaseMonikersInTable(This);
for (i = 0; i < moniker_count; i++)
{
res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]);
#endif
res=ReadClassStm(pStm,&clsid);
DPRINTF("res=%ld",res);
if (FAILED(res))
break;
if (IsEqualIID(&clsid,&CLSID_FileMoniker)){
res=CreateFileMoniker(string,&This->tabMoniker[This->tabLastIndex]);
if (FAILED(res))
break;
res=IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
if (FAILED(res))
break;
}
else if (IsEqualIID(&clsid,&CLSID_ItemMoniker)){
CreateItemMoniker(string,string,&This->tabMoniker[This->tabLastIndex]);
if (res!=S_OK)
break;
IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
if (FAILED(res))
break;
}
else if (IsEqualIID(&clsid,&CLSID_AntiMoniker)){
CreateAntiMoniker(&This->tabMoniker[This->tabLastIndex]);
if (FAILED(res))
break;
IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
if (FAILED(res))
break;
}
else if (IsEqualIID(&clsid,&CLSID_CompositeMoniker))
return E_FAIL;
else
{
FIXME("()\n");
/* FIXME: To whoever wrote this code: It's either return or break. it cannot be both! */
ERR("couldn't load moniker from stream, res = 0x%08x\n", res);
break;
return E_NOTIMPL;
}
/* resize the table if needed */
@@ -282,10 +262,11 @@ CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
static HRESULT WINAPI
CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
HRESULT res;
IEnumMoniker *enumMk;
IMoniker *pmk;
DWORD constant=3;
DWORD moniker_count = This->tabLastIndex;
TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);
@@ -295,7 +276,8 @@ CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
* at the beginning of the stream. I don't known why (there's no
* indication in the specification) !
*/
res=IStream_Write(pStm,&constant,sizeof(constant),NULL);
res=IStream_Write(pStm,&moniker_count,sizeof(moniker_count),NULL);
if (FAILED(res)) return res;
IMoniker_Enum(iface,TRUE,&enumMk);
@@ -307,7 +289,7 @@ CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
if (FAILED(res)){
IEnumMoniker_Release(pmk);
IEnumMoniker_Release(enumMk);
return res;
}
}
@@ -333,22 +315,20 @@ CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize)
TRACE("(%p,%p)\n",iface,pcbSize);
if (pcbSize!=NULL)
if (!pcbSize)
return E_POINTER;
pcbSize->u.LowPart =0;
pcbSize->u.HighPart=0;
pcbSize->QuadPart = sizeof(DWORD);
IMoniker_Enum(iface,TRUE,&enumMk);
while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)){
while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
IMoniker_GetSizeMax(pmk,&ptmpSize);
IMoniker_Release(pmk);
pcbSize->u.LowPart +=ptmpSize.u.LowPart;
pcbSize->u.HighPart+=ptmpSize.u.HighPart;
pcbSize->QuadPart = ptmpSize.QuadPart + sizeof(CLSID);
}
IEnumMoniker_Release(enumMk);
@@ -401,7 +381,7 @@ CompositeMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc,
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
res=CompositeMonikerImpl_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult);
res=IMoniker_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
@@ -418,7 +398,7 @@ CompositeMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
{
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk;
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
@@ -428,26 +408,34 @@ CompositeMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc,
/* This method recursively calls BindToStorage on the rightmost component of the composite, */
/* passing the rest of the composite as the pmkToLeft parameter for that call. */
if (pmkToLeft!=NULL){
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
res=CompositeMonikerImpl_BindToStorage(mostRigthMk,pbc,tempMk,riid,ppvResult);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
return res;
if (pmkToLeft)
{
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
if (FAILED(res)) return res;
}
else
return IMoniker_BindToStorage(iface,pbc,NULL,riid,ppvResult);
leftMk = iface;
IMoniker_Enum(iface, FALSE, &enumMoniker);
IEnumMoniker_Next(enumMoniker, 1, &mostRigthMk, NULL);
IEnumMoniker_Release(enumMoniker);
res = CreateAntiMoniker(&antiMk);
if (FAILED(res)) return res;
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
if (FAILED(res)) return res;
IMoniker_Release(antiMk);
res = IMoniker_BindToStorage(mostRigthMk, pbc, tempMk, riid, ppvResult);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (pmkToLeft)
IMoniker_Release(leftMk);
return res;
}
/******************************************************************************
@@ -461,7 +449,7 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@@ -478,7 +466,7 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
return CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
return IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
}
else if (*ppmkToLeft==NULL)
@@ -498,7 +486,7 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar
/* If any of the components reduces itself, the method returns S_OK and passes back a composite */
/* of the reduced components */
if (IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,NULL,&mostRigthReducedMk) &&
CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
)
return CreateGenericComposite(leftReducedComposedMk,mostRigthReducedMk,ppmkReduced);
@@ -634,15 +622,13 @@ CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
if(FAILED(res))
return res;
while(1){
res=IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL);
if(FAILED(res))
break;
*pdwHash = 0;
while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
res = IMoniker_Hash(tempMk, &tempHash);
if(FAILED(res))
break;
*pdwHash = (*pdwHash * 37) + tempHash;
*pdwHash = *pdwHash ^ tempHash;
IMoniker_Release(tempMk);
}
@@ -737,9 +723,8 @@ static HRESULT WINAPI
CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, FILETIME* pCompositeTime)
{
IRunningObjectTable* rot;
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk;
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);
@@ -751,36 +736,45 @@ CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
/* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
/* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
/* of the composite as the pmkToLeft parameter for that call. */
if (pmkToLeft!=NULL){
if (pmkToLeft)
{
IRunningObjectTable* rot;
res=CreateGenericComposite(pmkToLeft,iface,&tempMk);
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
res = IBindCtx_GetRunningObjectTable(pbc,&rot);
if (FAILED(res))
{
IMoniker_Release(leftMk);
return res;
}
if (IRunningObjectTable_GetTimeOfLastChange(rot,tempMk,pCompositeTime)==S_OK)
return res;
else
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
res=CompositeMonikerImpl_GetTimeOfLastChange(mostRigthMk,pbc,tempMk,pCompositeTime);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (IRunningObjectTable_GetTimeOfLastChange(rot,leftMk,pCompositeTime)==S_OK)
{
IMoniker_Release(leftMk);
return res;
}
}
else
return IMoniker_GetTimeOfLastChange(iface,pbc,NULL,pCompositeTime);
leftMk = iface;
IMoniker_Enum(iface, FALSE, &enumMoniker);
IEnumMoniker_Next(enumMoniker, 1, &mostRigthMk, NULL);
IEnumMoniker_Release(enumMoniker);
res = CreateAntiMoniker(&antiMk);
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
IMoniker_Release(antiMk);
res = IMoniker_GetTimeOfLastChange(mostRigthMk, pbc, tempMk, pCompositeTime);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (pmkToLeft)
IMoniker_Release(leftMk);
return res;
}
/******************************************************************************
@@ -1245,14 +1239,267 @@ static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface)
}
/******************************************************************************
* CompositeMonikerIROTData_GetComparaisonData
* CompositeMonikerIROTData_GetComparisonData
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
CompositeMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData, ULONG cbMax, ULONG* pcbData)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
IMoniker *This = impl_from_IROTData(iface);
IEnumMoniker *pEnumMk;
IMoniker *pmk;
HRESULT hr;
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID);
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
if (FAILED(hr)) return hr;
while(IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
IROTData *pROTData;
hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
if (FAILED(hr))
ERR("moniker doesn't support IROTData interface\n");
if (SUCCEEDED(hr))
{
ULONG cbData;
hr = IROTData_GetComparisonData(pROTData, NULL, 0, &cbData);
IROTData_Release(pROTData);
if (SUCCEEDED(hr) || (hr == E_OUTOFMEMORY))
{
*pcbData += cbData;
hr = S_OK;
}
else
ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
}
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
}
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
IEnumMoniker_Reset(pEnumMk);
memcpy(pbData, &CLSID_CompositeMoniker, sizeof(CLSID));
pbData += sizeof(CLSID);
cbMax -= sizeof(CLSID);
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
IROTData *pROTData;
hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
if (FAILED(hr))
ERR("moniker doesn't support IROTData interface\n");
if (SUCCEEDED(hr))
{
ULONG cbData;
hr = IROTData_GetComparisonData(pROTData, pbData, cbMax, &cbData);
IROTData_Release(pROTData);
if (SUCCEEDED(hr))
{
pbData += cbData;
cbMax -= cbData;
}
else
ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
}
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
}
IEnumMoniker_Release(pEnumMk);
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppv);
return CompositeMonikerImpl_QueryInterface(This, riid, ppv);
}
static ULONG WINAPI CompositeMonikerMarshalImpl_AddRef(IMarshal *iface)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p)\n",iface);
return CompositeMonikerImpl_AddRef(This);
}
static ULONG WINAPI CompositeMonikerMarshalImpl_Release(IMarshal *iface)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p)\n",iface);
return CompositeMonikerImpl_Release(This);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetUnmarshalClass(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
return IMoniker_GetClassID(This, pCid);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetMarshalSizeMax(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{
IMoniker *This = impl_from_IMarshal(iface);
IEnumMoniker *pEnumMk;
IMoniker *pmk;
HRESULT hr;
ULARGE_INTEGER size;
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pSize);
*pSize = 0x10; /* to match native */
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
if (FAILED(hr)) return hr;
hr = IMoniker_GetSizeMax(This, &size);
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
ULONG size;
hr = CoGetMarshalSizeMax(&size, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
if (SUCCEEDED(hr))
*pSize += size;
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
}
IEnumMoniker_Release(pEnumMk);
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_MarshalInterface(LPMARSHAL iface, IStream *pStm,
REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags)
{
IMoniker *This = impl_from_IMarshal(iface);
IEnumMoniker *pEnumMk;
IMoniker *pmk;
HRESULT hr;
ULONG i = 0;
TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags);
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
if (FAILED(hr)) return hr;
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
hr = CoMarshalInterface(pStm, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
i++;
}
if (i != 2)
FIXME("moniker count of %d not supported\n", i);
IEnumMoniker_Release(pEnumMk);
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)impl_from_IMarshal(iface);
HRESULT hr;
TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
CompositeMonikerImpl_ReleaseMonikersInTable(This);
/* resize the table if needed */
if (This->tabLastIndex + 2 > This->tabSize)
{
This->tabSize += max(BLOCK_TAB_SIZE, 2);
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
}
hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
if (FAILED(hr))
{
ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
return hr;
}
This->tabLastIndex++;
hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
if (FAILED(hr))
{
ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
return hr;
}
This->tabLastIndex++;
return IMoniker_QueryInterface((IMoniker *)&This->lpvtbl1, riid, ppv);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
{
TRACE("(%p)\n", pStm);
/* can't release a state-based marshal as nothing on server side to
* release */
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
{
TRACE("(0x%x)\n", dwReserved);
/* can't disconnect a state-based marshal as nothing on server side to
* disconnect from */
return S_OK;
}
/******************************************************************************
@@ -1337,8 +1584,10 @@ EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt,
/* retrieve the requested number of moniker from the current position */
for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
{
rgelt[i]=This->tabMoniker[This->currentPos++];
IMoniker_AddRef(rgelt[i]);
}
if (pceltFethed!=NULL)
*pceltFethed= i;
@@ -1423,7 +1672,7 @@ EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, ULONG tabSize,
/* Initialize the virtual function table. */
newEnumMoniker->lpVtbl = &VT_EnumMonikerImpl;
newEnumMoniker->ref = 0;
newEnumMoniker->ref = 1;
newEnumMoniker->tabSize=tabSize;
newEnumMoniker->currentPos=currentPos;
@@ -1491,27 +1740,47 @@ static const IROTDataVtbl VT_ROTDataImpl =
CompositeMonikerROTDataImpl_QueryInterface,
CompositeMonikerROTDataImpl_AddRef,
CompositeMonikerROTDataImpl_Release,
CompositeMonikerROTDataImpl_GetComparaisonData
CompositeMonikerROTDataImpl_GetComparisonData
};
static const IMarshalVtbl VT_MarshalImpl =
{
CompositeMonikerMarshalImpl_QueryInterface,
CompositeMonikerMarshalImpl_AddRef,
CompositeMonikerMarshalImpl_Release,
CompositeMonikerMarshalImpl_GetUnmarshalClass,
CompositeMonikerMarshalImpl_GetMarshalSizeMax,
CompositeMonikerMarshalImpl_MarshalInterface,
CompositeMonikerMarshalImpl_UnmarshalInterface,
CompositeMonikerMarshalImpl_ReleaseMarshalData,
CompositeMonikerMarshalImpl_DisconnectObject
};
/******************************************************************************
* Composite-Moniker_Construct (local function)
*******************************************************************************/
static HRESULT
CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
CompositeMonikerImpl_Construct(IMoniker** ppMoniker,
LPMONIKER pmkFirst, LPMONIKER pmkRest)
{
DWORD mkSys;
IEnumMoniker *enumMoniker;
IMoniker *tempMk;
HRESULT res;
CompositeMonikerImpl *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This)
return E_OUTOFMEMORY;
TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);
/* Initialize the virtual function table. */
This->lpvtbl1 = &VT_CompositeMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->lpvtblMarshal= &VT_MarshalImpl;
This->ref = 1;
This->tabSize=BLOCK_TAB_SIZE;
This->tabLastIndex=0;
@@ -1520,6 +1789,12 @@ CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
if (!pmkFirst && !pmkRest)
{
*ppMoniker = (IMoniker *)This;
return S_OK;
}
IMoniker_IsSystemMoniker(pmkFirst,&mkSys);
/* put the first moniker contents in the beginning of the table */
@@ -1637,6 +1912,16 @@ CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
IEnumMoniker_Release(enumMoniker);
}
/* only one moniker, then just return it */
if (This->tabLastIndex == 1)
{
*ppMoniker = This->tabMoniker[0];
IMoniker_AddRef(*ppMoniker);
IMoniker_Release((IMoniker *)This);
}
else
*ppMoniker = (IMoniker *)This;
return S_OK;
}
@@ -1647,7 +1932,7 @@ HRESULT WINAPI
CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest,
LPMONIKER* ppmkComposite)
{
CompositeMonikerImpl* newCompositeMoniker = 0;
IMoniker* moniker = 0;
HRESULT hr = S_OK;
TRACE("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);
@@ -1669,24 +1954,13 @@ CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest,
else if (pmkFirst==NULL && pmkRest==NULL)
return S_OK;
newCompositeMoniker = HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl));
hr = CompositeMonikerImpl_Construct(&moniker,pmkFirst,pmkRest);
if (newCompositeMoniker == 0)
return STG_E_INSUFFICIENTMEMORY;
hr = CompositeMonikerImpl_Construct(newCompositeMoniker,pmkFirst,pmkRest);
if (FAILED(hr)){
HeapFree(GetProcessHeap(),0,newCompositeMoniker);
if (FAILED(hr))
return hr;
}
if (newCompositeMoniker->tabLastIndex==1)
hr = IMoniker_QueryInterface(newCompositeMoniker->tabMoniker[0],&IID_IMoniker,(void**)ppmkComposite);
else
hr = IMoniker_QueryInterface((IMoniker*)newCompositeMoniker,&IID_IMoniker,(void**)ppmkComposite);
hr = IMoniker_QueryInterface(moniker,&IID_IMoniker,(void**)ppmkComposite);
IMoniker_Release(moniker);
return hr;
}
@@ -1700,3 +1974,71 @@ MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkComm
FIXME("(),stub!\n");
return E_NOTIMPL;
}
static HRESULT WINAPI CompositeMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI CompositeMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI CompositeMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI CompositeMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
IMoniker* pMoniker;
HRESULT hr;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
hr = CompositeMonikerImpl_Construct(&pMoniker, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
IMoniker_Release(pMoniker);
}
return hr;
}
static HRESULT WINAPI CompositeMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl CompositeMonikerCFVtbl =
{
CompositeMonikerCF_QueryInterface,
CompositeMonikerCF_AddRef,
CompositeMonikerCF_Release,
CompositeMonikerCF_CreateInstance,
CompositeMonikerCF_LockServer
};
static const IClassFactoryVtbl *CompositeMonikerCF = &CompositeMonikerCFVtbl;
HRESULT CompositeMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&CompositeMonikerCF, riid, ppv);
}
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 */
+11 -5
View File
@@ -13,7 +13,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* see http://www.microsoft.com/msj/0398/dcom.htm */
@@ -108,6 +108,14 @@ interface ObjectRpcBaseTypes
[size_is(wNumEntries)] unsigned short aStringArray[];
} DUALSTRINGARRAY;
typedef struct tagOXID_INFO {
DWORD dwTid;
DWORD dwPid;
IPID ipidRemUnknown;
DWORD dwAuthnHint;
DUALSTRINGARRAY *psa;
} OXID_INFO;
const unsigned long OBJREF_SIGNATURE = 0x574f454d; /* "MEOW" */
const unsigned long OBJREF_STANDARD = 0x1;
const unsigned long OBJREF_HANDLER = 0x2;
@@ -148,7 +156,7 @@ interface ObjectRpcBaseTypes
[case(OBJREF_CUSTOM)] struct OR_CUSTOM {
CLSID clsid;
unsigned long cbExtension;
unsigned long size;
ULONG size;
[size_is(size), ref] byte *pData;
} u_custom;
} u_objref;
@@ -184,7 +192,7 @@ interface IRemUnknown : IUnknown
HRESULT RemQueryInterface(
[in] REFIPID ripid,
[in] unsigned long cRefs,
[in] ULONG cRefs,
[in] unsigned short cIids,
[in, size_is(cIids)] IID *iids,
[out, size_is(,cIids)] REMQIRESULT **ppQIResults);
@@ -215,7 +223,6 @@ interface IRemUnknown2 : IRemUnknown
[out, size_is(cIids)] MInterfacePointer **ppMIF);
}
cpp_quote("#if 0")
[
uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),
pointer_default(unique)
@@ -289,4 +296,3 @@ interface IRemoteActivation
[out,size_is(Interfaces)] MInterfacePointer **ppInterfaceData,
[out,size_is(Interfaces)] HRESULT *pResults);
}
cpp_quote("#endif")
+31 -30
View File
@@ -16,7 +16,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
* The OLE2 default object handler supports a whole whack of
@@ -416,7 +416,8 @@ static void WINAPI DefaultHandler_Stop(DefaultHandler *This)
/* FIXME: call IOleCache_OnStop */
DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
if (This->dataAdviseHolder)
DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
if (This->pDataDelegate)
{
IDataObject_Release(This->pDataDelegate);
@@ -446,7 +447,7 @@ static HRESULT WINAPI DefaultHandler_Close(
DefaultHandler *This = impl_from_IOleObject(iface);
HRESULT hr;
TRACE("(%ld)\n", dwSaveOption);
TRACE("(%d)\n", dwSaveOption);
if (!This->pOleDelegate)
return S_OK;
@@ -472,7 +473,7 @@ static HRESULT WINAPI DefaultHandler_SetMoniker(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %p)\n",
TRACE("(%p, %d, %p)\n",
iface,
dwWhichMoniker,
pmk);
@@ -498,7 +499,7 @@ static HRESULT WINAPI DefaultHandler_GetMoniker(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %ld, %p)\n",
TRACE("(%p, %d, %d, %p)\n",
iface, dwAssign, dwWhichMoniker, ppmk);
if (This->pOleDelegate)
@@ -533,7 +534,7 @@ static HRESULT WINAPI DefaultHandler_InitFromData(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %p, %d, %ld)\n",
TRACE("(%p, %p, %d, %d)\n",
iface, pDataObject, fCreation, dwReserved);
if (This->pOleDelegate)
@@ -556,7 +557,7 @@ static HRESULT WINAPI DefaultHandler_GetClipboardData(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %p)\n",
TRACE("(%p, %d, %p)\n",
iface, dwReserved, ppDataObject);
if (This->pOleDelegate)
@@ -579,7 +580,7 @@ static HRESULT WINAPI DefaultHandler_DoVerb(
IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
HRESULT hr;
TRACE("(%ld, %p, %p, %ld, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
hr = IRunnableObject_Run(pRunnableObj, NULL);
if (FAILED(hr)) return hr;
@@ -651,9 +652,6 @@ static HRESULT WINAPI DefaultHandler_GetUserClassID(
TRACE("(%p, %p)\n", iface, pClsid);
if (This->pOleDelegate)
return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
if (This->pOleDelegate)
return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
@@ -681,7 +679,7 @@ static HRESULT WINAPI DefaultHandler_GetUserType(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
}
@@ -700,7 +698,7 @@ static HRESULT WINAPI DefaultHandler_SetExtent(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %lx, (%ld x %ld))\n", iface,
TRACE("(%p, %x, (%d x %d))\n", iface,
dwDrawAspect, psizel->cx, psizel->cy);
if (This->pOleDelegate)
@@ -728,7 +726,7 @@ static HRESULT WINAPI DefaultHandler_GetExtent(
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
if (This->pOleDelegate)
return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
@@ -805,7 +803,7 @@ static HRESULT WINAPI DefaultHandler_Unadvise(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld)\n", iface, dwConnection);
TRACE("(%p, %d)\n", iface, dwConnection);
/*
* If we don't have an advise holder yet, it means we don't have
@@ -841,10 +839,9 @@ static HRESULT WINAPI DefaultHandler_EnumAdvise(
*ppenumAdvise = NULL;
if (!This->oleAdviseHolder)
return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
ppenumAdvise);
return S_OK;
return S_OK;
return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
}
/************************************************************************
@@ -863,10 +860,7 @@ static HRESULT WINAPI DefaultHandler_GetMiscStatus(
HRESULT hres;
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
if (This->pOleDelegate)
return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
if (This->pOleDelegate)
return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
@@ -978,6 +972,9 @@ static HRESULT WINAPI DefaultHandler_GetData(
IDataObject_Release(cacheDataObject);
if (FAILED(hres) && This->pDataDelegate)
hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
return hres;
}
@@ -1021,6 +1018,9 @@ static HRESULT WINAPI DefaultHandler_QueryGetData(
IDataObject_Release(cacheDataObject);
if (FAILED(hres) && This->pDataDelegate)
hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
return hres;
}
@@ -1037,16 +1037,13 @@ static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
LPFORMATETC pformatetcOut)
{
DefaultHandler *This = impl_from_IDataObject(iface);
IDataObject *pDataObject;
HRESULT hr;
TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
if (!This->pOleDelegate)
if (!This->pDataDelegate)
return OLE_E_NOTRUNNING;
hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&pDataObject);
return IDataObject_GetCanonicalFormatEtc(pDataObject, pformatetcIn, pformatetcOut);
return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
}
/************************************************************************
@@ -1102,7 +1099,7 @@ static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
HRESULT hres;
DefaultHandler *This = impl_from_IDataObject(iface);
TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
@@ -1127,12 +1124,16 @@ static HRESULT WINAPI DefaultHandler_DAdvise(
HRESULT hres = S_OK;
DefaultHandler *This = impl_from_IDataObject(iface);
TRACE("(%p, %p, %ld, %p, %p)\n",
TRACE("(%p, %p, %d, %p, %p)\n",
iface, pformatetc, advf, pAdvSink, pdwConnection);
/* Make sure we have a data advise holder before we start. */
if (!This->dataAdviseHolder)
{
hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
if (SUCCEEDED(hres) && This->pDataDelegate)
DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
}
if (SUCCEEDED(hres))
hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
@@ -1159,7 +1160,7 @@ static HRESULT WINAPI DefaultHandler_DUnadvise(
{
DefaultHandler *This = impl_from_IDataObject(iface);
TRACE("(%p, %ld)\n", iface, dwConnection);
TRACE("(%p, %d)\n", iface, dwConnection);
/*
* If we don't have a data advise holder yet, it means that
+1 -1
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
+1 -1
View File
@@ -17,7 +17,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __DICTIONARY_H__
#define __DICTIONARY_H__
+202
View File
@@ -0,0 +1,202 @@
/*
* IEnum* implementation
*
* Copyright 2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
typedef struct tagEnumSTATPROPSETSTG_impl
{
const void *vtbl;
LONG ref;
struct list elements;
struct list *current;
ULONG elem_size;
GUID riid;
} enumx_impl;
/************************************************************************
* enumx_QueryInterface
*/
HRESULT WINAPI enumx_QueryInterface(
enumx_impl *This,
REFIID riid,
void** ppvObject)
{
if ( (This==0) || (ppvObject==0) )
return E_INVALIDARG;
*ppvObject = 0;
if (IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&This->riid, riid))
{
IUnknown_AddRef(((IUnknown*)This));
*ppvObject = This;
return S_OK;
}
return E_NOINTERFACE;
}
/************************************************************************
* enumx_AddRef
*/
ULONG WINAPI enumx_AddRef(enumx_impl *This)
{
return InterlockedIncrement(&This->ref);
}
/************************************************************************
* enumx_Release
*/
ULONG WINAPI enumx_Release(enumx_impl *This)
{
ULONG ref;
ref = InterlockedDecrement(&This->ref);
if (ref == 0)
{
while (!list_empty(&This->elements))
{
struct list *x = list_head(&This->elements);
list_remove(x);
HeapFree(GetProcessHeap(), 0, x);
}
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
/************************************************************************
* enumx_Next
*/
HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
void *rgelt, ULONG *pceltFetched)
{
unsigned char *p;
ULONG count = 0;
TRACE("%p %u %p\n", This, celt, pceltFetched);
if (This->current == NULL)
This->current = list_head(&This->elements);
p = rgelt;
while (count < celt && This->current && This->current != &This->elements)
{
memcpy(p, &This->current[1], This->elem_size);
p += This->elem_size;
This->current = This->current->next;
count++;
}
if (pceltFetched)
*pceltFetched = count;
if (count < celt)
return S_FALSE;
return S_OK;
}
/************************************************************************
* enumx_Skip
*/
HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
{
ULONG count = 0;
TRACE("%p %u\n", This, celt);
if (This->current == NULL)
This->current = list_head(&This->elements);
while (count < celt && This->current && This->current != &This->elements)
count++;
return S_OK;
}
/************************************************************************
* enumx_Reset
*/
HRESULT WINAPI enumx_Reset(enumx_impl *This)
{
TRACE("\n");
This->current = NULL;
return S_OK;
}
/************************************************************************
* enumx_fnClone
*/
HRESULT WINAPI enumx_Clone(
enumx_impl *iface,
enumx_impl **ppenum)
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* enumx_allocate
*
* Allocate a generic enumerator
*/
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
{
enumx_impl *enumx;
enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx);
if (enumx)
{
enumx->vtbl = vtbl;
enumx->ref = 1;
enumx->current = NULL;
enumx->elem_size = elem_size;
memcpy(&enumx->riid, riid, sizeof *riid);
list_init(&enumx->elements);
}
return enumx;
}
/************************************************************************
* enumx_add_element
*
* Add an element to the enumeration.
*/
void *enumx_add_element(enumx_impl *enumx, void *data)
{
struct list *element;
element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size);
if (!element)
return NULL;
memcpy(&element[1], data, enumx->elem_size);
list_add_tail(&enumx->elements, element);
return &element[1];
}
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright 2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __OLE_ENUM_H__
#define __OLE_ENUM_H__
typedef struct tagEnumSTATPROPSETSTG_impl enumx_impl;
extern HRESULT WINAPI enumx_QueryInterface(enumx_impl *, REFIID, void**);
extern ULONG WINAPI enumx_AddRef(enumx_impl *);
extern ULONG WINAPI enumx_Release(enumx_impl *);
extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *);
extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG);
extern HRESULT WINAPI enumx_Reset(enumx_impl *);
extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **);
extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG);
extern void *enumx_add_element(enumx_impl *, void *);
#endif
+26 -18
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
*
@@ -52,7 +52,7 @@ static BSTR WINAPI ERRORINFO_SysAllocString(const OLECHAR* in)
if (in == NULL)
return NULL;
/*
* Find the lenth of the buffer passed-in in bytes.
* Find the length of the buffer passed-in, in bytes.
*/
len = strlenW(in);
bufferSize = len * sizeof (WCHAR);
@@ -83,14 +83,10 @@ static BSTR WINAPI ERRORINFO_SysAllocString(const OLECHAR* in)
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.
* Copy the information in the buffer. It is not possible to pass
* a NULL pointer here.
*/
if (in != 0)
memcpy(newBuffer, in, bufferSize);
else
memset(newBuffer, 0, bufferSize);
memcpy(newBuffer, in, bufferSize);
/*
* Make sure that there is a nul character at the end of the
@@ -171,7 +167,7 @@ static inline ErrorInfoImpl *impl_from_ISupportErrorInfo( ISupportErrorInfo *ifa
#define _ICreateErrorInfo_(This) (ICreateErrorInfo*)&(This->lpvtcei)
#define _ISupportErrorInfo_(This) (ISupportErrorInfo*)&(This->lpvtsei)
IErrorInfo * IErrorInfoImpl_Constructor(void)
static IErrorInfo * IErrorInfoImpl_Constructor(void)
{
ErrorInfoImpl * ei = HeapAlloc(GetProcessHeap(), 0, sizeof(ErrorInfoImpl));
if (ei)
@@ -226,7 +222,7 @@ static ULONG WINAPI IErrorInfoImpl_AddRef(
IErrorInfo* iface)
{
ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
TRACE("(%p)->(count=%lu)\n",This,This->ref);
TRACE("(%p)->(count=%u)\n",This,This->ref);
return InterlockedIncrement(&This->ref);
}
@@ -236,7 +232,7 @@ static ULONG WINAPI IErrorInfoImpl_Release(
ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(count=%lu)\n",This,ref+1);
TRACE("(%p)->(count=%u)\n",This,ref+1);
if (!ref)
{
@@ -252,7 +248,7 @@ static HRESULT WINAPI IErrorInfoImpl_GetGUID(
GUID * pGUID)
{
ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
TRACE("(%p)->(count=%lu)\n",This,This->ref);
TRACE("(%p)->(count=%u)\n",This,This->ref);
if(!pGUID )return E_INVALIDARG;
memcpy(pGUID, &This->m_Guid, sizeof(GUID));
return S_OK;
@@ -405,7 +401,7 @@ static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext(
DWORD dwHelpContext)
{
ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
TRACE("(%p,%ld)\n",This,dwHelpContext);
TRACE("(%p,%d)\n",This,dwHelpContext);
This->m_dwHelpContext = dwHelpContext;
return S_OK;
}
@@ -490,10 +486,16 @@ HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
*/
HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
{
TRACE("(%ld, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->errorinfo);
TRACE("(%d, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->errorinfo);
if (dwReserved)
{
ERR("dwReserved (0x%x) != 0\n", dwReserved);
return E_INVALIDARG;
}
if(!pperrinfo) return E_INVALIDARG;
if (!COM_CurrentInfo()->errorinfo)
{
*pperrinfo = NULL;
@@ -514,8 +516,14 @@ HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
{
IErrorInfo * pei;
TRACE("(%ld, %p)\n", dwReserved, perrinfo);
TRACE("(%d, %p)\n", dwReserved, perrinfo);
if (dwReserved)
{
ERR("dwReserved (0x%x) != 0\n", dwReserved);
return E_INVALIDARG;
}
/* release old errorinfo */
pei = COM_CurrentInfo()->errorinfo;
if (pei) IErrorInfo_Release(pei);
+104 -8
View File
@@ -2,6 +2,7 @@
* FileMonikers implementation
*
* Copyright 1999 Noomen Hamza
* Copyright 2007 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -15,7 +16,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@@ -39,10 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
const CLSID CLSID_FileMoniker = {
0x303, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
};
/* filemoniker data structure */
typedef struct FileMonikerImpl{
@@ -530,7 +527,7 @@ FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft
}
if (pcf!=NULL){
IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)ppf);
IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)&ppf);
res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
@@ -643,7 +640,7 @@ static HRESULT WINAPI
FileMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@@ -1249,7 +1246,7 @@ FileMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
int i;
LPWSTR pszFileName;
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + len * sizeof(WCHAR);
if (cbMax < *pcbData)
@@ -1409,6 +1406,105 @@ HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
return hr;
}
/* find a character from a set in reverse without the string having to be null-terminated */
static inline WCHAR *memrpbrkW(const WCHAR *ptr, size_t n, const WCHAR *accept)
{
const WCHAR *end, *ret = NULL;
for (end = ptr + n; ptr < end; ptr++) if (strchrW(accept, *ptr)) ret = ptr;
return (WCHAR *)ret;
}
HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
LPCWSTR end;
static const WCHAR wszSeparators[] = {':','\\','/','!',0};
for (end = szDisplayName + strlenW(szDisplayName);
end && (end != szDisplayName);
end = memrpbrkW(szDisplayName, end - szDisplayName, wszSeparators))
{
HRESULT hr;
IRunningObjectTable *rot;
IMoniker *file_moniker;
LPWSTR file_display_name;
LPWSTR full_path_name;
DWORD full_path_name_len;
int len = end - szDisplayName;
file_display_name = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!file_display_name) return E_OUTOFMEMORY;
memcpy(file_display_name, szDisplayName, len * sizeof(WCHAR));
file_display_name[len] = '\0';
hr = CreateFileMoniker(file_display_name, &file_moniker);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
return hr;
}
hr = IBindCtx_GetRunningObjectTable(pbc, &rot);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return hr;
}
hr = IRunningObjectTable_IsRunning(rot, file_moniker);
IRunningObjectTable_Release(rot);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return hr;
}
if (hr == S_OK)
{
TRACE("found running file moniker for %s\n", debugstr_w(file_display_name));
*pchEaten = len;
*ppmk = file_moniker;
HeapFree(GetProcessHeap(), 0, file_display_name);
return S_OK;
}
full_path_name_len = GetFullPathNameW(file_display_name, 0, NULL, NULL);
if (!full_path_name_len)
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return MK_E_SYNTAX;
}
full_path_name = HeapAlloc(GetProcessHeap(), 0, full_path_name_len * sizeof(WCHAR));
if (!full_path_name)
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return E_OUTOFMEMORY;
}
GetFullPathNameW(file_display_name, full_path_name_len, full_path_name, NULL);
if (GetFileAttributesW(full_path_name) == INVALID_FILE_ATTRIBUTES)
TRACE("couldn't open file %s\n", debugstr_w(full_path_name));
else
{
TRACE("got file moniker for %s\n", debugstr_w(szDisplayName));
*pchEaten = len;
*ppmk = file_moniker;
HeapFree(GetProcessHeap(), 0, file_display_name);
HeapFree(GetProcessHeap(), 0, full_path_name);
return S_OK;
}
HeapFree(GetProcessHeap(), 0, file_display_name);
HeapFree(GetProcessHeap(), 0, full_path_name);
IMoniker_Release(file_moniker);
}
return MK_E_CANTOPENFILE;
}
static HRESULT WINAPI FileMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
+174 -16
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -34,6 +34,8 @@
#include "wine/debug.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
typedef struct _FTMarshalImpl {
@@ -136,7 +138,12 @@ static HRESULT WINAPI
FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
void *pvDestContext, DWORD mshlflags, CLSID * pCid)
{
FIXME ("(), stub!\n");
TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX)
memcpy(pCid, &CLSID_InProcFreeMarshaler, sizeof(CLSID_InProcFreeMarshaler));
else
memcpy(pCid, &CLSID_DfMarshal, sizeof(CLSID_InProcFreeMarshaler));
return S_OK;
}
@@ -148,15 +155,14 @@ FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD d
IMarshal *pMarshal = NULL;
HRESULT hres;
FTMarshalImpl *This = impl_from_IMarshal(iface);
FIXME ("(), stub!\n");
TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pSize);
/* 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;
*pSize = sizeof (mshlflags) + sizeof (pv) + sizeof (DWORD) + sizeof (GUID);
return S_OK;
}
/* use the standard marshaller to handle all other cases */
@@ -174,14 +180,37 @@ FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, vo
IMarshal *pMarshal = NULL;
HRESULT hres;
FTMarshalImpl *This = impl_from_IMarshal(iface);
FIXME ("(), stub!\n");
TRACE("(%p, %s, %p, 0x%x, %p, 0x%x)\n", pStm, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags);
/* 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);
void *object;
DWORD constant = 0;
GUID unknown_guid = { 0 };
hres = IUnknown_QueryInterface((IUnknown *)pv, riid, &object);
if (FAILED(hres))
return hres;
/* don't hold a reference to table-weak marshaled interfaces */
if (mshlflags & MSHLFLAGS_TABLEWEAK)
IUnknown_Release((IUnknown *)object);
hres = IStream_Write (pStm, &mshlflags, sizeof (mshlflags), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
hres = IStream_Write (pStm, &object, sizeof (object), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
hres = IStream_Write (pStm, &constant, sizeof (constant), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
hres = IStream_Write (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
return S_OK;
}
/* use the standard marshaler to handle all other cases */
@@ -194,19 +223,66 @@ FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, vo
static HRESULT WINAPI
FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
{
FIXME ("(), stub!\n");
return S_OK;
DWORD mshlflags;
IUnknown *object;
DWORD constant;
GUID unknown_guid;
HRESULT hres;
TRACE ("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &object, sizeof (object), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
if (hres != S_OK) return STG_E_READFAULT;
if (constant != 0)
FIXME("constant is 0x%x instead of 0\n", constant);
hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IUnknown_QueryInterface(object, riid, ppv);
if (!(mshlflags & (MSHLFLAGS_TABLEWEAK|MSHLFLAGS_TABLESTRONG)))
IUnknown_Release(object);
return hres;
}
static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
{
FIXME ("(), stub!\n");
DWORD mshlflags;
IUnknown *object;
DWORD constant;
GUID unknown_guid;
HRESULT hres;
TRACE ("(%p)\n", pStm);
hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &object, sizeof (object), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
if (hres != S_OK) return STG_E_READFAULT;
if (constant != 0)
FIXME("constant is 0x%x instead of 0\n", constant);
hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
if (hres != S_OK) return STG_E_READFAULT;
IUnknown_Release(object);
return S_OK;
}
static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
{
FIXME ("(), stub!\n");
TRACE ("()\n");
/* nothing to do */
return S_OK;
}
@@ -226,6 +302,23 @@ static const IMarshalVtbl ftmvtbl =
/***********************************************************************
* CoCreateFreeThreadedMarshaler [OLE32.@]
*
* Creates a free-threaded marshaler.
*
* PARAMS
* punkOuter [I] Optional. Outer unknown.
* ppunkMarshal [O] On return, the inner unknown of the created free-threaded marshaler.
*
* RETURNS
* Success: S_OK
* Failure: E_OUTOFMEMORY if no memory available to create object.
*
* NOTES
* Objects that ensure their state is maintained consistent when used by
* multiple threads and reference no single-threaded objects are known as
* free-threaded. The free-threaded marshaler enables these objects to be
* efficiently marshaled within the same process, by not creating proxies
* (as they aren't needed for the object to be safely used), whilst still
* allowing the object to be used in inter-process and inter-machine contexts.
*/
HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
{
@@ -241,8 +334,73 @@ HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * p
ftm->lpVtbl = &iunkvt;
ftm->lpvtblFTM = &ftmvtbl;
ftm->ref = 1;
ftm->pUnkOuter = punkOuter;
ftm->pUnkOuter = punkOuter ? punkOuter : _IFTMUnknown_(ftm);
*ppunkMarshal = _IFTMUnknown_ (ftm);
return S_OK;
}
static HRESULT WINAPI FTMarshalCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI FTMarshalCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI FTMarshalCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI FTMarshalCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
IUnknown *pUnknown;
HRESULT hr;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
hr = CoCreateFreeThreadedMarshaler(pUnk, &pUnknown);
if (SUCCEEDED(hr))
{
hr = IUnknown_QueryInterface(pUnknown, riid, ppv);
IUnknown_Release(pUnknown);
}
return hr;
}
static HRESULT WINAPI FTMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl FTMarshalCFVtbl =
{
FTMarshalCF_QueryInterface,
FTMarshalCF_AddRef,
FTMarshalCF_Release,
FTMarshalCF_CreateInstance,
FTMarshalCF_LockServer
};
static const IClassFactoryVtbl *FTMarshalCF = &FTMarshalCFVtbl;
HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&FTMarshalCF, riid, ppv);
}
+20 -38
View File
@@ -21,16 +21,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
@@ -42,11 +36,10 @@
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "winreg.h"
#include "winternl.h"
#include "compobj_private.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -65,8 +58,7 @@ typedef struct StdGITEntry
IID iid; /* IID of the interface */
IStream* stream; /* Holds the marshalled interface */
struct StdGITEntry* next;
struct StdGITEntry* prev;
struct list entry;
} StdGITEntry;
/* Class data */
@@ -75,8 +67,7 @@ typedef struct StdGlobalInterfaceTableImpl
const IGlobalInterfaceTableVtbl *lpVtbl;
ULONG ref;
struct StdGITEntry* firstEntry;
struct StdGITEntry* lastEntry;
struct list list;
ULONG nextCookie;
} StdGlobalInterfaceTableImpl;
@@ -94,7 +85,8 @@ static CRITICAL_SECTION git_section = { &critsect_debug, -1, 0, 0, 0, 0 };
/** This destroys it again. It should revoke all the held interfaces first **/
void StdGlobalInterfaceTable_Destroy(void* self) {
static void StdGlobalInterfaceTable_Destroy(void* self)
{
TRACE("(%p)\n", self);
FIXME("Revoke held interfaces here\n");
@@ -115,13 +107,11 @@ StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
TRACE("iface=%p, cookie=0x%x\n", iface, (UINT)cookie);
EnterCriticalSection(&git_section);
e = self->firstEntry;
while (e != NULL) {
LIST_FOR_EACH_ENTRY(e, &self->list, StdGITEntry, entry) {
if (e->cookie == cookie) {
LeaveCriticalSection(&git_section);
return e;
}
e = e->next;
}
LeaveCriticalSection(&git_section);
@@ -210,7 +200,7 @@ StdGlobalInterfaceTable_RegisterInterfaceInGlobal(
}
zero.QuadPart = 0;
IStream_Seek(stream, zero, SEEK_SET, NULL);
IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
if (entry == NULL) return E_OUTOFMEMORY;
@@ -223,18 +213,14 @@ StdGlobalInterfaceTable_RegisterInterfaceInGlobal(
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;
list_add_tail(&self->list, &entry->entry);
/* and return the cookie */
*pdwCookie = entry->cookie;
LeaveCriticalSection(&git_section);
TRACE("Cookie is 0x%lx\n", entry->cookie);
TRACE("Cookie is 0x%x\n", entry->cookie);
return S_OK;
}
@@ -242,7 +228,6 @@ static HRESULT WINAPI
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
IGlobalInterfaceTable* iface, DWORD dwCookie)
{
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
StdGITEntry* entry;
HRESULT hr;
@@ -258,17 +243,14 @@ StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
hr = CoReleaseMarshalData(entry->stream);
if (hr != S_OK)
{
WARN("Failed to release marshal data, hr = 0x%08lx\n", hr);
WARN("Failed to release marshal data, hr = 0x%08x\n", hr);
return hr;
}
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;
list_remove(&entry->entry);
LeaveCriticalSection(&git_section);
HeapFree(GetProcessHeap(), 0, entry);
@@ -285,7 +267,7 @@ StdGlobalInterfaceTable_GetInterfaceFromGlobal(
LARGE_INTEGER move;
LPUNKNOWN lpUnk;
TRACE("dwCookie=0x%lx, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
TRACE("dwCookie=0x%x, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
if (entry == NULL) return E_INVALIDARG;
@@ -298,16 +280,17 @@ StdGlobalInterfaceTable_GetInterfaceFromGlobal(
/* 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);
if (hres) {
WARN("Failed to unmarshal stream\n");
return hres;
}
/* addref it */
lpUnk = *ppv;
IUnknown_AddRef(lpUnk);
@@ -389,7 +372,7 @@ static const IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
};
/** This function constructs the GIT. It should only be called once **/
void* StdGlobalInterfaceTable_Construct()
void* StdGlobalInterfaceTable_Construct(void)
{
StdGlobalInterfaceTableImpl* newGIT;
@@ -398,8 +381,7 @@ void* StdGlobalInterfaceTable_Construct()
newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
newGIT->ref = 1; /* Initialise the reference count */
newGIT->firstEntry = NULL; /* we start with an empty table */
newGIT->lastEntry = NULL;
list_init(&newGIT->list);
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
TRACE("Created the GIT at %p\n", newGIT);
+36 -49
View File
@@ -18,7 +18,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -49,7 +49,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
/****************************************************************************
* HGLOBALStreamImpl definition.
*
* This class imlements the IStream inteface and represents a stream
* This class implements the IStream interface and represents a stream
* supported by an HGLOBAL pointer.
*/
struct HGLOBALStreamImpl
@@ -148,11 +148,9 @@ static HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
/*
* 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)
if (IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_ISequentialStream, riid) ||
IsEqualIID(&IID_IStream, riid))
{
*ppvObject = (IStream*)This;
}
@@ -216,7 +214,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
TRACE("(%p, %p, %ld, %p)\n", iface,
TRACE("(%p, %p, %d, %p)\n", iface,
pv, cb, pcbRead);
/*
@@ -255,14 +253,11 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
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
* Always returns S_OK even if the end of the stream is reached before the
* buffer is filled
*/
if(*pcbRead == cb)
return S_OK;
return S_FALSE;
return S_OK;
}
/***
@@ -287,8 +282,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
TRACE("(%p, %p, %ld, %p)\n", iface,
pv, cb, pcbWritten);
TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten);
/*
* If the caller is not interested in the number of bytes written,
@@ -298,14 +292,10 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
pcbWritten = &bytesWritten;
if (cb == 0)
{
return S_OK;
}
else
{
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
}
goto out;
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
/*
* Verify if we need to grow the stream
@@ -316,7 +306,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
HRESULT hr = IStream_SetSize(iface, newSize);
if (FAILED(hr))
{
ERR("IStream_SetSize failed with error 0x%08lx\n", hr);
ERR("IStream_SetSize failed with error 0x%08x\n", hr);
return hr;
}
}
@@ -333,16 +323,17 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
*/
This->currentPosition.u.LowPart+=cb;
/*
* Return the number of bytes read.
*/
*pcbWritten = cb;
/*
* Cleanup
*/
GlobalUnlock(This->supportHandle);
out:
/*
* Return the number of bytes read.
*/
*pcbWritten = cb;
return S_OK;
}
@@ -364,7 +355,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
ULARGE_INTEGER newPosition;
TRACE("(%p, %lx%08lx, %ld, %p)\n", iface, dlibMove.u.HighPart,
TRACE("(%p, %x%08x, %d, %p)\n", iface, dlibMove.u.HighPart,
dlibMove.u.LowPart, dwOrigin, plibNewPosition);
/*
@@ -418,13 +409,11 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
HGLOBAL supportHandle;
TRACE("(%p, %ld)\n", iface, libNewSize.u.LowPart);
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
/*
* As documented.
* HighPart is ignored as shown in tests
*/
if (libNewSize.u.HighPart != 0)
return STG_E_INVALIDFUNCTION;
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
@@ -435,7 +424,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
if (supportHandle == 0)
return STG_E_MEDIUMFULL;
return E_OUTOFMEMORY;
This->supportHandle = supportHandle;
This->streamSize.u.LowPart = libNewSize.u.LowPart;
@@ -463,7 +452,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
ULARGE_INTEGER totalBytesRead;
ULARGE_INTEGER totalBytesWritten;
TRACE("(%p, %p, %ld, %p, %p)\n", iface, pstm,
TRACE("(%p, %p, %d, %p, %p)\n", iface, pstm,
cb.u.LowPart, pcbRead, pcbWritten);
/*
@@ -487,21 +476,19 @@ static HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
else
copySize = cb.u.LowPart;
IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
hr = IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
if (FAILED(hr))
break;
totalBytesRead.u.LowPart += bytesRead;
IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
totalBytesWritten.u.LowPart += bytesWritten;
/*
* Check that read & write operations were succesfull
*/
if (bytesRead != bytesWritten)
if (bytesRead)
{
hr = STG_E_MEDIUMFULL;
break;
hr = IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
if (FAILED(hr))
break;
totalBytesWritten.u.LowPart += bytesWritten;
}
if (bytesRead!=copySize)
@@ -570,7 +557,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
return S_OK;
return STG_E_INVALIDFUNCTION;
}
/*
@@ -664,7 +651,7 @@ static const IStreamVtbl HGLOBALStreamImpl_Vtbl =
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
* when the IStream object is destroyed.
*/
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
static HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
{
+10 -10
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -166,7 +166,7 @@ static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) {
LPVOID addr;
TRACE("(%ld)\n",cb);
TRACE("(%d)\n",cb);
if(Malloc32.pSpy) {
DWORD preAllocResult;
@@ -200,7 +200,7 @@ static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
LPVOID pNewMemory;
TRACE("(%p,%ld)\n",pv,cb);
TRACE("(%p,%d)\n",pv,cb);
if(Malloc32.pSpy) {
LPVOID pRealMemory;
@@ -396,7 +396,7 @@ static ULONG WINAPI IMallocSpy_fnAddRef (LPMALLOCSPY iface)
_MallocSpy *This = (_MallocSpy *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE ("(%p)->(count=%lu)\n", This, ref - 1);
TRACE ("(%p)->(count=%u)\n", This, ref - 1);
return ref;
}
@@ -413,7 +413,7 @@ static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
_MallocSpy *This = (_MallocSpy *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE ("(%p)->(count=%lu)\n", This, ref + 1);
TRACE ("(%p)->(count=%u)\n", This, ref + 1);
if (!ref) {
/* our allocation list MUST be empty here */
@@ -424,7 +424,7 @@ static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
static ULONG WINAPI IMallocSpy_fnPreAlloc(LPMALLOCSPY iface, ULONG cbRequest)
{
_MallocSpy *This = (_MallocSpy *)iface;
TRACE ("(%p)->(%lu)\n", This, cbRequest);
TRACE ("(%p)->(%u)\n", This, cbRequest);
return cbRequest;
}
static PVOID WINAPI IMallocSpy_fnPostAlloc(LPMALLOCSPY iface, void* pActual)
@@ -449,7 +449,7 @@ static void WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL 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);
TRACE ("(%p)->(%p %u %u)\n", This, pRequest, cbRequest, fSpyed);
*ppNewRequest = pRequest;
return cbRequest;
}
@@ -471,7 +471,7 @@ static PVOID WINAPI IMallocSpy_fnPreGetSize(LPMALLOCSPY iface, void* pRequest, B
static ULONG WINAPI IMallocSpy_fnPostGetSize(LPMALLOCSPY iface, ULONG cbActual, BOOL fSpyed)
{
_MallocSpy *This = (_MallocSpy *)iface;
TRACE ("(%p)->(%lu %u)\n", This, cbActual, fSpyed);
TRACE ("(%p)->(%u %u)\n", This, cbActual, fSpyed);
return cbActual;
}
@@ -502,7 +502,7 @@ static void WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
}
static void MallocSpyDumpLeaks(void) {
TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft);
TRACE("leaks: %u\n", Malloc32.SpyedAllocationsLeft);
}
static const IMallocSpyVtbl VT_IMallocSpy =
@@ -665,7 +665,7 @@ HRESULT WINAPI CoRevokeMallocSpy(void)
}
if (Malloc32.SpyedAllocationsLeft) {
TRACE("SpyReleasePending with %lu allocations left\n", Malloc32.SpyedAllocationsLeft);
TRACE("SpyReleasePending with %u allocations left\n", Malloc32.SpyedAllocationsLeft);
Malloc32.SpyReleasePending = TRUE;
hres = E_ACCESSDENIED;
} else {
+1 -4
View File
@@ -13,7 +13,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_OLE_IFS_H
@@ -38,7 +38,6 @@ typedef LPCSTR LPCOLESTR16;
* IMalloc16 interface
*/
#undef INTERFACE
typedef struct IMalloc16 *LPMALLOC16;
#define INTERFACE IMalloc16
@@ -58,8 +57,6 @@ DECLARE_INTERFACE_(IMalloc16,IUnknown)
};
#undef INTERFACE
typedef struct IMalloc16 *LPMALLOC16;
/**********************************************************************/
extern LPMALLOC16 IMalloc16_Constructor(void);
+13 -26
View File
@@ -1,4 +1,4 @@
/***************************************************************************************
/*
* ItemMonikers implementation
*
* Copyright 1999 Noomen Hamza
@@ -15,8 +15,8 @@
*
* 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
***************************************************************************************/
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
@@ -38,10 +38,6 @@
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{
@@ -101,8 +97,8 @@ static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx*
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);
static HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
static HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
/********************************************************************************/
/* IROTData prototype functions */
@@ -392,7 +388,7 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
/******************************************************************************
* ItemMoniker_Construct (local function)
*******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
static HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
{
int sizeStr1=lstrlenW(lpszItem), sizeStr2;
@@ -430,7 +426,7 @@ HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDe
/******************************************************************************
* ItemMoniker_Destroy (local function)
*******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
static HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
{
TRACE("(%p)\n",This);
@@ -521,7 +517,7 @@ HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@@ -661,8 +657,8 @@ HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker
HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
int h = 0,i,skip,len;
DWORD h = 0;
int i,len;
int off = 0;
LPOLESTR val;
@@ -672,17 +668,8 @@ HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
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];
}
}
for (i = len ; i > 0; i--)
h = (h * 3) ^ toupperW(val[off++]);
*pdwHash=h;
@@ -980,7 +967,7 @@ HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
LPWSTR pszItemName;
LPWSTR pszItemDelimiter;
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);
if (cbMax < *pcbData)
+370 -132
View File
@@ -17,14 +17,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
@@ -35,10 +31,7 @@
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "rpc.h"
#include "winerror.h"
#include "winreg.h"
#include "wtypes.h"
#include "wine/unicode.h"
#include "compobj_private.h"
@@ -50,13 +43,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
extern const CLSID CLSID_DfMarshal;
/* number of refs given out for normal marshaling */
#define NORMALEXTREFS 1 /* FIXME: this should be 5, but we have to wait for IRemUnknown support first */
#define NORMALEXTREFS 5
/* private flag indicating that the caller does not want to notify the stub
* when the proxy disconnects or is destroyed */
#define SORFP_NOLIFETIMEMGMT SORF_OXRES1
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFIID riid, void **object);
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
MSHCTX dest_context, void *dest_context_data,
REFIID riid, const OXID_INFO *oxid_info,
void **object);
/* Marshalling just passes a unique identifier to the remote client,
* that makes it possible to find the passed interface again.
@@ -73,7 +69,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
* IPIDs identify an interface stub and are apartment scoped
*/
inline static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
{
HRESULT hr;
CLSID clsid;
@@ -98,10 +94,14 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
if (hr != S_OK)
return hr;
hr = apartment_createwindowifneeded(apt);
if (hr != S_OK)
return hr;
hr = IUnknown_QueryInterface(object, riid, (void **)&iobject);
if (hr != S_OK)
{
ERR("object doesn't expose interface %s, failing with error 0x%08lx\n",
ERR("object doesn't expose interface %s, failing with error 0x%08x\n",
debugstr_guid(riid), hr);
return E_NOINTERFACE;
}
@@ -124,7 +124,8 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
IPSFactoryBuffer_Release(psfb);
if (hr != S_OK)
{
ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s\n", debugstr_guid(riid));
ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s with error 0x%08x\n",
debugstr_guid(riid), hr);
IUnknown_Release(iobject);
return hr;
}
@@ -156,17 +157,18 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
/* make sure ifstub that we are creating is unique */
ifstub = stub_manager_find_ifstub(manager, riid, mshlflags);
if (!ifstub)
{
ifstub = stub_manager_new_ifstub(manager, stub, iobject, riid, mshlflags);
IUnknown_Release(iobject);
if (stub) IRpcStubBuffer_Release(stub);
if (!ifstub)
{
stub_manager_int_release(manager);
/* FIXME: should we do another release to completely destroy the
* stub manager? */
return E_OUTOFMEMORY;
}
if (stub) IRpcStubBuffer_Release(stub);
IUnknown_Release(iobject);
if (!ifstub)
{
stub_manager_int_release(manager);
/* destroy the stub manager if it has no ifstubs by releasing
* zero external references */
stub_manager_ext_release(manager, 0, TRUE);
return E_OUTOFMEMORY;
}
if (!tablemarshal)
@@ -216,7 +218,7 @@ static HRESULT WINAPI ClientIdentity_QueryInterface(IMultiQI * iface, REFIID rii
static ULONG WINAPI ClientIdentity_AddRef(IMultiQI * iface)
{
struct proxy_manager * This = (struct proxy_manager *)iface;
TRACE("%p - before %ld\n", iface, This->refs);
TRACE("%p - before %d\n", iface, This->refs);
return InterlockedIncrement(&This->refs);
}
@@ -224,7 +226,7 @@ static ULONG WINAPI ClientIdentity_Release(IMultiQI * iface)
{
struct proxy_manager * This = (struct proxy_manager *)iface;
ULONG refs = InterlockedDecrement(&This->refs);
TRACE("%p - after %ld\n", iface, refs);
TRACE("%p - after %d\n", iface, refs);
if (!refs)
proxy_manager_destroy(This);
return refs;
@@ -241,13 +243,13 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
/* mapping of RemQueryInterface index to QueryMultipleInterfaces index */
ULONG *mapping = HeapAlloc(GetProcessHeap(), 0, cMQIs * sizeof(*mapping));
TRACE("cMQIs: %ld\n", cMQIs);
TRACE("cMQIs: %d\n", cMQIs);
/* try to get a local interface - this includes already active proxy
* interfaces and also interfaces exposed by the proxy manager */
for (i = 0; i < cMQIs; i++)
{
TRACE("iid[%ld] = %s\n", i, debugstr_guid(pMQIs[i].pIID));
TRACE("iid[%d] = %s\n", i, debugstr_guid(pMQIs[i].pIID));
pMQIs[i].hr = proxy_manager_query_local_interface(This, pMQIs[i].pIID, (void **)&pMQIs[i].pItf);
if (pMQIs[i].hr == S_OK)
successful_mqis++;
@@ -259,7 +261,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
}
}
TRACE("%ld interfaces not found locally\n", nonlocal_mqis);
TRACE("%d interfaces not found locally\n", nonlocal_mqis);
/* if we have more than one interface not found locally then we must try
* to query the remote object for it */
@@ -282,7 +284,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
nonlocal_mqis, iids, &qiresults);
if (FAILED(hr))
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08lx\n", hr);
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
}
/* IRemUnknown_RemQueryInterface can return S_FALSE if only some of
@@ -296,7 +298,9 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
HRESULT hrobj = qiresults[i].hResult;
if (hrobj == S_OK)
hrobj = unmarshal_object(&qiresults[i].std, This->parent,
pMQIs[index].pIID,
This->dest_context,
This->dest_context_data,
pMQIs[index].pIID, &This->oxid_info,
(void **)&pMQIs[index].pItf);
if (hrobj == S_OK)
@@ -311,7 +315,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
CoTaskMemFree(qiresults);
}
TRACE("%ld/%ld successfully queried\n", successful_mqis, cMQIs);
TRACE("%d/%d successfully queried\n", successful_mqis, cMQIs);
HeapFree(GetProcessHeap(), 0, iids);
HeapFree(GetProcessHeap(), 0, mapping);
@@ -332,6 +336,13 @@ static const IMultiQIVtbl ClientIdentity_Vtbl =
ClientIdentity_QueryMultipleInterfaces
};
/* FIXME: remove these */
static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid);
static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize);
static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv);
static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm);
static HRESULT WINAPI StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved);
static HRESULT WINAPI Proxy_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblMarshal, iface);
@@ -344,13 +355,6 @@ static ULONG WINAPI Proxy_AddRef(IMarshal *iface)
return IMultiQI_AddRef((IMultiQI *)&This->lpVtbl);
}
/* FIXME: remove these */
static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid);
static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize);
static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv);
static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm);
static HRESULT WINAPI StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved);
static ULONG WINAPI Proxy_Release(IMarshal *iface)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblMarshal, iface);
@@ -362,25 +366,97 @@ static HRESULT WINAPI Proxy_MarshalInterface(
void* pvDestContext, DWORD mshlflags)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblMarshal, iface);
ULONG res;
HRESULT hr;
STDOBJREF stdobjref;
struct ifproxy *ifproxy;
TRACE("(...,%s,...)\n", debugstr_guid(riid));
hr = proxy_manager_find_ifproxy(This, riid, &ifproxy);
if (FAILED(hr))
if (SUCCEEDED(hr))
{
ERR("couldn't find proxy for interface %s, error 0x%08lx\n", debugstr_guid(riid), hr);
return hr;
}
STDOBJREF stdobjref = ifproxy->stdobjref;
ULONG cPublicRefs = ifproxy->refs;
ULONG cPublicRefsOld;
stdobjref = ifproxy->stdobjref;
/* FIXME: optimization - share out proxy's public references if possible
* instead of making new proxy do a roundtrip through the server */
stdobjref.cPublicRefs = 0; /* InterlockedDecrement(&This->stdobjref.cPublicRefs) >= 0 ? 1 : 0 */
hr = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
/* optimization - share out proxy's public references if possible
* instead of making new proxy do a roundtrip through the server */
do
{
ULONG cPublicRefsNew;
cPublicRefsOld = cPublicRefs;
stdobjref.cPublicRefs = cPublicRefs / 2;
cPublicRefsNew = cPublicRefs - stdobjref.cPublicRefs;
cPublicRefs = InterlockedCompareExchange(
(LONG *)&ifproxy->refs, cPublicRefsNew, cPublicRefsOld);
} while (cPublicRefs != cPublicRefsOld);
if (!stdobjref.cPublicRefs)
{
IRemUnknown *remunk;
hr = proxy_manager_get_remunknown(This, &remunk);
if (hr == S_OK)
{
HRESULT hrref = S_OK;
REMINTERFACEREF rif;
rif.ipid = ifproxy->stdobjref.ipid;
rif.cPublicRefs = NORMALEXTREFS;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
if (hr == S_OK && hrref == S_OK)
stdobjref.cPublicRefs = rif.cPublicRefs;
else
ERR("IRemUnknown_RemAddRef returned with 0x%08x, hrref = 0x%08x\n", hr, hrref);
}
}
if (SUCCEEDED(hr))
{
TRACE("writing stdobjref:\n\tflags = %04lx\n\tcPublicRefs = %ld\n\toxid = %s\n\toid = %s\n\tipid = %s\n",
stdobjref.flags, stdobjref.cPublicRefs,
wine_dbgstr_longlong(stdobjref.oxid),
wine_dbgstr_longlong(stdobjref.oid),
debugstr_guid(&stdobjref.ipid));
hr = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), NULL);
}
}
else
{
/* we don't have the interface already unmarshaled so we have to
* request the object from the server */
IRemUnknown *remunk;
IPID *ipid;
REMQIRESULT *qiresults = NULL;
IID iid = *riid;
/* get the ipid of the first entry */
/* FIXME: should we implement ClientIdentity on the ifproxies instead
* of the proxy_manager so we use the correct ipid here? */
ipid = &LIST_ENTRY(list_head(&This->interfaces), struct ifproxy, entry)->stdobjref.ipid;
/* get IRemUnknown proxy so we can communicate with the remote object */
hr = proxy_manager_get_remunknown(This, &remunk);
if (hr == S_OK)
{
hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
1, &iid, &qiresults);
if (SUCCEEDED(hr))
{
hr = IStream_Write(pStm, &qiresults->std, sizeof(qiresults->std), NULL);
if (FAILED(hr))
{
REMINTERFACEREF rif;
rif.ipid = qiresults->std.ipid;
rif.cPublicRefs = qiresults->std.cPublicRefs;
rif.cPrivateRefs = 0;
IRemUnknown_RemRelease(remunk, 1, &rif);
}
CoTaskMemFree(qiresults);
}
else
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
}
}
return hr;
}
@@ -398,6 +474,72 @@ static const IMarshalVtbl ProxyMarshal_Vtbl =
StdMarshalImpl_DisconnectObject
};
static HRESULT WINAPI ProxyCliSec_QueryInterface(IClientSecurity *iface, REFIID riid, void **ppvObject)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblCliSec, iface);
return IMultiQI_QueryInterface((IMultiQI *)&This->lpVtbl, riid, ppvObject);
}
static ULONG WINAPI ProxyCliSec_AddRef(IClientSecurity *iface)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblCliSec, iface);
return IMultiQI_AddRef((IMultiQI *)&This->lpVtbl);
}
static ULONG WINAPI ProxyCliSec_Release(IClientSecurity *iface)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblCliSec, iface);
return IMultiQI_Release((IMultiQI *)&This->lpVtbl);
}
static HRESULT WINAPI ProxyCliSec_QueryBlanket(IClientSecurity *iface,
IUnknown *pProxy,
DWORD *pAuthnSvc,
DWORD *pAuthzSvc,
OLECHAR **pServerPrincName,
DWORD *pAuthnLevel,
DWORD *pImpLevel,
void **pAuthInfo,
DWORD *pCapabilities)
{
FIXME("(%p, %p, %p, %p, %p, %p, %p, %p): stub\n", pProxy, pAuthnSvc,
pAuthzSvc, pServerPrincName, pAuthnLevel, pImpLevel, pAuthInfo,
pCapabilities);
return E_NOTIMPL;
}
static HRESULT WINAPI ProxyCliSec_SetBlanket(IClientSecurity *iface,
IUnknown *pProxy, DWORD AuthnSvc,
DWORD AuthzSvc,
OLECHAR *pServerPrincName,
DWORD AuthnLevel, DWORD ImpLevel,
void *pAuthInfo,
DWORD Capabilities)
{
FIXME("(%p, %d, %d, %s, %d, %d, %p, 0x%x): stub\n", pProxy, AuthnSvc,
AuthzSvc, debugstr_w(pServerPrincName), AuthnLevel, ImpLevel,
pAuthInfo, Capabilities);
return E_NOTIMPL;
}
static HRESULT WINAPI ProxyCliSec_CopyProxy(IClientSecurity *iface,
IUnknown *pProxy, IUnknown **ppCopy)
{
FIXME("(%p, %p): stub\n", pProxy, ppCopy);
*ppCopy = NULL;
return E_NOTIMPL;
}
static const IClientSecurityVtbl ProxyCliSec_Vtbl =
{
ProxyCliSec_QueryInterface,
ProxyCliSec_AddRef,
ProxyCliSec_Release,
ProxyCliSec_QueryBlanket,
ProxyCliSec_SetBlanket,
ProxyCliSec_CopyProxy
};
static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
{
HRESULT hr = S_OK;
@@ -417,16 +559,16 @@ static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
hr = proxy_manager_get_remunknown(This->parent, &remunk);
if (hr == S_OK)
{
HRESULT hrref;
HRESULT hrref = S_OK;
REMINTERFACEREF rif;
rif.ipid = This->stdobjref.ipid;
rif.cPublicRefs = NORMALEXTREFS;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
if (hr == S_OK && hrref == S_OK)
This->refs += NORMALEXTREFS;
InterlockedExchangeAdd((LONG *)&This->refs, NORMALEXTREFS);
else
ERR("IRemUnknown_RemAddRef returned with 0x%08lx, hrref = 0x%08lx\n", hr, hrref);
ERR("IRemUnknown_RemAddRef returned with 0x%08x, hrref = 0x%08x\n", hr, hrref);
}
}
ReleaseMutex(This->parent->remoting_mutex);
@@ -437,6 +579,7 @@ static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
static HRESULT ifproxy_release_public_refs(struct ifproxy * This)
{
HRESULT hr = S_OK;
LONG public_refs;
if (WAIT_OBJECT_0 != WaitForSingleObject(This->parent->remoting_mutex, INFINITE))
{
@@ -444,29 +587,30 @@ static HRESULT ifproxy_release_public_refs(struct ifproxy * This)
return E_UNEXPECTED;
}
if (This->refs > 0)
public_refs = This->refs;
if (public_refs > 0)
{
IRemUnknown *remunk = NULL;
TRACE("releasing %ld refs\n", This->refs);
TRACE("releasing %d refs\n", public_refs);
hr = proxy_manager_get_remunknown(This->parent, &remunk);
if (hr == S_OK)
{
REMINTERFACEREF rif;
rif.ipid = This->stdobjref.ipid;
rif.cPublicRefs = This->refs;
rif.cPublicRefs = public_refs;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemRelease(remunk, 1, &rif);
if (hr == S_OK)
This->refs = 0;
InterlockedExchangeAdd((LONG *)&This->refs, -public_refs);
else if (hr == RPC_E_DISCONNECTED)
WARN("couldn't release references because object was "
"disconnected: oxid = %s, oid = %s\n",
wine_dbgstr_longlong(This->parent->oxid),
wine_dbgstr_longlong(This->parent->oid));
else
ERR("IRemUnknown_RemRelease failed with error 0x%08lx\n", hr);
ERR("IRemUnknown_RemRelease failed with error 0x%08x\n", hr);
}
}
ReleaseMutex(This->parent->remoting_mutex);
@@ -501,16 +645,14 @@ static void ifproxy_destroy(struct ifproxy * This)
This->chan = NULL;
}
/* note: we don't call Release for This->proxy because its lifetime is
* controlled by the return value from ClientIdentity_Release, which this
* function is always called from */
if (This->proxy) IRpcProxyBuffer_Release(This->proxy);
HeapFree(GetProcessHeap(), 0, This);
}
static HRESULT proxy_manager_construct(
APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid,
struct proxy_manager ** proxy_manager)
const OXID_INFO *oxid_info, struct proxy_manager ** proxy_manager)
{
struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This) return E_OUTOFMEMORY;
@@ -522,8 +664,28 @@ static HRESULT proxy_manager_construct(
return HRESULT_FROM_WIN32(GetLastError());
}
if (oxid_info)
{
This->oxid_info.dwPid = oxid_info->dwPid;
This->oxid_info.dwTid = oxid_info->dwTid;
This->oxid_info.ipidRemUnknown = oxid_info->ipidRemUnknown;
This->oxid_info.dwAuthnHint = oxid_info->dwAuthnHint;
This->oxid_info.psa = NULL /* FIXME: copy from oxid_info */;
}
else
{
HRESULT hr = RPC_ResolveOxid(oxid, &This->oxid_info);
if (FAILED(hr))
{
CloseHandle(This->remoting_mutex);
HeapFree(GetProcessHeap(), 0, This);
return hr;
}
}
This->lpVtbl = &ClientIdentity_Vtbl;
This->lpVtblMarshal = &ProxyMarshal_Vtbl;
This->lpVtblCliSec = &ProxyCliSec_Vtbl;
list_init(&This->entry);
list_init(&This->interfaces);
@@ -548,6 +710,11 @@ static HRESULT proxy_manager_construct(
/* we create the IRemUnknown proxy on demand */
This->remunk = NULL;
/* initialise these values to the weakest values and they will be
* overwritten in proxy_manager_set_context */
This->dest_context = MSHCTX_INPROC;
This->dest_context_data = NULL;
EnterCriticalSection(&apt->cs);
/* FIXME: we are dependent on the ordering in here to make sure a proxy's
* IRemUnknown proxy doesn't get destroyed before the regual proxy does
@@ -564,6 +731,63 @@ static HRESULT proxy_manager_construct(
return S_OK;
}
static inline void proxy_manager_set_context(struct proxy_manager *This, MSHCTX dest_context, void *dest_context_data)
{
MSHCTX old_dest_context = This->dest_context;
MSHCTX new_dest_context;
do
{
new_dest_context = old_dest_context;
/* "stronger" values overwrite "weaker" values. stronger values are
* ones that disable more optimisations */
switch (old_dest_context)
{
case MSHCTX_INPROC:
new_dest_context = dest_context;
break;
case MSHCTX_CROSSCTX:
switch (dest_context)
{
case MSHCTX_INPROC:
break;
default:
new_dest_context = dest_context;
}
break;
case MSHCTX_LOCAL:
switch (dest_context)
{
case MSHCTX_INPROC:
case MSHCTX_CROSSCTX:
break;
default:
new_dest_context = dest_context;
}
break;
case MSHCTX_NOSHAREDMEM:
switch (dest_context)
{
case MSHCTX_DIFFERENTMACHINE:
new_dest_context = dest_context;
break;
default:
break;
}
break;
default:
break;
}
if (old_dest_context == new_dest_context) break;
old_dest_context = InterlockedCompareExchange((PLONG)&This->dest_context, new_dest_context, old_dest_context);
} while (new_dest_context != old_dest_context);
if (dest_context_data)
InterlockedExchangePointer(&This->dest_context_data, dest_context_data);
}
static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This, REFIID riid, void ** ppv)
{
HRESULT hr;
@@ -586,9 +810,9 @@ static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This,
}
if (IsEqualIID(riid, &IID_IClientSecurity))
{
FIXME("requesting IClientSecurity, but it is unimplemented\n");
*ppv = NULL;
return E_NOINTERFACE;
*ppv = (void *)&This->lpVtblCliSec;
IUnknown_AddRef((IUnknown *)*ppv);
return S_OK;
}
hr = proxy_manager_find_ifproxy(This, riid, &ifproxy);
@@ -617,7 +841,7 @@ static HRESULT proxy_manager_create_ifproxy(
ifproxy->parent = This;
ifproxy->stdobjref = *stdobjref;
ifproxy->iid = *riid;
ifproxy->refs = stdobjref->cPublicRefs;
ifproxy->refs = 0;
ifproxy->proxy = NULL;
assert(channel);
@@ -644,21 +868,17 @@ static HRESULT proxy_manager_create_ifproxy(
&ifproxy->proxy, &ifproxy->iface);
IPSFactoryBuffer_Release(psfb);
if (hr != S_OK)
ERR("Could not create proxy for interface %s, error 0x%08lx\n",
ERR("Could not create proxy for interface %s, error 0x%08x\n",
debugstr_guid(riid), hr);
}
else
ERR("Could not get IPSFactoryBuffer for interface %s, error 0x%08lx\n",
ERR("Could not get IPSFactoryBuffer for interface %s, error 0x%08x\n",
debugstr_guid(riid), hr);
if (hr == S_OK)
hr = IRpcProxyBuffer_Connect(ifproxy->proxy, ifproxy->chan);
}
/* get at least one external reference to the object to keep it alive */
if (hr == S_OK)
hr = ifproxy_get_public_ref(ifproxy);
if (hr == S_OK)
{
EnterCriticalSection(&This->cs);
@@ -751,23 +971,18 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
stdobjref.oxid = This->oxid;
/* FIXME: what should be used for the oid? The DCOM draft doesn't say */
stdobjref.oid = (OID)-1;
/* FIXME: this is a hack around not having an OXID resolver yet -
* the OXID resolver should give us the IPID of the IRemUnknown
* interface */
stdobjref.ipid.Data1 = 0xffffffff;
stdobjref.ipid.Data2 = 0xffff;
stdobjref.ipid.Data3 = 0xffff;
assert(sizeof(stdobjref.ipid.Data4) == sizeof(stdobjref.oxid));
memcpy(&stdobjref.ipid.Data4, &stdobjref.oxid, sizeof(OXID));
stdobjref.ipid = This->oxid_info.ipidRemUnknown;
/* do the unmarshal */
hr = unmarshal_object(&stdobjref, This->parent, &IID_IRemUnknown, (void**)&This->remunk);
hr = unmarshal_object(&stdobjref, This->parent, This->dest_context,
This->dest_context_data, &IID_IRemUnknown,
&This->oxid_info, (void**)&This->remunk);
if (hr == S_OK)
*remunk = This->remunk;
}
LeaveCriticalSection(&This->cs);
TRACE("got IRemUnknown* pointer %p, hr = 0x%08lx\n", *remunk, hr);
TRACE("got IRemUnknown* pointer %p, hr = 0x%08x\n", *remunk, hr);
return hr;
}
@@ -808,6 +1023,7 @@ static void proxy_manager_destroy(struct proxy_manager * This)
}
if (This->remunk) IRemUnknown_Release(This->remunk);
CoTaskMemFree(This->oxid_info.psa);
DEBUG_CLEAR_CRITSEC_NAME(&This->cs);
DeleteCriticalSection(&This->cs);
@@ -939,7 +1155,7 @@ StdMarshalImpl_MarshalInterface(
hres = marshal_object(apt, &stdobjref, riid, (IUnknown *)pv, mshlflags);
if (hres)
{
ERR("Failed to create ifstub, hres=0x%lx\n", hres);
ERR("Failed to create ifstub, hres=0x%x\n", hres);
return hres;
}
@@ -952,7 +1168,10 @@ StdMarshalImpl_MarshalInterface(
/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
* no questions asked about the rules surrounding same-apartment unmarshals
* and table marshaling */
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFIID riid, void **object)
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
MSHCTX dest_context, void *dest_context_data,
REFIID riid, const OXID_INFO *oxid_info,
void **object)
{
struct proxy_manager *proxy_manager = NULL;
HRESULT hr = S_OK;
@@ -965,12 +1184,12 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
wine_dbgstr_longlong(stdobjref->oid),
debugstr_guid(&stdobjref->ipid));
/* create an a new proxy manager if one doesn't already exist for the
/* create a new proxy manager if one doesn't already exist for the
* object */
if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
{
hr = proxy_manager_construct(apt, stdobjref->flags,
stdobjref->oxid, stdobjref->oid,
stdobjref->oxid, stdobjref->oid, oxid_info,
&proxy_manager);
}
else
@@ -979,11 +1198,18 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
if (hr == S_OK)
{
struct ifproxy * ifproxy;
proxy_manager_set_context(proxy_manager, dest_context, dest_context_data);
hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
if (hr == E_NOINTERFACE)
{
IRpcChannelBuffer *chanbuf;
hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, &chanbuf);
hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid,
&proxy_manager->oxid_info,
proxy_manager->dest_context,
proxy_manager->dest_context_data,
&chanbuf);
if (hr == S_OK)
hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref,
riid, chanbuf, &ifproxy);
@@ -991,6 +1217,15 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
else
IUnknown_AddRef((IUnknown *)ifproxy->iface);
if (hr == S_OK)
{
InterlockedExchangeAdd((LONG *)&ifproxy->refs, stdobjref->cPublicRefs);
/* get at least one external reference to the object to keep it alive */
hr = ifproxy_get_public_ref(ifproxy);
if (FAILED(hr))
ifproxy_destroy(ifproxy);
}
if (hr == S_OK)
*object = ifproxy->iface;
}
@@ -1005,7 +1240,8 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
static HRESULT WINAPI
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
{
struct stub_manager *stubmgr;
StdMarshalImpl *This = (StdMarshalImpl *)iface;
struct stub_manager *stubmgr = NULL;
STDOBJREF stdobjref;
ULONG res;
HRESULT hres;
@@ -1039,7 +1275,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
/* unref the ifstub. FIXME: only do this on success? */
if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid))
stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs);
stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, TRUE);
stub_manager_int_release(stubmgr);
return hres;
@@ -1056,8 +1292,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
{
if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
hres = CO_E_OBJNOTCONNECTED;
stub_manager_int_release(stubmgr);
}
else
{
@@ -1066,17 +1300,20 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
wine_dbgstr_longlong(stdobjref.oid));
hres = CO_E_OBJNOTCONNECTED;
}
apartment_release(stub_apt);
}
else
TRACE("Treating unmarshal from OXID %s as inter-process\n",
wine_dbgstr_longlong(stdobjref.oxid));
if (hres == S_OK)
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
hres = unmarshal_object(&stdobjref, apt, This->dwDestContext,
This->pvDestContext, riid,
stubmgr ? &stubmgr->oxid_info : NULL, ppv);
if (hres) WARN("Failed with error 0x%08lx\n", hres);
if (stubmgr) stub_manager_int_release(stubmgr);
if (stub_apt) apartment_release(stub_apt);
if (hres) WARN("Failed with error 0x%08x\n", hres);
else TRACE("Successfully created proxy %p\n", *ppv);
return hres;
@@ -1185,11 +1422,11 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk,
if (pUnk == NULL)
{
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
FIXME("(%s,NULL,%x,%p,%x,%p), unimplemented yet.\n",
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal);
return E_NOTIMPL;
}
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
TRACE("(%s,%p,%x,%p,%x,%p)\n",
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal);
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
dm = (StdMarshalImpl*) *ppMarshal;
@@ -1241,7 +1478,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
if (hr || (res != FIELD_OFFSET(OBJREF, u_objref)))
{
ERR("Failed to read common OBJREF header, 0x%08lx\n", hr);
ERR("Failed to read common OBJREF header, 0x%08x\n", hr);
return STG_E_READFAULT;
}
@@ -1270,7 +1507,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
custom_header_size, &res);
if (hr || (res != custom_header_size))
{
ERR("Failed to read OR_CUSTOM header, 0x%08lx\n", hr);
ERR("Failed to read OR_CUSTOM header, 0x%08x\n", hr);
return STG_E_READFAULT;
}
/* now create the marshaler specified in the stream */
@@ -1286,7 +1523,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
}
if (hr)
ERR("Failed to create marshal, 0x%08lx\n", hr);
ERR("Failed to create marshal, 0x%08x\n", hr);
return hr;
}
@@ -1327,20 +1564,20 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
pvDestContext, mshlFlags, &marshaler_clsid);
if (hr)
{
ERR("IMarshal::GetUnmarshalClass failed, 0x%08lx\n", hr);
ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr);
IMarshal_Release(pMarshal);
return hr;
}
hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags, pulSize);
/* add on the size of the common header */
*pulSize += FIELD_OFFSET(OBJREF, u_objref);
/* if custom marshaling, add on size of custom header */
if (!IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
*pulSize += FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
FIELD_OFFSET(OBJREF, u_objref.u_custom);
if (IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
/* add on the size of the common header */
*pulSize += FIELD_OFFSET(OBJREF, u_objref);
else
/* custom marshaling: add on the size of the whole OBJREF structure
* like native does */
*pulSize += sizeof(OBJREF);
IMarshal_Release(pMarshal);
return hr;
@@ -1400,12 +1637,12 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
OBJREF objref;
LPMARSHAL pMarshal;
TRACE("(%p, %s, %p, %lx, %p,", pStream, debugstr_guid(riid), pUnk,
TRACE("(%p, %s, %p, %x, %p,", pStream, debugstr_guid(riid), pUnk,
dwDestContext, pvDestContext);
dump_MSHLFLAGS(mshlFlags);
TRACE(")\n");
if (pUnk == NULL)
if (!pUnk || !pStream)
return E_INVALIDARG;
objref.signature = OBJREF_SIGNATURE;
@@ -1415,7 +1652,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal);
if (hr)
{
ERR("Failed to get marshaller, 0x%08lx\n", hr);
ERR("Failed to get marshaller, 0x%08x\n", hr);
return hr;
}
@@ -1423,7 +1660,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
pvDestContext, mshlFlags, &marshaler_clsid);
if (hr)
{
ERR("IMarshal::GetUnmarshalClass failed, 0x%08lx\n", hr);
ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr);
goto cleanup;
}
@@ -1437,7 +1674,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL);
if (hr)
{
ERR("Failed to write OBJREF header to stream, 0x%08lx\n", hr);
ERR("Failed to write OBJREF header to stream, 0x%08x\n", hr);
goto cleanup;
}
}
@@ -1453,7 +1690,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
&objref.u_objref.u_custom.size);
if (hr)
{
ERR("Failed to get max size of marshal data, error 0x%08lx\n", hr);
ERR("Failed to get max size of marshal data, error 0x%08x\n", hr);
goto cleanup;
}
/* write constant sized common header and OR_CUSTOM data into stream */
@@ -1461,7 +1698,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL);
if (hr)
{
ERR("Failed to write OR_CUSTOM header to stream with 0x%08lx\n", hr);
ERR("Failed to write OR_CUSTOM header to stream with 0x%08x\n", hr);
goto cleanup;
}
}
@@ -1473,14 +1710,14 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
if (hr)
{
ERR("Failed to marshal the interface %s, %lx\n", debugstr_guid(riid), hr);
ERR("Failed to marshal the interface %s, %x\n", debugstr_guid(riid), hr);
goto cleanup;
}
cleanup:
IMarshal_Release(pMarshal);
TRACE("completed with hr 0x%08lx\n", hr);
TRACE("completed with hr 0x%08x\n", hr);
return hr;
}
@@ -1514,6 +1751,9 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
TRACE("(%p, %s, %p)\n", pStream, debugstr_guid(riid), ppv);
if (!pStream || !ppv)
return E_INVALIDARG;
hr = get_unmarshaler_from_stream(pStream, &pMarshal, &iid);
if (hr != S_OK)
return hr;
@@ -1521,20 +1761,17 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
/* call the helper object to do the actual unmarshaling */
hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object);
if (hr)
ERR("IMarshal::UnmarshalInterface failed, 0x%08lx\n", hr);
/* IID_NULL means use the interface ID of the marshaled object */
if (!IsEqualIID(riid, &IID_NULL))
iid = *riid;
ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr);
if (hr == S_OK)
{
if (!IsEqualIID(riid, &iid))
/* IID_NULL means use the interface ID of the marshaled object */
if (!IsEqualIID(riid, &IID_NULL) && !IsEqualIID(riid, &iid))
{
TRACE("requested interface != marshalled interface, additional QI needed\n");
hr = IUnknown_QueryInterface(object, &iid, ppv);
hr = IUnknown_QueryInterface(object, riid, ppv);
if (hr)
ERR("Couldn't query for interface %s, hr = 0x%08lx\n",
ERR("Couldn't query for interface %s, hr = 0x%08x\n",
debugstr_guid(riid), hr);
IUnknown_Release(object);
}
@@ -1546,7 +1783,7 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
IMarshal_Release(pMarshal);
TRACE("completed with hr 0x%lx\n", hr);
TRACE("completed with hr 0x%x\n", hr);
return hr;
}
@@ -1588,7 +1825,7 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
/* call the helper object to do the releasing of marshal data */
hr = IMarshal_ReleaseMarshalData(pMarshal, pStream);
if (hr)
ERR("IMarshal::ReleaseMarshalData failed with error 0x%08lx\n", hr);
ERR("IMarshal::ReleaseMarshalData failed with error 0x%08x\n", hr);
IMarshal_Release(pMarshal);
return hr;
@@ -1603,7 +1840,7 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
* 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.
* ppStm [O] Pointer to IStream object that is created and then used to store the marshalled interface.
*
* RETURNS
* Success: S_OK
@@ -1628,7 +1865,7 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(
if (SUCCEEDED(hres))
{
memset(&seekto, 0, sizeof(seekto));
IStream_Seek(*ppStm, seekto, SEEK_SET, &xpos);
IStream_Seek(*ppStm, seekto, STREAM_SEEK_SET, &xpos);
}
else
{
@@ -1642,10 +1879,10 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(
/***********************************************************************
* CoGetInterfaceAndReleaseStream [OLE32.@]
*
* Unmarshalls an inteface from a stream and then releases the stream.
* Unmarshalls an interface from a stream and then releases the stream.
*
* PARAMS
* pStm [I] Stream that contains the marshalled inteface.
* pStm [I] Stream that contains the marshalled interface.
* riid [I] Interface identifier of the object to unmarshall.
* ppv [O] Address of pointer where the requested interface object will be stored.
*
@@ -1654,7 +1891,7 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(
* Failure: A COM error code
*
* SEE ALSO
* CoMarshalInterThreadInterfaceInStream() and CoUnmarshalInteface()
* CoMarshalInterThreadInterfaceInStream() and CoUnmarshalInterface()
*/
HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid,
LPVOID *ppv)
@@ -1663,6 +1900,7 @@ HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid,
TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
if(!pStm) return E_INVALIDARG;
hres = CoUnmarshalInterface(pStm, riid, ppv);
IStream_Release(pStm);
return hres;
+43 -91
View File
@@ -16,7 +16,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -43,7 +43,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
/******************************************************************************
* HGLOBALLockBytesImpl definition.
*
* This class imlements the ILockBytes inteface and represents a byte array
* This class implements the ILockBytes interface and represents a byte array
* object supported by an HGLOBAL pointer.
*/
struct HGLOBALLockBytesImpl
@@ -81,77 +81,15 @@ typedef struct HGLOBALLockBytesImpl HGLOBALLockBytesImpl;
/*
* Method definition for the HGLOBALLockBytesImpl class.
*/
HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(
static HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease);
void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This);
static void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This);
HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
ILockBytes* iface,
REFIID riid, /* [in] */
void** ppvObject); /* [iid_is][out] */
static HRESULT WINAPI HGLOBALLockBytesImpl_SetSize( ILockBytes* iface, ULARGE_INTEGER libNewSize );
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 const ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl =
{
HGLOBALLockBytesImpl_QueryInterface,
HGLOBALLockBytesImpl_AddRef,
HGLOBALLockBytesImpl_Release,
HGLOBALLockBytesImpl_ReadAt,
HGLOBALLockBytesImpl_WriteAt,
HGLOBALLockBytesImpl_Flush,
HGLOBALLockBytesImpl_SetSize,
HGLOBALLockBytesImpl_LockRegion,
HGLOBALLockBytesImpl_UnlockRegion,
HGLOBALLockBytesImpl_Stat,
};
static const ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl;
/******************************************************************************
* CreateILockBytesOnHGlobal [OLE32.@]
@@ -224,10 +162,10 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
/* 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);
ERR("Cannot ILockBytes_Stat, %x\n",hres);
return hres;
}
FIXME("cbSize is %ld\n",stbuf.cbSize.u.LowPart);
FIXME("cbSize is %d\n",stbuf.cbSize.u.LowPart);
*phglobal = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, stbuf.cbSize.u.LowPart);
if (!*phglobal)
return E_INVALIDARG;
@@ -235,11 +173,11 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
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);
FIXME("%p->ReadAt failed with %x\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);
FIXME("Read size is not requested size %d vs %d?\n",stbuf.cbSize.u.LowPart, xread);
}
return S_OK;
}
@@ -258,8 +196,8 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
* fDeleteOnRelease [ I] Flag set to TRUE if the HGLOBAL will be released
* when the IStream object is destroyed.
*/
HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
static HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
{
HGLOBALLockBytesImpl* newLockBytes;
newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl));
@@ -306,7 +244,7 @@ HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
* HGLOBALLockBytesImpl class. The pointer passed-in to this function will be
* freed and will not be valid anymore.
*/
void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
static void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
{
/*
* Release the HGlobal if the constructor asked for that.
@@ -327,7 +265,7 @@ void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
* This implements the IUnknown method QueryInterface for this
* class
*/
HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
static HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
ILockBytes* iface,
REFIID riid, /* [in] */
void** ppvObject) /* [iid_is][out] */
@@ -348,11 +286,8 @@ HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
/*
* 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)
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_ILockBytes))
{
*ppvObject = (ILockBytes*)This;
}
@@ -367,7 +302,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
* Query Interface always increases the reference count by one when it is
* successful
*/
HGLOBALLockBytesImpl_AddRef(iface);
IUnknown_AddRef(iface);
return S_OK;
}
@@ -376,7 +311,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
* This implements the IUnknown method AddRef for this
* class
*/
ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
static ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
{
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
return InterlockedIncrement(&This->ref);
@@ -386,7 +321,7 @@ ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
* This implements the IUnknown method Release for this
* class
*/
ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
static ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
{
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
ULONG ref;
@@ -412,7 +347,7 @@ ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
static HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [length_is][size_is][out] */
@@ -484,7 +419,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
static HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [size_is][in] */
@@ -549,7 +484,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface)
static HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface)
{
return S_OK;
}
@@ -561,7 +496,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
static HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
ILockBytes* iface,
ULARGE_INTEGER libNewSize) /* [in] */
{
@@ -598,7 +533,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
static HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
ILockBytes* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@@ -614,7 +549,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
static HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
ILockBytes* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@@ -631,7 +566,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
static HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
ILockBytes* iface,
STATSTG* pstatstg, /* [out] */
DWORD grfStatFlag) /* [in] */
@@ -646,3 +581,20 @@ HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
return S_OK;
}
/*
* Virtual function table for the HGLOBALLockBytesImpl class.
*/
static const ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl =
{
HGLOBALLockBytesImpl_QueryInterface,
HGLOBALLockBytesImpl_AddRef,
HGLOBALLockBytesImpl_Release,
HGLOBALLockBytesImpl_ReadAt,
HGLOBALLockBytesImpl_WriteAt,
HGLOBALLockBytesImpl_Flush,
HGLOBALLockBytesImpl_SetSize,
HGLOBALLockBytesImpl_LockRegion,
HGLOBALLockBytesImpl_UnlockRegion,
HGLOBALLockBytesImpl_Stat,
};
+15 -15
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -43,7 +43,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
/******************************************************************************
* HGLOBALLockBytesImpl16 definition.
*
* This class imlements the ILockBytes inteface and represents a byte array
* This class implements the ILockBytes interface and represents a byte array
* object supported by an HGLOBAL pointer.
*/
struct HGLOBALLockBytesImpl16
@@ -174,7 +174,7 @@ static void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This)
* This implements the IUnknown method AddRef for this
* class
*/
ULONG HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
ULONG CDECL HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
{
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
@@ -188,7 +188,7 @@ ULONG HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
* This implements the IUnknown method QueryInterface for this
* class
*/
HRESULT HGLOBALLockBytesImpl16_QueryInterface(
HRESULT CDECL HGLOBALLockBytesImpl16_QueryInterface(
ILockBytes16* iface, /* [in] SEGPTR */
REFIID riid, /* [in] */
void** ppvObject) /* [out][iid_is] (ptr to SEGPTR!) */
@@ -235,7 +235,7 @@ HRESULT HGLOBALLockBytesImpl16_QueryInterface(
* This implements the IUnknown method Release for this
* class
*/
ULONG HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
ULONG CDECL HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
{
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
ULONG ref;
@@ -260,7 +260,7 @@ ULONG HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_ReadAt(
HRESULT CDECL HGLOBALLockBytesImpl16_ReadAt(
ILockBytes16* iface,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [out][length_is][size_is] */
@@ -273,7 +273,7 @@ HRESULT HGLOBALLockBytesImpl16_ReadAt(
ULONG bytesReadBuffer = 0;
ULONG bytesToReadFromBuffer;
TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbRead);
TRACE("(%p,%d,%p,%d,%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.
@@ -332,14 +332,14 @@ HRESULT HGLOBALLockBytesImpl16_ReadAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_SetSize(
HRESULT CDECL HGLOBALLockBytesImpl16_SetSize(
ILockBytes16* iface,
ULARGE_INTEGER libNewSize) /* [in] */
{
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
HGLOBAL16 supportHandle;
TRACE("(%p,%ld)\n",This,libNewSize.u.LowPart);
TRACE("(%p,%d)\n",This,libNewSize.u.LowPart);
/*
* As documented.
*/
@@ -371,7 +371,7 @@ HRESULT HGLOBALLockBytesImpl16_SetSize(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_WriteAt(
HRESULT CDECL HGLOBALLockBytesImpl16_WriteAt(
ILockBytes16* iface,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [in][size_is] */
@@ -384,7 +384,7 @@ HRESULT HGLOBALLockBytesImpl16_WriteAt(
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbWritten);
TRACE("(%p,%d,%p,%d,%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.
@@ -433,7 +433,7 @@ HRESULT HGLOBALLockBytesImpl16_WriteAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
HRESULT CDECL HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
{
TRACE("(%p)\n",iface);
return S_OK;
@@ -446,7 +446,7 @@ HRESULT HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_LockRegion(
HRESULT CDECL HGLOBALLockBytesImpl16_LockRegion(
ILockBytes16* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@@ -462,7 +462,7 @@ HRESULT HGLOBALLockBytesImpl16_LockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_UnlockRegion(
HRESULT CDECL HGLOBALLockBytesImpl16_UnlockRegion(
ILockBytes16* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@@ -479,7 +479,7 @@ HRESULT HGLOBALLockBytesImpl16_UnlockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_Stat(
HRESULT CDECL HGLOBALLockBytesImpl16_Stat(
ILockBytes16*iface,
STATSTG16* pstatstg, /* [out] */
DWORD grfStatFlag) /* [in] */
+392 -101
View File
@@ -4,6 +4,7 @@
* Copyright 1998 Marcus Meissner
* Copyright 1999 Noomen Hamza
* Copyright 2005 Robert Shearman (for CodeWeavers)
* Copyright 2007 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +18,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* TODO:
* - IRunningObjectTable should work interprocess, but currently doesn't.
@@ -40,11 +41,17 @@
#include "wine/list.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "compobj_private.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* see MSDN docs for IROTData::GetComparisonData, which states what this
* constant is (http://msdn2.microsoft.com/en-us/library/ms693773.aspx) */
#define MAX_COMPARISON_DATA 2048
/* define the structure of the running object table elements */
struct rot_entry
{
@@ -139,26 +146,77 @@ static HRESULT get_moniker_comparison_data(IMoniker *pMoniker, MInterfacePointer
{
HRESULT hr;
IROTData *pROTData = NULL;
ULONG size = 0;
hr = IMoniker_QueryInterface(pMoniker, &IID_IROTData, (void *)&pROTData);
if (hr != S_OK)
if (SUCCEEDED(hr))
{
ERR("Failed to query moniker for IROTData interface, hr = 0x%08lx\n", hr);
return hr;
ULONG size = MAX_COMPARISON_DATA;
*moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer, abData[size]));
hr = IROTData_GetComparisonData(pROTData, (*moniker_data)->abData, size, &size);
if (hr != S_OK)
{
ERR("Failed to copy comparison data into buffer, hr = 0x%08x\n", hr);
HeapFree(GetProcessHeap(), 0, *moniker_data);
return hr;
}
(*moniker_data)->ulCntData = size;
}
IROTData_GetComparisonData(pROTData, NULL, 0, &size);
*moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer, abData[size]));
(*moniker_data)->ulCntData = size;
hr = IROTData_GetComparisonData(pROTData, (*moniker_data)->abData, size, &size);
if (hr != S_OK)
else
{
ERR("Failed to copy comparison data into buffer, hr = 0x%08lx\n", hr);
HeapFree(GetProcessHeap(), 0, *moniker_data);
return hr;
IBindCtx *pbc;
LPOLESTR pszDisplayName;
CLSID clsid;
int len;
TRACE("generating comparison data from display name\n");
hr = CreateBindCtx(0, &pbc);
if (FAILED(hr))
return hr;
hr = IMoniker_GetDisplayName(pMoniker, pbc, NULL, &pszDisplayName);
IBindCtx_Release(pbc);
if (FAILED(hr))
return hr;
hr = IMoniker_GetClassID(pMoniker, &clsid);
if (FAILED(hr))
{
CoTaskMemFree(pszDisplayName);
return hr;
}
len = strlenW(pszDisplayName);
*moniker_data = HeapAlloc(GetProcessHeap(), 0,
FIELD_OFFSET(MInterfacePointer, abData[sizeof(CLSID) + (len+1)*sizeof(WCHAR)]));
if (!*moniker_data)
{
CoTaskMemFree(pszDisplayName);
return E_OUTOFMEMORY;
}
(*moniker_data)->ulCntData = sizeof(CLSID) + (len+1)*sizeof(WCHAR);
memcpy(&(*moniker_data)->abData[0], &clsid, sizeof(clsid));
memcpy(&(*moniker_data)->abData[sizeof(clsid)], pszDisplayName, (len+1)*sizeof(WCHAR));
}
return S_OK;
}
static HRESULT reduce_moniker(IMoniker *pmk, IBindCtx *pbc, IMoniker **pmkReduced)
{
IBindCtx *pbcNew = NULL;
HRESULT hr;
if (!pbc)
{
hr = CreateBindCtx(0, &pbcNew);
if (FAILED(hr))
return hr;
pbc = pbcNew;
}
hr = IMoniker_Reduce(pmk, pbc, MKRREDUCE_ALL, NULL, pmkReduced);
if (FAILED(hr))
ERR("reducing moniker failed with error 0x%08x\n", hr);
if (pbcNew) IBindCtx_Release(pbcNew);
return hr;
}
/***********************************************************************
* RunningObjectTable_QueryInterface
*/
@@ -223,6 +281,9 @@ RunningObjectTableImpl_Destroy(void)
rot_entry_delete(rot_entry);
}
DEBUG_CLEAR_CRITSEC_NAME(&runningObjectTableInstance->lock);
DeleteCriticalSection(&runningObjectTableInstance->lock);
/* free the ROT structure memory */
HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
runningObjectTableInstance = NULL;
@@ -279,18 +340,13 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
HRESULT hr = S_OK;
IStream *pStream = NULL;
DWORD mshlflags;
IBindCtx *pbc;
TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
TRACE("(%p,%d,%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) )
if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
{
ERR("Invalid combination of ROTFLAGS: %lx\n", grfFlags);
ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
return E_INVALIDARG;
}
@@ -301,8 +357,6 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
if (!rot_entry)
return E_OUTOFMEMORY;
CoFileTimeNow(&rot_entry->last_modified);
/* marshal object */
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
if (hr != S_OK)
@@ -335,10 +389,36 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
return hr;
}
hr = get_moniker_comparison_data(pmkObjectName, &rot_entry->moniker_data);
hr = CreateBindCtx(0, &pbc);
if (FAILED(hr))
{
rot_entry_delete(rot_entry);
return hr;
}
hr = reduce_moniker(pmkObjectName, pbc, &pmkObjectName);
if (FAILED(hr))
{
rot_entry_delete(rot_entry);
IBindCtx_Release(pbc);
return hr;
}
hr = IMoniker_GetTimeOfLastChange(pmkObjectName, pbc, NULL,
&rot_entry->last_modified);
IBindCtx_Release(pbc);
if (FAILED(hr))
{
CoFileTimeNow(&rot_entry->last_modified);
hr = S_OK;
}
hr = get_moniker_comparison_data(pmkObjectName,
&rot_entry->moniker_data);
if (hr != S_OK)
{
rot_entry_delete(rot_entry);
IMoniker_Release(pmkObjectName);
return hr;
}
@@ -346,10 +426,12 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
if (hr != S_OK)
{
rot_entry_delete(rot_entry);
IMoniker_Release(pmkObjectName);
return hr;
}
/* marshal moniker */
hr = CoMarshalInterface(pStream, &IID_IMoniker, (IUnknown *)pmkObjectName, MSHCTX_LOCAL | MSHCTX_NOSHAREDMEM, NULL, MSHLFLAGS_TABLESTRONG);
hr = CoMarshalInterface(pStream, &IID_IMoniker, (IUnknown *)pmkObjectName,
MSHCTX_LOCAL | MSHCTX_NOSHAREDMEM, NULL, MSHLFLAGS_TABLESTRONG);
/* FIXME: a cleaner way would be to create an IStream class that writes
* directly to an MInterfacePointer */
if (hr == S_OK)
@@ -367,6 +449,7 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
}
}
IStream_Release(pStream);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
{
rot_entry_delete(rot_entry);
@@ -404,7 +487,7 @@ RunningObjectTableImpl_Revoke( IRunningObjectTable* iface, DWORD dwRegister)
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
struct rot_entry *rot_entry;
TRACE("(%p,%ld)\n",This,dwRegister);
TRACE("(%p,%d)\n",This,dwRegister);
EnterCriticalSection(&This->lock);
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
@@ -439,7 +522,11 @@ RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface, IMoniker *pmkObjec
TRACE("(%p,%p)\n",This,pmkObjectName);
hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
if (FAILED(hr))
return hr;
hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
return hr;
@@ -448,7 +535,7 @@ RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface, IMoniker *pmkObjec
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(moniker_data, rot_entry->moniker_data, moniker_data->ulCntData))
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
hr = S_OK;
break;
@@ -486,7 +573,11 @@ RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
*ppunkObject = NULL;
hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
if (FAILED(hr))
return hr;
hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
return hr;
@@ -494,7 +585,7 @@ RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(moniker_data, rot_entry->moniker_data, moniker_data->ulCntData))
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
IStream *pStream;
hr = create_stream_on_mip_ro(rot_entry->object, &pStream);
@@ -535,7 +626,7 @@ RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
struct rot_entry *rot_entry;
TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
TRACE("(%p,%d,%p)\n",This,dwRegister,pfiletime);
EnterCriticalSection(&This->lock);
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
@@ -575,7 +666,11 @@ RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
if (pmkObjectName==NULL || pfiletime==NULL)
return E_INVALIDARG;
hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
if (FAILED(hr))
return hr;
hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
return hr;
@@ -585,7 +680,7 @@ RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(moniker_data, rot_entry->moniker_data, moniker_data->ulCntData))
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
*pfiletime = rot_entry->last_modified;
hr = S_OK;
@@ -641,70 +736,6 @@ RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
return hr;
}
/***********************************************************************
* 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 = IRunningObjectTable_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;
}
/* Virtual function table for the IRunningObjectTable class. */
static const IRunningObjectTableVtbl VT_RunningObjectTableImpl =
{
@@ -743,6 +774,7 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void)
list_init(&runningObjectTableInstance->rot);
InitializeCriticalSection(&runningObjectTableInstance->lock);
DEBUG_SET_CRITSEC_NAME(&runningObjectTableInstance->lock, "RunningObjectTableImpl.lock");
return S_OK;
}
@@ -750,7 +782,7 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void)
/***********************************************************************
* RunningObjectTable_UnInitialize
*/
HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void)
{
TRACE("\n");
@@ -764,6 +796,265 @@ HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
return S_OK;
}
/***********************************************************************
* GetRunningObjectTable (OLE32.@)
*
* Retrieves the global running object table.
*
* PARAMS
* reserved [I] Reserved. Set to 0.
* pprot [O] Address that receives the pointer to the running object table.
*
* RETURNS
* Success: S_OK.
* Failure: Any HRESULT code.
*/
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 = IRunningObjectTable_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
return res;
}
static HRESULT get_moniker_for_progid_display_name(LPBC pbc,
LPCOLESTR szDisplayName,
LPDWORD pchEaten,
LPMONIKER *ppmk)
{
CLSID clsid;
HRESULT hr;
LPWSTR progid;
LPCWSTR start = szDisplayName;
LPCWSTR end;
int len;
IMoniker *class_moniker;
if (*start == '@')
start++;
/* find end delimiter */
for (end = start; *end; end++)
if (*end == ':')
break;
len = end - start;
/* must start with '@' or have a ':' somewhere and mustn't be one character
* long (since that looks like an absolute path) */
if (((start == szDisplayName) && (*end == '\0')) || (len <= 1))
return MK_E_SYNTAX;
progid = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (progid)
{
memcpy(progid, start, len * sizeof(WCHAR));
progid[len] = '\0';
}
hr = CLSIDFromProgID(progid, &clsid);
HeapFree(GetProcessHeap(), 0, progid);
if (FAILED(hr))
return MK_E_SYNTAX;
hr = CreateClassMoniker(&clsid, &class_moniker);
if (SUCCEEDED(hr))
{
IParseDisplayName *pdn;
hr = IMoniker_BindToObject(class_moniker, pbc, NULL,
&IID_IParseDisplayName, (void **)&pdn);
IMoniker_Release(class_moniker);
if (SUCCEEDED(hr))
{
hr = IParseDisplayName_ParseDisplayName(pdn, pbc,
(LPOLESTR)szDisplayName,
pchEaten, ppmk);
IParseDisplayName_Release(pdn);
}
}
return hr;
}
/******************************************************************************
* MkParseDisplayName [OLE32.@]
*/
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
HRESULT hr = MK_E_SYNTAX;
static const WCHAR wszClsidColon[] = {'c','l','s','i','d',':'};
IMoniker *moniker;
DWORD chEaten;
TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk);
if (!(IsValidInterface((LPUNKNOWN) pbc)))
return E_INVALIDARG;
*pchEaten = 0;
*ppmk = NULL;
if (!strncmpiW(szDisplayName, wszClsidColon, sizeof(wszClsidColon)/sizeof(wszClsidColon[0])))
{
hr = ClassMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker);
if (FAILED(hr) && (hr != MK_E_SYNTAX))
return hr;
}
else
{
hr = get_moniker_for_progid_display_name(pbc, szDisplayName, &chEaten, &moniker);
if (FAILED(hr) && (hr != MK_E_SYNTAX))
return hr;
}
if (FAILED(hr))
{
hr = FileMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker);
if (FAILED(hr) && (hr != MK_E_SYNTAX))
return hr;
}
if (SUCCEEDED(hr))
{
while (TRUE)
{
IMoniker *next_moniker;
*pchEaten += chEaten;
szDisplayName += chEaten;
if (!*szDisplayName)
{
*ppmk = moniker;
return S_OK;
}
chEaten = 0;
hr = IMoniker_ParseDisplayName(moniker, pbc, NULL,
(LPOLESTR)szDisplayName, &chEaten,
&next_moniker);
IMoniker_Release(moniker);
if (FAILED(hr))
{
*pchEaten = 0;
break;
}
moniker = next_moniker;
}
}
return hr;
}
/***********************************************************************
* GetClassFile (OLE32.@)
*
* Retrieves the class ID associated with the given filename.
*
* PARAMS
* filePathName [I] Filename to retrieve the class ID for.
* pclsid [O] Address that receives the class ID for the file.
*
* RETURNS
* Success: S_OK.
* Failure: Any HRESULT code.
*/
HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid)
{
IStorage *pstg=0;
HRESULT res;
int nbElm, length, i;
LONG sizeProgId;
LPOLESTR *pathDec=0,absFile=0,progId=0;
LPWSTR extension;
static const WCHAR bkslashW[] = {'\\',0};
static const WCHAR dotW[] = {'.',0};
TRACE("%s, %p\n", debugstr_w(filePathName), pclsid);
/* if the file contain a storage object the return the CLSID written by IStorage_SetClass method*/
if((StgIsStorageFile(filePathName))==S_OK){
res=StgOpenStorage(filePathName,NULL,STGM_READ | STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
if (SUCCEEDED(res))
res=ReadClassStg(pstg,pclsid);
IStorage_Release(pstg);
return res;
}
/* if the file is not a storage object then attemps to match various bits in the file against a
pattern in the registry. this case is not frequently used ! so I present only the psodocode for
this case
for(i=0;i<nFileTypes;i++)
for(i=0;j<nPatternsForType;j++){
PATTERN pat;
HANDLE hFile;
pat=ReadPatternFromRegistry(i,j);
hFile=CreateFileW(filePathName,,,,,,hFile);
SetFilePosition(hFile,pat.offset);
ReadFile(hFile,buf,pat.size,&r,NULL);
if (memcmp(buf&pat.mask,pat.pattern.pat.size)==0){
*pclsid=ReadCLSIDFromRegistry(i);
return S_OK;
}
}
*/
/* if the above strategies fail then search for the extension key in the registry */
/* get the last element (absolute file) in the path name */
nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec);
absFile=pathDec[nbElm-1];
/* failed if the path represente a directory and not an absolute file name*/
if (!lstrcmpW(absFile, bkslashW))
return MK_E_INVALIDEXTENSION;
/* get the extension of the file */
extension = NULL;
length=lstrlenW(absFile);
for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--)
/* nothing */;
if (!extension || !lstrcmpW(extension, dotW))
return MK_E_INVALIDEXTENSION;
res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId);
/* get the progId associated to the extension */
progId = CoTaskMemAlloc(sizeProgId);
res = RegQueryValueW(HKEY_CLASSES_ROOT, extension, progId, &sizeProgId);
if (res==ERROR_SUCCESS)
/* return the clsid associated to the progId */
res= CLSIDFromProgID(progId,pclsid);
for(i=0; pathDec[i]!=NULL;i++)
CoTaskMemFree(pathDec[i]);
CoTaskMemFree(pathDec);
CoTaskMemFree(progId);
if (res==ERROR_SUCCESS)
return res;
return MK_E_INVALIDEXTENSION;
}
/***********************************************************************
* EnumMoniker_QueryInterface
*/
@@ -817,7 +1108,7 @@ static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface)
ref = InterlockedDecrement(&This->ref);
/* unitialize rot structure if there's no more reference to it*/
/* uninitialize rot structure if there's no more reference to it*/
if (ref == 0)
{
ULONG i;
@@ -841,7 +1132,7 @@ static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface, ULONG celt, IM
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
HRESULT hr = S_OK;
TRACE("(%p) TabCurrentPos %ld Tablastindx %ld\n", This, This->pos, This->moniker_count);
TRACE("(%p) TabCurrentPos %d Tablastindx %d\n", This, This->pos, This->moniker_count);
/* retrieve the requested number of moniker from the current position */
for(i = 0; (This->pos < This->moniker_count) && (i < celt); i++)
@@ -1046,7 +1337,7 @@ static HRESULT WINAPI MonikerMarshal_GetUnmarshalClass(
{
MonikerMarshal *This = impl_from_IMarshal(iface);
TRACE("(%s, %p, %lx, %p, %lx, %p)\n", debugstr_guid(riid), pv,
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
return IMoniker_GetClassID(This->moniker, pCid);
@@ -1060,7 +1351,7 @@ static HRESULT WINAPI MonikerMarshal_GetMarshalSizeMax(
HRESULT hr;
ULARGE_INTEGER size;
TRACE("(%s, %p, %lx, %p, %lx, %p)\n", debugstr_guid(riid), pv,
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pSize);
hr = IMoniker_GetSizeMax(This->moniker, &size);
@@ -1075,7 +1366,7 @@ static HRESULT WINAPI MonikerMarshal_MarshalInterface(LPMARSHAL iface, IStream *
{
MonikerMarshal *This = impl_from_IMarshal(iface);
TRACE("(%p, %s, %p, %lx, %p, %lx)\n", pStm, debugstr_guid(riid), pv,
TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags);
return IMoniker_Save(This->moniker, pStm, FALSE);
+38 -3
View File
@@ -1,12 +1,47 @@
/*
* Monikers
*
* Copyright 1998 Marcus Meissner
* Copyright 1999 Noomen Hamza
* Copyright 2005 Robert Shearman (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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_MONIKER_H__
#define __WINE_MONIKER_H__
extern const CLSID CLSID_FileMoniker;
extern const CLSID CLSID_ItemMoniker;
extern const CLSID CLSID_AntiMoniker;
DEFINE_OLEGUID( CLSID_FileMoniker, 0x303, 0, 0 );
DEFINE_OLEGUID( CLSID_ItemMoniker, 0x304, 0, 0 );
DEFINE_OLEGUID( CLSID_AntiMoniker, 0x305, 0, 0 );
DEFINE_OLEGUID( CLSID_CompositeMoniker, 0x309, 0, 0 );
DEFINE_OLEGUID( CLSID_ClassMoniker, 0x31a, 0, 0 );
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT AntiMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT CompositeMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv);
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk);
HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk);
HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer);
+86 -23
View File
@@ -19,7 +19,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -69,7 +69,7 @@ typedef struct
/******************************************************************************
* IMalloc16_QueryInterface [COMPOBJ.500]
*/
HRESULT IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
HRESULT CDECL IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
@@ -85,7 +85,7 @@ HRESULT IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
/******************************************************************************
* IMalloc16_AddRef [COMPOBJ.501]
*/
ULONG IMalloc16_fnAddRef(IMalloc16* iface) {
ULONG CDECL IMalloc16_fnAddRef(IMalloc16* iface) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->AddRef()\n",This);
return 1; /* cannot be freed */
@@ -94,7 +94,7 @@ ULONG IMalloc16_fnAddRef(IMalloc16* iface) {
/******************************************************************************
* IMalloc16_Release [COMPOBJ.502]
*/
ULONG IMalloc16_fnRelease(IMalloc16* iface) {
ULONG CDECL IMalloc16_fnRelease(IMalloc16* iface) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Release()\n",This);
return 1; /* cannot be freed */
@@ -103,20 +103,20 @@ ULONG IMalloc16_fnRelease(IMalloc16* iface) {
/******************************************************************************
* IMalloc16_Alloc [COMPOBJ.503]
*/
SEGPTR IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
SEGPTR CDECL IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Alloc(%ld)\n",This,cb);
TRACE("(%p)->Alloc(%d)\n",This,cb);
return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
}
/******************************************************************************
* IMalloc16_Free [COMPOBJ.505]
*/
VOID IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
VOID CDECL IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
{
void *ptr = MapSL(pv);
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Free(%08lx)\n",This,pv);
TRACE("(%p)->Free(%08x)\n",This,pv);
UnMapLS(pv);
HeapFree( GetProcessHeap(), 0, ptr );
}
@@ -124,11 +124,11 @@ VOID IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
/******************************************************************************
* IMalloc16_Realloc [COMPOBJ.504]
*/
SEGPTR IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
SEGPTR CDECL IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
{
SEGPTR ret;
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
TRACE("(%p)->Realloc(%08x,%d)\n",This,pv,cb);
if (!pv)
ret = IMalloc16_fnAlloc(iface, cb);
else if (cb) {
@@ -144,17 +144,17 @@ SEGPTR IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
/******************************************************************************
* IMalloc16_GetSize [COMPOBJ.506]
*/
DWORD IMalloc16_fnGetSize(IMalloc16* iface,SEGPTR pv)
DWORD CDECL IMalloc16_fnGetSize(IMalloc16* iface,SEGPTR pv)
{
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->GetSize(%08lx)\n",This,pv);
TRACE("(%p)->GetSize(%08x)\n",This,pv);
return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
}
/******************************************************************************
* IMalloc16_DidAlloc [COMPOBJ.507]
*/
INT16 IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
INT16 CDECL IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
IMalloc16 *This = (IMalloc16 *)iface;
TRACE("(%p)->DidAlloc(%p)\n",This,pv);
return (INT16)-1;
@@ -163,7 +163,7 @@ INT16 IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
/******************************************************************************
* IMalloc16_HeapMinimize [COMPOBJ.508]
*/
LPVOID IMalloc16_fnHeapMinimize(IMalloc16* iface) {
LPVOID CDECL IMalloc16_fnHeapMinimize(IMalloc16* iface) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->HeapMinimize()\n",This);
return NULL;
@@ -284,8 +284,62 @@ HRESULT WINAPI CLSIDFromString16(
LPCOLESTR16 idstr, /* [in] string representation of guid */
CLSID *id) /* [out] GUID converted from string */
{
const BYTE *s;
int i;
BYTE table[256];
return __CLSIDFromStringA(idstr,id);
if (!idstr) {
memset( id, 0, sizeof (CLSID) );
return S_OK;
}
/* validate the CLSID string */
if (strlen(idstr) != 38)
return CO_E_CLASSSTRING;
s = (const BYTE *) idstr;
if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))
return CO_E_CLASSSTRING;
for (i=1; i<37; i++) {
if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
if (!(((s[i] >= '0') && (s[i] <= '9')) ||
((s[i] >= 'a') && (s[i] <= 'f')) ||
((s[i] >= 'A') && (s[i] <= 'F'))))
return CO_E_CLASSSTRING;
}
TRACE("%s -> %p\n", s, id);
/* quick lookup table */
memset(table, 0, 256);
for (i = 0; i < 10; i++) {
table['0' + i] = i;
}
for (i = 0; i < 6; i++) {
table['A' + i] = i+10;
table['a' + i] = i+10;
}
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
id->Data1 = (table[s[1]] << 28 | table[s[2]] << 24 | table[s[3]] << 20 | table[s[4]] << 16 |
table[s[5]] << 12 | table[s[6]] << 8 | table[s[7]] << 4 | table[s[8]]);
id->Data2 = table[s[10]] << 12 | table[s[11]] << 8 | table[s[12]] << 4 | table[s[13]];
id->Data3 = table[s[15]] << 12 | table[s[16]] << 8 | table[s[17]] << 4 | table[s[18]];
/* these are just sequential bytes */
id->Data4[0] = table[s[20]] << 4 | table[s[21]];
id->Data4[1] = table[s[22]] << 4 | table[s[23]];
id->Data4[2] = table[s[25]] << 4 | table[s[26]];
id->Data4[3] = table[s[27]] << 4 | table[s[28]];
id->Data4[4] = table[s[29]] << 4 | table[s[30]];
id->Data4[5] = table[s[31]] << 4 | table[s[32]];
id->Data4[6] = table[s[33]] << 4 | table[s[34]];
id->Data4[7] = table[s[35]] << 4 | table[s[36]];
return S_OK;
}
/******************************************************************************
@@ -317,7 +371,7 @@ _xmalloc16(DWORD size, SEGPTR *ptr) {
(LPVOID)args,
(LPDWORD)ptr
)) {
ERR("CallTo16 IMalloc16 (%ld) failed\n",size);
ERR("CallTo16 IMalloc16 (%d) failed\n",size);
return E_FAIL;
}
return S_OK;
@@ -429,7 +483,7 @@ HRESULT WINAPI CoRegisterClassObject16(
DWORD flags, /* [in] REGCLS flags indicating how connections are made */
LPDWORD lpdwRegister
) {
FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
FIXME("(%s,%p,0x%08x,0x%08x,%p),stub\n",
debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister
);
return 0;
@@ -441,7 +495,7 @@ HRESULT WINAPI CoRegisterClassObject16(
*/
HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
{
FIXME("(0x%08lx),stub!\n", dwRegister);
FIXME("(0x%08x),stub!\n", dwRegister);
return 0;
}
@@ -504,7 +558,7 @@ HRESULT WINAPI CoGetState16(LPDWORD state)
*/
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);
TRACE("(%08x, %04x, %04x, %04x, %08x, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
return TRUE;
}
@@ -516,7 +570,7 @@ SEGPTR WINAPI CoMemAlloc(DWORD size, DWORD dwMemContext, DWORD x) {
SEGPTR segptr;
/* FIXME: check context handling */
TRACE("(%ld, 0x%08lx, 0x%08lx)\n", size, dwMemContext, x);
TRACE("(%d, 0x%08x, 0x%08x)\n", size, dwMemContext, x);
hres = _xmalloc16(size, &segptr);
if (hres != S_OK)
return (SEGPTR)0;
@@ -556,7 +610,7 @@ HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid)
return CO_E_CLASSSTRING;
}
RegCloseKey(xhkey);
return __CLSIDFromStringA(buf2,riid);
return CLSIDFromString16(buf2,riid);
}
/***********************************************************************
@@ -586,13 +640,22 @@ HRESULT WINAPI CoCreateInstance16(
REFIID iid,
LPVOID *ppv)
{
FIXME("(%s, %p, %lx, %s, %p), stub!\n",
FIXME("(%s, %p, %x, %s, %p), stub!\n",
debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid),
ppv
);
return E_NOTIMPL;
}
/***********************************************************************
* CoDisconnectObject [COMPOBJ.15]
*/
HRESULT WINAPI CoDisconnectObject16( LPUNKNOWN lpUnk, DWORD reserved )
{
FIXME("(%p, 0x%08x): stub!\n", lpUnk, reserved);
return E_NOTIMPL;
}
/***********************************************************************
* DllGetClassObject [OLE2.4]
*/
@@ -608,6 +671,6 @@ HRESULT WINAPI DllGetClassObject16(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
HRESULT WINAPI
GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
{
FIXME("(%ld,%p),stub!\n",reserved,pprot);
FIXME("(%d,%p),stub!\n",reserved,pprot);
return E_NOTIMPL;
}
File diff suppressed because it is too large Load Diff
+7 -4
View File
@@ -18,7 +18,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -120,7 +120,7 @@ HGLOBAL16 WINAPI OleMetaFilePictFromIconAndLabel16(
mf16 = (METAFILEPICT16 *)GlobalLock16(hmf16);
mf16->mm = MM_ANISOTROPIC;
mf16->xExt = 20; /* FIXME: bogus */
mf16->yExt = 20; /* dito */
mf16->yExt = 20; /* ditto */
mfSize = GetMetaFileBitsEx(hmf, 0, 0);
mf16->hMF = GlobalAlloc16(GMEM_MOVEABLE, mfSize);
if(mf16->hMF)
@@ -154,9 +154,12 @@ HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName,LPMONIKER* ppmk)
/******************************************************************************
* OleSetMenuDescriptor (OLE2.41)
*
* PARAMS
* hOleMenu FIXME: Should probably be an HOLEMENU16.
*/
HRESULT WINAPI OleSetMenuDescriptor16(
HOLEMENU hOleMenu, /* FIXME: HOLEMENU16 likely */
HOLEMENU hOleMenu,
HWND16 hwndFrame,
HWND16 hwndActiveObject,
LPOLEINPLACEFRAME lpFrame,
@@ -205,7 +208,7 @@ HRESULT WINAPI OleLoad16(
SEGPTR pClientSite,
LPVOID* ppvObj)
{
FIXME("(%lx,%s,%lx,%p), stub!\n", pStg, debugstr_guid(riid), pClientSite, ppvObj);
FIXME("(%x,%s,%x,%p), stub!\n", pStg, debugstr_guid(riid), pClientSite, ppvObj);
return E_NOTIMPL;
}
+1 -1
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
+1 -1
View File
@@ -17,7 +17,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
+3 -3
View File
@@ -16,7 +16,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define NONAMELESSUNION
@@ -39,7 +39,7 @@ 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);
FIXME("(%p,%p,%i,%p,%p,%p,%p), stub!\n",lpszFileName, riid, renderopt, lpFormatEtc, pClientSite, pStg, ppvObj);
return E_NOTIMPL;
}
@@ -115,7 +115,7 @@ HRESULT WINAPI OleRegEnumFormatEtc (
DWORD dwDirection,
LPENUMFORMATETC* ppenumFormatetc)
{
FIXME("(%p, %ld, %p), stub!\n", clsid, dwDirection, ppenumFormatetc);
FIXME("(%p, %d, %p), stub!\n", clsid, dwDirection, ppenumFormatetc);
return E_NOTIMPL;
}
+9 -6
View File
@@ -4,27 +4,29 @@
<include base="ole32">.</include>
<include base="ReactOS">include/reactos/wine</include>
<define name="__REACTOS__" />
<define name="__WINESRC__" />
<define name="__USE_W32API" />
<define name="_WIN32_IE">0x600</define>
<define name="_WIN32_WINNT">0x501</define>
<define name="WINVER">0x501</define>
<define name="_STDDEF_H" />
<library>wine</library>
<library>uuid</library>
<library>ntdll</library>
<library>kernel32</library>
<library>advapi32</library>
<library>gdi32</library>
<library>user32</library>
<library>gdi32</library>
<library>rpcrt4</library>
<library>kernel32</library>
<library>ntdll</library>
<library>uuid</library>
<file>antimoniker.c</file>
<file>bindctx.c</file>
<file>classmoniker.c</file>
<file>clipboard.c</file>
<file>compobj.c</file>
<file>compositemoniker.c</file>
<file>datacache.c</file>
<file>dictionary.c</file>
<file>defaulthandler.c</file>
<file>dictionary.c</file>
<file>enumx.c</file>
<file>errorinfo.c</file>
<file>filemoniker.c</file>
<file>ftmarshal.c</file>
@@ -50,5 +52,6 @@
<file>stubmanager.c</file>
<file>usrmarshal.c</file>
<file>ole32res.rc</file>
<file>dcom.idl</file>
<file>ole32.spec</file>
</module>
+17 -16
View File
@@ -20,7 +20,7 @@
@ stdcall CoFreeAllLibraries()
@ stdcall CoFreeLibrary(long)
@ stdcall CoFreeUnusedLibraries()
@ stub CoGetCallContext #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
@ stdcall CoGetCallContext(ptr ptr)
@ stub CoGetCallerTID
@ stdcall CoGetClassObject(ptr long ptr ptr ptr)
@ stub CoGetCurrentLogicalThreadId
@@ -30,13 +30,13 @@
@ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr)
@ stdcall CoGetMalloc(long ptr)
@ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long)
@ stub CoGetObject
@ stdcall CoGetObject(wstr ptr ptr ptr)
@ stdcall CoGetPSClsid(ptr ptr)
@ stdcall CoGetStandardMarshal(ptr ptr long ptr long ptr)
@ stdcall CoGetState(ptr)
@ stub CoGetTIDFromIPID
@ stdcall CoGetTreatAsClass(ptr ptr)
@ stub CoImpersonateClient
@ stdcall CoImpersonateClient()
@ stdcall CoInitialize(ptr)
@ stdcall CoInitializeEx(ptr long)
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
@@ -49,19 +49,19 @@
@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr)
@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long)
@ stub CoQueryAuthenticationServices
@ stub CoQueryClientBlanket
@ stdcall CoQueryClientBlanket(ptr ptr ptr ptr ptr ptr ptr)
@ stdcall CoQueryProxyBlanket(ptr ptr ptr ptr ptr ptr ptr ptr)
@ stub CoQueryReleaseObject
@ stub CoRegisterChannelHook
@ stdcall CoRegisterChannelHook(ptr ptr)
@ stdcall CoRegisterClassObject(ptr ptr long long ptr)
@ stdcall CoRegisterMallocSpy (ptr)
@ stdcall CoRegisterMessageFilter(ptr ptr)
@ stub CoRegisterPSClsid #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
@ stdcall CoRegisterPSClsid(ptr ptr)
@ stub CoRegisterSurrogate
@ stdcall CoReleaseMarshalData(ptr)
@ stdcall CoReleaseServerProcess()
@ stdcall CoResumeClassObjects()
@ stub CoRevertToSelf #@ stdcall () return 0,ERR_NOTIMPLEMENTED
@ stdcall CoRevertToSelf()
@ stdcall CoRevokeClassObject(long)
@ stdcall CoRevokeMallocSpy()
@ stdcall CoSetProxyBlanket(ptr long long wstr long long ptr long)
@@ -76,6 +76,7 @@
@ stub CoUnloadingWOW
@ stdcall CoUnmarshalHresult(ptr ptr)
@ stdcall CoUnmarshalInterface(ptr ptr ptr)
@ stdcall CoWaitForMultipleHandles(long long long ptr ptr)
@ stdcall CreateAntiMoniker(ptr)
@ stdcall CreateBindCtx(long ptr)
@ stdcall CreateClassMoniker(ptr ptr)
@@ -135,14 +136,14 @@
@ stdcall HMENU_UserMarshal(ptr ptr ptr)
@ stdcall HMENU_UserSize(ptr long ptr)
@ stdcall HMENU_UserUnmarshal(ptr ptr ptr)
@ stub HMETAFILEPICT_UserFree
@ stub HMETAFILEPICT_UserMarshal
@ stub HMETAFILEPICT_UserSize
@ stub HMETAFILEPICT_UserUnmarshal
@ stub HMETAFILE_UserFree
@ stub HMETAFILE_UserMarshal
@ stub HMETAFILE_UserSize
@ stub HMETAFILE_UserUnmarshal
@ stdcall HMETAFILEPICT_UserFree(ptr ptr)
@ stdcall HMETAFILEPICT_UserMarshal(ptr ptr ptr)
@ stdcall HMETAFILEPICT_UserSize(ptr long ptr)
@ stdcall HMETAFILEPICT_UserUnmarshal(ptr ptr ptr)
@ stdcall HMETAFILE_UserFree(ptr ptr)
@ stdcall HMETAFILE_UserMarshal(ptr ptr ptr)
@ stdcall HMETAFILE_UserSize(ptr long ptr)
@ stdcall HMETAFILE_UserUnmarshal(ptr ptr ptr)
@ stdcall HPALETTE_UserFree(ptr ptr)
@ stdcall HPALETTE_UserMarshal(ptr ptr ptr)
@ stdcall HPALETTE_UserSize(ptr long ptr)
@@ -200,7 +201,7 @@
@ stdcall OleLoadFromStream(ptr ptr ptr)
@ stdcall OleLockRunning(ptr long long)
@ stdcall OleMetafilePictFromIconAndLabel(long ptr ptr long)
@ stub OleNoteObjectVisible
@ stdcall OleNoteObjectVisible(ptr long)
@ stdcall OleQueryCreateFromData(ptr)
@ stdcall OleQueryLinkFromData(ptr)
@ stdcall OleRegEnumFormatEtc(ptr long ptr)
+57 -8
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@@ -32,6 +32,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
#define HIMETRIC_INCHES 2540
/***********************************************************************
* OleMetafilePictFromIconAndLabel (OLE32.@)
*/
@@ -40,27 +42,70 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
{
METAFILEPICT mfp;
HDC hdc;
UINT dy;
HGLOBAL hmem = NULL;
LPVOID mfdata;
static const char szIconOnly[] = "IconOnly";
SIZE text_size = { 0, 0 };
INT width;
INT icon_width;
INT icon_height;
INT label_offset;
HDC hdcScreen;
LOGFONTW lf;
HFONT font;
TRACE("%p %p %s %d\n", hIcon, lpszLabel, debugstr_w(lpszSourceFile), iIconIndex);
if( !hIcon )
return NULL;
if (!SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
return NULL;
font = CreateFontIndirectW(&lf);
if (!font)
return NULL;
hdc = CreateMetaFileW(NULL);
if( !hdc )
{
DeleteObject(font);
return NULL;
}
SelectObject(hdc, font);
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);
icon_width = GetSystemMetrics(SM_CXICON);
icon_height = GetSystemMetrics(SM_CYICON);
/* FIXME: should we give the label a bit of padding here? */
label_offset = icon_height;
if (lpszLabel)
{
HFONT screen_old_font;
/* metafile DCs don't support GetTextExtentPoint32, so size the font
* using the desktop window DC */
hdcScreen = GetDC(NULL);
screen_old_font = SelectObject(hdcScreen, font);
GetTextExtentPoint32W(hdcScreen, lpszLabel, lstrlenW(lpszLabel), &text_size);
SelectObject(hdcScreen, screen_old_font);
ReleaseDC(NULL, hdcScreen);
width = 3 * icon_width;
}
else
width = icon_width;
SetMapMode(hdc, MM_ANISOTROPIC);
SetWindowOrgEx(hdc, 0, 0, NULL);
SetWindowExtEx(hdc, width, label_offset + text_size.cy, NULL);
/* draw the icon centred */
DrawIcon(hdc, (width-icon_width) / 2, 0, hIcon);
if(lpszLabel)
TextOutW(hdc, 0, dy, lpszLabel, lstrlenW(lpszLabel));
/* draw the label centred too, if provided */
TextOutW(hdc, (width-text_size.cx) / 2, label_offset, lpszLabel, lstrlenW(lpszLabel));
if (lpszSourceFile)
{
@@ -80,9 +125,13 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
ExtEscape(hdc, MFCOMMENT, strlen(szIconIndex)+1, szIconIndex, 0, NULL);
}
mfp.mm = MM_ISOTROPIC;
mfp.xExt = mfp.yExt = 0; /* FIXME ? */
mfp.mm = MM_ANISOTROPIC;
hdcScreen = GetDC(NULL);
mfp.xExt = MulDiv(width, HIMETRIC_INCHES, GetDeviceCaps(hdcScreen, LOGPIXELSX));
mfp.yExt = MulDiv(label_offset + text_size.cy, HIMETRIC_INCHES, GetDeviceCaps(hdcScreen, LOGPIXELSY));
ReleaseDC(NULL, hdcScreen);
mfp.hMF = CloseMetaFile(hdc);
DeleteObject(font);
if( !mfp.hMF )
return NULL;
+12
View File
@@ -0,0 +1,12 @@
Index: rpc.c
===================================================================
--- rpc.c (revision 23782)
+++ rpc.c (working copy)
@@ -24,6 +24,7 @@
#include "wine/port.h"
#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#define COBJMACROS
+1 -1
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "windef.h"
+274 -26
View File
@@ -16,7 +16,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
@@ -50,6 +50,156 @@ typedef struct OleAdviseHolderImpl
} OleAdviseHolderImpl;
static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum);
typedef struct
{
const IEnumSTATDATAVtbl *lpvtbl;
LONG ref;
ULONG index;
OleAdviseHolderImpl *pOleAdviseHolder;
} EnumOleSTATDATA;
static HRESULT WINAPI EnumOleSTATDATA_QueryInterface(
IEnumSTATDATA *iface, REFIID riid, void **ppv)
{
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IEnumSTATDATA))
{
IUnknown_AddRef(iface);
*ppv = iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI EnumOleSTATDATA_AddRef(
IEnumSTATDATA *iface)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
TRACE("()\n");
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI EnumOleSTATDATA_Release(
IEnumSTATDATA *iface)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
LONG refs = InterlockedDecrement(&This->ref);
TRACE("()\n");
if (!refs)
{
IOleAdviseHolder_Release((IOleAdviseHolder *)This->pOleAdviseHolder);
HeapFree(GetProcessHeap(), 0, This);
}
return refs;
}
static HRESULT WINAPI EnumOleSTATDATA_Next(
IEnumSTATDATA *iface, ULONG celt, LPSTATDATA rgelt,
ULONG *pceltFetched)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
HRESULT hr = S_OK;
TRACE("(%d, %p, %p)\n", celt, rgelt, pceltFetched);
if (pceltFetched)
*pceltFetched = 0;
for (; celt; celt--, rgelt++)
{
while ((This->index < This->pOleAdviseHolder->maxSinks) &&
!This->pOleAdviseHolder->arrayOfSinks[This->index])
{
This->index++;
}
if (This->index >= This->pOleAdviseHolder->maxSinks)
{
hr = S_FALSE;
break;
}
memset(&rgelt->formatetc, 0, sizeof(rgelt->formatetc));
rgelt->advf = 0;
rgelt->pAdvSink = This->pOleAdviseHolder->arrayOfSinks[This->index];
IAdviseSink_AddRef(rgelt->pAdvSink);
rgelt->dwConnection = This->index;
if (pceltFetched)
(*pceltFetched)++;
This->index++;
}
return hr;
}
static HRESULT WINAPI EnumOleSTATDATA_Skip(
IEnumSTATDATA *iface, ULONG celt)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
TRACE("(%d)\n", celt);
for (; celt; celt--)
{
while ((This->index < This->pOleAdviseHolder->maxSinks) &&
!This->pOleAdviseHolder->arrayOfSinks[This->index])
{
This->index++;
}
if (This->index >= This->pOleAdviseHolder->maxSinks)
return S_FALSE;
This->index++;
}
return S_OK;
}
static HRESULT WINAPI EnumOleSTATDATA_Reset(
IEnumSTATDATA *iface)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
TRACE("()\n");
This->index = 0;
return S_OK;
}
static HRESULT WINAPI EnumOleSTATDATA_Clone(
IEnumSTATDATA *iface,
IEnumSTATDATA **ppenum)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
return EnumOleSTATDATA_Construct(This->pOleAdviseHolder, This->index, ppenum);
}
static const IEnumSTATDATAVtbl EnumOleSTATDATA_VTable =
{
EnumOleSTATDATA_QueryInterface,
EnumOleSTATDATA_AddRef,
EnumOleSTATDATA_Release,
EnumOleSTATDATA_Next,
EnumOleSTATDATA_Skip,
EnumOleSTATDATA_Reset,
EnumOleSTATDATA_Clone
};
static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum)
{
EnumOleSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This)
return E_OUTOFMEMORY;
This->lpvtbl = &EnumOleSTATDATA_VTable;
This->ref = 1;
This->index = index;
This->pOleAdviseHolder = pOleAdviseHolder;
IOleAdviseHolder_AddRef((IOleAdviseHolder *)pOleAdviseHolder);
*ppenum = (IEnumSTATDATA *)&This->lpvtbl;
return S_OK;
}
/**************************************************************************
* OleAdviseHolderImpl_Destructor
*/
@@ -127,7 +277,7 @@ static ULONG WINAPI OleAdviseHolderImpl_AddRef(
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->(ref=%ld)\n", This, ref - 1);
TRACE("(%p)->(ref=%d)\n", This, ref - 1);
return ref;
}
@@ -140,7 +290,7 @@ static ULONG WINAPI OleAdviseHolderImpl_Release(
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
ULONG ref;
TRACE("(%p)->(ref=%ld)\n", This, This->ref);
TRACE("(%p)->(ref=%d)\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
if (ref == 0) OleAdviseHolderImpl_Destructor(This);
@@ -224,7 +374,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
TRACE("(%p)->(%lu)\n", This, dwConnection);
TRACE("(%p)->(%u)\n", This, dwConnection);
/*
* So we don't return 0 as a cookie, the index was
@@ -258,11 +408,12 @@ static HRESULT WINAPI
OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)->(%p)\n", This, ppenumAdvise);
TRACE("(%p)->(%p)\n", This, ppenumAdvise);
*ppenumAdvise = NULL;
return S_OK;
return EnumOleSTATDATA_Construct(This, 0, ppenumAdvise);
}
/******************************************************************************
@@ -271,11 +422,25 @@ OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumA
static HRESULT WINAPI
OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)->(%p)\n", This, pmk);
IEnumSTATDATA *pEnum;
HRESULT hr;
TRACE("(%p)->(%p)\n", iface, pmk);
return S_OK;
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
if (SUCCEEDED(hr))
{
STATDATA statdata;
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
{
IAdviseSink_OnRename(statdata.pAdvSink, pmk);
IAdviseSink_Release(statdata.pAdvSink);
}
IEnumSTATDATA_Release(pEnum);
}
return hr;
}
/******************************************************************************
@@ -284,10 +449,25 @@ OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
static HRESULT WINAPI
OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)\n", This);
IEnumSTATDATA *pEnum;
HRESULT hr;
return S_OK;
TRACE("(%p)->()\n", iface);
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
if (SUCCEEDED(hr))
{
STATDATA statdata;
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
{
IAdviseSink_OnSave(statdata.pAdvSink);
IAdviseSink_Release(statdata.pAdvSink);
}
IEnumSTATDATA_Release(pEnum);
}
return hr;
}
/******************************************************************************
@@ -296,11 +476,25 @@ OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
static HRESULT WINAPI
OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)\n", This);
IEnumSTATDATA *pEnum;
HRESULT hr;
TRACE("(%p)->()\n", iface);
return S_OK;
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
if (SUCCEEDED(hr))
{
STATDATA statdata;
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
{
IAdviseSink_OnClose(statdata.pAdvSink);
IAdviseSink_Release(statdata.pAdvSink);
}
IEnumSTATDATA_Release(pEnum);
}
return hr;
}
/**************************************************************************
@@ -361,6 +555,7 @@ typedef struct DataAdviseHolder
LONG ref;
DWORD maxCons;
DataAdviseConnection* Connections;
IDataObject* delegate;
} DataAdviseHolder;
/* this connection has also has been advised to the delegate data object */
@@ -378,6 +573,11 @@ static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
{
if (ptrToDestroy->Connections[index].sink != NULL)
{
if (ptrToDestroy->delegate &&
(ptrToDestroy->Connections[index].advf & WINE_ADVF_REMOTE))
IDataObject_DUnadvise(ptrToDestroy->delegate,
ptrToDestroy->Connections[index].remote_connection);
IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
ptrToDestroy->Connections[index].sink = NULL;
}
@@ -445,7 +645,7 @@ static ULONG WINAPI DataAdviseHolder_AddRef(
IDataAdviseHolder* iface)
{
DataAdviseHolder *This = (DataAdviseHolder *)iface;
TRACE("(%p) (ref=%ld)\n", This, This->ref);
TRACE("(%p) (ref=%d)\n", This, This->ref);
return InterlockedIncrement(&This->ref);
}
@@ -459,7 +659,7 @@ static ULONG WINAPI DataAdviseHolder_Release(
{
DataAdviseHolder *This = (DataAdviseHolder *)iface;
ULONG ref;
TRACE("(%p) (ref=%ld)\n", This, This->ref);
TRACE("(%p) (ref=%d)\n", This, This->ref);
/*
* Decrease the reference count on this object.
@@ -490,7 +690,7 @@ static HRESULT WINAPI DataAdviseHolder_Advise(
DataAdviseHolder *This = (DataAdviseHolder *)iface;
TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf,
TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This, pDataObject, pFetc, advf,
pAdvise, pdwConnection);
/*
* Sanity check
@@ -523,14 +723,42 @@ static HRESULT WINAPI DataAdviseHolder_Advise(
* Store the new sink
*/
This->Connections[index].sink = pAdvise;
memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
This->Connections[index].advf = advf & ~WINE_ADVF_REMOTE;
memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
if (pFetc->ptd)
{
This->Connections[index].fmat.ptd = CoTaskMemAlloc(pFetc->ptd->tdSize);
if (!This->Connections[index].fmat.ptd)
{
IDataAdviseHolder_Unadvise(iface, index + 1);
return E_OUTOFMEMORY;
}
memcpy(This->Connections[index].fmat.ptd, pFetc->ptd, pFetc->ptd->tdSize);
}
if (This->Connections[index].sink != NULL) {
IAdviseSink_AddRef(This->Connections[index].sink);
if(advf & ADVF_PRIMEFIRST) {
IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
/* if we are already connected advise the remote object */
if (This->delegate)
{
HRESULT hr;
hr = IDataObject_DAdvise(This->delegate, &This->Connections[index].fmat,
This->Connections[index].advf,
This->Connections[index].sink,
&This->Connections[index].remote_connection);
if (FAILED(hr))
{
IDataAdviseHolder_Unadvise(iface, index + 1);
return hr;
}
This->Connections[index].advf |= WINE_ADVF_REMOTE;
}
else if(advf & ADVF_PRIMEFIRST)
/* only do this if we have no delegate, since in the above case the
* delegate will do the priming for us */
IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
}
/*
* Return the index as the cookie.
@@ -551,7 +779,7 @@ static HRESULT WINAPI DataAdviseHolder_Unadvise(
{
DataAdviseHolder *This = (DataAdviseHolder *)iface;
TRACE("(%p)->(%lu)\n", This, dwConnection);
TRACE("(%p)->(%u)\n", This, dwConnection);
/*
* So we don't return 0 as a cookie, the index was
@@ -569,11 +797,16 @@ static HRESULT WINAPI DataAdviseHolder_Unadvise(
if (This->Connections[dwConnection].sink == NULL)
return OLE_E_NOCONNECTION;
if (This->delegate && This->Connections[dwConnection].advf & WINE_ADVF_REMOTE)
IDataObject_DUnadvise(This->delegate,
This->Connections[dwConnection].remote_connection);
/*
* 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;
}
@@ -601,16 +834,17 @@ static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
STGMEDIUM stg;
HRESULT res;
TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf);
TRACE("(%p)->(%p,%08x,%08x)\n", This, pDataObject, dwReserved, advf);
for(index = 0; index < This->maxCons; index++) {
if(This->Connections[index].sink != NULL) {
memset(&stg, 0, sizeof(stg));
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("returns %08x\n", res);
}
TRACE("Calling IAdviseSink_OnDataChange\n");
IAdviseSink_OnDataChange(This->Connections[index].sink,
@@ -658,13 +892,26 @@ HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDeleg
This->Connections[index].advf |= WINE_ADVF_REMOTE;
}
}
/* FIXME: store pDelegate somewhere */
This->delegate = pDelegate;
return hr;
}
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface)
{
/* FIXME: Unadvise all remote interfaces */
DataAdviseHolder *This = (DataAdviseHolder *)iface;
DWORD index;
for(index = 0; index < This->maxCons; index++)
{
if((This->Connections[index].sink != NULL) &&
(This->Connections[index].advf & WINE_ADVF_REMOTE))
{
IDataObject_DUnadvise(This->delegate,
This->Connections[index].remote_connection);
This->Connections[index].advf &= ~WINE_ADVF_REMOTE;
}
}
This->delegate = NULL;
}
/******************************************************************************
@@ -683,6 +930,7 @@ static IDataAdviseHolder* DataAdviseHolder_Constructor(void)
HEAP_ZERO_MEMORY,
newHolder->maxCons *
sizeof(DataAdviseConnection));
newHolder->delegate = NULL;
TRACE("returning %p\n", newHolder);
return (IDataAdviseHolder*)newHolder;
+66 -56
View File
@@ -16,7 +16,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Documentation on MSDN:
@@ -39,7 +39,6 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
@@ -64,8 +63,7 @@
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} };
static ULONG WINAPI RURpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface);
/* From: http://msdn.microsoft.com/library/en-us/com/cmi_m_4lda.asp
*
@@ -161,7 +159,7 @@ CFStub_Invoke(
ULONG res;
if (msg->cbBuffer < sizeof(IID)) {
FIXME("Not enough bytes in buffer (%ld instead of %d)?\n",msg->cbBuffer,sizeof(IID));
FIXME("Not enough bytes in buffer (%d)?\n",msg->cbBuffer);
return E_FAIL;
}
memcpy(&iid,msg->Buffer,sizeof(iid));
@@ -173,51 +171,58 @@ CFStub_Invoke(
}
hres = IClassFactory_CreateInstance(classfac,NULL,&iid,(LPVOID*)&ppv);
IClassFactory_Release(classfac);
msg->cbBuffer = 0;
if (hres) {
msg->cbBuffer = 0;
FIXME("Failed to create an instance of %s\n",debugstr_guid(&iid));
return hres;
goto getbuffer;
}
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
if (hres) {
FIXME("Failed to create stream on hglobal\n");
return hres;
goto getbuffer;
}
hres = CoMarshalInterface(pStm,&iid,ppv,0,NULL,0);
IUnknown_Release((IUnknown*)ppv);
hres = IStream_Write(pStm, &ppv, sizeof(ppv), NULL);
if (hres) {
FIXME("CoMarshalInterface failed, %lx!\n",hres);
msg->cbBuffer = 0;
return hres;
ERR("IStream_Write failed, 0x%08x\n", hres);
goto getbuffer;
}
if (ppv) {
hres = CoMarshalInterface(pStm,&iid,ppv,0,NULL,0);
IUnknown_Release(ppv);
if (hres) {
FIXME("CoMarshalInterface failed, %x!\n",hres);
goto getbuffer;
}
}
hres = IStream_Stat(pStm,&ststg,0);
if (hres) {
FIXME("Stat failed.\n");
return hres;
goto getbuffer;
}
msg->cbBuffer = ststg.cbSize.u.LowPart;
I_RpcGetBuffer((RPC_MESSAGE *)msg);
getbuffer:
IRpcChannelBuffer_GetBuffer(chanbuf, msg, &IID_IClassFactory);
if (hres) return hres;
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);
FIXME("IStream_Seek failed, %x\n",hres);
return hres;
}
hres = IStream_Read(pStm,msg->Buffer,msg->cbBuffer,&res);
if (hres) {
FIXME("Stream Read failed, %lx\n",hres);
FIXME("Stream Read failed, %x\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);
FIXME("iMethod is %d\n",msg->iMethod);
FIXME("cbBuffer is %d\n",msg->cbBuffer);
return E_FAIL;
}
@@ -346,18 +351,11 @@ static ULONG WINAPI CFProxy_AddRef(LPCLASSFACTORY iface) {
}
static ULONG WINAPI CFProxy_Release(LPCLASSFACTORY iface) {
ULONG ref;
ICOM_THIS_MULTI(CFProxy,lpvtbl_cf,iface);
if (This->outer_unknown)
ref = IUnknown_Release(This->outer_unknown);
else
ref = InterlockedDecrement(&This->ref);
if (!ref) {
if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf);
HeapFree(GetProcessHeap(),0,This);
}
return ref;
return IUnknown_Release(This->outer_unknown);
else
return IRpcProxyBufferImpl_Release((IRpcProxyBuffer *)&This->lpvtbl_proxy);
}
static HRESULT WINAPI CFProxy_CreateInstance(
@@ -384,36 +382,48 @@ static HRESULT WINAPI CFProxy_CreateInstance(
msg.Buffer = NULL;
hres = IRpcChannelBuffer_GetBuffer(This->chanbuf,&msg,&IID_IClassFactory);
if (hres) {
FIXME("IRpcChannelBuffer_GetBuffer failed with %lx?\n",hres);
FIXME("IRpcChannelBuffer_GetBuffer failed with %x?\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);
FIXME("IRpcChannelBuffer_SendReceive failed with %x?\n",hres);
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
return hres;
}
if (!msg.cbBuffer) /* interface not found on remote */
if (!msg.cbBuffer) { /* interface not found on remote */
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
return srstatus;
}
/* We got back: [Marshalled Interface data] */
TRACE("got %ld bytes data.\n",msg.cbBuffer);
TRACE("got %d 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);
FIXME("CreateStreamOnHGlobal failed with %x\n",hres);
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
return hres;
}
hres = CoUnmarshalInterface(
pStream,
riid,
ppv
);
hres = IStream_Read(pStream, ppv, sizeof(*ppv), NULL);
if (hres != S_OK)
hres = E_FAIL;
else if (*ppv) {
hres = CoUnmarshalInterface(
pStream,
riid,
ppv
);
}
IStream_Release(pStream); /* Does GlobalFree hGlobal too. */
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
if (hres) {
FIXME("CoMarshalInterface failed, %lx\n",hres);
FIXME("CoMarshalInterface failed, %x\n",hres);
return hres;
}
return S_OK;
@@ -530,7 +540,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
LPBYTE buf = pMsg->Buffer;
HRESULT hr = RPC_E_INVALIDMETHOD;
TRACE("(%p)->Invoke(%p,%p) method %ld\n", This, pMsg, pChannel, iMethod);
TRACE("(%p)->Invoke(%p,%p) method %d\n", This, pMsg, pChannel, iMethod);
switch (iMethod)
{
case 3: /* RemQueryInterface */
@@ -555,7 +565,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
/* out */
pMsg->cbBuffer = cIids * sizeof(REMQIRESULT) + sizeof(HRESULT);
I_RpcGetBuffer((RPC_MESSAGE *)pMsg);
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
buf = pMsg->Buffer;
*(HRESULT *)buf = hr;
@@ -585,7 +595,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
/* out */
pMsg->cbBuffer = cIids * sizeof(HRESULT);
I_RpcGetBuffer((RPC_MESSAGE *)pMsg);
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
if (!hr)
{
buf = pMsg->Buffer;
@@ -610,6 +620,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
/* out */
pMsg->cbBuffer = 0;
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
break;
}
}
@@ -713,19 +724,12 @@ static ULONG WINAPI RemUnkProxy_AddRef(LPREMUNKNOWN iface)
static ULONG WINAPI RemUnkProxy_Release(LPREMUNKNOWN iface)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
ULONG refs;
TRACE("(%p)->Release()\n",This);
if (This->outer_unknown)
refs = IUnknown_Release(This->outer_unknown);
else
refs = InterlockedDecrement(&This->refs);
if (!refs) {
if (This->chan) IRpcChannelBuffer_Release(This->chan);
HeapFree(GetProcessHeap(),0,This);
}
return refs;
return IUnknown_Release(This->outer_unknown);
else
return IRpcProxyBufferImpl_Release((IRpcProxyBuffer *)&This->lpvtbl_proxy);
}
static HRESULT WINAPI RemUnkProxy_RemQueryInterface(LPREMUNKNOWN iface,
@@ -740,7 +744,7 @@ static HRESULT WINAPI RemUnkProxy_RemQueryInterface(LPREMUNKNOWN iface,
HRESULT hr = S_OK;
ULONG status;
TRACE("(%p)->(%s,%ld,%d,%p,%p)\n",This,
TRACE("(%p)->(%s,%d,%d,%p,%p)\n",This,
debugstr_guid(ripid),cRefs,cIids,iids,ppQIResults);
*ppQIResults = NULL;
@@ -869,14 +873,14 @@ static HRESULT WINAPI RURpcProxyBufferImpl_QueryInterface(LPRPCPROXYBUFFER iface
static ULONG WINAPI RURpcProxyBufferImpl_AddRef(LPRPCPROXYBUFFER iface) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
TRACE("%p, %ld\n", iface, This->refs + 1);
TRACE("%p, %d\n", iface, This->refs + 1);
return InterlockedIncrement(&This->refs);
}
static ULONG WINAPI RURpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
ULONG ref = InterlockedDecrement(&This->refs);
TRACE("%p, %ld\n", iface, ref);
TRACE("%p, %d\n", iface, ref);
if (!ref) {
IRpcProxyBuffer_Disconnect(iface);
HeapFree(GetProcessHeap(),0,This);
@@ -1015,6 +1019,12 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
return FileMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ItemMoniker))
return ItemMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_AntiMoniker))
return AntiMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_CompositeMoniker))
return CompositeMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ClassMoniker))
return ClassMonikerCF_Create(iid, ppv);
FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
return CLASS_E_CLASSNOTAVAILABLE;
+1 -1
View File
@@ -13,7 +13,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if !defined( __WINE_OLESTD_H_ )
+175 -20
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -30,9 +30,11 @@
#include "winerror.h"
#include "objbase.h"
#include "compobj_private.h"
#include "ole2.h"
#include "olectl.h"
#include "initguid.h"
#include "compobj_private.h"
#include "moniker.h"
#include "wine/debug.h"
@@ -66,6 +68,7 @@ struct regsvr_coclass
LPCSTR ips; /* can be NULL to omit */
LPCSTR ips32; /* can be NULL to omit */
LPCSTR ips32_tmodel; /* can be NULL to omit */
LPCSTR progid; /* can be NULL to omit */
};
static HRESULT register_coclasses(struct regsvr_coclass const *list);
@@ -95,6 +98,8 @@ static WCHAR const ips_keyname[13] = {
static WCHAR const ips32_keyname[15] = {
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
'3', '2', 0 };
static WCHAR const progid_keyname[7] = {
'P', 'r', 'o', 'g', 'I', 'D', 0 };
static char const tmodel_valuename[] = "ThreadingModel";
/***********************************************************************
@@ -105,7 +110,10 @@ 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 register_progid(WCHAR const *clsid, char const *progid,
char const *name);
static LONG recursive_delete_key(HKEY key);
static LONG recursive_delete_keyA(HKEY base, char const *name);
/***********************************************************************
@@ -137,7 +145,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
}
if (list->base_iid) {
register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
@@ -159,12 +167,12 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
}
if (list->ps_clsid) {
register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
res = 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);
res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
@@ -266,6 +274,15 @@ static HRESULT register_coclasses(struct regsvr_coclass const *list)
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->progid) {
res = register_key_defvalueA(clsid_key, progid_keyname,
list->progid);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = register_progid(buf, list->progid, list->name);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
error_close_clsid_key:
RegCloseKey(clsid_key);
}
@@ -304,6 +321,11 @@ static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
res = recursive_delete_key(clsid_key);
RegCloseKey(clsid_key);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
if (list->progid) {
res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
}
error_close_coclass_key:
@@ -363,6 +385,38 @@ static LONG register_key_defvalueA(
return res;
}
/***********************************************************************
* regsvr_progid
*/
static LONG register_progid(
WCHAR const *clsid,
char const *progid,
char const *name)
{
LONG res;
HKEY progid_key;
res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL,
&progid_key, NULL);
if (res != ERROR_SUCCESS) return res;
if (name) {
res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
(CONST BYTE*)name, strlen(name) + 1);
if (res != ERROR_SUCCESS) goto error_close_progid_key;
}
if (clsid) {
res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
if (res != ERROR_SUCCESS) goto error_close_progid_key;
}
error_close_progid_key:
RegCloseKey(progid_key);
return res;
}
/***********************************************************************
* recursive_delete_key
*/
@@ -395,29 +449,50 @@ static LONG recursive_delete_key(HKEY key)
return res;
}
/***********************************************************************
* recursive_delete_keyA
*/
static LONG recursive_delete_keyA(HKEY base, char const *name)
{
LONG res;
HKEY key;
res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
if (res != ERROR_SUCCESS) return res;
res = recursive_delete_key(key);
RegCloseKey(key);
return res;
}
/***********************************************************************
* coclass list
*/
static GUID const CLSID_FileMoniker = {
0x00000303, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_StdOleLink = {
0x00000300, 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} };
static GUID const CLSID_PointerMoniker = {
0x00000306, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
/* FIXME: DfMarshal and PSFactoryBuffer are defined elsewhere too */
static GUID const CLSID_PackagerMoniker = {
0x00000308, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
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} };
extern GUID const CLSID_Picture_Metafile;
extern GUID const CLSID_Picture_Dib;
static struct regsvr_coclass const coclass_list[] = {
{ &CLSID_StdOleLink,
"StdOleLink",
NULL,
"ole32.dll",
NULL
},
{ &CLSID_FileMoniker,
"FileMoniker",
NULL,
"ole32.dll",
"Both"
"Both",
"file"
},
{ &CLSID_ItemMoniker,
"ItemMoniker",
@@ -425,12 +500,57 @@ static struct regsvr_coclass const coclass_list[] = {
"ole32.dll",
"Both"
},
{ &CLSID_AntiMoniker,
"AntiMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_PointerMoniker,
"PointerMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_PackagerMoniker,
"PackagerMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_CompositeMoniker,
"CompositeMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_DfMarshal,
"DfMarshal",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_Picture_Metafile,
"Picture (Metafile)",
NULL,
"ole32.dll",
NULL,
"StaticMetafile"
},
{ &CLSID_Picture_Dib,
"Picture (Device Independent Bitmap)",
NULL,
"ole32.dll",
NULL,
"StaticDib"
},
{ &CLSID_ClassMoniker,
"ClassMoniker",
NULL,
"ole32.dll",
"Both",
"CLSID"
},
{ &CLSID_PSFactoryBuffer,
"PSFactoryBuffer",
NULL,
@@ -451,6 +571,7 @@ static struct regsvr_coclass const coclass_list[] = {
*/
#define INTERFACE_ENTRY(interface, base, clsid32, clsid16) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), clsid16, clsid32 }
#define BAS_INTERFACE_ENTRY(interface, base) INTERFACE_ENTRY(interface, &IID_##base, &CLSID_PSFactoryBuffer, NULL)
#define STD_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, &CLSID_PSFactoryBuffer, NULL)
#define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL, NULL)
@@ -459,31 +580,65 @@ static const struct regsvr_interface interface_list[] = {
STD_INTERFACE_ENTRY(IClassFactory),
LCL_INTERFACE_ENTRY(IMalloc),
LCL_INTERFACE_ENTRY(IMarshal),
STD_INTERFACE_ENTRY(ILockBytes),
STD_INTERFACE_ENTRY(IStorage),
STD_INTERFACE_ENTRY(IStream),
STD_INTERFACE_ENTRY(IEnumSTATSTG),
STD_INTERFACE_ENTRY(IBindCtx),
BAS_INTERFACE_ENTRY(IMoniker, IPersistStream),
STD_INTERFACE_ENTRY(IRunningObjectTable),
STD_INTERFACE_ENTRY(IRootStorage),
LCL_INTERFACE_ENTRY(IMessageFilter),
LCL_INTERFACE_ENTRY(IStdMarshalInfo),
LCL_INTERFACE_ENTRY(IExternalConnection),
LCL_INTERFACE_ENTRY(IMallocSpy),
LCL_INTERFACE_ENTRY(IMultiQI),
STD_INTERFACE_ENTRY(IStream),
STD_INTERFACE_ENTRY(IPersistStorage),
STD_INTERFACE_ENTRY(IEnumUnknown),
STD_INTERFACE_ENTRY(IEnumString),
STD_INTERFACE_ENTRY(IEnumMoniker),
STD_INTERFACE_ENTRY(IEnumFORMATETC),
STD_INTERFACE_ENTRY(IEnumOLEVERB),
STD_INTERFACE_ENTRY(IEnumSTATDATA),
BAS_INTERFACE_ENTRY(IPersistStream, IPersist),
BAS_INTERFACE_ENTRY(IPersistStorage, IPersist),
BAS_INTERFACE_ENTRY(IPersistFile, IPersist),
STD_INTERFACE_ENTRY(IPersist),
STD_INTERFACE_ENTRY(IViewObject),
STD_INTERFACE_ENTRY(IDataObject),
STD_INTERFACE_ENTRY(IAdviseSink),
LCL_INTERFACE_ENTRY(IDataAdviseHolder),
LCL_INTERFACE_ENTRY(IOleAdviseHolder),
STD_INTERFACE_ENTRY(IOleObject),
BAS_INTERFACE_ENTRY(IOleInPlaceObject, IOleWindow),
STD_INTERFACE_ENTRY(IOleWindow),
BAS_INTERFACE_ENTRY(IOleInPlaceUIWindow, IOleWindow),
STD_INTERFACE_ENTRY(IOleInPlaceFrame),
BAS_INTERFACE_ENTRY(IOleInPlaceActiveObject, IOleWindow),
STD_INTERFACE_ENTRY(IOleClientSite),
BAS_INTERFACE_ENTRY(IOleInPlaceSite, IOleWindow),
STD_INTERFACE_ENTRY(IParseDisplayName),
BAS_INTERFACE_ENTRY(IOleContainer, IParseDisplayName),
BAS_INTERFACE_ENTRY(IOleItemContainer, IOleContainer),
STD_INTERFACE_ENTRY(IOleLink),
STD_INTERFACE_ENTRY(IOleCache),
LCL_INTERFACE_ENTRY(IDropSource),
STD_INTERFACE_ENTRY(IDropTarget),
BAS_INTERFACE_ENTRY(IAdviseSink2, IAdviseSink),
STD_INTERFACE_ENTRY(IRunnableObject),
BAS_INTERFACE_ENTRY(IViewObject2, IViewObject),
BAS_INTERFACE_ENTRY(IOleCache2, IOleCache),
STD_INTERFACE_ENTRY(IOleCacheControl),
STD_INTERFACE_ENTRY(IRemUnknown),
LCL_INTERFACE_ENTRY(IClientSecurity),
LCL_INTERFACE_ENTRY(IServerSecurity),
STD_INTERFACE_ENTRY(ISequentialStream),
{ NULL } /* list terminator */
};
/***********************************************************************
* DllRegisterServer (OLE32.@)
*/
HRESULT WINAPI DllRegisterServer()
HRESULT WINAPI DllRegisterServer(void)
{
HRESULT hr;
@@ -498,7 +653,7 @@ HRESULT WINAPI DllRegisterServer()
/***********************************************************************
* DllUnregisterServer (OLE32.@)
*/
HRESULT WINAPI DllUnregisterServer()
HRESULT WINAPI DllUnregisterServer(void)
{
HRESULT hr;
File diff suppressed because it is too large Load Diff
+245 -192
View File
@@ -28,7 +28,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@@ -91,6 +91,7 @@ struct MappedPage
MappedPage *prev;
DWORD page_index;
DWORD mapped_bytes;
LPVOID lpBytes;
LONG refcnt;
@@ -108,16 +109,12 @@ static void BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This,
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);
static void BIGBLOCKFILE_DeleteList(LPBIGBLOCKFILE This, MappedPage *list);
/* Note that this evaluates a and b multiple times, so don't
* pass expressions with side effects. */
@@ -248,7 +245,7 @@ static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
This->maplist = NULL;
TRACE("file len %lu\n", This->filesize.u.LowPart);
TRACE("file len %u\n", This->filesize.u.LowPart);
return TRUE;
}
@@ -285,7 +282,7 @@ static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
This->pbytearray = GlobalLock(This->hbytearray);
TRACE("mem on %p len %lu\n", This->pbytearray, This->filesize.u.LowPart);
TRACE("mem on %p len %u\n", This->pbytearray, This->filesize.u.LowPart);
return TRUE;
}
@@ -317,46 +314,11 @@ void BIGBLOCKFILE_Destructor(
}
/******************************************************************************
* BIGBLOCKFILE_GetROBigBlock
* BIGBLOCKFILE_EnsureExists
*
* Returns the specified block in read only mode.
* Will return NULL if the block doesn't exists.
* Grows the file if necessary to make sure the block is valid.
*/
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)
void BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index)
{
/*
* block index starts at -1
@@ -379,28 +341,6 @@ void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
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);
}
/******************************************************************************
@@ -414,57 +354,40 @@ 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);
TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart);
/*
* unmap all views, must be done before call to SetEndFile
*
* Just ditch the victim list because there is no guarentee we will need them
* and it is not worth the performance hit to unmap and remap them all.
*/
BIGBLOCKFILE_DeleteList(This, This->victimhead);
This->victimhead = NULL;
This->victimtail = NULL;
This->num_victim_pages = 0;
BIGBLOCKFILE_UnmapAllMappedPages(This);
if (This->fileBased)
{
char buf[10];
DWORD w;
LARGE_INTEGER newpos;
/*
* close file-mapping object, must be done before call to SetEndFile
*/
if( This->hfilemap )
CloseHandle(This->hfilemap);
This->hfilemap = 0;
newpos.QuadPart = newSize.QuadPart;
if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
{
if( This->hfilemap ) CloseHandle(This->hfilemap);
/*
* 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, &w, NULL);
/*
* END HACK
*/
SetEndOfFile(This->hfile);
/*
* 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);
/*
* re-create the file mapping object
*/
This->hfilemap = CreateFileMappingA(This->hfile,
NULL,
This->flProtect,
0, 0,
NULL);
}
}
else
{
@@ -499,85 +422,6 @@ 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]
*
@@ -686,13 +530,15 @@ static BOOL BIGBLOCKFILE_MapPage(LPBIGBLOCKFILE This, MappedPage *page)
page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
lowoffset, numBytesToMap);
page->mapped_bytes = numBytesToMap;
}
else
{
page->lpBytes = (LPBYTE)This->pbytearray + lowoffset;
page->mapped_bytes = PAGE_SIZE;
}
TRACE("mapped page %lu to %p\n", page->page_index, page->lpBytes);
TRACE("mapped page %u to %p\n", page->page_index, page->lpBytes);
return page->lpBytes != NULL;
}
@@ -712,7 +558,11 @@ static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
page->next = NULL;
page->prev = NULL;
BIGBLOCKFILE_MapPage(This, page);
if (!BIGBLOCKFILE_MapPage(This, page))
{
HeapFree(GetProcessHeap(),0,page);
return NULL;
}
BIGBLOCKFILE_Zero(&page->readable_blocks);
BIGBLOCKFILE_Zero(&page->writable_blocks);
@@ -722,7 +572,7 @@ static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page)
{
TRACE("%ld at %p\n", page->page_index, page->lpBytes);
TRACE("%d at %p\n", page->page_index, page->lpBytes);
if (page->refcnt > 0)
ERR("unmapping inuse page %p\n", page->lpBytes);
@@ -836,7 +686,7 @@ static void BIGBLOCKFILE_RemapList(LPBIGBLOCKFILE This, MappedPage *list)
if (list->page_index * PAGE_SIZE > This->filesize.u.LowPart)
{
TRACE("discarding %lu\n", list->page_index);
TRACE("discarding %u\n", list->page_index);
/* page is entirely outside of the file, delete it */
BIGBLOCKFILE_UnlinkPage(list);
@@ -874,3 +724,206 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
}
return PAGE_READONLY;
}
/* ILockByte Interfaces */
/******************************************************************************
* 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.
*/
static HRESULT WINAPI ImplBIGBLOCKFILE_ReadAt(
BigBlockFile* const This,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [length_is][size_is][out] */
ULONG cb, /* [in] */
ULONG* pcbRead) /* [out] */
{
ULONG first_page = ulOffset.u.LowPart / PAGE_SIZE;
ULONG offset_in_page = ulOffset.u.LowPart % PAGE_SIZE;
ULONG bytes_left = cb;
ULONG page_index = first_page;
ULONG bytes_from_page;
LPVOID writePtr = pv;
HRESULT rc = S_OK;
TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbRead);
/* verify a sane environment */
if (!This) return E_FAIL;
if (offset_in_page + bytes_left > PAGE_SIZE)
bytes_from_page = PAGE_SIZE - offset_in_page;
else
bytes_from_page = bytes_left;
if (pcbRead)
*pcbRead = 0;
while (bytes_left)
{
LPBYTE readPtr;
BOOL eof = FALSE;
MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index);
if (!page || !page->lpBytes)
{
rc = STG_E_READFAULT;
break;
}
TRACE("page %i, offset %u, bytes_from_page %u, bytes_left %u\n",
page->page_index, offset_in_page, bytes_from_page, bytes_left);
if (page->mapped_bytes < bytes_from_page)
{
eof = TRUE;
bytes_from_page = page->mapped_bytes;
}
readPtr = (BYTE*)page->lpBytes + offset_in_page;
memcpy(writePtr,readPtr,bytes_from_page);
BIGBLOCKFILE_ReleaseMappedPage(This, page);
if (pcbRead)
*pcbRead += bytes_from_page;
bytes_left -= bytes_from_page;
if (bytes_left && !eof)
{
writePtr = (LPBYTE)writePtr + bytes_from_page;
page_index ++;
offset_in_page = 0;
if (bytes_left > PAGE_SIZE)
bytes_from_page = PAGE_SIZE;
else
bytes_from_page = bytes_left;
}
if (eof)
{
rc = STG_E_READFAULT;
break;
}
}
TRACE("finished\n");
return rc;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It writes the specified bytes at the specified offset.
* position. If the file is too small, it will be resized.
*
* See the documentation of ILockBytes for more info.
*/
static HRESULT WINAPI ImplBIGBLOCKFILE_WriteAt(
BigBlockFile* const This,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [size_is][in] */
ULONG cb, /* [in] */
ULONG* pcbWritten) /* [out] */
{
ULONG size_needed = ulOffset.u.LowPart + cb;
ULONG first_page = ulOffset.u.LowPart / PAGE_SIZE;
ULONG offset_in_page = ulOffset.u.LowPart % PAGE_SIZE;
ULONG bytes_left = cb;
ULONG page_index = first_page;
ULONG bytes_to_page;
LPCVOID readPtr = pv;
HRESULT rc = S_OK;
TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbWritten);
/* verify a sane environment */
if (!This) return E_FAIL;
if (This->flProtect != PAGE_READWRITE)
return STG_E_ACCESSDENIED;
if (size_needed > This->filesize.u.LowPart)
{
ULARGE_INTEGER newSize;
newSize.u.HighPart = 0;
newSize.u.LowPart = size_needed;
BIGBLOCKFILE_SetSize(This, newSize);
}
if (offset_in_page + bytes_left > PAGE_SIZE)
bytes_to_page = PAGE_SIZE - offset_in_page;
else
bytes_to_page = bytes_left;
if (pcbWritten)
*pcbWritten = 0;
while (bytes_left)
{
LPBYTE writePtr;
MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index);
TRACE("page %i, offset %u, bytes_to_page %u, bytes_left %u\n",
page ? page->page_index : 0, offset_in_page, bytes_to_page, bytes_left);
if (!page)
{
ERR("Unable to get a page to write. This should never happen\n");
rc = E_FAIL;
break;
}
if (page->mapped_bytes < bytes_to_page)
{
ERR("Not enough bytes mapped to the page. This should never happen\n");
rc = E_FAIL;
break;
}
writePtr = (BYTE*)page->lpBytes + offset_in_page;
memcpy(writePtr,readPtr,bytes_to_page);
BIGBLOCKFILE_ReleaseMappedPage(This, page);
if (pcbWritten)
*pcbWritten += bytes_to_page;
bytes_left -= bytes_to_page;
if (bytes_left)
{
readPtr = (LPBYTE)readPtr + bytes_to_page;
page_index ++;
offset_in_page = 0;
if (bytes_left > PAGE_SIZE)
bytes_to_page = PAGE_SIZE;
else
bytes_to_page = bytes_left;
}
}
return rc;
}
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, ULONG size, ULONG* bytesRead)
{
if (This->fileBased)
return ImplBIGBLOCKFILE_ReadAt(This,offset,buffer,size,bytesRead);
else
return ILockBytes_ReadAt(This->pLkbyt,offset,buffer,size,bytesRead);
}
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, const ULONG size, ULONG* bytesRead)
{
if (This->fileBased)
return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);
else
return ILockBytes_WriteAt(This->pLkbyt,offset,buffer,size,bytesRead);
}
+343 -102
View File
@@ -23,7 +23,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* There's a decent overview of property set storage here:
* http://msdn.microsoft.com/archive/en-us/dnarolegen/html/msdn_propset.asp
@@ -39,7 +39,6 @@
* - Not all PROPVARIANT types are supported.
* - User defined properties are not supported, see comment in
* PropertyStorage_ReadFromStream
* - IPropertyStorage::Enum is unimplemented
*/
#include <assert.h>
@@ -60,6 +59,7 @@
#include "wine/debug.h"
#include "dictionary.h"
#include "storage32.h"
#include "enumx.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);
@@ -82,6 +82,11 @@ static inline StorageImpl *impl_from_IPropertySetStorage( IPropertySetStorage *i
#define MAX_VERSION_0_PROP_NAME_LENGTH 256
#define CFTAG_WINDOWS (-1L)
#define CFTAG_MACINTOSH (-2L)
#define CFTAG_FMTID (-3L)
#define CFTAG_NODATA 0L
/* The format version (and what it implies) is described here:
* http://msdn.microsoft.com/library/en-us/stg/stg/format_version.asp
*/
@@ -112,25 +117,23 @@ typedef struct tagPROPERTYIDOFFSET
DWORD dwOffset; /* from beginning of section */
} PROPERTYIDOFFSET;
struct tagPropertyStorage_impl;
typedef struct tagPropertyStorage_impl PropertyStorage_impl;
/* Initializes the property storage from the stream (and undoes any uncommitted
* changes in the process.) Returns an error if there is an error reading or
* if the stream format doesn't match what's expected.
*/
static HRESULT PropertyStorage_ReadFromStream(struct tagPropertyStorage_impl *);
static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *);
static HRESULT PropertyStorage_WriteToStream(struct tagPropertyStorage_impl *);
static HRESULT PropertyStorage_WriteToStream(PropertyStorage_impl *);
/* Creates the dictionaries used by the property storage. If successful, all
* the dictionaries have been created. If failed, none has been. (This makes
* it a bit easier to deal with destroying them.)
*/
static HRESULT PropertyStorage_CreateDictionaries(
struct tagPropertyStorage_impl *);
static HRESULT PropertyStorage_CreateDictionaries(PropertyStorage_impl *);
static void PropertyStorage_DestroyDictionaries(
struct tagPropertyStorage_impl *);
static void PropertyStorage_DestroyDictionaries(PropertyStorage_impl *);
/* Copies from propvar to prop. If propvar's type is VT_LPSTR, copies the
* string using PropertyStorage_StringCopy.
@@ -149,11 +152,15 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
LCID targetCP);
static const IPropertyStorageVtbl IPropertyStorage_Vtbl;
static const IEnumSTATPROPSETSTGVtbl IEnumSTATPROPSETSTG_Vtbl;
static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl;
static HRESULT create_EnumSTATPROPSETSTG(StorageImpl *, IEnumSTATPROPSETSTG**);
static HRESULT create_EnumSTATPROPSTG(PropertyStorage_impl *, IEnumSTATPROPSTG**);
/***********************************************************************
* Implementation of IPropertyStorage
*/
typedef struct tagPropertyStorage_impl
struct tagPropertyStorage_impl
{
const IPropertyStorageVtbl *vtbl;
LONG ref;
@@ -172,7 +179,7 @@ typedef struct tagPropertyStorage_impl
struct dictionary *name_to_propid;
struct dictionary *propid_to_name;
struct dictionary *propid_to_prop;
} PropertyStorage_impl;
};
/************************************************************************
* IPropertyStorage_fnQueryInterface (IPropertyStorage)
@@ -226,6 +233,7 @@ static ULONG WINAPI IPropertyStorage_fnRelease(
if (This->dirty)
IPropertyStorage_Commit(iface, STGC_DEFAULT);
IStream_Release(This->stm);
This->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->cs);
PropertyStorage_DestroyDictionaries(This);
HeapFree(GetProcessHeap(), 0, This);
@@ -238,7 +246,6 @@ static PROPVARIANT *PropertyStorage_FindProperty(PropertyStorage_impl *This,
{
PROPVARIANT *ret = NULL;
assert(This);
dictionary_find(This->propid_to_prop, (void *)propid, (void **)&ret);
TRACE("returning %p\n", ret);
return ret;
@@ -251,7 +258,6 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName(
PROPVARIANT *ret = NULL;
PROPID propid;
assert(This);
if (!name)
return NULL;
if (This->codePage == CP_UNICODE)
@@ -282,7 +288,6 @@ static LPWSTR PropertyStorage_FindPropertyNameById(PropertyStorage_impl *This,
{
LPWSTR ret = NULL;
assert(This);
dictionary_find(This->propid_to_name, (void *)propid, (void **)&ret);
TRACE("returning %p\n", ret);
return ret;
@@ -298,13 +303,14 @@ static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
PROPVARIANT rgpropvar[])
{
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
HRESULT hr = S_FALSE;
HRESULT hr = S_OK;
ULONG i;
TRACE("(%p, %ld, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (!This)
return E_INVALIDARG;
if (cpspec && (!rgpspec || !rgpropvar))
TRACE("(%p, %d, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (!cpspec)
return S_FALSE;
if (!rgpspec || !rgpropvar)
return E_INVALIDARG;
EnterCriticalSection(&This->cs);
for (i = 0; i < cpspec; i++)
@@ -339,6 +345,8 @@ static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
if (prop)
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop,
GetACP(), This->codePage);
else
hr = S_FALSE;
}
}
}
@@ -353,7 +361,7 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
HRESULT hr = S_OK;
int len;
TRACE("%s, %p, %ld, %ld\n",
TRACE("%s, %p, %d, %d\n",
srcCP == CP_UNICODE ? debugstr_w((LPCWSTR)src) : debugstr_a(src), dst,
dstCP, srcCP);
assert(src);
@@ -386,16 +394,20 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
}
else
{
LPWSTR wideStr;
LPCWSTR wideStr = NULL;
LPWSTR wideStr_tmp = NULL;
if (srcCP == CP_UNICODE)
wideStr = (LPWSTR)src;
wideStr = (LPCWSTR)src;
else
{
len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
wideStr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (wideStr)
MultiByteToWideChar(srcCP, 0, src, -1, wideStr, len);
wideStr_tmp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (wideStr_tmp)
{
MultiByteToWideChar(srcCP, 0, src, -1, wideStr_tmp, len);
wideStr = wideStr_tmp;
}
else
hr = STG_E_INSUFFICIENTMEMORY;
}
@@ -419,11 +431,10 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
}
}
}
if (wideStr != (LPWSTR)src)
HeapFree(GetProcessHeap(), 0, wideStr);
HeapFree(GetProcessHeap(), 0, wideStr_tmp);
}
}
TRACE("returning 0x%08lx (%s)\n", hr,
TRACE("returning 0x%08x (%s)\n", hr,
dstCP == CP_UNICODE ? debugstr_w((LPCWSTR)*dst) : debugstr_a(*dst));
return hr;
}
@@ -460,7 +471,6 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
HRESULT hr = S_OK;
PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);
assert(This);
assert(propvar);
if (propvar->vt & VT_BYREF || propvar->vt & VT_ARRAY)
This->format = 1;
@@ -473,7 +483,7 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
case VT_VECTOR|VT_I1:
This->format = 1;
}
TRACE("Setting 0x%08lx to type %d\n", propid, propvar->vt);
TRACE("Setting 0x%08x to type %d\n", propid, propvar->vt);
if (prop)
{
PropVariantClear(prop);
@@ -531,7 +541,7 @@ static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This,
if (strlen(name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
This->format = 1;
}
TRACE("Adding prop name %s, propid %ld\n",
TRACE("Adding prop name %s, propid %d\n",
This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) :
debugstr_a(name), id);
dictionary_insert(This->name_to_propid, name, (void *)id);
@@ -554,9 +564,8 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
HRESULT hr = S_OK;
ULONG i;
TRACE("(%p, %ld, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (cpspec && (!rgpspec || !rgpropvar))
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@@ -654,9 +663,8 @@ static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
ULONG i;
HRESULT hr;
TRACE("(%p, %ld, %p)\n", iface, cpspec, rgpspec);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p)\n", iface, cpspec, rgpspec);
if (cpspec && !rgpspec)
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@@ -703,9 +711,8 @@ static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
ULONG i;
HRESULT hr = S_FALSE;
TRACE("(%p, %ld, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (cpropid && (!rgpropid || !rglpwstrName))
return E_INVALIDARG;
EnterCriticalSection(&This->cs);
@@ -744,9 +751,8 @@ static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
ULONG i;
HRESULT hr;
TRACE("(%p, %ld, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (cpropid && (!rgpropid || !rglpwstrName))
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@@ -778,9 +784,8 @@ static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
ULONG i;
HRESULT hr;
TRACE("(%p, %ld, %p)\n", iface, cpropid, rgpropid);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p)\n", iface, cpropid, rgpropid);
if (cpropid && !rgpropid)
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@@ -815,9 +820,8 @@ static HRESULT WINAPI IPropertyStorage_fnCommit(
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
HRESULT hr;
TRACE("(%p, 0x%08lx)\n", iface, grfCommitFlags);
if (!This)
return E_INVALIDARG;
TRACE("(%p, 0x%08x)\n", iface, grfCommitFlags);
if (!(This->grfMode & STGM_READWRITE))
return STG_E_ACCESSDENIED;
EnterCriticalSection(&This->cs);
@@ -839,8 +843,6 @@ static HRESULT WINAPI IPropertyStorage_fnRevert(
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
TRACE("%p\n", iface);
if (!This)
return E_INVALIDARG;
EnterCriticalSection(&This->cs);
if (This->dirty)
@@ -863,8 +865,8 @@ static HRESULT WINAPI IPropertyStorage_fnEnum(
IPropertyStorage* iface,
IEnumSTATPROPSTG** ppenum)
{
FIXME("\n");
return E_NOTIMPL;
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
return create_EnumSTATPROPSTG(This, ppenum);
}
/************************************************************************
@@ -890,7 +892,8 @@ static HRESULT WINAPI IPropertyStorage_fnSetClass(
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
TRACE("%p, %s\n", iface, debugstr_guid(clsid));
if (!This || !clsid)
if (!clsid)
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
return STG_E_ACCESSDENIED;
@@ -913,7 +916,8 @@ static HRESULT WINAPI IPropertyStorage_fnStat(
HRESULT hr;
TRACE("%p, %p\n", iface, statpsstg);
if (!This || !statpsstg)
if (!statpsstg)
return E_INVALIDARG;
hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
@@ -961,7 +965,7 @@ static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
static int PropertyStorage_PropCompare(const void *a, const void *b,
void *extra)
{
TRACE("(%ld, %ld)\n", (PROPID)a, (PROPID)b);
TRACE("(%d, %d)\n", (PROPID)a, (PROPID)b);
return (PROPID)a - (PROPID)b;
}
@@ -1000,12 +1004,11 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
DWORD numEntries, i;
HRESULT hr = S_OK;
assert(This);
assert(This->name_to_propid);
assert(This->propid_to_name);
StorageUtl_ReadDWord(ptr, 0, &numEntries);
TRACE("Reading %ld entries:\n", numEntries);
TRACE("Reading %d entries:\n", numEntries);
ptr += sizeof(DWORD);
for (i = 0; SUCCEEDED(hr) && i < numEntries; i++)
{
@@ -1016,7 +1019,7 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
ptr += sizeof(PROPID);
StorageUtl_ReadDWord(ptr, 0, &cbEntry);
ptr += sizeof(DWORD);
TRACE("Reading entry with ID 0x%08lx, %ld bytes\n", propid, cbEntry);
TRACE("Reading entry with ID 0x%08x, %d bytes\n", propid, cbEntry);
/* Make sure the source string is NULL-terminated */
if (This->codePage != CP_UNICODE)
ptr[cbEntry - 1] = '\0';
@@ -1075,7 +1078,7 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
case VT_UINT:
case VT_UI4:
StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
TRACE("Read ulong %ld\n", prop->u.ulVal);
TRACE("Read ulong %d\n", prop->u.ulVal);
break;
case VT_LPSTR:
{
@@ -1138,6 +1141,25 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
StorageUtl_ReadULargeInteger(data, 0,
(ULARGE_INTEGER *)&prop->u.filetime);
break;
case VT_CF:
{
DWORD len = 0, tag = 0;
StorageUtl_ReadDWord(data, 0, &len);
StorageUtl_ReadDWord(data, 4, &tag);
if (len > 8)
{
len -= 8;
prop->u.pclipdata = CoTaskMemAlloc(sizeof (CLIPDATA));
prop->u.pclipdata->cbSize = len;
prop->u.pclipdata->ulClipFmt = tag;
prop->u.pclipdata->pClipData = CoTaskMemAlloc(len);
memcpy(prop->u.pclipdata->pClipData, data+8, len);
}
else
hr = STG_E_INVALIDPARAMETER;
}
break;
default:
FIXME("unsupported type %d\n", prop->vt);
hr = STG_E_INVALIDPARAMETER;
@@ -1159,7 +1181,7 @@ static HRESULT PropertyStorage_ReadHeaderFromStream(IStream *stm,
{
if (count != sizeof(buf))
{
WARN("read %ld, expected %d\n", count, sizeof(buf));
WARN("read only %d\n", count);
hr = STG_E_INVALIDHEADER;
}
else
@@ -1176,7 +1198,7 @@ static HRESULT PropertyStorage_ReadHeaderFromStream(IStream *stm,
&hdr->reserved);
}
}
TRACE("returning 0x%08lx\n", hr);
TRACE("returning 0x%08x\n", hr);
return hr;
}
@@ -1194,7 +1216,7 @@ static HRESULT PropertyStorage_ReadFmtIdOffsetFromStream(IStream *stm,
{
if (count != sizeof(buf))
{
WARN("read %ld, expected %d\n", count, sizeof(buf));
WARN("read only %d\n", count);
hr = STG_E_INVALIDHEADER;
}
else
@@ -1205,7 +1227,7 @@ static HRESULT PropertyStorage_ReadFmtIdOffsetFromStream(IStream *stm,
&fmt->dwOffset);
}
}
TRACE("returning 0x%08lx\n", hr);
TRACE("returning 0x%08x\n", hr);
return hr;
}
@@ -1223,7 +1245,7 @@ static HRESULT PropertyStorage_ReadSectionHeaderFromStream(IStream *stm,
{
if (count != sizeof(buf))
{
WARN("read %ld, expected %d\n", count, sizeof(buf));
WARN("read only %d\n", count);
hr = STG_E_INVALIDHEADER;
}
else
@@ -1234,7 +1256,7 @@ static HRESULT PropertyStorage_ReadSectionHeaderFromStream(IStream *stm,
cProperties), &hdr->cProperties);
}
}
TRACE("returning 0x%08lx\n", hr);
TRACE("returning 0x%08x\n", hr);
return hr;
}
@@ -1251,7 +1273,6 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
ULONG count = 0;
DWORD dictOffset = 0;
assert(This);
This->dirty = FALSE;
This->highestProp = 0;
hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
@@ -1307,7 +1328,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
goto end;
if (fmtOffset.dwOffset > stat.cbSize.u.LowPart)
{
WARN("invalid offset %ld (stream length is %ld)\n", fmtOffset.dwOffset,
WARN("invalid offset %d (stream length is %d)\n", fmtOffset.dwOffset,
stat.cbSize.u.LowPart);
hr = STG_E_INVALIDHEADER;
goto end;
@@ -1325,8 +1346,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
/* The section size includes the section header, so check it */
if (sectionHdr.cbSection < sizeof(PROPERTYSECTIONHEADER))
{
WARN("section header too small, got %ld, expected at least %d\n",
sectionHdr.cbSection, sizeof(PROPERTYSECTIONHEADER));
WARN("section header too small, got %d\n", sectionHdr.cbSection);
hr = STG_E_INVALIDHEADER;
goto end;
}
@@ -1341,7 +1361,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
sizeof(PROPERTYSECTIONHEADER), &count);
if (FAILED(hr))
goto end;
TRACE("Reading %ld properties:\n", sectionHdr.cProperties);
TRACE("Reading %d properties:\n", sectionHdr.cProperties);
for (i = 0; SUCCEEDED(hr) && i < sectionHdr.cProperties; i++)
{
PROPERTYIDOFFSET *idOffset = (PROPERTYIDOFFSET *)(buf +
@@ -1363,16 +1383,17 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
* later.
*/
dictOffset = idOffset->dwOffset;
TRACE("Dictionary offset is %ld\n", dictOffset);
TRACE("Dictionary offset is %d\n", dictOffset);
}
else
{
PROPVARIANT prop;
PropVariantInit(&prop);
if (SUCCEEDED(PropertyStorage_ReadProperty(This, &prop,
buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER))))
{
TRACE("Read property with ID 0x%08lx, type %d\n",
TRACE("Read property with ID 0x%08x, type %d\n",
idOffset->propid, prop.vt);
switch(idOffset->propid)
{
@@ -1410,7 +1431,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
}
if (!This->locale)
This->locale = LOCALE_SYSTEM_DEFAULT;
TRACE("Code page is %d, locale is %ld\n", This->codePage, This->locale);
TRACE("Code page is %d, locale is %d\n", This->codePage, This->locale);
if (dictOffset)
hr = PropertyStorage_ReadDictionary(This,
buf + dictOffset - sizeof(PROPERTYSECTIONHEADER));
@@ -1432,7 +1453,6 @@ end:
static void PropertyStorage_MakeHeader(PropertyStorage_impl *This,
PROPERTYSETHEADER *hdr)
{
assert(This);
assert(hdr);
StorageUtl_WriteWord((BYTE *)&hdr->wByteOrder, 0,
PROPSETHDR_BYTEORDER_MAGIC);
@@ -1445,7 +1465,6 @@ static void PropertyStorage_MakeHeader(PropertyStorage_impl *This,
static void PropertyStorage_MakeFmtIdOffset(PropertyStorage_impl *This,
FORMATIDOFFSET *fmtOffset)
{
assert(This);
assert(fmtOffset);
StorageUtl_WriteGUID((BYTE *)fmtOffset, 0, &This->fmtid);
StorageUtl_WriteDWord((BYTE *)fmtOffset, offsetof(FORMATIDOFFSET, dwOffset),
@@ -1485,7 +1504,6 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
ULONG count;
assert(key);
assert(This);
assert(closure);
StorageUtl_WriteDWord((LPBYTE)&propid, 0, (DWORD)value);
c->hr = IStream_Write(This->stm, &propid, sizeof(propid), &count);
@@ -1497,7 +1515,7 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
DWORD keyLen, pad = 0;
StorageUtl_WriteDWord((LPBYTE)&keyLen, 0,
(lstrlenW((LPWSTR)key) + 1) * sizeof(WCHAR));
(lstrlenW((LPCWSTR)key) + 1) * sizeof(WCHAR));
c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
if (FAILED(c->hr))
goto end;
@@ -1553,7 +1571,6 @@ static HRESULT PropertyStorage_WriteDictionaryToStream(
DWORD dwTemp;
struct DictionaryClosure closure;
assert(This);
assert(sectionOffset);
/* The dictionary's always the first property written, so seek to its
@@ -1590,9 +1607,9 @@ static HRESULT PropertyStorage_WriteDictionaryToStream(
*sectionOffset += closure.bytesWritten;
if (closure.bytesWritten % sizeof(DWORD))
{
TRACE("adding %ld bytes of padding\n", sizeof(DWORD) -
closure.bytesWritten % sizeof(DWORD));
*sectionOffset += sizeof(DWORD) - closure.bytesWritten % sizeof(DWORD);
DWORD padding = sizeof(DWORD) - closure.bytesWritten % sizeof(DWORD);
TRACE("adding %d bytes of padding\n", padding);
*sectionOffset += padding;
}
end:
@@ -1608,11 +1625,10 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
ULONG count;
DWORD dwType, bytesWritten;
assert(This);
assert(var);
assert(sectionOffset);
TRACE("%p, %ld, 0x%08lx, (%d), (%ld)\n", This, propNum, propid, var->vt,
TRACE("%p, %d, 0x%08x, (%d), (%d)\n", This, propNum, propid, var->vt,
*sectionOffset);
seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER) +
@@ -1706,6 +1722,22 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
bytesWritten = count;
break;
}
case VT_CF:
{
DWORD cf_hdr[2], len;
len = var->u.pclipdata->cbSize;
StorageUtl_WriteDWord((LPBYTE)&cf_hdr[0], 0, len + 8);
StorageUtl_WriteDWord((LPBYTE)&cf_hdr[1], 0, var->u.pclipdata->ulClipFmt);
hr = IStream_Write(This->stm, &cf_hdr, sizeof(cf_hdr), &count);
if (FAILED(hr))
goto end;
hr = IStream_Write(This->stm, &var->u.pclipdata->pClipData, len, &count);
if (FAILED(hr))
goto end;
bytesWritten = count + sizeof cf_hdr;
break;
}
default:
FIXME("unsupported type: %d\n", var->vt);
return STG_E_INVALIDPARAMETER;
@@ -1716,9 +1748,9 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
*sectionOffset += bytesWritten;
if (bytesWritten % sizeof(DWORD))
{
TRACE("adding %ld bytes of padding\n", sizeof(DWORD) -
bytesWritten % sizeof(DWORD));
*sectionOffset += sizeof(DWORD) - bytesWritten % sizeof(DWORD);
DWORD padding = sizeof(DWORD) - bytesWritten % sizeof(DWORD);
TRACE("adding %d bytes of padding\n", padding);
*sectionOffset += padding;
}
}
@@ -1753,7 +1785,6 @@ static HRESULT PropertyStorage_WritePropertiesToStream(
{
struct PropertyClosure closure;
assert(This);
assert(sectionOffset);
closure.hr = S_OK;
closure.propNum = startingPropNum;
@@ -1771,7 +1802,6 @@ static HRESULT PropertyStorage_WriteHeadersToStream(PropertyStorage_impl *This)
PROPERTYSETHEADER hdr;
FORMATIDOFFSET fmtOffset;
assert(This);
hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr))
goto end;
@@ -1809,8 +1839,6 @@ static HRESULT PropertyStorage_WriteToStream(PropertyStorage_impl *This)
DWORD numProps, prop, sectionOffset, dwTemp;
PROPVARIANT var;
assert(This);
PropertyStorage_WriteHeadersToStream(This);
/* Count properties. Always at least one property, the code page */
@@ -1897,7 +1925,6 @@ end:
*/
static void PropertyStorage_DestroyDictionaries(PropertyStorage_impl *This)
{
assert(This);
dictionary_destroy(This->name_to_propid);
This->name_to_propid = NULL;
dictionary_destroy(This->propid_to_name);
@@ -1910,7 +1937,6 @@ static HRESULT PropertyStorage_CreateDictionaries(PropertyStorage_impl *This)
{
HRESULT hr = S_OK;
assert(This);
This->name_to_propid = dictionary_create(
PropertyStorage_PropNameCompare, PropertyStorage_PropNameDestroy,
This);
@@ -1953,6 +1979,7 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
(*pps)->vtbl = &IPropertyStorage_Vtbl;
(*pps)->ref = 1;
InitializeCriticalSection(&(*pps)->cs);
(*pps)->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStorage_impl.cs");
(*pps)->stm = stm;
memcpy(&(*pps)->fmtid, rfmtid, sizeof((*pps)->fmtid));
(*pps)->grfMode = grfMode;
@@ -1961,6 +1988,7 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
if (FAILED(hr))
{
IStream_Release(stm);
(*pps)->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&(*pps)->cs);
HeapFree(GetProcessHeap(), 0, *pps);
*pps = NULL;
@@ -2017,7 +2045,7 @@ static HRESULT PropertyStorage_ConstructEmpty(IStream *stm,
else
ps->codePage = CP_UNICODE;
ps->locale = LOCALE_SYSTEM_DEFAULT;
TRACE("Code page is %d, locale is %ld\n", ps->codePage, ps->locale);
TRACE("Code page is %d, locale is %d\n", ps->codePage, ps->locale);
*pps = (IPropertyStorage *)ps;
TRACE("PropertyStorage %p constructed\n", ps);
hr = S_OK;
@@ -2084,7 +2112,7 @@ static HRESULT WINAPI IPropertySetStorage_fnCreate(
IStream *stm = NULL;
HRESULT r;
TRACE("%p %s %08lx %08lx %p\n", This, debugstr_guid(rfmtid), grfFlags,
TRACE("%p %s %08x %08x %p\n", This, debugstr_guid(rfmtid), grfFlags,
grfMode, ppprstg);
/* be picky */
@@ -2121,7 +2149,7 @@ static HRESULT WINAPI IPropertySetStorage_fnCreate(
r = PropertyStorage_ConstructEmpty(stm, rfmtid, grfFlags, grfMode, ppprstg);
end:
TRACE("returning 0x%08lx\n", r);
TRACE("returning 0x%08x\n", r);
return r;
}
@@ -2139,7 +2167,7 @@ static HRESULT WINAPI IPropertySetStorage_fnOpen(
WCHAR name[CCH_MAX_PROPSTG_NAME];
HRESULT r;
TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
TRACE("%p %s %08x %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
/* be picky */
if (grfMode != (STGM_READWRITE|STGM_SHARE_EXCLUSIVE) &&
@@ -2166,7 +2194,7 @@ static HRESULT WINAPI IPropertySetStorage_fnOpen(
r = PropertyStorage_ConstructFromStream(stm, rfmtid, grfMode, ppprstg);
end:
TRACE("returning 0x%08lx\n", r);
TRACE("returning 0x%08x\n", r);
return r;
}
@@ -2203,10 +2231,201 @@ static HRESULT WINAPI IPropertySetStorage_fnEnum(
IEnumSTATPROPSETSTG** ppenum)
{
StorageImpl *This = impl_from_IPropertySetStorage(ppstg);
FIXME("%p\n", This);
return E_NOTIMPL;
return create_EnumSTATPROPSETSTG(This, ppenum);
}
/************************************************************************
* Implement IEnumSTATPROPSETSTG using enumx
*/
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnQueryInterface(
IEnumSTATPROPSETSTG *iface,
REFIID riid,
void** ppvObject)
{
return enumx_QueryInterface((enumx_impl*)iface, riid, ppvObject);
}
static ULONG WINAPI IEnumSTATPROPSETSTG_fnAddRef(
IEnumSTATPROPSETSTG *iface)
{
return enumx_AddRef((enumx_impl*)iface);
}
static ULONG WINAPI IEnumSTATPROPSETSTG_fnRelease(
IEnumSTATPROPSETSTG *iface)
{
return enumx_Release((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnNext(
IEnumSTATPROPSETSTG *iface,
ULONG celt,
STATPROPSETSTG *rgelt,
ULONG *pceltFetched)
{
return enumx_Next((enumx_impl*)iface, celt, rgelt, pceltFetched);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnSkip(
IEnumSTATPROPSETSTG *iface,
ULONG celt)
{
return enumx_Skip((enumx_impl*)iface, celt);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnReset(
IEnumSTATPROPSETSTG *iface)
{
return enumx_Reset((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnClone(
IEnumSTATPROPSETSTG *iface,
IEnumSTATPROPSETSTG **ppenum)
{
return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
}
static HRESULT create_EnumSTATPROPSETSTG(
StorageImpl *This,
IEnumSTATPROPSETSTG** ppenum)
{
IStorage *stg = (IStorage*) &This->base.lpVtbl;
IEnumSTATSTG *penum = NULL;
STATSTG stat;
ULONG count;
HRESULT r;
STATPROPSETSTG statpss;
enumx_impl *enumx;
TRACE("%p %p\n", This, ppenum);
enumx = enumx_allocate(&IID_IEnumSTATPROPSETSTG,
&IEnumSTATPROPSETSTG_Vtbl,
sizeof (STATPROPSETSTG));
/* add all the property set elements into a list */
r = IStorage_EnumElements(stg, 0, NULL, 0, &penum);
if (FAILED(r))
return E_OUTOFMEMORY;
while (1)
{
count = 0;
r = IEnumSTATSTG_Next(penum, 1, &stat, &count);
if (FAILED(r))
break;
if (!count)
break;
if (!stat.pwcsName)
continue;
if (stat.pwcsName[0] == 5 && stat.type == STGTY_STREAM)
{
PropStgNameToFmtId(stat.pwcsName, &statpss.fmtid);
TRACE("adding %s (%s)\n", debugstr_w(stat.pwcsName),
debugstr_guid(&statpss.fmtid));
statpss.mtime = stat.mtime;
statpss.atime = stat.atime;
statpss.ctime = stat.ctime;
statpss.grfFlags = stat.grfMode;
memcpy(&statpss.clsid, &stat.clsid, sizeof stat.clsid);
enumx_add_element(enumx, &statpss);
}
CoTaskMemFree(stat.pwcsName);
}
IEnumSTATSTG_Release(penum);
*ppenum = (IEnumSTATPROPSETSTG*) enumx;
return S_OK;
}
/************************************************************************
* Implement IEnumSTATPROPSTG using enumx
*/
static HRESULT WINAPI IEnumSTATPROPSTG_fnQueryInterface(
IEnumSTATPROPSTG *iface,
REFIID riid,
void** ppvObject)
{
return enumx_QueryInterface((enumx_impl*)iface, riid, ppvObject);
}
static ULONG WINAPI IEnumSTATPROPSTG_fnAddRef(
IEnumSTATPROPSTG *iface)
{
return enumx_AddRef((enumx_impl*)iface);
}
static ULONG WINAPI IEnumSTATPROPSTG_fnRelease(
IEnumSTATPROPSTG *iface)
{
return enumx_Release((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnNext(
IEnumSTATPROPSTG *iface,
ULONG celt,
STATPROPSTG *rgelt,
ULONG *pceltFetched)
{
return enumx_Next((enumx_impl*)iface, celt, rgelt, pceltFetched);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnSkip(
IEnumSTATPROPSTG *iface,
ULONG celt)
{
return enumx_Skip((enumx_impl*)iface, celt);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnReset(
IEnumSTATPROPSTG *iface)
{
return enumx_Reset((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnClone(
IEnumSTATPROPSTG *iface,
IEnumSTATPROPSTG **ppenum)
{
return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
}
static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
{
enumx_impl *enumx = arg;
PROPID propid = (PROPID) k;
const PROPVARIANT *prop = v;
STATPROPSTG stat;
stat.lpwstrName = NULL;
stat.propid = propid;
stat.vt = prop->vt;
enumx_add_element(enumx, &stat);
return TRUE;
}
static HRESULT create_EnumSTATPROPSTG(
PropertyStorage_impl *This,
IEnumSTATPROPSTG** ppenum)
{
enumx_impl *enumx;
TRACE("%p %p\n", This, ppenum);
enumx = enumx_allocate(&IID_IEnumSTATPROPSTG,
&IEnumSTATPROPSTG_Vtbl,
sizeof (STATPROPSTG));
dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx);
*ppenum = (IEnumSTATPROPSTG*) enumx;
return S_OK;
}
/***********************************************************************
* vtables
@@ -2241,6 +2460,28 @@ static const IPropertyStorageVtbl IPropertyStorage_Vtbl =
IPropertyStorage_fnStat,
};
static const IEnumSTATPROPSETSTGVtbl IEnumSTATPROPSETSTG_Vtbl =
{
IEnumSTATPROPSETSTG_fnQueryInterface,
IEnumSTATPROPSETSTG_fnAddRef,
IEnumSTATPROPSETSTG_fnRelease,
IEnumSTATPROPSETSTG_fnNext,
IEnumSTATPROPSETSTG_fnSkip,
IEnumSTATPROPSETSTG_fnReset,
IEnumSTATPROPSETSTG_fnClone,
};
static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl =
{
IEnumSTATPROPSTG_fnQueryInterface,
IEnumSTATPROPSTG_fnAddRef,
IEnumSTATPROPSTG_fnRelease,
IEnumSTATPROPSTG_fnNext,
IEnumSTATPROPSTG_fnSkip,
IEnumSTATPROPSTG_fnReset,
IEnumSTATPROPSTG_fnClone,
};
/***********************************************************************
* Format ID <-> name conversion
*/
@@ -2286,12 +2527,12 @@ HRESULT WINAPI FmtIdToPropStgName(const FMTID *rfmtid, LPOLESTR str)
lstrcpyW(str, szDocSummaryInfo);
else
{
BYTE *fmtptr;
const BYTE *fmtptr;
WCHAR *pstr = str;
ULONG bitsRemaining = BITS_PER_BYTE;
*pstr++ = 5;
for (fmtptr = (BYTE *)rfmtid; fmtptr < (BYTE *)rfmtid + sizeof(FMTID); )
for (fmtptr = (const BYTE *)rfmtid; fmtptr < (const BYTE *)rfmtid + sizeof(FMTID); )
{
ULONG i = *fmtptr >> (BITS_PER_BYTE - bitsRemaining);
+153 -31
View File
@@ -20,7 +20,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@@ -58,8 +58,21 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This)
/*
* Release the reference we are holding on the parent storage.
* IStorage_Release((IStorage*)This->parentStorage);
*
* No, don't do this. Some apps call IStorage_Release without
* calling IStream_Release first. If we grab a reference the
* file is not closed, and the app fails when it tries to
* reopen the file (Easy-PC, for example). Just inform the
* storage that we have closed the stream
*/
IStorage_Release((IStorage*)This->parentStorage);
if(This->parentStorage) {
StorageBaseImpl_RemoveStream(This->parentStorage, This);
}
This->parentStorage = 0;
/*
@@ -108,8 +121,11 @@ static HRESULT WINAPI StgStreamImpl_QueryInterface(
/*
* Compare the riid with the interface IDs implemented by this object.
*/
if (IsEqualGUID(&IID_IUnknown, riid)||
IsEqualGUID(&IID_IStream, riid))
if (IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_IPersist, riid) ||
IsEqualIID(&IID_IPersistStream, riid) ||
IsEqualIID(&IID_ISequentialStream, riid) ||
IsEqualIID(&IID_IStream, riid))
{
*ppvObject = (IStream*)This;
}
@@ -173,7 +189,7 @@ static void StgStreamImpl_OpenBlockChain(
StgStreamImpl* This)
{
StgProperty curProperty;
BOOL readSucessful;
BOOL readSuccessful;
/*
* Make sure no old object is left over.
@@ -193,11 +209,11 @@ static void StgStreamImpl_OpenBlockChain(
/*
* Read the information from the property.
*/
readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
if (readSucessful)
if (readSuccessful)
{
This->streamSize = curProperty.size;
@@ -251,9 +267,15 @@ static HRESULT WINAPI StgStreamImpl_Read(
ULONG bytesToReadFromBuffer;
HRESULT res;
TRACE("(%p, %p, %ld, %p)\n",
TRACE("(%p, %p, %d, %p)\n",
iface, pv, cb, pcbRead);
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* If the caller is not interested in the number of bytes read,
* we use another buffer to avoid "if" statements in the code.
@@ -282,15 +304,11 @@ static HRESULT WINAPI StgStreamImpl_Read(
}
else if (This->bigBlockChain!=0)
{
BOOL success = BlockChainStream_ReadAt(This->bigBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
if (success)
res = S_OK;
else
res = STG_E_READFAULT;
res = BlockChainStream_ReadAt(This->bigBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
}
else
{
@@ -319,7 +337,7 @@ static HRESULT WINAPI StgStreamImpl_Read(
}
end:
TRACE("<-- %08lx\n", res);
TRACE("<-- %08x\n", res);
return res;
}
@@ -343,8 +361,9 @@ static HRESULT WINAPI StgStreamImpl_Write(
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
HRESULT res;
TRACE("(%p, %p, %ld, %p)\n",
TRACE("(%p, %p, %d, %p)\n",
iface, pv, cb, pcbWritten);
/*
@@ -356,12 +375,19 @@ static HRESULT WINAPI StgStreamImpl_Write(
case STGM_READWRITE:
break;
default:
WARN("access denied by flags: 0x%x\n", STGM_ACCESS_MODE(This->grfMode));
return STG_E_ACCESSDENIED;
}
if (!pv)
return STG_E_INVALIDPOINTER;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* If the caller is not interested in the number of bytes written,
* we use another buffer to avoid "if" statements in the code.
@@ -376,6 +402,7 @@ static HRESULT WINAPI StgStreamImpl_Write(
if (cb == 0)
{
TRACE("<-- S_OK, written 0\n");
return S_OK;
}
else
@@ -390,7 +417,9 @@ static HRESULT WINAPI StgStreamImpl_Write(
if (newSize.u.LowPart > This->streamSize.u.LowPart)
{
/* grow stream */
IStream_SetSize(iface, newSize);
res = IStream_SetSize(iface, newSize);
if (FAILED(res))
return res;
}
/*
@@ -399,7 +428,7 @@ static HRESULT WINAPI StgStreamImpl_Write(
*/
if (This->smallBlockChain!=0)
{
SmallBlockChainStream_WriteAt(This->smallBlockChain,
res = SmallBlockChainStream_WriteAt(This->smallBlockChain,
This->currentPosition,
cb,
pv,
@@ -408,21 +437,27 @@ static HRESULT WINAPI StgStreamImpl_Write(
}
else if (This->bigBlockChain!=0)
{
BlockChainStream_WriteAt(This->bigBlockChain,
res = BlockChainStream_WriteAt(This->bigBlockChain,
This->currentPosition,
cb,
pv,
pcbWritten);
}
else
{
/* this should never happen because the IStream_SetSize call above will
* make sure a big or small block chain is created */
assert(FALSE);
res = 0;
}
/*
* Advance the position pointer for the number of positions written.
*/
This->currentPosition.u.LowPart += *pcbWritten;
return S_OK;
TRACE("<-- S_OK, written %u\n", *pcbWritten);
return res;
}
/***
@@ -443,9 +478,19 @@ static HRESULT WINAPI StgStreamImpl_Seek(
ULARGE_INTEGER newPosition;
TRACE("(%p, %ld, %ld, %p)\n",
TRACE("(%p, %d, %d, %p)\n",
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
/*
* fail if the stream has no parent (as does windows)
*/
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* 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
@@ -473,6 +518,7 @@ static HRESULT WINAPI StgStreamImpl_Seek(
*plibNewPosition = This->streamSize;
break;
default:
WARN("invalid dwOrigin %d\n", dwOrigin);
return STG_E_INVALIDFUNCTION;
}
@@ -504,19 +550,31 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
StgProperty curProperty;
BOOL Success;
TRACE("(%p, %ld)\n", iface, libNewSize.u.LowPart);
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
if(!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* As documented.
*/
if (libNewSize.u.HighPart != 0)
{
WARN("invalid value for libNewSize.u.HighPart %d\n", libNewSize.u.HighPart);
return STG_E_INVALIDFUNCTION;
}
/*
* Do we have permission?
*/
if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
{
WARN("access denied\n");
return STG_E_ACCESSDENIED;
}
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
@@ -609,18 +667,26 @@ static HRESULT WINAPI StgStreamImpl_CopyTo(
ULARGE_INTEGER* pcbRead, /* [out] */
ULARGE_INTEGER* pcbWritten) /* [out] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
HRESULT hr = S_OK;
BYTE tmpBuffer[128];
ULONG bytesRead, bytesWritten, copySize;
ULARGE_INTEGER totalBytesRead;
ULARGE_INTEGER totalBytesWritten;
TRACE("(%p, %p, %ld, %p, %p)\n",
TRACE("(%p, %p, %d, %p, %p)\n",
iface, pstm, cb.u.LowPart, pcbRead, pcbWritten);
/*
* Sanity check
*/
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
if ( pstm == 0 )
return STG_E_INVALIDPOINTER;
@@ -653,6 +719,7 @@ static HRESULT WINAPI StgStreamImpl_CopyTo(
if (bytesRead != bytesWritten)
{
hr = STG_E_MEDIUMFULL;
WARN("medium full\n");
break;
}
@@ -691,6 +758,14 @@ static HRESULT WINAPI StgStreamImpl_Commit(
IStream* iface,
DWORD grfCommitFlags) /* [in] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
return S_OK;
}
@@ -714,6 +789,14 @@ static HRESULT WINAPI StgStreamImpl_LockRegion(
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
FIXME("not implemented!\n");
return E_NOTIMPL;
}
@@ -724,6 +807,14 @@ static HRESULT WINAPI StgStreamImpl_UnlockRegion(
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
FIXME("not implemented!\n");
return E_NOTIMPL;
}
@@ -744,16 +835,28 @@ static HRESULT WINAPI StgStreamImpl_Stat(
StgStreamImpl* const This=(StgStreamImpl*)iface;
StgProperty curProperty;
BOOL readSucessful;
BOOL readSuccessful;
TRACE("%p %p %d\n", This, pstatstg, grfStatFlag);
/*
* if stream has no parent, return STG_E_REVERTED
*/
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* Read the information from the property.
*/
readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
if (readSucessful)
if (readSuccessful)
{
StorageUtl_CopyPropertyToSTATSTG(pstatstg,
&curProperty,
@@ -764,6 +867,7 @@ static HRESULT WINAPI StgStreamImpl_Stat(
return S_OK;
}
WARN("failed to read properties\n");
return E_FAIL;
}
@@ -788,9 +892,15 @@ static HRESULT WINAPI StgStreamImpl_Clone(
StgStreamImpl* new_stream;
LARGE_INTEGER seek_pos;
TRACE("%p %p\n", This, ppstm);
/*
* Sanity check
*/
if (!This->parentStorage)
return STG_E_REVERTED;
if ( ppstm == 0 )
return STG_E_INVALIDPOINTER;
@@ -800,6 +910,8 @@ static HRESULT WINAPI StgStreamImpl_Clone(
return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */
*ppstm = (IStream*) new_stream;
IStream_AddRef(*ppstm);
seek_pos.QuadPart = This->currentPosition.QuadPart;
hres=StgStreamImpl_Seek (*ppstm, seek_pos, STREAM_SEEK_SET, NULL);
@@ -858,12 +970,19 @@ StgStreamImpl* StgStreamImpl_Construct(
newStream->lpVtbl = &StgStreamImpl_Vtbl;
newStream->ref = 0;
newStream->parentStorage = parentStorage;
/*
* We want to nail-down the reference to the storage in case the
* stream out-lives the storage in the client application.
*
* -- IStorage_AddRef((IStorage*)newStream->parentStorage);
*
* No, don't do this. Some apps call IStorage_Release without
* calling IStream_Release first. If we grab a reference the
* file is not closed, and the app fails when it tries to
* reopen the file (Easy-PC, for example)
*/
newStream->parentStorage = parentStorage;
IStorage_AddRef((IStorage*)newStream->parentStorage);
newStream->grfMode = grfMode;
newStream->ownerProperty = ownerProperty;
@@ -887,6 +1006,9 @@ StgStreamImpl* StgStreamImpl_Construct(
* this stream are large or small.
*/
StgStreamImpl_OpenBlockChain(newStream);
/* add us to the storage's list of active streams */
StorageBaseImpl_AddStream(parentStorage, newStream);
}
return newStream;
+52 -49
View File
@@ -18,7 +18,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@@ -353,12 +353,12 @@ STORAGE_get_big_block(stream_access16 *str,int n,BYTE *block)
if ((SetFilePointer( str->hf, (n+1)*BIGSIZE, NULL,
SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
{
WARN("(%p,%d,%p), seek failed (%ld)\n",str->hf, n, block, GetLastError());
WARN("(%p,%d,%p), seek failed (%d)\n",str->hf, n, block, GetLastError());
return FALSE;
}
if (!ReadFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
{
WARN("(hf=%p, block size %d): read didn't read (%ld)\n",str->hf,n,GetLastError());
WARN("(hf=%p, block size %d): read didn't read (%d)\n",str->hf,n,GetLastError());
return FALSE;
}
} else {
@@ -382,7 +382,7 @@ STORAGE_get_big_block(stream_access16 *str,int n,BYTE *block)
(LPVOID)args,
(LPDWORD)&hres
)) {
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %x\n",hres);
return FALSE;
}
memcpy(block, MapSL(args[3]), BIGSIZE);
@@ -414,7 +414,7 @@ _ilockbytes16_writeat(SEGPTR lockbytes, DWORD offset, DWORD length, void *buffer
(LPVOID)args,
(LPDWORD)&hres
)) {
ERR("CallTo16 ILockBytes16::WriteAt() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::WriteAt() failed, hres %x\n",hres);
return FALSE;
}
UnMapLS(args[3]);
@@ -434,12 +434,12 @@ STORAGE_put_big_block(stream_access16 *str,int n,BYTE *block)
if ((SetFilePointer( str->hf, (n+1)*BIGSIZE, NULL,
SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
{
WARN("seek failed (%ld)\n",GetLastError());
WARN("seek failed (%d)\n",GetLastError());
return FALSE;
}
if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
{
WARN(" write failed (%ld)\n",GetLastError());
WARN(" write failed (%d)\n",GetLastError());
return FALSE;
}
return TRUE;
@@ -719,9 +719,9 @@ STORAGE_dump_pps_entry(struct storage_pps_entry *stde) {
return;
DPRINTF("name: %s\n",name);
DPRINTF("type: %d\n",stde->pps_type);
DPRINTF("prev pps: %ld\n",stde->pps_prev);
DPRINTF("next pps: %ld\n",stde->pps_next);
DPRINTF("dir pps: %ld\n",stde->pps_dir);
DPRINTF("prev pps: %d\n",stde->pps_prev);
DPRINTF("next pps: %d\n",stde->pps_next);
DPRINTF("dir pps: %d\n",stde->pps_dir);
DPRINTF("guid: %s\n",debugstr_guid(&(stde->pps_guid)));
if (stde->pps_type !=2) {
time_t t;
@@ -733,8 +733,8 @@ STORAGE_dump_pps_entry(struct storage_pps_entry *stde) {
t = dw;
DPRINTF("ts2: %s\n",ctime(&t));
}
DPRINTF("startblock: %ld\n",stde->pps_sb);
DPRINTF("size: %ld\n",stde->pps_size);
DPRINTF("startblock: %d\n",stde->pps_sb);
DPRINTF("size: %d\n",stde->pps_size);
}
/******************************************************************************
@@ -1071,7 +1071,7 @@ typedef struct
/******************************************************************************
* IStream16_QueryInterface [STORAGE.518]
*/
HRESULT IStream16_fnQueryInterface(
HRESULT CDECL IStream16_fnQueryInterface(
IStream16* iface,REFIID refiid,LPVOID *obj
) {
IStream16Impl *This = (IStream16Impl *)iface;
@@ -1087,7 +1087,7 @@ HRESULT IStream16_fnQueryInterface(
/******************************************************************************
* IStream16_AddRef [STORAGE.519]
*/
ULONG IStream16_fnAddRef(IStream16* iface) {
ULONG CDECL IStream16_fnAddRef(IStream16* iface) {
IStream16Impl *This = (IStream16Impl *)iface;
return InterlockedIncrement(&This->ref);
}
@@ -1107,7 +1107,7 @@ _ilockbytes16_addref(SEGPTR lockbytes) {
(LPVOID)args,
(LPDWORD)&hres
))
ERR("CallTo16 ILockBytes16::AddRef() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::AddRef() failed, hres %x\n",hres);
}
static void
@@ -1125,7 +1125,7 @@ _ilockbytes16_release(SEGPTR lockbytes) {
(LPVOID)args,
(LPDWORD)&hres
))
ERR("CallTo16 ILockBytes16::Release() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::Release() failed, hres %x\n",hres);
}
static void
@@ -1143,13 +1143,13 @@ _ilockbytes16_flush(SEGPTR lockbytes) {
(LPVOID)args,
(LPDWORD)&hres
))
ERR("CallTo16 ILockBytes16::Flush() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::Flush() failed, hres %x\n",hres);
}
/******************************************************************************
* IStream16_Release [STORAGE.520]
*/
ULONG IStream16_fnRelease(IStream16* iface) {
ULONG CDECL IStream16_fnRelease(IStream16* iface) {
IStream16Impl *This = (IStream16Impl *)iface;
ULONG ref;
@@ -1176,11 +1176,11 @@ ULONG IStream16_fnRelease(IStream16* iface) {
* FIXME
* Does not handle 64 bits
*/
HRESULT IStream16_fnSeek(
HRESULT CDECL IStream16_fnSeek(
IStream16* iface,LARGE_INTEGER offset,DWORD whence,ULARGE_INTEGER *newpos
) {
IStream16Impl *This = (IStream16Impl *)iface;
TRACE_(relay)("(%p)->([%ld.%ld],%ld,%p)\n",This,offset.u.HighPart,offset.u.LowPart,whence,newpos);
TRACE_(relay)("(%p)->([%d.%d],%d,%p)\n",This,offset.u.HighPart,offset.u.LowPart,whence,newpos);
switch (whence) {
/* unix SEEK_xx should be the same as win95 ones */
@@ -1220,7 +1220,7 @@ HRESULT IStream16_fnSeek(
/******************************************************************************
* IStream16_Read [STORAGE.521]
*/
HRESULT IStream16_fnRead(
HRESULT CDECL IStream16_fnRead(
IStream16* iface,void *pv,ULONG cb,ULONG *pcbRead
) {
IStream16Impl *This = (IStream16Impl *)iface;
@@ -1229,7 +1229,7 @@ HRESULT IStream16_fnRead(
int blocknr;
LPBYTE pbv = pv;
TRACE_(relay)("(%p)->(%p,%ld,%p)\n",This,pv,cb,pcbRead);
TRACE_(relay)("(%p)->(%p,%d,%p)\n",This,pv,cb,pcbRead);
if (!pcbRead) bytesread=&xxread;
*bytesread = 0;
@@ -1282,7 +1282,7 @@ HRESULT IStream16_fnRead(
/******************************************************************************
* IStream16_Write [STORAGE.522]
*/
HRESULT IStream16_fnWrite(
HRESULT CDECL IStream16_fnWrite(
IStream16* iface,const void *pv,ULONG cb,ULONG *pcbWrite
) {
IStream16Impl *This = (IStream16Impl *)iface;
@@ -1294,7 +1294,7 @@ HRESULT IStream16_fnWrite(
if (!pcbWrite) byteswritten=&xxwritten;
*byteswritten = 0;
TRACE_(relay)("(%p)->(%p,%ld,%p)\n",This,pv,cb,pcbWrite);
TRACE_(relay)("(%p)->(%p,%d,%p)\n",This,pv,cb,pcbWrite);
/* do we need to junk some blocks? */
newsize = This->offset.u.LowPart+cb;
oldsize = This->stde.pps_size;
@@ -1667,7 +1667,7 @@ ULONG WINAPI IStream_fnRelease(IStream* iface) {
/******************************************************************************
* IStorage16_QueryInterface [STORAGE.500]
*/
HRESULT IStorage16_fnQueryInterface(
HRESULT CDECL IStorage16_fnQueryInterface(
IStorage16* iface,REFIID refiid,LPVOID *obj
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@@ -1684,7 +1684,7 @@ HRESULT IStorage16_fnQueryInterface(
/******************************************************************************
* IStorage16_AddRef [STORAGE.501]
*/
ULONG IStorage16_fnAddRef(IStorage16* iface) {
ULONG CDECL IStorage16_fnAddRef(IStorage16* iface) {
IStorage16Impl *This = (IStorage16Impl *)iface;
return InterlockedIncrement(&This->ref);
}
@@ -1692,7 +1692,7 @@ ULONG IStorage16_fnAddRef(IStorage16* iface) {
/******************************************************************************
* IStorage16_Release [STORAGE.502]
*/
ULONG IStorage16_fnRelease(IStorage16* iface) {
ULONG CDECL IStorage16_fnRelease(IStorage16* iface) {
IStorage16Impl *This = (IStorage16Impl *)iface;
ULONG ref;
ref = InterlockedDecrement(&This->ref);
@@ -1707,14 +1707,14 @@ ULONG IStorage16_fnRelease(IStorage16* iface) {
/******************************************************************************
* IStorage16_Stat [STORAGE.517]
*/
HRESULT IStorage16_fnStat(
HRESULT CDECL IStorage16_fnStat(
LPSTORAGE16 iface,STATSTG16 *pstatstg, DWORD grfStatFlag
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
DWORD len = WideCharToMultiByte( CP_ACP, 0, This->stde.pps_rawname, -1, NULL, 0, NULL, NULL );
LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, len );
TRACE("(%p)->(%p,0x%08lx)\n",
TRACE("(%p)->(%p,0x%08x)\n",
This,pstatstg,grfStatFlag
);
WideCharToMultiByte( CP_ACP, 0, This->stde.pps_rawname, -1, nameA, len, NULL, NULL );
@@ -1735,11 +1735,11 @@ HRESULT IStorage16_fnStat(
/******************************************************************************
* IStorage16_Commit [STORAGE.509]
*/
HRESULT IStorage16_fnCommit(
HRESULT CDECL IStorage16_fnCommit(
LPSTORAGE16 iface,DWORD commitflags
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
FIXME("(%p)->(0x%08lx),STUB!\n",
FIXME("(%p)->(0x%08x),STUB!\n",
This,commitflags
);
return S_OK;
@@ -1748,9 +1748,9 @@ HRESULT IStorage16_fnCommit(
/******************************************************************************
* IStorage16_CopyTo [STORAGE.507]
*/
HRESULT IStorage16_fnCopyTo(LPSTORAGE16 iface,DWORD ciidExclude,const IID *rgiidExclude,SNB16 SNB16Exclude,IStorage16 *pstgDest) {
HRESULT CDECL IStorage16_fnCopyTo(LPSTORAGE16 iface,DWORD ciidExclude,const IID *rgiidExclude,SNB16 SNB16Exclude,IStorage16 *pstgDest) {
IStorage16Impl *This = (IStorage16Impl *)iface;
FIXME("IStorage16(%p)->(0x%08lx,%s,%p,%p),stub!\n",
FIXME("IStorage16(%p)->(0x%08x,%s,%p,%p),stub!\n",
This,ciidExclude,debugstr_guid(rgiidExclude),SNB16Exclude,pstgDest
);
return S_OK;
@@ -1760,7 +1760,7 @@ HRESULT IStorage16_fnCopyTo(LPSTORAGE16 iface,DWORD ciidExclude,const IID *rgiid
/******************************************************************************
* IStorage16_CreateStorage [STORAGE.505]
*/
HRESULT IStorage16_fnCreateStorage(
HRESULT CDECL IStorage16_fnCreateStorage(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName,DWORD grfMode,DWORD dwStgFormat,DWORD reserved2, IStorage16 **ppstg
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@@ -1772,7 +1772,7 @@ HRESULT IStorage16_fnCreateStorage(
int nPPSEntries;
READ_HEADER(&This->str);
TRACE("(%p)->(%s,0x%08lx,0x%08lx,0x%08lx,%p)\n",
TRACE("(%p)->(%s,0x%08x,0x%08x,0x%08x,%p)\n",
This,pwcsName,grfMode,dwStgFormat,reserved2,ppstg
);
if (grfMode & STGM_TRANSACTED)
@@ -1829,7 +1829,7 @@ HRESULT IStorage16_fnCreateStorage(
/******************************************************************************
* IStorage16_CreateStream [STORAGE.503]
*/
HRESULT IStorage16_fnCreateStream(
HRESULT CDECL IStorage16_fnCreateStream(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName,DWORD grfMode,DWORD reserved1,DWORD reserved2, IStream16 **ppstm
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@@ -1839,7 +1839,7 @@ HRESULT IStorage16_fnCreateStream(
BOOL ret;
int nPPSEntries;
TRACE("(%p)->(%s,0x%08lx,0x%08lx,0x%08lx,%p)\n",
TRACE("(%p)->(%s,0x%08x,0x%08x,0x%08x,%p)\n",
This,pwcsName,grfMode,reserved1,reserved2,ppstm
);
if (grfMode & STGM_TRANSACTED)
@@ -1893,7 +1893,7 @@ HRESULT IStorage16_fnCreateStream(
/******************************************************************************
* IStorage16_OpenStorage [STORAGE.506]
*/
HRESULT IStorage16_fnOpenStorage(
HRESULT CDECL IStorage16_fnOpenStorage(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName, IStorage16 *pstgPrio, DWORD grfMode, SNB16 snbExclude, DWORD reserved, IStorage16 **ppstg
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@@ -1901,7 +1901,7 @@ HRESULT IStorage16_fnOpenStorage(
WCHAR name[33];
int newpps;
TRACE("(%p)->(%s,%p,0x%08lx,%p,0x%08lx,%p)\n",
TRACE("(%p)->(%s,%p,0x%08x,%p,0x%08x,%p)\n",
This,pwcsName,pstgPrio,grfMode,snbExclude,reserved,ppstg
);
if (grfMode & STGM_TRANSACTED)
@@ -1933,7 +1933,7 @@ HRESULT IStorage16_fnOpenStorage(
/******************************************************************************
* IStorage16_OpenStream [STORAGE.504]
*/
HRESULT IStorage16_fnOpenStream(
HRESULT CDECL IStorage16_fnOpenStream(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream16 **ppstm
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@@ -1941,7 +1941,7 @@ HRESULT IStorage16_fnOpenStream(
WCHAR name[33];
int newpps;
TRACE("(%p)->(%s,%p,0x%08lx,0x%08lx,%p)\n",
TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p)\n",
This,pwcsName,reserved1,grfMode,reserved2,ppstm
);
if (grfMode & STGM_TRANSACTED)
@@ -2052,13 +2052,13 @@ HRESULT WINAPI StgCreateDocFile16(
IStorage16Impl* lpstg;
struct storage_pps_entry stde;
TRACE("(%s,0x%08lx,0x%08lx,%p)\n",
TRACE("(%s,0x%08x,0x%08x,%p)\n",
pwcsName,grfMode,reserved,ppstgOpen
);
_create_istorage16(ppstgOpen);
hf = CreateFileA(pwcsName,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,0,0);
if (hf==INVALID_HANDLE_VALUE) {
WARN("couldn't open file for storage:%ld\n",GetLastError());
WARN("couldn't open file for storage:%d\n",GetLastError());
return E_FAIL;
}
lpstg = MapSL((SEGPTR)*ppstgOpen);
@@ -2113,7 +2113,7 @@ HRESULT WINAPI StgOpenStorage16(
IStorage16Impl* lpstg;
struct storage_pps_entry stde;
TRACE("(%s,%p,0x%08lx,%p,%ld,%p)\n",
TRACE("(%s,%p,0x%08x,%p,%d,%p)\n",
pwcsName,pstgPriority,grfMode,snbExclude,reserved,ppstgOpen
);
_create_istorage16(ppstgOpen);
@@ -2168,7 +2168,7 @@ HRESULT WINAPI StgIsStorageILockBytes16(SEGPTR plkbyt)
(LPVOID)args,
(LPDWORD)&hres
)) {
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %x\n",hres);
return hres;
}
if (memcmp(MapSL(args[3]), STORAGE_magic, sizeof(STORAGE_magic)) == 0) {
@@ -2181,9 +2181,12 @@ HRESULT WINAPI StgIsStorageILockBytes16(SEGPTR plkbyt)
/******************************************************************************
* StgOpenStorageOnILockBytes [STORAGE.4]
*
* PARAMS
* plkbyt FIXME: Should probably be an ILockBytes16 *.
*/
HRESULT WINAPI StgOpenStorageOnILockBytes16(
SEGPTR /*ILockBytes16 **/plkbyt,
SEGPTR plkbyt,
IStorage16 *pstgPriority,
DWORD grfMode,
SNB16 snbExclude,
@@ -2194,7 +2197,7 @@ HRESULT WINAPI StgOpenStorageOnILockBytes16(
int i,ret;
struct storage_pps_entry stde;
FIXME("(%lx, %p, 0x%08lx, %d, %lx, %p)\n", plkbyt, pstgPriority, grfMode, (int)snbExclude, reserved, ppstgOpen);
FIXME("(%x, %p, 0x%08x, %d, %x, %p)\n", plkbyt, pstgPriority, grfMode, (int)snbExclude, reserved, ppstgOpen);
if ((plkbyt == 0) || (ppstgOpen == 0))
return STG_E_INVALIDPOINTER;
@@ -2241,7 +2244,7 @@ HRESULT WINAPI ReadClassStg16(SEGPTR pstg, CLSID *pclsid)
HRESULT hres;
DWORD args[3];
TRACE("(%lx, %p)\n", pstg, pclsid);
TRACE("(%x, %p)\n", pstg, pclsid);
if(pclsid==NULL)
return E_POINTER;
@@ -2262,7 +2265,7 @@ HRESULT WINAPI ReadClassStg16(SEGPTR pstg, CLSID *pclsid)
(LPDWORD)&hres
)) {
WOWGlobalUnlockFree16(args[1]);
ERR("CallTo16 IStorage16::Stat() failed, hres %lx\n",hres);
ERR("CallTo16 IStorage16::Stat() failed, hres %x\n",hres);
return hres;
}
memcpy(&statstg, MapSL(args[1]), sizeof(STATSTG16));
File diff suppressed because it is too large Load Diff
+29 -212
View File
@@ -24,7 +24,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __STORAGE32_H__
#define __STORAGE32_H__
@@ -37,6 +37,7 @@
#include "objbase.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/list.h"
/*
* Definitions for the file format offsets.
@@ -110,19 +111,12 @@ static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
/*
* 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;
@@ -190,11 +184,12 @@ BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
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_EnsureExists(LPBIGBLOCKFILE This, ULONG index);
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This);
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, ULONG size, ULONG* bytesRead);
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, const ULONG size, ULONG* bytesRead);
/*************************************************************************
* Ole Convert support
@@ -219,6 +214,12 @@ struct StorageBaseImpl
const IPropertySetStorageVtbl *pssVtbl; /* interface for adding a properties stream */
/*
* Stream tracking list
*/
struct list strmHead;
/*
* Reference count of this object
*/
@@ -246,6 +247,12 @@ struct StorageBaseImpl
DWORD openFlags;
};
/****************************************************************************
* StorageBaseImpl stream list handlers
*/
void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm);
void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm);
/****************************************************************************
* Storage32Impl definitions.
@@ -298,63 +305,6 @@ struct StorageImpl
BigBlockFile* bigBlockFile;
};
void StorageImpl_Destroy(
StorageBaseImpl* 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,
@@ -369,114 +319,10 @@ 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
{
struct StorageBaseImpl base;
/*
* There is no specific data for this class.
*/
};
/*
* Method definitions for the Storage32InternalImpl class.
*/
StorageInternalImpl* StorageInternalImpl_Construct(
StorageImpl* ancestorStorage,
DWORD openFlags,
ULONG rootTropertyIndex);
void StorageInternalImpl_Destroy(
StorageBaseImpl* 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
{
const IEnumSTATSTGVtbl *lpVtbl; /* Needs to be the first item in the struct
* since we want to cast this in an IEnumSTATSTG pointer */
LONG 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
};
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
* This class implements the IStream32 interface and represents a stream
* located inside a storage object.
*/
struct StgStreamImpl
@@ -484,6 +330,12 @@ struct StgStreamImpl
const IStreamVtbl *lpVtbl; /* Needs to be the first item in the struct
* since we want to cast this to an IStream pointer */
/*
* We are an entry in the storage object's stream handler list
*/
struct list StrmListEntry;
/*
* Reference count
*/
@@ -598,17 +450,14 @@ BlockChainStream* BlockChainStream_Construct(
void BlockChainStream_Destroy(
BlockChainStream* This);
ULONG BlockChainStream_GetHeadOfChain(
BlockChainStream* This);
BOOL BlockChainStream_ReadAt(
HRESULT BlockChainStream_ReadAt(
BlockChainStream* This,
ULARGE_INTEGER offset,
ULONG size,
void* buffer,
ULONG* bytesRead);
BOOL BlockChainStream_WriteAt(
HRESULT BlockChainStream_WriteAt(
BlockChainStream* This,
ULARGE_INTEGER offset,
ULONG size,
@@ -619,12 +468,6 @@ BOOL BlockChainStream_SetSize(
BlockChainStream* This,
ULARGE_INTEGER newSize);
ULARGE_INTEGER BlockChainStream_GetSize(
BlockChainStream* This);
ULONG BlockChainStream_GetCount(
BlockChainStream* This);
/****************************************************************************
* SmallBlockChainStream definitions.
*
@@ -647,26 +490,6 @@ SmallBlockChainStream* SmallBlockChainStream_Construct(
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);
HRESULT SmallBlockChainStream_ReadAt(
SmallBlockChainStream* This,
ULARGE_INTEGER offset,
@@ -674,7 +497,7 @@ HRESULT SmallBlockChainStream_ReadAt(
void* buffer,
ULONG* bytesRead);
BOOL SmallBlockChainStream_WriteAt(
HRESULT SmallBlockChainStream_WriteAt(
SmallBlockChainStream* This,
ULARGE_INTEGER offset,
ULONG size,
@@ -685,11 +508,5 @@ BOOL SmallBlockChainStream_SetSize(
SmallBlockChainStream* This,
ULARGE_INTEGER newSize);
ULARGE_INTEGER SmallBlockChainStream_GetSize(
SmallBlockChainStream* This);
ULONG SmallBlockChainStream_GetCount(
SmallBlockChainStream* This);
#endif /* __STORAGE32_H__ */
+74 -49
View File
@@ -20,7 +20,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
@@ -35,9 +35,8 @@
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "ole2ver.h"
#include "rpc.h"
#include "wine/debug.h"
#include "compobj_private.h"
@@ -71,6 +70,23 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
* and the caller will also hold a reference */
sm->refs = 2;
sm->oxid_info.dwPid = GetCurrentProcessId();
sm->oxid_info.dwTid = GetCurrentThreadId();
/*
* FIXME: this is a hack for marshalling IRemUnknown. In real
* DCOM, the IPID of the IRemUnknown interface is generated like
* any other and passed to the OXID resolver which then returns it
* when queried. We don't have an OXID resolver yet so instead we
* use a magic IPID reserved for IRemUnknown.
*/
sm->oxid_info.ipidRemUnknown.Data1 = 0xffffffff;
sm->oxid_info.ipidRemUnknown.Data2 = 0xffff;
sm->oxid_info.ipidRemUnknown.Data3 = 0xffff;
assert(sizeof(sm->oxid_info.ipidRemUnknown.Data4) == sizeof(apt->oxid));
memcpy(&sm->oxid_info.ipidRemUnknown.Data4, &apt->oxid, sizeof(OXID));
sm->oxid_info.dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
sm->oxid_info.psa = NULL /* FIXME */;
/* yes, that's right, this starts at zero. that's zero EXTERNAL
* refs, ie nobody has unmarshalled anything yet. we can't have
* negative refs because the stub manager cannot be explicitly
@@ -103,6 +119,7 @@ static void stub_manager_delete(struct stub_manager *m)
stub_manager_delete_ifstub(m, ifstub);
}
CoTaskMemFree(m->oxid_info.psa);
IUnknown_Release(m->object);
DEBUG_CLEAR_CRITSEC_NAME(&m->lock);
@@ -205,7 +222,7 @@ ULONG stub_manager_int_addref(struct stub_manager *This)
refs = ++This->refs;
LeaveCriticalSection(&This->apt->cs);
TRACE("before %ld\n", refs - 1);
TRACE("before %d\n", refs - 1);
return refs;
}
@@ -219,7 +236,7 @@ ULONG stub_manager_int_release(struct stub_manager *This)
EnterCriticalSection(&apt->cs);
refs = --This->refs;
TRACE("after %ld\n", refs);
TRACE("after %d\n", refs);
/* remove from apartment so no other thread can access it... */
if (!refs)
@@ -247,13 +264,13 @@ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs)
LeaveCriticalSection(&m->lock);
TRACE("added %lu refs to %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
TRACE("added %u refs to %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
return rc;
}
/* remove some external references */
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs)
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL last_unlock_releases)
{
ULONG rc;
@@ -265,9 +282,9 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs)
LeaveCriticalSection(&m->lock);
TRACE("removed %lu refs from %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
if (rc == 0)
if (rc == 0 && last_unlock_releases)
stub_manager_int_release(m);
return rc;
@@ -365,29 +382,41 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
return S_OK;
}
/* gets the apartment and IRpcStubBuffer from an object. the caller must
* release the references to both objects */
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt)
/* gets the apartment, stub and channel of an object. the caller must
* release the references to all objects (except iface) if the function
* returned success, otherwise no references are returned. */
HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt,
IRpcStubBuffer **stub, IRpcChannelBuffer **chan,
IID *iid, IUnknown **iface)
{
IRpcStubBuffer *ret = NULL;
struct stub_manager *stubmgr;
struct ifstub *ifstub;
APARTMENT *apt;
HRESULT hr;
*stub_apt = NULL;
hr = ipid_to_stub_manager(ipid, stub_apt, &stubmgr);
if (hr != S_OK) return NULL;
hr = ipid_to_stub_manager(ipid, &apt, &stubmgr);
if (hr != S_OK) return RPC_E_DISCONNECTED;
ifstub = stub_manager_ipid_to_ifstub(stubmgr, ipid);
if (ifstub)
ret = ifstub->stubbuffer;
{
*stub = ifstub->stubbuffer;
IRpcStubBuffer_AddRef(*stub);
*chan = ifstub->chan;
IRpcChannelBuffer_AddRef(*chan);
*stub_apt = apt;
*iid = ifstub->iid;
*iface = ifstub->iface;
if (ret) IRpcStubBuffer_AddRef(ret);
stub_manager_int_release(stubmgr);
return ret;
stub_manager_int_release(stubmgr);
return S_OK;
}
else
{
stub_manager_int_release(stubmgr);
apartment_release(apt);
return RPC_E_DISCONNECTED;
}
}
/* generates an ipid in the following format (similar to native version):
@@ -417,6 +446,7 @@ static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags)
{
struct ifstub *stub;
HRESULT hr;
TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s\n",
wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid));
@@ -424,6 +454,13 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub));
if (!stub) return NULL;
hr = RPC_CreateServerChannel(&stub->chan);
if (hr != S_OK)
{
HeapFree(GetProcessHeap(), 0, stub);
return NULL;
}
stub->stubbuffer = sb;
if (sb) IRpcStubBuffer_AddRef(sb);
@@ -432,21 +469,10 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
stub->flags = flags;
stub->iid = *iid;
/*
* FIXME: this is a hack for marshalling IRemUnknown. In real
* DCOM, the IPID of the IRemUnknown interface is generated like
* any other and passed to the OXID resolver which then returns it
* when queried. We don't have an OXID resolver yet so instead we
* use a magic IPID reserved for IRemUnknown.
*/
if (IsEqualIID(iid, &IID_IRemUnknown))
{
stub->ipid.Data1 = 0xffffffff;
stub->ipid.Data2 = 0xffff;
stub->ipid.Data3 = 0xffff;
assert(sizeof(stub->ipid.Data4) == sizeof(m->apt->oxid));
memcpy(&stub->ipid.Data4, &m->apt->oxid, sizeof(OXID));
}
/* FIXME: find a cleaner way of identifying that we are creating an ifstub
* for the remunknown interface */
if (flags & MSHLFLAGSP_REMUNKNOWN)
stub->ipid = m->oxid_info.ipidRemUnknown;
else
generate_ipid(m, &stub->ipid);
@@ -468,9 +494,10 @@ static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *if
list_remove(&ifstub->entry);
RPC_UnregisterInterface(&ifstub->iid);
if (ifstub->stubbuffer) IUnknown_Release(ifstub->stubbuffer);
IUnknown_Release(ifstub->iface);
IRpcChannelBuffer_Release(ifstub->chan);
HeapFree(GetProcessHeap(), 0, ifstub);
}
@@ -516,10 +543,10 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const
if (ifstub->flags & MSHLFLAGS_TABLEWEAK)
refs = 0;
else
else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
refs = 1;
stub_manager_ext_release(m, refs);
stub_manager_ext_release(m, refs, TRUE);
}
/* is an ifstub table marshaled? */
@@ -542,8 +569,6 @@ BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)
* interacts with stub managers.
*/
const IID IID_IRemUnknown = { 0x00000131, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
typedef struct rem_unknown
{
const IRemUnknownVtbl *lpVtbl;
@@ -592,7 +617,7 @@ static ULONG WINAPI RemUnknown_AddRef(IRemUnknown *iface)
refs = InterlockedIncrement(&This->refs);
TRACE("%p before: %ld\n", iface, refs-1);
TRACE("%p before: %d\n", iface, refs-1);
return refs;
}
@@ -605,7 +630,7 @@ static ULONG WINAPI RemUnknown_Release(IRemUnknown *iface)
if (!refs)
HeapFree(GetProcessHeap(), 0, This);
TRACE("%p after: %ld\n", iface, refs);
TRACE("%p after: %d\n", iface, refs);
return refs;
}
@@ -619,7 +644,7 @@ static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface,
APARTMENT *apt;
struct stub_manager *stubmgr;
TRACE("(%p)->(%s, %ld, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
TRACE("(%p)->(%s, %d, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
hr = ipid_to_stub_manager(ripid, &apt, &stubmgr);
if (hr != S_OK) return hr;
@@ -701,7 +726,7 @@ static HRESULT WINAPI RemUnknown_RemRelease(IRemUnknown *iface,
break;
}
stub_manager_ext_release(stubmgr, InterfaceRefs[i].cPublicRefs);
stub_manager_ext_release(stubmgr, InterfaceRefs[i].cPublicRefs, TRUE);
if (InterfaceRefs[i].cPrivateRefs)
FIXME("Releasing %ld refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
@@ -723,7 +748,7 @@ static const IRemUnknownVtbl RemUnknown_Vtbl =
};
/* starts the IRemUnknown listener for the current apartment */
HRESULT start_apartment_remote_unknown()
HRESULT start_apartment_remote_unknown(void)
{
IRemUnknown *pRemUnknown;
HRESULT hr = S_OK;
@@ -738,7 +763,7 @@ HRESULT start_apartment_remote_unknown()
{
STDOBJREF stdobjref; /* dummy - not used */
/* register it with the stub manager */
hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL);
hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL|MSHLFLAGSP_REMUNKNOWN);
/* release our reference to the object as the stub manager will manage the life cycle for us */
IRemUnknown_Release(pRemUnknown);
if (hr == S_OK)
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -15,7 +15,7 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define WINE_OLESELFREGISTER