- Sync to Wine-1.1.40. Along with improvements, it provides many memory corruption fixes.

svn path=/trunk/; revision=46056
This commit is contained in:
Aleksey Bragin 2010-03-10 14:28:56 +00:00
parent 5d434b2f15
commit f4fa6270ae
24 changed files with 2857 additions and 2470 deletions

View file

@ -1608,6 +1608,8 @@ void OLEClipbrd_UnInitialize(void)
}
IStream_Release(clipbrd->marshal_data);
if (clipbrd->src_data) IDataObject_Release(clipbrd->src_data);
HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
HeapFree(GetProcessHeap(), 0, clipbrd);
theOleClipboard = NULL;
}
@ -1699,7 +1701,11 @@ static HRESULT set_clipboard_formats(ole_clipbrd *clipbrd, IDataObject *data)
td_offs_to_ptr(clipbrd->cached_enum, (DWORD_PTR)clipbrd->cached_enum->entries[idx].fmtetc.ptd);
GlobalUnlock(priv_data_handle);
SetClipboardData(ole_private_data_clipboard_format, priv_data_handle);
if(!SetClipboardData(ole_private_data_clipboard_format, priv_data_handle))
{
GlobalFree(priv_data_handle);
return CLIPBRD_E_CANT_SET;
}
return S_OK;
}
@ -1757,7 +1763,11 @@ static HRESULT expose_marshalled_dataobject(ole_clipbrd *clipbrd, IDataObject *d
if(!h) return E_OUTOFMEMORY;
SetClipboardData(wine_marshal_clipboard_format, h);
if(!SetClipboardData(wine_marshal_clipboard_format, h))
{
GlobalFree(h);
return CLIPBRD_E_CANT_SET;
}
return S_OK;
}

View file

@ -828,6 +828,16 @@ static DWORD COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *v
if (keytype == REG_EXPAND_SZ) {
if (dstlen <= ExpandEnvironmentStringsW(src, dst, dstlen)) ret = ERROR_MORE_DATA;
} else {
const WCHAR *quote_start;
quote_start = strchrW(src, '\"');
if (quote_start) {
const WCHAR *quote_end = strchrW(quote_start + 1, '\"');
if (quote_end) {
memmove(src, quote_start + 1,
(quote_end - quote_start - 1) * sizeof(WCHAR));
src[quote_end - quote_start - 1] = '\0';
}
}
lstrcpynW(dst, src, dstlen);
}
}
@ -1621,7 +1631,7 @@ INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
'%','0','4','X','-','%','0','2','X','%','0','2','X','-',
'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
'%','0','2','X','%','0','2','X','}',0 };
if (cmax < CHARS_IN_GUID) return 0;
if (!id || cmax < CHARS_IN_GUID) return 0;
sprintfW( str, formatW, id->Data1, id->Data2, id->Data3,
id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
@ -2052,6 +2062,7 @@ HRESULT WINAPI CoRegisterClassObject(
DWORD flags,
LPDWORD lpdwRegister)
{
static LONG next_cookie;
RegisteredClass* newClass;
LPUNKNOWN foundObject;
HRESULT hr;
@ -2105,11 +2116,8 @@ HRESULT WINAPI CoRegisterClassObject(
newClass->pMarshaledData = NULL;
newClass->RpcRegistration = NULL;
/*
* Use the address of the chain node as the cookie since we are sure it's
* unique. FIXME: not on 64-bit platforms.
*/
newClass->dwCookie = (DWORD)newClass;
if (!(newClass->dwCookie = InterlockedIncrement( &next_cookie )))
newClass->dwCookie = InterlockedIncrement( &next_cookie );
/*
* Since we're making a copy of the object pointer, we have to increase its
@ -2130,7 +2138,7 @@ HRESULT WINAPI CoRegisterClassObject(
FIXME("Failed to create stream on hglobal, %x\n", hr);
return hr;
}
hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IClassFactory,
hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IUnknown,
newClass->classObject, MSHCTX_LOCAL, NULL,
MSHLFLAGS_TABLESTRONG);
if (hr) {
@ -2380,7 +2388,7 @@ HRESULT WINAPI CoGetClassObject(
if (CLSCTX_REMOTE_SERVER & dwClsContext)
{
FIXME ("CLSCTX_REMOTE_SERVER not supported\n");
hres = E_NOINTERFACE;
hres = REGDB_E_CLASSNOTREG;
}
if (FAILED(hres))
@ -4106,6 +4114,33 @@ HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
return S_OK;
}
HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
static const WCHAR wszInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};
HKEY hkey;
HRESULT hres;
hres = COM_OpenKeyForCLSID(rclsid, wszInprocHandler32, KEY_READ, &hkey);
if (SUCCEEDED(hres))
{
WCHAR dllpath[MAX_PATH+1];
if (COM_RegReadPath(hkey, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS)
{
static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
if (!strcmpiW(dllpath, wszOle32))
{
RegCloseKey(hkey);
return HandlerCF_Create(rclsid, riid, ppv);
}
}
else
WARN("not creating object for inproc handler path %s\n", debugstr_w(dllpath));
RegCloseKey(hkey);
}
return CLASS_E_CLASSNOTAVAILABLE;
}
/***********************************************************************
* DllMain (OLE32.@)

View file

@ -313,6 +313,9 @@ extern HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID
extern HRESULT WINAPI OLE32_DllRegisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLE32_DllUnregisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
extern HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
/* Exported non-interface Data Advise Holder functions */
HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate);
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface);

View file

@ -670,7 +670,7 @@ CompositeMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc,
else{
if (pbc==NULL)
return E_POINTER;
return E_INVALIDARG;
/* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
/* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */

View file

@ -234,6 +234,12 @@ static void DataCache_Destroy(
LIST_FOR_EACH_ENTRY_SAFE(cache_entry, next_cache_entry, &ptrToDestroy->cache_list, DataCacheEntry, entry)
DataCacheEntry_Destroy(cache_entry);
if (ptrToDestroy->presentationStorage != NULL)
{
IStorage_Release(ptrToDestroy->presentationStorage);
ptrToDestroy->presentationStorage = NULL;
}
/*
* Free the datacache pointer.
*/

View file

@ -1960,9 +1960,21 @@ static DefaultHandler* DefaultHandler_Construct(
&IID_IUnknown,
(void**)&This->dataCache);
if(SUCCEEDED(hr))
{
hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
/* keeping a reference to This->dataCache_PersistStg causes us to keep a
* reference on the outer object */
if (SUCCEEDED(hr))
IUnknown_Release(This->outerUnknown);
else
IUnknown_Release(This->dataCache);
}
if(FAILED(hr))
{
ERR("Unexpected error creating data cache\n");
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
This->clsid = *clsid;
This->clientSite = NULL;
@ -2009,6 +2021,13 @@ static DefaultHandler* DefaultHandler_Construct(
static void DefaultHandler_Destroy(
DefaultHandler* This)
{
TRACE("(%p)\n", This);
/* AddRef/Release may be called on this object during destruction.
* Prevent the object being destroyed recursively by artificially raising
* the reference count. */
This->ref = 10000;
/* release delegates */
DefaultHandler_Stop(This);
release_delegates(This);
@ -2020,6 +2039,9 @@ static void DefaultHandler_Destroy(
if (This->dataCache)
{
/* to balance out the release of dataCache_PersistStg which will result
* in a reference being released from the outer unknown */
IUnknown_AddRef(This->outerUnknown);
IPersistStorage_Release(This->dataCache_PersistStg);
IUnknown_Release(This->dataCache);
This->dataCache_PersistStg = NULL;
@ -2122,3 +2144,77 @@ HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
NULL, riid, ppvObj);
}
typedef struct HandlerCF
{
const IClassFactoryVtbl *lpVtbl;
LONG refs;
CLSID clsid;
} HandlerCF;
static HRESULT WINAPI
HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid,&IID_IUnknown) ||
IsEqualIID(riid,&IID_IClassFactory))
{
*ppv = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
{
HandlerCF *This = (HandlerCF *)iface;
return InterlockedIncrement(&This->refs);
}
static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
{
HandlerCF *This = (HandlerCF *)iface;
ULONG refs = InterlockedDecrement(&This->refs);
if (!refs)
HeapFree(GetProcessHeap(), 0, This);
return refs;
}
static HRESULT WINAPI
HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
REFIID riid, LPVOID *ppv)
{
HandlerCF *This = (HandlerCF *)iface;
return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
}
static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
HandlerCF_QueryInterface,
HandlerCF_AddRef,
HandlerCF_Release,
HandlerCF_CreateInstance,
HandlerCF_LockServer
};
HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
HRESULT hr;
HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This) return E_OUTOFMEMORY;
This->lpVtbl = &HandlerClassFactoryVtbl;
This->refs = 0;
This->clsid = *rclsid;
hr = IUnknown_QueryInterface((IUnknown *)&This->lpVtbl, riid, ppv);
if (FAILED(hr))
HeapFree(GetProcessHeap(), 0, This);
return hr;
}

View file

@ -237,6 +237,10 @@ static ULONG WINAPI IErrorInfoImpl_Release(
if (!ref)
{
TRACE("-- destroying IErrorInfo(%p)\n",This);
ERRORINFO_SysFreeString(This->bstrSource);
ERRORINFO_SysFreeString(This->bstrDescription);
ERRORINFO_SysFreeString(This->bstrHelpFile);
HeapFree(GetProcessHeap(),0,This);
return 0;
}

View file

@ -198,9 +198,9 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm)
TRACE("(%p,%p)\n",iface,pStm);
/* first WORD must be 0 */
/* first WORD */
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread!=sizeof(WORD) || wbuffer!=0)
if (bread!=sizeof(WORD))
{
WARN("Couldn't read 0 word\n");
goto fail;
@ -229,18 +229,26 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm)
goto fail;
}
/* read the first constant */
IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
/* read the unknown value */
IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread != sizeof(WORD))
{
WARN("Couldn't read 0xDEADFFFF constant\n");
WARN("Couldn't read unknown value\n");
goto fail;
}
/* read the DEAD constant */
IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread != sizeof(WORD))
{
WARN("Couldn't read DEAD constant\n");
goto fail;
}
for(i=0;i<5;i++)
{
res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
if (bread!=sizeof(DWORD) || dwbuffer!=0)
if (bread!=sizeof(DWORD))
{
WARN("Couldn't read 0 padding\n");
goto fail;
@ -320,18 +328,20 @@ FileMonikerImpl_Load(IMoniker* iface, IStream* pStm)
* of Windows have minor variations.
*
* Data which must be written on stream is:
* 1) WORD constant:zero
* 1) WORD constant: zero (not validated by Windows)
* 2) length of the path string ("\0" included)
* 3) path string type A
* 4) DWORD constant : 0xDEADFFFF
* 5) five DWORD constant: zero
* 6) If we're only writing the multibyte version,
* 4) Unknown WORD value: Frequently 0xFFFF, but not always. If set very large,
* Windows returns E_OUTOFMEMORY
* 5) WORD Constant: 0xDEAD (not validated by Windows)
* 6) five DWORD constant: zero (not validated by Windows)
* 7) If we're only writing the multibyte version,
* write a zero DWORD and finish.
*
* 7) DWORD: double-length of the path string type W ("\0" not
* 8) DWORD: double-length of the path string type W ("\0" not
* included)
* 8) WORD constant: 0x3
* 9) filePath unicode string.
* 9) WORD constant: 0x3
* 10) filePath unicode string.
*
*/
static HRESULT WINAPI
@ -344,7 +354,8 @@ FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
CHAR* filePathA;
DWORD bytesA, bytesW, len;
static const DWORD DEADFFFF = 0xDEADFFFF; /* Constants */
static const WORD FFFF = 0xFFFF; /* Constants */
static const WORD DEAD = 0xDEAD;
static const DWORD ZERO = 0;
static const WORD THREE = 0x3;
@ -374,8 +385,12 @@ FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
HeapFree(GetProcessHeap(),0,filePathA);
if (FAILED(res)) return res;
/* write a DWORD 0xDEADFFFF */
res=IStream_Write(pStm,&DEADFFFF,sizeof(DWORD),NULL);
/* write a WORD 0xFFFF */
res=IStream_Write(pStm,&FFFF,sizeof(WORD),NULL);
if (FAILED(res)) return res;
/* write a WORD 0xDEAD */
res=IStream_Write(pStm,&DEAD,sizeof(WORD),NULL);
if (FAILED(res)) return res;
/* write 5 zero DWORDs */
@ -945,20 +960,32 @@ FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** p
if(mkSys==MKSYS_FILEMONIKER){
HRESULT ret;
CreateBindCtx(0,&pbind);
ret = CreateBindCtx(0,&pbind);
if (FAILED(ret))
return ret;
/* create a string based on common part of the two paths */
IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis);
IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther);
ret = IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis);
if (FAILED(ret))
return ret;
ret = IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther);
if (FAILED(ret))
return ret;
nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1);
if (FAILED(nb1))
return nb1;
nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2);
if (FAILED(nb2))
return nb2;
if (nb1==0 || nb2==0)
return MK_E_NOPREFIX;
commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1));
if (!commonPath)
return E_OUTOFMEMORY;
*commonPath=0;
@ -1021,7 +1048,7 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
TRACE("%s, %p\n", debugstr_w(str), *stringTable);
strgtable = CoTaskMemAlloc(len*sizeof(WCHAR));
strgtable = CoTaskMemAlloc((len + 1)*sizeof(*strgtable));
if (strgtable==NULL)
return E_OUTOFMEMORY;

