mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
Autosyncing with Wine HEAD
svn path=/trunk/; revision=26436
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
+1125
-441
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+864
-333
File diff suppressed because it is too large
Load Diff
@@ -1,515 +0,0 @@
|
||||
/*** Autogenerated by WIDL 0.1 from dcom.idl - Do not edit ***/
|
||||
#include <rpc.h>
|
||||
#include <rpcndr.h>
|
||||
|
||||
#ifndef __WIDL_DCOM_H
|
||||
#define __WIDL_DCOM_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <unknwn.h>
|
||||
typedef MIDL_uhyper ID;
|
||||
|
||||
typedef ID MID;
|
||||
|
||||
typedef ID OXID;
|
||||
|
||||
typedef ID OID;
|
||||
|
||||
typedef ID SETID;
|
||||
|
||||
typedef GUID IPID;
|
||||
|
||||
typedef GUID CID;
|
||||
|
||||
typedef REFGUID REFIPID;
|
||||
|
||||
#define COM_MINOR_VERSION_1 (1)
|
||||
|
||||
#define COM_MINOR_VERSION_2 (2)
|
||||
|
||||
#define COM_MAJOR_VERSION (5)
|
||||
|
||||
#define COM_MINOR_VERSION (3)
|
||||
|
||||
typedef struct tagCOMVERSION {
|
||||
unsigned short MajorVersion;
|
||||
unsigned short MinorVersion;
|
||||
} COMVERSION;
|
||||
|
||||
#define ORPCF_NULL (0)
|
||||
|
||||
#define ORPCF_LOCAL (1)
|
||||
|
||||
#define ORPCF_RESERVED1 (2)
|
||||
|
||||
#define ORPCF_RESERVED2 (4)
|
||||
|
||||
#define ORPCF_RESERVED3 (8)
|
||||
|
||||
#define ORPCF_RESERVED4 (16)
|
||||
|
||||
typedef struct tagORPC_EXTENT {
|
||||
GUID id;
|
||||
unsigned long size;
|
||||
byte data[1];
|
||||
} ORPC_EXTENT;
|
||||
|
||||
typedef struct tagORPC_EXTENT_ARRAY {
|
||||
unsigned long size;
|
||||
unsigned long reserved;
|
||||
ORPC_EXTENT **extent;
|
||||
} ORPC_EXTENT_ARRAY;
|
||||
|
||||
typedef struct tagORPCTHIS {
|
||||
COMVERSION version;
|
||||
unsigned long flags;
|
||||
unsigned long reserved1;
|
||||
CID cid;
|
||||
ORPC_EXTENT_ARRAY *extensions;
|
||||
} ORPCTHIS;
|
||||
|
||||
typedef struct tagORPCTHAT {
|
||||
unsigned long flags;
|
||||
ORPC_EXTENT_ARRAY *extensions;
|
||||
} ORPCTHAT;
|
||||
|
||||
#define NCADG_IP_UDP (0x8)
|
||||
|
||||
#define NCACN_IP_TCP (0x7)
|
||||
|
||||
#define NCADG_IPX (0xe)
|
||||
|
||||
#define NCACN_SPX (0xc)
|
||||
|
||||
#define NCACN_NB_NB (0x12)
|
||||
|
||||
#define NCACN_NB_IPX (0xd)
|
||||
|
||||
#define NCACN_DNET_NSP (0x4)
|
||||
|
||||
#define NCACN_HTTP (0x1f)
|
||||
|
||||
typedef struct tagSTRINGBINDING {
|
||||
unsigned short wTowerId;
|
||||
unsigned short aNetworkAddr[1];
|
||||
} STRINGBINDING;
|
||||
|
||||
#define COM_C_AUTHZ_NONE (0xffff)
|
||||
|
||||
typedef struct tagSECURITYBINDING {
|
||||
unsigned short wAuthnSvc;
|
||||
unsigned short wAuthzSvc;
|
||||
unsigned short aPrincName[1];
|
||||
} SECURITYBINDING;
|
||||
|
||||
typedef struct tagDUALSTRINGARRAY {
|
||||
unsigned short wNumEntries;
|
||||
unsigned short wSecurityOffset;
|
||||
unsigned short aStringArray[1];
|
||||
} DUALSTRINGARRAY;
|
||||
|
||||
#define OBJREF_SIGNATURE (0x574f454d)
|
||||
|
||||
#define OBJREF_STANDARD (0x1)
|
||||
|
||||
#define OBJREF_HANDLER (0x2)
|
||||
|
||||
#define OBJREF_CUSTOM (0x4)
|
||||
|
||||
#define SORF_OXRES1 (0x1)
|
||||
|
||||
#define SORF_OXRES2 (0x20)
|
||||
|
||||
#define SORF_OXRES3 (0x40)
|
||||
|
||||
#define SORF_OXRES4 (0x80)
|
||||
|
||||
#define SORF_OXRES5 (0x100)
|
||||
|
||||
#define SORF_OXRES6 (0x200)
|
||||
|
||||
#define SORF_OXRES7 (0x400)
|
||||
|
||||
#define SORF_OXRES8 (0x800)
|
||||
|
||||
#define SORF_NULL (0x0)
|
||||
|
||||
#define SORF_NOPING (0x1000)
|
||||
|
||||
typedef struct tagSTDOBJREF {
|
||||
unsigned long flags;
|
||||
unsigned long cPublicRefs;
|
||||
OXID oxid;
|
||||
OID oid;
|
||||
IPID ipid;
|
||||
} STDOBJREF;
|
||||
|
||||
typedef struct tagOBJREF {
|
||||
unsigned long signature;
|
||||
unsigned long flags;
|
||||
GUID iid;
|
||||
union {
|
||||
struct OR_STANDARD {
|
||||
STDOBJREF std;
|
||||
DUALSTRINGARRAY saResAddr;
|
||||
} u_standard;
|
||||
struct OR_HANDLER {
|
||||
STDOBJREF std;
|
||||
CLSID clsid;
|
||||
DUALSTRINGARRAY saResAddr;
|
||||
} u_handler;
|
||||
struct OR_CUSTOM {
|
||||
CLSID clsid;
|
||||
unsigned long cbExtension;
|
||||
unsigned long size;
|
||||
byte *pData;
|
||||
} u_custom;
|
||||
} u_objref;
|
||||
} OBJREF;
|
||||
|
||||
typedef struct tagMInterfacePointer {
|
||||
ULONG ulCntData;
|
||||
BYTE abData[1];
|
||||
} MInterfacePointer;
|
||||
|
||||
typedef MInterfacePointer *PMInterfacePointer;
|
||||
|
||||
#ifndef __IRemUnknown_FWD_DEFINED__
|
||||
#define __IRemUnknown_FWD_DEFINED__
|
||||
typedef struct IRemUnknown IRemUnknown;
|
||||
#endif
|
||||
|
||||
typedef IRemUnknown *LPREMUNKNOWN;
|
||||
|
||||
typedef struct tagREMQIRESULT {
|
||||
HRESULT hResult;
|
||||
STDOBJREF std;
|
||||
} REMQIRESULT;
|
||||
|
||||
typedef struct tagREMINTERFACEREF {
|
||||
IPID ipid;
|
||||
unsigned long cPublicRefs;
|
||||
unsigned long cPrivateRefs;
|
||||
} REMINTERFACEREF;
|
||||
|
||||
/*****************************************************************************
|
||||
* IRemUnknown interface
|
||||
*/
|
||||
#ifndef __IRemUnknown_INTERFACE_DEFINED__
|
||||
#define __IRemUnknown_INTERFACE_DEFINED__
|
||||
|
||||
DEFINE_GUID(IID_IRemUnknown, 0x00000131, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
struct IRemUnknown : public IUnknown
|
||||
{
|
||||
virtual HRESULT STDMETHODCALLTYPE RemQueryInterface(
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE RemAddRef(
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE RemRelease(
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs) = 0;
|
||||
|
||||
};
|
||||
#else
|
||||
typedef struct IRemUnknownVtbl IRemUnknownVtbl;
|
||||
struct IRemUnknown {
|
||||
const IRemUnknownVtbl* lpVtbl;
|
||||
};
|
||||
struct IRemUnknownVtbl {
|
||||
BEGIN_INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
|
||||
IRemUnknown* This,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *AddRef)(
|
||||
IRemUnknown* This);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *Release)(
|
||||
IRemUnknown* This);
|
||||
|
||||
/*** IRemUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *RemQueryInterface)(
|
||||
IRemUnknown* This,
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemAddRef)(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemRelease)(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs);
|
||||
|
||||
END_INTERFACE
|
||||
};
|
||||
|
||||
#ifdef COBJMACROS
|
||||
/*** IUnknown methods ***/
|
||||
#define IRemUnknown_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IRemUnknown_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IRemUnknown_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IRemUnknown methods ***/
|
||||
#define IRemUnknown_RemQueryInterface(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface(p,a,b,c,d,e)
|
||||
#define IRemUnknown_RemAddRef(p,a,b,c) (p)->lpVtbl->RemAddRef(p,a,b,c)
|
||||
#define IRemUnknown_RemRelease(p,a,b) (p)->lpVtbl->RemRelease(p,a,b)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define IRemUnknown_METHODS \
|
||||
/*** IUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE; \
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE; \
|
||||
/*** IRemUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,RemQueryInterface)(THIS_ REFIPID ripid, unsigned long cRefs, unsigned short cIids, IID* iids, REMQIRESULT** ppQIResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemAddRef)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs, HRESULT* pResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemRelease)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs) PURE;
|
||||
|
||||
HRESULT CALLBACK IRemUnknown_RemQueryInterface_Proxy(
|
||||
IRemUnknown* This,
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults);
|
||||
void __RPC_STUB IRemUnknown_RemQueryInterface_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IRemUnknown_RemAddRef_Proxy(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults);
|
||||
void __RPC_STUB IRemUnknown_RemAddRef_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IRemUnknown_RemRelease_Proxy(
|
||||
IRemUnknown* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs);
|
||||
void __RPC_STUB IRemUnknown_RemRelease_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
|
||||
#endif /* __IRemUnknown_INTERFACE_DEFINED__ */
|
||||
|
||||
#ifndef __IRemUnknown2_FWD_DEFINED__
|
||||
#define __IRemUnknown2_FWD_DEFINED__
|
||||
typedef struct IRemUnknown2 IRemUnknown2;
|
||||
#endif
|
||||
|
||||
typedef IRemUnknown2 *LPREMUNKNOWN2;
|
||||
|
||||
/*****************************************************************************
|
||||
* IRemUnknown2 interface
|
||||
*/
|
||||
#ifndef __IRemUnknown2_INTERFACE_DEFINED__
|
||||
#define __IRemUnknown2_INTERFACE_DEFINED__
|
||||
|
||||
DEFINE_GUID(IID_IRemUnknown2, 0x00000142, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
struct IRemUnknown2 : public IRemUnknown
|
||||
{
|
||||
virtual HRESULT STDMETHODCALLTYPE RemQueryInterface2(
|
||||
REFIPID ripid,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppMIF) = 0;
|
||||
|
||||
};
|
||||
#else
|
||||
typedef struct IRemUnknown2Vtbl IRemUnknown2Vtbl;
|
||||
struct IRemUnknown2 {
|
||||
const IRemUnknown2Vtbl* lpVtbl;
|
||||
};
|
||||
struct IRemUnknown2Vtbl {
|
||||
BEGIN_INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
|
||||
IRemUnknown2* This,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *AddRef)(
|
||||
IRemUnknown2* This);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *Release)(
|
||||
IRemUnknown2* This);
|
||||
|
||||
/*** IRemUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *RemQueryInterface)(
|
||||
IRemUnknown2* This,
|
||||
REFIPID ripid,
|
||||
unsigned long cRefs,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
REMQIRESULT** ppQIResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemAddRef)(
|
||||
IRemUnknown2* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs,
|
||||
HRESULT* pResults);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *RemRelease)(
|
||||
IRemUnknown2* This,
|
||||
unsigned short cInterfaceRefs,
|
||||
REMINTERFACEREF* InterfaceRefs);
|
||||
|
||||
/*** IRemUnknown2 methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *RemQueryInterface2)(
|
||||
IRemUnknown2* This,
|
||||
REFIPID ripid,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppMIF);
|
||||
|
||||
END_INTERFACE
|
||||
};
|
||||
|
||||
#ifdef COBJMACROS
|
||||
/*** IUnknown methods ***/
|
||||
#define IRemUnknown2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IRemUnknown2_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IRemUnknown2_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IRemUnknown methods ***/
|
||||
#define IRemUnknown2_RemQueryInterface(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface(p,a,b,c,d,e)
|
||||
#define IRemUnknown2_RemAddRef(p,a,b,c) (p)->lpVtbl->RemAddRef(p,a,b,c)
|
||||
#define IRemUnknown2_RemRelease(p,a,b) (p)->lpVtbl->RemRelease(p,a,b)
|
||||
/*** IRemUnknown2 methods ***/
|
||||
#define IRemUnknown2_RemQueryInterface2(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface2(p,a,b,c,d,e)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define IRemUnknown2_METHODS \
|
||||
/*** IUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE; \
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE; \
|
||||
/*** IRemUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,RemQueryInterface)(THIS_ REFIPID ripid, unsigned long cRefs, unsigned short cIids, IID* iids, REMQIRESULT** ppQIResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemAddRef)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs, HRESULT* pResults) PURE; \
|
||||
STDMETHOD_(HRESULT,RemRelease)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs) PURE; \
|
||||
/*** IRemUnknown2 methods ***/ \
|
||||
STDMETHOD_(HRESULT,RemQueryInterface2)(THIS_ REFIPID ripid, unsigned short cIids, IID* iids, HRESULT* phr, MInterfacePointer** ppMIF) PURE;
|
||||
|
||||
HRESULT CALLBACK IRemUnknown2_RemQueryInterface2_Proxy(
|
||||
IRemUnknown2* This,
|
||||
REFIPID ripid,
|
||||
unsigned short cIids,
|
||||
IID* iids,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppMIF);
|
||||
void __RPC_STUB IRemUnknown2_RemQueryInterface2_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
|
||||
#endif /* __IRemUnknown2_INTERFACE_DEFINED__ */
|
||||
|
||||
#if 0
|
||||
/*****************************************************************************
|
||||
* IOXIDResolver interface (v0.0)
|
||||
*/
|
||||
DEFINE_GUID(IID_IOXIDResolver, 0x99fcfec4, 0x5260, 0x101b, 0xbb,0xcb, 0x00,0xaa,0x00,0x21,0x34,0x7a);
|
||||
extern RPC_IF_HANDLE IOXIDResolver_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE IOXIDResolver_v0_0_s_ifspec;
|
||||
error_status_t ResolveOxid(
|
||||
handle_t hRpc,
|
||||
OXID* pOxid,
|
||||
unsigned short cRequestedProtseqs,
|
||||
unsigned short arRequestedProtseqs[],
|
||||
DUALSTRINGARRAY** ppdsaOxidBindings,
|
||||
IPID* pipidRemUnknown,
|
||||
DWORD* pAuthnHint);
|
||||
error_status_t SimplePing(
|
||||
handle_t hRpc,
|
||||
SETID* pSetId);
|
||||
error_status_t ComplexPing(
|
||||
handle_t hRpc,
|
||||
SETID* pSetId,
|
||||
unsigned short SequenceNum,
|
||||
unsigned short cAddToSet,
|
||||
unsigned short cDelFromSet,
|
||||
OID AddToSet[],
|
||||
OID DelFromSet[],
|
||||
unsigned short* pPingBackoffFactor);
|
||||
error_status_t ServerAlive(
|
||||
handle_t hRpc);
|
||||
error_status_t ResolveOxid2(
|
||||
handle_t hRpc,
|
||||
OXID* pOxid,
|
||||
unsigned short cRequestedProtseqs,
|
||||
unsigned short arRequestedProtseqs[],
|
||||
DUALSTRINGARRAY** ppdsaOxidBindings,
|
||||
IPID* pipidRemUnknown,
|
||||
DWORD* pAuthnHint,
|
||||
COMVERSION* pComVersion);
|
||||
|
||||
#define MODE_GET_CLASS_OBJECT (0xffffffff)
|
||||
|
||||
/*****************************************************************************
|
||||
* IRemoteActivation interface (v0.0)
|
||||
*/
|
||||
DEFINE_GUID(IID_IRemoteActivation, 0x4d9f4ab8, 0x7d1c, 0x11cf, 0x86,0x1e, 0x00,0x20,0xaf,0x6e,0x7c,0x57);
|
||||
extern RPC_IF_HANDLE IRemoteActivation_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE IRemoteActivation_v0_0_s_ifspec;
|
||||
HRESULT RemoteActivation(
|
||||
handle_t hRpc,
|
||||
ORPCTHIS* ORPCthis,
|
||||
ORPCTHAT* ORPCthat,
|
||||
GUID* Clsid,
|
||||
WCHAR* pwszObjectName,
|
||||
MInterfacePointer* pObjectStorage,
|
||||
DWORD ClientImpLevel,
|
||||
DWORD Mode,
|
||||
DWORD Interfaces,
|
||||
IID* pIIDs,
|
||||
unsigned short cRequestedProtseqs,
|
||||
unsigned short RequestedProtseqs[],
|
||||
OXID* pOxid,
|
||||
DUALSTRINGARRAY** ppdsaOxidBindings,
|
||||
IPID* pipidRemUnknown,
|
||||
DWORD* pAuthnHint,
|
||||
COMVERSION* pServerVersion,
|
||||
HRESULT* phr,
|
||||
MInterfacePointer** ppInterfaceData,
|
||||
HRESULT* pResults);
|
||||
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __WIDL_DCOM_H */
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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,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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+307
-286
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_ )
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+1093
-125
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
+670
-445
File diff suppressed because it is too large
Load Diff
@@ -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__ */
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1169
-106
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user