View file

@ -365,11 +365,18 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
{
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
ULARGE_INTEGER newPosition;
ULARGE_INTEGER newPosition = This->currentPosition;
HRESULT hr = S_OK;
TRACE("(%p, %x%08x, %d, %p)\n", iface, dlibMove.u.HighPart,
dlibMove.u.LowPart, dwOrigin, plibNewPosition);
if (dlibMove.u.LowPart >= 0x80000000)
{
hr = STG_E_SEEKERROR;
goto end;
}
/*
* The file pointer is moved depending on the given "function"
* parameter.
@ -381,13 +388,13 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
newPosition.u.LowPart = 0;
break;
case STREAM_SEEK_CUR:
newPosition = This->currentPosition;
break;
case STREAM_SEEK_END:
newPosition = This->streamSize;
break;
default:
return STG_E_INVALIDFUNCTION;
hr = STG_E_SEEKERROR;
goto end;
}
/*
@ -395,14 +402,14 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
* If the file pointer ends-up after the end of the stream, the next Write operation will
* make the file larger. This is how it is documented.
*/
if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart) return STG_E_INVALIDFUNCTION;
newPosition.QuadPart += dlibMove.QuadPart;
newPosition.u.HighPart = 0;
newPosition.u.LowPart += dlibMove.QuadPart;
end:
if (plibNewPosition) *plibNewPosition = newPosition;
This->currentPosition = newPosition;
return S_OK;
return hr;
}
/***

View file

@ -62,99 +62,12 @@ static inline IMoniker *impl_from_IROTData( IROTData *iface )
return (IMoniker *)((char*)iface - FIELD_OFFSET(ItemMonikerImpl, lpvtbl2));
}
/********************************************************************************/
/* ItemMoniker prototype functions : */
/* IUnknown prototype functions */
static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface);
static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface);
/* IPersist prototype functions */
static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
/* IPersistStream prototype functions */
static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface);
static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm);
static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
/* IMoniker prototype functions */
static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime);
static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
/* Local function used by ItemMoniker implementation */
static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
/********************************************************************************/
/* IROTData prototype functions */
/* IUnknown prototype functions */
static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
/* IROTData prototype function */
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
/********************************************************************************/
/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
/* IPersistStream and IMoniker functions. */
static const IMonikerVtbl VT_ItemMonikerImpl =
{
ItemMonikerImpl_QueryInterface,
ItemMonikerImpl_AddRef,
ItemMonikerImpl_Release,
ItemMonikerImpl_GetClassID,
ItemMonikerImpl_IsDirty,
ItemMonikerImpl_Load,
ItemMonikerImpl_Save,
ItemMonikerImpl_GetSizeMax,
ItemMonikerImpl_BindToObject,
ItemMonikerImpl_BindToStorage,
ItemMonikerImpl_Reduce,
ItemMonikerImpl_ComposeWith,
ItemMonikerImpl_Enum,
ItemMonikerImpl_IsEqual,
ItemMonikerImpl_Hash,
ItemMonikerImpl_IsRunning,
ItemMonikerImpl_GetTimeOfLastChange,
ItemMonikerImpl_Inverse,
ItemMonikerImpl_CommonPrefixWith,
ItemMonikerImpl_RelativePathTo,
ItemMonikerImpl_GetDisplayName,
ItemMonikerImpl_ParseDisplayName,
ItemMonikerImpl_IsSystemMoniker
};
/********************************************************************************/
/* Virtual function table for the IROTData class. */
static const IROTDataVtbl VT_ROTDataImpl =
{
ItemMonikerROTDataImpl_QueryInterface,
ItemMonikerROTDataImpl_AddRef,
ItemMonikerROTDataImpl_Release,
ItemMonikerROTDataImpl_GetComparisonData
};
/*******************************************************************************
* ItemMoniker_QueryInterface
*******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -192,7 +105,7 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
return E_NOINTERFACE;
/* Query Interface always increases the reference count by one when it is successful */
ItemMonikerImpl_AddRef(iface);
IMoniker_AddRef(iface);
return S_OK;
}
@ -200,7 +113,7 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
/******************************************************************************
* ItemMoniker_AddRef
******************************************************************************/
ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -212,7 +125,7 @@ ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
/******************************************************************************
* ItemMoniker_Release
******************************************************************************/
ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
ULONG ref;
@ -230,7 +143,7 @@ ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
/******************************************************************************
* ItemMoniker_GetClassID
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
TRACE("(%p,%p)\n",iface,pClassID);
@ -245,7 +158,7 @@ HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
/******************************************************************************
* ItemMoniker_IsDirty
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
{
/* Note that the OLE-provided implementations of the IPersistStream::IsDirty
method in the OLE-provided moniker interfaces always return S_FALSE because
@ -259,7 +172,7 @@ HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
/******************************************************************************
* ItemMoniker_Load
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -328,9 +241,9 @@ HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
/******************************************************************************
* ItemMoniker_Save
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
IStream* pStm,/* pointer to the stream where the object is to be saved */
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
IStream* pStm,/* pointer to the stream where the object is to be saved */
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
HRESULT res;
@ -364,8 +277,8 @@ HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
/******************************************************************************
* ItemMoniker_GetSizeMax
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
@ -388,67 +301,14 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
return S_OK;
}
/******************************************************************************
* ItemMoniker_Construct (local function)
*******************************************************************************/
static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
{
int sizeStr1=lstrlenW(lpszItem), sizeStr2;
static const OLECHAR emptystr[1];
LPCOLESTR delim;
TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));
/* Initialize the virtual function table. */
This->lpvtbl1 = &VT_ItemMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->pMarshal = NULL;
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
if (!This->itemName)
return E_OUTOFMEMORY;
lstrcpyW(This->itemName,lpszItem);
if (!lpszDelim)
FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
delim = lpszDelim ? lpszDelim : emptystr;
sizeStr2=lstrlenW(delim);
This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
if (!This->itemDelimiter) {
HeapFree(GetProcessHeap(),0,This->itemName);
return E_OUTOFMEMORY;
}
lstrcpyW(This->itemDelimiter,delim);
return S_OK;
}
/******************************************************************************
* ItemMoniker_Destroy (local function)
*******************************************************************************/
static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
{
TRACE("(%p)\n",This);
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This->itemName);
HeapFree(GetProcessHeap(),0,This->itemDelimiter);
HeapFree(GetProcessHeap(),0,This);
return S_OK;
}
/******************************************************************************
* ItemMoniker_BindToObject
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -481,11 +341,11 @@ HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
/******************************************************************************
* ItemMoniker_BindToStorage
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -514,11 +374,11 @@ HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
/******************************************************************************
* ItemMoniker_Reduce
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
IBindCtx* pbc,
DWORD dwReduceHowFar,
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
IBindCtx* pbc,
DWORD dwReduceHowFar,
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
@ -534,10 +394,10 @@ HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
/******************************************************************************
* ItemMoniker_ComposeWith
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric,
IMoniker** ppmkComposite)
static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric,
IMoniker** ppmkComposite)
{
HRESULT res=S_OK;
DWORD mkSys,mkSys2;
@ -609,7 +469,7 @@ HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
/******************************************************************************
* ItemMoniker_Enum
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
@ -624,7 +484,7 @@ HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker*
/******************************************************************************
* ItemMoniker_IsEqual
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
CLSID clsid;
@ -657,7 +517,7 @@ HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker
/******************************************************************************
* ItemMoniker_Hash
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
DWORD h = 0;
@ -682,10 +542,10 @@ HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
/******************************************************************************
* ItemMoniker_IsRunning
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
{
IRunningObjectTable* rot;
HRESULT res;
@ -701,7 +561,7 @@ HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
return S_OK;
else {
if (pbc==NULL)
return E_POINTER;
return E_INVALIDARG;
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
@ -734,10 +594,10 @@ HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
/******************************************************************************
* ItemMoniker_GetTimeOfLastChange
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
FILETIME* pItemTime)
static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
FILETIME* pItemTime)
{
IRunningObjectTable* rot;
HRESULT res;
@ -775,7 +635,7 @@ HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
/******************************************************************************
* ItemMoniker_Inverse
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
TRACE("(%p,%p)\n",iface,ppmk);
@ -788,7 +648,7 @@ HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
/******************************************************************************
* ItemMoniker_CommonPrefixWith
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
DWORD mkSys;
@ -815,7 +675,7 @@ HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOth
/******************************************************************************
* ItemMoniker_RelativePathTo
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
@ -830,10 +690,10 @@ HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther,
/******************************************************************************
* ItemMoniker_GetDisplayName
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -862,12 +722,12 @@ HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
/******************************************************************************
* ItemMoniker_ParseDisplayName
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR pszDisplayName,
ULONG* pchEaten,
IMoniker** ppmkOut)
static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR pszDisplayName,
ULONG* pchEaten,
IMoniker** ppmkOut)
{
IOleItemContainer* poic=0;
IParseDisplayName* ppdn=0;
@ -906,7 +766,7 @@ HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
/******************************************************************************
* ItemMoniker_IsSystemMoniker
******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
TRACE("(%p,%p)\n",iface,pwdMksys);
@ -921,7 +781,7 @@ HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
/*******************************************************************************
* ItemMonikerIROTData_QueryInterface
*******************************************************************************/
HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
{
IMoniker *This = impl_from_IROTData(iface);
@ -934,7 +794,7 @@ HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid
/***********************************************************************
* ItemMonikerIROTData_AddRef
*/
ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
{
IMoniker *This = impl_from_IROTData(iface);
@ -946,7 +806,7 @@ ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
/***********************************************************************
* ItemMonikerIROTData_Release
*/
ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
{
IMoniker *This = impl_from_IROTData(iface);
@ -958,10 +818,10 @@ ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
/******************************************************************************
* ItemMonikerIROTData_GetComparisonData
******************************************************************************/
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData,
ULONG cbMax,
ULONG* pcbData)
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData,
ULONG cbMax,
ULONG* pcbData)
{
IMoniker *This = impl_from_IROTData(iface);
ItemMonikerImpl *This1 = (ItemMonikerImpl *)This;
@ -989,6 +849,99 @@ HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
return S_OK;
}
/********************************************************************************/
/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
/* IPersistStream and IMoniker functions. */
static const IMonikerVtbl VT_ItemMonikerImpl =
{
ItemMonikerImpl_QueryInterface,
ItemMonikerImpl_AddRef,
ItemMonikerImpl_Release,
ItemMonikerImpl_GetClassID,
ItemMonikerImpl_IsDirty,
ItemMonikerImpl_Load,
ItemMonikerImpl_Save,
ItemMonikerImpl_GetSizeMax,
ItemMonikerImpl_BindToObject,
ItemMonikerImpl_BindToStorage,
ItemMonikerImpl_Reduce,
ItemMonikerImpl_ComposeWith,
ItemMonikerImpl_Enum,
ItemMonikerImpl_IsEqual,
ItemMonikerImpl_Hash,
ItemMonikerImpl_IsRunning,
ItemMonikerImpl_GetTimeOfLastChange,
ItemMonikerImpl_Inverse,
ItemMonikerImpl_CommonPrefixWith,
ItemMonikerImpl_RelativePathTo,
ItemMonikerImpl_GetDisplayName,
ItemMonikerImpl_ParseDisplayName,
ItemMonikerImpl_IsSystemMoniker
};
/********************************************************************************/
/* Virtual function table for the IROTData class. */
static const IROTDataVtbl VT_ROTDataImpl =
{
ItemMonikerROTDataImpl_QueryInterface,
ItemMonikerROTDataImpl_AddRef,
ItemMonikerROTDataImpl_Release,
ItemMonikerROTDataImpl_GetComparisonData
};
/******************************************************************************
* ItemMoniker_Construct (local function)
*******************************************************************************/
static HRESULT ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
{
int sizeStr1=lstrlenW(lpszItem), sizeStr2;
static const OLECHAR emptystr[1];
LPCOLESTR delim;
TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));
/* Initialize the virtual function table. */
This->lpvtbl1 = &VT_ItemMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->pMarshal = NULL;
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
if (!This->itemName)
return E_OUTOFMEMORY;
lstrcpyW(This->itemName,lpszItem);
if (!lpszDelim)
FIXME("lpszDelim is NULL. Using empty string which is possibly wrong.\n");
delim = lpszDelim ? lpszDelim : emptystr;
sizeStr2=lstrlenW(delim);
This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
if (!This->itemDelimiter) {
HeapFree(GetProcessHeap(),0,This->itemName);
return E_OUTOFMEMORY;
}
lstrcpyW(This->itemDelimiter,delim);
return S_OK;
}
/******************************************************************************
* ItemMoniker_Destroy (local function)
*******************************************************************************/
static HRESULT ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
{
TRACE("(%p)\n",This);
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This->itemName);
HeapFree(GetProcessHeap(),0,This->itemDelimiter);
HeapFree(GetProcessHeap(),0,This);
return S_OK;
}
/******************************************************************************
* CreateItemMoniker [OLE32.@]
******************************************************************************/

View file

@ -553,9 +553,9 @@ static HRESULT WINAPI ProxyCliSec_SetBlanket(IClientSecurity *iface,
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);
FIXME("(%p, %d, %d, %s, %d, %d, %p, 0x%x): stub\n", pProxy, AuthnSvc, AuthzSvc,
pServerPrincName == COLE_DEFAULT_PRINCIPAL ? "<default principal>" : debugstr_w(pServerPrincName),
AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
return E_NOTIMPL;
}
@ -1336,7 +1336,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, stdobjref.flags & SORFP_TABLEWEAK, TRUE);
stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, FALSE);
stub_manager_int_release(stubmgr);
return hres;

View file

@ -124,30 +124,18 @@ static BOOL start_rpcss(void)
{
PROCESS_INFORMATION pi;
STARTUPINFOW si;
static WCHAR cmd[6];
static const WCHAR rpcss[] = {'r','p','c','s','s',0};
WCHAR cmd[MAX_PATH];
static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0};
BOOL rslt;
TRACE("\n");
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFOA));
si.cb = sizeof(STARTUPINFOA);
GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) );
strcatW( cmd, rpcss );
memcpy(cmd, rpcss, sizeof(rpcss));
rslt = CreateProcessW(
NULL, /* executable */
cmd, /* command line */
NULL, /* process security attributes */
NULL, /* primary thread security attributes */
FALSE, /* inherit handles */
0, /* creation flags */
NULL, /* use parent's environment */
NULL, /* use parent's current directory */
&si, /* STARTUPINFO pointer */
&pi /* PROCESS_INFORMATION */
);
rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
if (rslt)
{

View file

@ -190,6 +190,9 @@ HRESULT WINAPI OleInitialize(LPVOID reserved)
if (FAILED(hr))
return hr;
if (!COM_CurrentInfo()->ole_inits)
hr = S_OK;
/*
* Then, it has to initialize the OLE specific modules.
* This includes:
@ -1140,8 +1143,8 @@ HRESULT WINAPI OleLockRunning(LPUNKNOWN pUnknown, BOOL fLock, BOOL fLastUnlockCl
return hres;
}
else
return E_INVALIDARG;
return S_OK;
}

View file

@ -70,7 +70,7 @@
@ stdcall CoRevokeClassObject(long)
@ stdcall CoRevokeInitializeSpy(double)
@ stdcall CoRevokeMallocSpy()
@ stdcall CoSetProxyBlanket(ptr long long wstr long long ptr long)
@ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long)
@ stdcall CoSetState(ptr)
@ stdcall CoSuspendClassObjects()
@ stdcall CoSwitchCallContext(ptr ptr)

View file

@ -23,7 +23,10 @@
#include "winuser.h"
#include "winnls.h"
#include "version.rc"
#define WINE_OLESELFREGISTER
#define WINE_FILENAME_STR "ole32.dll"
#include <wine/wine_common_ver.rc>
/*
* Everything that does not depend on language,
@ -44,12 +47,3 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/* @makedep: drag_link.cur */
3 CURSOR drag_link.cur
/*
* Everything specific to any language goes
* in one of the specific files.
* Note that you can and may override resources
* which also have a neutral version. This is to
* get localized bitmaps for example.
*/

View file

@ -46,6 +46,8 @@
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
{
HRESULT hr;
*ppv = NULL;
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
IsEqualIID(iid,&IID_IClassFactory) ||
@ -70,5 +72,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr))
return ComCatCF_Create(iid, ppv);
return OLE32_DllGetClassObject(rclsid, iid, ppv);
hr = OLE32_DllGetClassObject(rclsid, iid, ppv);
if (SUCCEEDED(hr))
return hr;
return Handler_DllGetClassObject(rclsid, iid, ppv);
}

View file

@ -408,9 +408,6 @@ static GUID const CLSID_StdOleLink = {
static GUID const CLSID_PackagerMoniker = {
0x00000308, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_PSFactoryBuffer_actxprxy = {
0xB8DA6310, 0xE19B, 0x11D0, {0x93,0x3C,0x00,0xA0,0xC9,0x0D,0xCA,0xA9} };
extern GUID const CLSID_Picture_Metafile;
extern GUID const CLSID_Picture_Dib;
@ -510,42 +507,35 @@ static struct regsvr_coclass const coclass_list[] = {
* interface list
*/
#define INTERFACE_ENTRY(interface, base, clsid32) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), NULL, clsid32 }
#define BAS_INTERFACE_ENTRY(interface, base) INTERFACE_ENTRY(interface, &IID_##base, NULL)
#define ACTX_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, &CLSID_PSFactoryBuffer_actxprxy)
#define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL)
#define INTERFACE_ENTRY(interface, base) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), NULL, NULL }
static const struct regsvr_interface interface_list[] = {
LCL_INTERFACE_ENTRY(IUnknown),
LCL_INTERFACE_ENTRY(IMalloc),
LCL_INTERFACE_ENTRY(IMarshal),
BAS_INTERFACE_ENTRY(IMoniker, IPersistStream),
LCL_INTERFACE_ENTRY(IMessageFilter),
LCL_INTERFACE_ENTRY(IStdMarshalInfo),
LCL_INTERFACE_ENTRY(IExternalConnection),
LCL_INTERFACE_ENTRY(IMallocSpy),
LCL_INTERFACE_ENTRY(IMultiQI),
BAS_INTERFACE_ENTRY(IPersistStream, IPersist),
BAS_INTERFACE_ENTRY(IPersistStorage, IPersist),
BAS_INTERFACE_ENTRY(IPersistFile, IPersist),
LCL_INTERFACE_ENTRY(IDataAdviseHolder),
LCL_INTERFACE_ENTRY(IOleAdviseHolder),
BAS_INTERFACE_ENTRY(IOleInPlaceObject, IOleWindow),
BAS_INTERFACE_ENTRY(IOleInPlaceUIWindow, IOleWindow),
BAS_INTERFACE_ENTRY(IOleInPlaceActiveObject, IOleWindow),
BAS_INTERFACE_ENTRY(IOleInPlaceSite, IOleWindow),
BAS_INTERFACE_ENTRY(IOleContainer, IParseDisplayName),
BAS_INTERFACE_ENTRY(IOleItemContainer, IOleContainer),
LCL_INTERFACE_ENTRY(IDropSource),
BAS_INTERFACE_ENTRY(IAdviseSink2, IAdviseSink),
BAS_INTERFACE_ENTRY(IViewObject2, IViewObject),
BAS_INTERFACE_ENTRY(IOleCache2, IOleCache),
LCL_INTERFACE_ENTRY(IClientSecurity),
LCL_INTERFACE_ENTRY(IServerSecurity),
ACTX_INTERFACE_ENTRY(IEnumGUID),
ACTX_INTERFACE_ENTRY(IEnumCATEGORYINFO),
ACTX_INTERFACE_ENTRY(ICatRegister),
ACTX_INTERFACE_ENTRY(ICatInformation),
INTERFACE_ENTRY( IUnknown, NULL ),
INTERFACE_ENTRY( IMalloc, NULL ),
INTERFACE_ENTRY( IMarshal, NULL ),
INTERFACE_ENTRY( IMoniker, &IID_IPersistStream ),
INTERFACE_ENTRY( IMessageFilter, NULL ),
INTERFACE_ENTRY( IStdMarshalInfo, NULL ),
INTERFACE_ENTRY( IExternalConnection, NULL ),
INTERFACE_ENTRY( IMallocSpy, NULL ),
INTERFACE_ENTRY( IMultiQI, NULL ),
INTERFACE_ENTRY( IPersistStream, &IID_IPersist ),
INTERFACE_ENTRY( IPersistStorage, &IID_IPersist ),
INTERFACE_ENTRY( IPersistFile, &IID_IPersist ),
INTERFACE_ENTRY( IDataAdviseHolder, NULL ),
INTERFACE_ENTRY( IOleAdviseHolder, NULL ),
INTERFACE_ENTRY( IOleInPlaceObject, &IID_IOleWindow ),
INTERFACE_ENTRY( IOleInPlaceUIWindow, &IID_IOleWindow ),
INTERFACE_ENTRY( IOleInPlaceActiveObject, &IID_IOleWindow ),
INTERFACE_ENTRY( IOleInPlaceSite, &IID_IOleWindow ),
INTERFACE_ENTRY( IOleContainer, &IID_IParseDisplayName ),
INTERFACE_ENTRY( IOleItemContainer, &IID_IOleContainer ),
INTERFACE_ENTRY( IDropSource, NULL ),
INTERFACE_ENTRY( IAdviseSink2, &IID_IAdviseSink ),
INTERFACE_ENTRY( IViewObject2, &IID_IViewObject ),
INTERFACE_ENTRY( IOleCache2, &IID_IOleCache ),
INTERFACE_ENTRY( IClientSecurity, NULL ),
INTERFACE_ENTRY( IServerSecurity, NULL ),
{ NULL } /* list terminator */
};

View file

@ -1358,7 +1358,7 @@ void RPC_ExecuteCall(struct dispatch_params *params)
handlecall = IMessageFilter_HandleInComingCall(COM_CurrentApt()->filter,
calltype,
(HTASK)GetCurrentProcessId(),
UlongToHandle(GetCurrentProcessId()),
0 /* FIXME */,
&interface_info);
TRACE("IMessageFilter_HandleInComingCall returned %d\n", handlecall);

View file

@ -236,7 +236,7 @@ static PROPVARIANT *PropertyStorage_FindProperty(PropertyStorage_impl *This,
{
PROPVARIANT *ret = NULL;
dictionary_find(This->propid_to_prop, (void *)propid, (void **)&ret);
dictionary_find(This->propid_to_prop, UlongToPtr(propid), (void **)&ret);
TRACE("returning %p\n", ret);
return ret;
}
@ -246,14 +246,14 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName(
PropertyStorage_impl *This, LPCWSTR name)
{
PROPVARIANT *ret = NULL;
PROPID propid;
void *propid;
if (!name)
return NULL;
if (This->codePage == CP_UNICODE)
{
if (dictionary_find(This->name_to_propid, name, (void **)&propid))
ret = PropertyStorage_FindProperty(This, propid);
if (dictionary_find(This->name_to_propid, name, &propid))
ret = PropertyStorage_FindProperty(This, PtrToUlong(propid));
}
else
{
@ -263,9 +263,8 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName(
if (SUCCEEDED(hr))
{
if (dictionary_find(This->name_to_propid, ansiName,
(void **)&propid))
ret = PropertyStorage_FindProperty(This, propid);
if (dictionary_find(This->name_to_propid, ansiName, &propid))
ret = PropertyStorage_FindProperty(This, PtrToUlong(propid));
CoTaskMemFree(ansiName);
}
}
@ -278,7 +277,7 @@ static LPWSTR PropertyStorage_FindPropertyNameById(PropertyStorage_impl *This,
{
LPWSTR ret = NULL;
dictionary_find(This->propid_to_name, (void *)propid, (void **)&ret);
dictionary_find(This->propid_to_name, UlongToPtr(propid), (void **)&ret);
TRACE("returning %p\n", ret);
return ret;
}
@ -490,7 +489,7 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
lcid);
if (SUCCEEDED(hr))
{
dictionary_insert(This->propid_to_prop, (void *)propid, prop);
dictionary_insert(This->propid_to_prop, UlongToPtr(propid), prop);
if (propid > This->highestProp)
This->highestProp = propid;
}
@ -534,8 +533,8 @@ static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This,
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);
dictionary_insert(This->propid_to_name, (void *)id, name);
dictionary_insert(This->name_to_propid, name, UlongToPtr(id));
dictionary_insert(This->propid_to_name, UlongToPtr(id), name);
}
return hr;
}
@ -666,18 +665,16 @@ static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
{
if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
{
PROPID propid;
void *propid;
if (dictionary_find(This->name_to_propid,
(void *)rgpspec[i].u.lpwstr, (void **)&propid))
dictionary_remove(This->propid_to_prop, (void *)propid);
if (dictionary_find(This->name_to_propid, rgpspec[i].u.lpwstr, &propid))
dictionary_remove(This->propid_to_prop, propid);
}
else
{
if (rgpspec[i].u.propid >= PID_FIRST_USABLE &&
rgpspec[i].u.propid < PID_MIN_READONLY)
dictionary_remove(This->propid_to_prop,
(void *)rgpspec[i].u.propid);
dictionary_remove(This->propid_to_prop, UlongToPtr(rgpspec[i].u.propid));
else
hr = STG_E_INVALIDPARAMETER;
}
@ -787,10 +784,9 @@ static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
{
LPWSTR name = NULL;
if (dictionary_find(This->propid_to_name, (void *)rgpropid[i],
(void **)&name))
if (dictionary_find(This->propid_to_name, UlongToPtr(rgpropid[i]), (void **)&name))
{
dictionary_remove(This->propid_to_name, (void *)rgpropid[i]);
dictionary_remove(This->propid_to_name, UlongToPtr(rgpropid[i]));
dictionary_remove(This->name_to_propid, name);
}
}
@ -955,8 +951,8 @@ static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
static int PropertyStorage_PropCompare(const void *a, const void *b,
void *extra)
{
TRACE("(%d, %d)\n", (PROPID)a, (PROPID)b);
return (PROPID)a - (PROPID)b;
TRACE("(%d, %d)\n", PtrToUlong(a), PtrToUlong(b));
return PtrToUlong(a) - PtrToUlong(b);
}
static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
@ -1143,8 +1139,8 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
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);
prop->u.pclipdata->pClipData = CoTaskMemAlloc(len - sizeof(prop->u.pclipdata->ulClipFmt));
memcpy(prop->u.pclipdata->pClipData, data+8, len - sizeof(prop->u.pclipdata->ulClipFmt));
}
else
hr = STG_E_INVALIDPARAMETER;
@ -1406,6 +1402,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
idOffset->propid, &prop, This->codePage);
}
}
PropVariantClear(&prop);
}
}
}
@ -1512,7 +1509,7 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
assert(key);
assert(closure);
StorageUtl_WriteDWord((LPBYTE)&propid, 0, (DWORD)value);
StorageUtl_WriteDWord((LPBYTE)&propid, 0, PtrToUlong(value));
c->hr = IStream_Write(This->stm, &propid, sizeof(propid), &count);
if (FAILED(c->hr))
goto end;
@ -1735,7 +1732,8 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
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);
hr = IStream_Write(This->stm, var->u.pclipdata->pClipData,
len - sizeof(var->u.pclipdata->ulClipFmt), &count);
if (FAILED(hr))
goto end;
bytesWritten = count + sizeof cf_hdr;
@ -1779,7 +1777,7 @@ static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value,
assert(extra);
assert(closure);
c->hr = PropertyStorage_WritePropertyToStream(This, c->propNum++,
(DWORD)key, value, c->sectionOffset);
PtrToUlong(key), value, c->sectionOffset);
return SUCCEEDED(c->hr);
}
@ -2396,7 +2394,7 @@ static HRESULT WINAPI IEnumSTATPROPSTG_fnClone(
static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
{
enumx_impl *enumx = arg;
PROPID propid = (PROPID) k;
PROPID propid = PtrToUlong(k);
const PROPVARIANT *prop = v;
STATPROPSTG stat;

View file

@ -74,21 +74,6 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This)
This->parentStorage = 0;
/*
* Make sure we clean-up the block chain stream objects that we were using.
*/
if (This->bigBlockChain != 0)
{
BlockChainStream_Destroy(This->bigBlockChain);
This->bigBlockChain = 0;
}
if (This->smallBlockChain != 0)
{
SmallBlockChainStream_Destroy(This->smallBlockChain);
This->smallBlockChain = 0;
}
/*
* Finally, free the memory used-up by the class.
*/
@ -179,73 +164,6 @@ static ULONG WINAPI StgStreamImpl_Release(
return ref;
}
/***
* This method will open the block chain pointed by the property
* that describes the stream.
* If the stream's size is null, no chain is opened.
*/
static void StgStreamImpl_OpenBlockChain(
StgStreamImpl* This)
{
StgProperty curProperty;
BOOL readSuccessful;
/*
* Make sure no old object is left over.
*/
if (This->smallBlockChain != 0)
{
SmallBlockChainStream_Destroy(This->smallBlockChain);
This->smallBlockChain = 0;
}
if (This->bigBlockChain != 0)
{
BlockChainStream_Destroy(This->bigBlockChain);
This->bigBlockChain = 0;
}
/*
* Read the information from the property.
*/
readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
if (readSuccessful)
{
This->streamSize = curProperty.size;
/*
* This code supports only streams that are <32 bits in size.
*/
assert(This->streamSize.u.HighPart == 0);
if(curProperty.startingBlock == BLOCK_END_OF_CHAIN)
{
assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) );
}
else
{
if ( (This->streamSize.u.HighPart == 0) &&
(This->streamSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )
{
This->smallBlockChain = SmallBlockChainStream_Construct(
This->parentStorage->ancestorStorage,
NULL,
This->ownerProperty);
}
else
{
This->bigBlockChain = BlockChainStream_Construct(
This->parentStorage->ancestorStorage,
NULL,
This->ownerProperty);
}
}
}
}
/***
* This method is part of the ISequentialStream interface.
*
@ -264,7 +182,6 @@ static HRESULT WINAPI StgStreamImpl_Read(
StgStreamImpl* const This=(StgStreamImpl*)iface;
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
HRESULT res;
TRACE("(%p, %p, %d, %p)\n",
@ -283,60 +200,21 @@ static HRESULT WINAPI StgStreamImpl_Read(
if (pcbRead==0)
pcbRead = &bytesReadBuffer;
/*
* Using the known size of the stream, calculate the number of bytes
* to read from the block chain
*/
bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
/*
* Depending on the type of chain that was opened when the stream was constructed,
* we delegate the work to the method that reads the block chains.
*/
if (This->smallBlockChain!=0)
{
res = SmallBlockChainStream_ReadAt(This->smallBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
}
else if (This->bigBlockChain!=0)
{
res = BlockChainStream_ReadAt(This->bigBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
}
else
{
/*
* Small and big block chains are both NULL. This case will happen
* when a stream starts with BLOCK_END_OF_CHAIN and has size zero.
*/
*pcbRead = 0;
res = S_OK;
goto end;
}
res = StorageBaseImpl_StreamReadAt(This->parentStorage,
This->dirEntry,
This->currentPosition,
cb,
pv,
pcbRead);
if (SUCCEEDED(res))
{
/*
* We should always be able to read the proper amount of data from the
* chain.
*/
assert(bytesToReadFromBuffer == *pcbRead);
/*
* Advance the pointer for the number of positions read.
*/
This->currentPosition.u.LowPart += *pcbRead;
/*
* Advance the pointer for the number of positions read.
*/
This->currentPosition.u.LowPart += *pcbRead;
}
end:
TRACE("<-- %08x\n", res);
return res;
}
@ -359,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
HRESULT res;
@ -405,51 +282,13 @@ static HRESULT WINAPI StgStreamImpl_Write(
TRACE("<-- S_OK, written 0\n");
return S_OK;
}
else
{
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
}
/*
* Verify if we need to grow the stream
*/
if (newSize.u.LowPart > This->streamSize.u.LowPart)
{
/* grow stream */
res = IStream_SetSize(iface, newSize);
if (FAILED(res))
return res;
}
/*
* Depending on the type of chain that was opened when the stream was constructed,
* we delegate the work to the method that readwrites to the block chains.
*/
if (This->smallBlockChain!=0)
{
res = SmallBlockChainStream_WriteAt(This->smallBlockChain,
This->currentPosition,
cb,
pv,
pcbWritten);
}
else if (This->bigBlockChain!=0)
{
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;
}
res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
This->dirEntry,
This->currentPosition,
cb,
pv,
pcbWritten);
/*
* Advance the position pointer for the number of positions written.
@ -477,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek(
StgStreamImpl* const This=(StgStreamImpl*)iface;
ULARGE_INTEGER newPosition;
DirEntry currentEntry;
HRESULT hr;
TRACE("(%p, %d, %d, %p)\n",
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
@ -515,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek(
*plibNewPosition = This->currentPosition;
break;
case STREAM_SEEK_END:
*plibNewPosition = This->streamSize;
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, &currentEntry);
if (FAILED(hr)) return hr;
*plibNewPosition = currentEntry.size;
break;
default:
WARN("invalid dwOrigin %d\n", dwOrigin);
@ -545,8 +388,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
StgProperty curProperty;
BOOL Success;
HRESULT hr;
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
@ -574,99 +416,8 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
return STG_E_ACCESSDENIED;
}
/* In simple mode keep the stream size above the small block limit */
if (This->parentStorage->ancestorStorage->base.openFlags & STGM_SIMPLE)
libNewSize.u.LowPart = max(libNewSize.u.LowPart, LIMIT_TO_USE_SMALL_BLOCK);
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
/*
* This will happen if we're creating a stream
*/
if ((This->smallBlockChain == 0) && (This->bigBlockChain == 0))
{
if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK)
{
This->smallBlockChain = SmallBlockChainStream_Construct(
This->parentStorage->ancestorStorage,
NULL,
This->ownerProperty);
}
else
{
This->bigBlockChain = BlockChainStream_Construct(
This->parentStorage->ancestorStorage,
NULL,
This->ownerProperty);
}
}
/*
* Read this stream's property to see if it's small blocks or big blocks
*/
Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
/*
* Determine if we have to switch from small to big blocks or vice versa
*/
if ( (This->smallBlockChain!=0) &&
(curProperty.size.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )
{
if (libNewSize.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK)
{
/*
* Transform the small block chain into a big block chain
*/
This->bigBlockChain = Storage32Impl_SmallBlocksToBigBlocks(
This->parentStorage->ancestorStorage,
&This->smallBlockChain);
}
}
else if ( (This->bigBlockChain!=0) &&
(curProperty.size.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) )
{
if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK)
{
/*
* Transform the big block chain into a small block chain
*/
This->smallBlockChain = Storage32Impl_BigBlocksToSmallBlocks(
This->parentStorage->ancestorStorage,
&This->bigBlockChain);
}
}
if (This->smallBlockChain!=0)
{
Success = SmallBlockChainStream_SetSize(This->smallBlockChain, libNewSize);
}
else
{
Success = BlockChainStream_SetSize(This->bigBlockChain, libNewSize);
}
/*
* Write the new information about this stream to the property
*/
Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
curProperty.size.u.HighPart = libNewSize.u.HighPart;
curProperty.size.u.LowPart = libNewSize.u.LowPart;
if (Success)
{
StorageImpl_WriteProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
}
This->streamSize = libNewSize;
return S_OK;
hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
return hr;
}
/***
@ -834,8 +585,8 @@ static HRESULT WINAPI StgStreamImpl_Stat(
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
StgProperty curProperty;
BOOL readSuccessful;
DirEntry currentEntry;
HRESULT hr;
TRACE("%p %p %d\n", This, pstatstg, grfStatFlag);
@ -850,31 +601,30 @@ static HRESULT WINAPI StgStreamImpl_Stat(
}
/*
* Read the information from the property.
* Read the information from the directory entry.
*/
readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage,
This->dirEntry,
&currentEntry);
if (readSuccessful)
if (SUCCEEDED(hr))
{
StorageImpl *root = This->parentStorage->ancestorStorage;
StorageUtl_CopyPropertyToSTATSTG(pstatstg,
&curProperty,
StorageUtl_CopyDirEntryToSTATSTG(This->parentStorage,
pstatstg,
&currentEntry,
grfStatFlag);
pstatstg->grfMode = This->grfMode;
/* In simple create mode cbSize is the current pos */
if((root->base.openFlags & STGM_SIMPLE) && root->create)
if((This->parentStorage->openFlags & STGM_SIMPLE) && This->parentStorage->create)
pstatstg->cbSize = This->currentPosition;
return S_OK;
}
WARN("failed to read properties\n");
return E_FAIL;
WARN("failed to read entry\n");
return hr;
}
/***
@ -910,7 +660,7 @@ static HRESULT WINAPI StgStreamImpl_Clone(
if ( ppstm == 0 )
return STG_E_INVALIDPOINTER;
new_stream = StgStreamImpl_Construct (This->parentStorage, This->grfMode, This->ownerProperty);
new_stream = StgStreamImpl_Construct (This->parentStorage, This->grfMode, This->dirEntry);
if (!new_stream)
return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */
@ -957,12 +707,12 @@ static const IStreamVtbl StgStreamImpl_Vtbl =
*
* Params:
* parentStorage - Pointer to the storage that contains the stream to open
* ownerProperty - Index of the property that points to this stream.
* dirEntry - Index of the directory entry that points to this stream.
*/
StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage,
DWORD grfMode,
ULONG ownerProperty)
DirRef dirEntry)
{
StgStreamImpl* newStream;
@ -991,7 +741,7 @@ StgStreamImpl* StgStreamImpl_Construct(
*/
newStream->grfMode = grfMode;
newStream->ownerProperty = ownerProperty;
newStream->dirEntry = dirEntry;
/*
* Start the stream at the beginning.
@ -999,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct(
newStream->currentPosition.u.HighPart = 0;
newStream->currentPosition.u.LowPart = 0;
/*
* Initialize the rest of the data.
*/
newStream->streamSize.u.HighPart = 0;
newStream->streamSize.u.LowPart = 0;
newStream->bigBlockChain = 0;
newStream->smallBlockChain = 0;
/*
* Read the size from the property and determine if the blocks forming
* this stream are large or small.
*/
StgStreamImpl_OpenBlockChain(newStream);
/* add us to the storage's list of active streams */
StorageBaseImpl_AddStream(parentStorage, newStream);
}

File diff suppressed because it is too large Load diff

View file

@ -53,15 +53,15 @@ static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048;
static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C;
static const ULONG OFFSET_PS_NAME = 0x00000000;
static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040;
static const ULONG OFFSET_PS_PROPERTYTYPE = 0x00000042;
static const ULONG OFFSET_PS_PREVIOUSPROP = 0x00000044;
static const ULONG OFFSET_PS_NEXTPROP = 0x00000048;
static const ULONG OFFSET_PS_DIRPROP = 0x0000004C;
static const ULONG OFFSET_PS_STGTYPE = 0x00000042;
static const ULONG OFFSET_PS_LEFTCHILD = 0x00000044;
static const ULONG OFFSET_PS_RIGHTCHILD = 0x00000048;
static const ULONG OFFSET_PS_DIRROOT = 0x0000004C;
static const ULONG OFFSET_PS_GUID = 0x00000050;
static const ULONG OFFSET_PS_TSS1 = 0x00000064;
static const ULONG OFFSET_PS_TSD1 = 0x00000068;
static const ULONG OFFSET_PS_TSS2 = 0x0000006C;
static const ULONG OFFSET_PS_TSD2 = 0x00000070;
static const ULONG OFFSET_PS_CTIMELOW = 0x00000064;
static const ULONG OFFSET_PS_CTIMEHIGH = 0x00000068;
static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C;
static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070;
static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074;
static const ULONG OFFSET_PS_SIZE = 0x00000078;
static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009;
@ -72,26 +72,24 @@ static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC;
static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD;
static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
static const ULONG BLOCK_UNUSED = 0xFFFFFFFF;
static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
static const ULONG DIRENTRY_NULL = 0xFFFFFFFF;
#define PROPERTY_NAME_MAX_LEN 0x20
#define PROPERTY_NAME_BUFFER_LEN 0x40
#define DIRENTRY_NAME_MAX_LEN 0x20
#define DIRENTRY_NAME_BUFFER_LEN 0x40
#define PROPSET_BLOCK_SIZE 0x00000080
#define RAW_DIRENTRY_SIZE 0x00000080
/*
* Property type of relation
* Type of child entry link
*/
#define PROPERTY_RELATION_PREVIOUS 0
#define PROPERTY_RELATION_NEXT 1
#define PROPERTY_RELATION_DIR 2
#define DIRENTRY_RELATION_PREVIOUS 0
#define DIRENTRY_RELATION_NEXT 1
#define DIRENTRY_RELATION_DIR 2
/*
* Property type constants
* type constant used in files for the root storage
*/
#define PROPTYPE_STORAGE 0x01
#define PROPTYPE_STREAM 0x02
#define PROPTYPE_ROOT 0x05
#define STGTY_ROOT 0x05
/*
* These defines assume a hardcoded blocksize. The code will assert
@ -116,30 +114,34 @@ static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
* module.
*/
typedef struct StorageBaseImpl StorageBaseImpl;
typedef struct StorageBaseImplVtbl StorageBaseImplVtbl;
typedef struct StorageImpl StorageImpl;
typedef struct BlockChainStream BlockChainStream;
typedef struct SmallBlockChainStream SmallBlockChainStream;
typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
typedef struct StgProperty StgProperty;
typedef struct DirEntry DirEntry;
typedef struct StgStreamImpl StgStreamImpl;
/*
* This utility structure is used to read/write the information in a storage
* property.
* A reference to a directory entry in the file or a transacted cache.
*/
struct StgProperty
typedef ULONG DirRef;
/*
* This utility structure is used to read/write the information in a directory
* entry.
*/
struct DirEntry
{
WCHAR name[PROPERTY_NAME_MAX_LEN];
WCHAR name[DIRENTRY_NAME_MAX_LEN];
WORD sizeOfNameString;
BYTE propertyType;
ULONG previousProperty;
ULONG nextProperty;
ULONG dirProperty;
GUID propertyUniqueID;
ULONG timeStampS1;
ULONG timeStampD1;
ULONG timeStampS2;
ULONG timeStampD2;
BYTE stgType;
DirRef leftChild;
DirRef rightChild;
DirRef dirRootEntry;
GUID clsid;
FILETIME ctime;
FILETIME mtime;
ULONG startingBlock;
ULARGE_INTEGER size;
};
@ -178,6 +180,7 @@ HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void OLECONVERT_CreateOleStream(LPSTORAGE pStorage);
HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName);
/****************************************************************************
* Storage32BaseImpl definitions.
*
@ -200,26 +203,30 @@ struct StorageBaseImpl
struct list strmHead;
/*
* Storage tracking list
*/
struct list storageHead;
/*
* Reference count of this object
*/
LONG ref;
/*
* Ancestor storage (top level)
* TRUE if this object has been invalidated
*/
StorageImpl* ancestorStorage;
int reverted;
/*
* Index of the property for the root of
* this storage
* Index of the directory entry of this storage
*/
ULONG rootPropertySetIndex;
DirRef storageDirEntry;
/*
* virtual Destructor method.
* virtual methods.
*/
void (*v_destructor)(StorageBaseImpl*);
const StorageBaseImplVtbl *baseVtbl;
/*
* flags that this storage was opened or created with
@ -230,8 +237,87 @@ struct StorageBaseImpl
* State bits appear to only be preserved while running. No in the stream
*/
DWORD stateBits;
/* If set, this overrides the root storage name returned by IStorage_Stat */
LPCWSTR filename;
BOOL create; /* Was the storage created or opened.
The behaviour of STGM_SIMPLE depends on this */
/*
* If this storage was opened in transacted mode, the object that implements
* the transacted snapshot or cache.
*/
StorageBaseImpl *transactedChild;
};
/* virtual methods for StorageBaseImpl objects */
struct StorageBaseImplVtbl {
void (*Destroy)(StorageBaseImpl*);
void (*Invalidate)(StorageBaseImpl*);
HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*);
HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*);
HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER);
};
static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
{
This->baseVtbl->Destroy(This);
}
static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This)
{
This->baseVtbl->Invalidate(This);
}
static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This,
const DirEntry *newData, DirRef *index)
{
return This->baseVtbl->CreateDirEntry(This, newData, index);
}
static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This,
DirRef index, const DirEntry *data)
{
return This->baseVtbl->WriteDirEntry(This, index, data);
}
static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This,
DirRef index, DirEntry *data)
{
return This->baseVtbl->ReadDirEntry(This, index, data);
}
static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This,
DirRef index)
{
return This->baseVtbl->DestroyDirEntry(This, index);
}
/* Read up to size bytes from this directory entry's stream at the given offset. */
static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This,
DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
{
return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead);
}
/* Write size bytes to this directory entry's stream at the given offset,
* growing the stream if necessary. */
static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This,
DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten)
{
return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten);
}
static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This,
DirRef index, ULARGE_INTEGER newsize)
{
return This->baseVtbl->StreamSetSize(This, index, newsize);
}
/****************************************************************************
* StorageBaseImpl stream list handlers
*/
@ -239,6 +325,9 @@ struct StorageBaseImpl
void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm);
void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm);
/* Number of BlockChainStream objects to cache in a StorageImpl */
#define BLOCKCHAIN_CACHE_SIZE 4
/****************************************************************************
* Storage32Impl definitions.
*
@ -255,11 +344,6 @@ struct StorageImpl
*/
HANDLE hFile; /* Physical support for the Docfile */
LPOLESTR pwcsName; /* Full path of the document file */
BOOL create; /* Was the storage created or opened.
The behaviour of STGM_SIMPLE depends on this */
/* FIXME: should this be in Storage32BaseImpl ? */
WCHAR filename[PROPERTY_NAME_BUFFER_LEN];
/*
* File header
@ -286,21 +370,39 @@ struct StorageImpl
BlockChainStream* smallBlockDepotChain;
BlockChainStream* smallBlockRootChain;
/* Cache of block chain streams objects for directory entries */
BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE];
UINT blockChainToEvict;
/*
* Pointer to the big block file abstraction
*/
BigBlockFile* bigBlockFile;
};
BOOL StorageImpl_ReadProperty(
StorageImpl* This,
ULONG index,
StgProperty* buffer);
HRESULT StorageImpl_ReadRawDirEntry(
StorageImpl *This,
ULONG index,
BYTE *buffer);
BOOL StorageImpl_WriteProperty(
void UpdateRawDirEntry(
BYTE *buffer,
const DirEntry *newData);
HRESULT StorageImpl_WriteRawDirEntry(
StorageImpl *This,
ULONG index,
const BYTE *buffer);
HRESULT StorageImpl_ReadDirEntry(
StorageImpl* This,
DirRef index,
DirEntry* buffer);
HRESULT StorageImpl_WriteDirEntry(
StorageImpl* This,
ULONG index,
const StgProperty* buffer);
DirRef index,
const DirEntry* buffer);
BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
StorageImpl* This,
@ -343,27 +445,14 @@ struct StgStreamImpl
DWORD grfMode;
/*
* Index of the property that owns (points to) this stream.
* Index of the directory entry that owns (points to) this stream.
*/
ULONG ownerProperty;
/*
* Helper variable that contains the size of the stream
*/
ULARGE_INTEGER streamSize;
DirRef dirEntry;
/*
* This is the current position of the cursor in the stream
*/
ULARGE_INTEGER currentPosition;
/*
* The information in the stream is represented by a chain of small blocks
* or a chain of large blocks. Depending on the case, one of the two
* following variables points to that information.
*/
BlockChainStream* bigBlockChain;
SmallBlockChainStream* smallBlockChain;
};
/*
@ -372,7 +461,7 @@ struct StgStreamImpl
StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage,
DWORD grfMode,
ULONG ownerProperty);
DirRef dirEntry);
/******************************************************************************
@ -409,8 +498,8 @@ void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
const ULARGE_INTEGER *value);
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination, const StgProperty* source,
int statFlags);
void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination,
const DirEntry* source, int statFlags);
/****************************************************************************
* BlockChainStream definitions.
@ -422,7 +511,7 @@ struct BlockChainStream
{
StorageImpl* parentStorage;
ULONG* headOfStreamPlaceHolder;
ULONG ownerPropertyIndex;
DirRef ownerDirEntry;
ULONG lastBlockNoInSequence;
ULONG lastBlockNoInSequenceIndex;
ULONG tailIndex;
@ -435,7 +524,7 @@ struct BlockChainStream
BlockChainStream* BlockChainStream_Construct(
StorageImpl* parentStorage,
ULONG* headOfStreamPlaceHolder,
ULONG propertyIndex);
DirRef dirEntry);
void BlockChainStream_Destroy(
BlockChainStream* This);
@ -467,7 +556,7 @@ BOOL BlockChainStream_SetSize(
struct SmallBlockChainStream
{
StorageImpl* parentStorage;
ULONG ownerPropertyIndex;
DirRef ownerDirEntry;
ULONG* headOfStreamPlaceHolder;
};
@ -477,7 +566,7 @@ struct SmallBlockChainStream
SmallBlockChainStream* SmallBlockChainStream_Construct(
StorageImpl* parentStorage,
ULONG* headOfStreamPlaceHolder,
ULONG propertyIndex);
DirRef dirEntry);
void SmallBlockChainStream_Destroy(
SmallBlockChainStream* This);

View file

@ -406,13 +406,15 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea
rc = (m->extrefs -= refs);
if (tableweak)
rc += --m->weakrefs;
--m->weakrefs;
if (!last_unlock_releases)
rc += m->weakrefs;
LeaveCriticalSection(&m->lock);
TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
if (rc == 0 && last_unlock_releases)
if (rc == 0)
stub_manager_int_release(m);
return rc;
@ -551,7 +553,7 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const
else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
refs = 1;
stub_manager_ext_release(m, refs, tableweak, TRUE);
stub_manager_ext_release(m, refs, tableweak, FALSE);
}
/* is an ifstub table marshaled? */

View file

@ -170,11 +170,9 @@ unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *
pBuffer += sizeof(UINT);
*(UINT *)pBuffer = len;
pBuffer += sizeof(UINT);
TRACE("marshaling format name %s\n", debugstr_wn(format, len-1));
lstrcpynW((LPWSTR)pBuffer, format, len);
TRACE("marshaling format name %s\n", debugstr_w(format));
memcpy(pBuffer, format, len * sizeof(WCHAR));
pBuffer += len * sizeof(WCHAR);
*(WCHAR *)pBuffer = '\0';
pBuffer += sizeof(WCHAR);
}
else
{
@ -238,11 +236,11 @@ unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char
if (*(UINT *)pBuffer != len)
RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
pBuffer += sizeof(UINT);
if (((WCHAR *)pBuffer)[len] != '\0')
if (((WCHAR *)pBuffer)[len - 1] != '\0')
RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR)pBuffer));
cf = RegisterClipboardFormatW((LPCWSTR)pBuffer);
pBuffer += (len + 1) * sizeof(WCHAR);
pBuffer += len * sizeof(WCHAR);
if (!cf)
RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
*pCF = cf;