- 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); IStream_Release(clipbrd->marshal_data);
if (clipbrd->src_data) IDataObject_Release(clipbrd->src_data);
HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
HeapFree(GetProcessHeap(), 0, clipbrd); HeapFree(GetProcessHeap(), 0, clipbrd);
theOleClipboard = NULL; 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); td_offs_to_ptr(clipbrd->cached_enum, (DWORD_PTR)clipbrd->cached_enum->entries[idx].fmtetc.ptd);
GlobalUnlock(priv_data_handle); 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; return S_OK;
} }
@ -1757,7 +1763,11 @@ static HRESULT expose_marshalled_dataobject(ole_clipbrd *clipbrd, IDataObject *d
if(!h) return E_OUTOFMEMORY; 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; 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 (keytype == REG_EXPAND_SZ) {
if (dstlen <= ExpandEnvironmentStringsW(src, dst, dstlen)) ret = ERROR_MORE_DATA; if (dstlen <= ExpandEnvironmentStringsW(src, dst, dstlen)) ret = ERROR_MORE_DATA;
} else { } 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); 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','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','2','X','%','0','2','X',
'%','0','2','X','%','0','2','X','}',0 }; '%','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, sprintfW( str, formatW, id->Data1, id->Data2, id->Data3,
id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
@ -2052,6 +2062,7 @@ HRESULT WINAPI CoRegisterClassObject(
DWORD flags, DWORD flags,
LPDWORD lpdwRegister) LPDWORD lpdwRegister)
{ {
static LONG next_cookie;
RegisteredClass* newClass; RegisteredClass* newClass;
LPUNKNOWN foundObject; LPUNKNOWN foundObject;
HRESULT hr; HRESULT hr;
@ -2105,11 +2116,8 @@ HRESULT WINAPI CoRegisterClassObject(
newClass->pMarshaledData = NULL; newClass->pMarshaledData = NULL;
newClass->RpcRegistration = NULL; newClass->RpcRegistration = NULL;
/* if (!(newClass->dwCookie = InterlockedIncrement( &next_cookie )))
* Use the address of the chain node as the cookie since we are sure it's newClass->dwCookie = InterlockedIncrement( &next_cookie );
* unique. FIXME: not on 64-bit platforms.
*/
newClass->dwCookie = (DWORD)newClass;
/* /*
* Since we're making a copy of the object pointer, we have to increase its * 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); FIXME("Failed to create stream on hglobal, %x\n", hr);
return hr; return hr;
} }
hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IClassFactory, hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IUnknown,
newClass->classObject, MSHCTX_LOCAL, NULL, newClass->classObject, MSHCTX_LOCAL, NULL,
MSHLFLAGS_TABLESTRONG); MSHLFLAGS_TABLESTRONG);
if (hr) { if (hr) {
@ -2380,7 +2388,7 @@ HRESULT WINAPI CoGetClassObject(
if (CLSCTX_REMOTE_SERVER & dwClsContext) if (CLSCTX_REMOTE_SERVER & dwClsContext)
{ {
FIXME ("CLSCTX_REMOTE_SERVER not supported\n"); FIXME ("CLSCTX_REMOTE_SERVER not supported\n");
hres = E_NOINTERFACE; hres = REGDB_E_CLASSNOTREG;
} }
if (FAILED(hres)) if (FAILED(hres))
@ -4106,6 +4114,33 @@ HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
return S_OK; 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.@) * 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_DllRegisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLE32_DllUnregisterServer(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 */ /* Exported non-interface Data Advise Holder functions */
HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate); HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate);
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface); void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface);

View file

@ -670,7 +670,7 @@ CompositeMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc,
else{ else{
if (pbc==NULL) if (pbc==NULL)
return E_POINTER; return E_INVALIDARG;
/* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */ /* 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 */ /* 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) LIST_FOR_EACH_ENTRY_SAFE(cache_entry, next_cache_entry, &ptrToDestroy->cache_list, DataCacheEntry, entry)
DataCacheEntry_Destroy(cache_entry); DataCacheEntry_Destroy(cache_entry);
if (ptrToDestroy->presentationStorage != NULL)
{
IStorage_Release(ptrToDestroy->presentationStorage);
ptrToDestroy->presentationStorage = NULL;
}
/* /*
* Free the datacache pointer. * Free the datacache pointer.
*/ */

View file

@ -1960,9 +1960,21 @@ static DefaultHandler* DefaultHandler_Construct(
&IID_IUnknown, &IID_IUnknown,
(void**)&This->dataCache); (void**)&This->dataCache);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{
hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg); 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)) if(FAILED(hr))
{
ERR("Unexpected error creating data cache\n"); ERR("Unexpected error creating data cache\n");
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
This->clsid = *clsid; This->clsid = *clsid;
This->clientSite = NULL; This->clientSite = NULL;
@ -2009,6 +2021,13 @@ static DefaultHandler* DefaultHandler_Construct(
static void DefaultHandler_Destroy( static void DefaultHandler_Destroy(
DefaultHandler* This) 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 */ /* release delegates */
DefaultHandler_Stop(This); DefaultHandler_Stop(This);
release_delegates(This); release_delegates(This);
@ -2020,6 +2039,9 @@ static void DefaultHandler_Destroy(
if (This->dataCache) 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); IPersistStorage_Release(This->dataCache_PersistStg);
IUnknown_Release(This->dataCache); IUnknown_Release(This->dataCache);
This->dataCache_PersistStg = NULL; This->dataCache_PersistStg = NULL;
@ -2122,3 +2144,77 @@ HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW, return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
NULL, riid, ppvObj); 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) if (!ref)
{ {
TRACE("-- destroying IErrorInfo(%p)\n",This); TRACE("-- destroying IErrorInfo(%p)\n",This);
ERRORINFO_SysFreeString(This->bstrSource);
ERRORINFO_SysFreeString(This->bstrDescription);
ERRORINFO_SysFreeString(This->bstrHelpFile);
HeapFree(GetProcessHeap(),0,This); HeapFree(GetProcessHeap(),0,This);
return 0; return 0;
} }

View file

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

View file

@ -365,11 +365,18 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
{ {
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface; 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, TRACE("(%p, %x%08x, %d, %p)\n", iface, dlibMove.u.HighPart,
dlibMove.u.LowPart, dwOrigin, plibNewPosition); 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" * The file pointer is moved depending on the given "function"
* parameter. * parameter.
@ -381,13 +388,13 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
newPosition.u.LowPart = 0; newPosition.u.LowPart = 0;
break; break;
case STREAM_SEEK_CUR: case STREAM_SEEK_CUR:
newPosition = This->currentPosition;
break; break;
case STREAM_SEEK_END: case STREAM_SEEK_END:
newPosition = This->streamSize; newPosition = This->streamSize;
break; break;
default: 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 * 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. * make the file larger. This is how it is documented.
*/ */
if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart) return STG_E_INVALIDFUNCTION; newPosition.u.HighPart = 0;
newPosition.u.LowPart += dlibMove.QuadPart;
newPosition.QuadPart += dlibMove.QuadPart;
end:
if (plibNewPosition) *plibNewPosition = newPosition; if (plibNewPosition) *plibNewPosition = newPosition;
This->currentPosition = 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)); 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); 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 * 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; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -192,7 +105,7 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
return E_NOINTERFACE; return E_NOINTERFACE;
/* Query Interface always increases the reference count by one when it is successful */ /* Query Interface always increases the reference count by one when it is successful */
ItemMonikerImpl_AddRef(iface); IMoniker_AddRef(iface);
return S_OK; return S_OK;
} }
@ -200,7 +113,7 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
/****************************************************************************** /******************************************************************************
* ItemMoniker_AddRef * ItemMoniker_AddRef
******************************************************************************/ ******************************************************************************/
ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface) static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -212,7 +125,7 @@ ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface)
/****************************************************************************** /******************************************************************************
* ItemMoniker_Release * ItemMoniker_Release
******************************************************************************/ ******************************************************************************/
ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface) static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
ULONG ref; ULONG ref;
@ -230,7 +143,7 @@ ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
/****************************************************************************** /******************************************************************************
* ItemMoniker_GetClassID * 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); TRACE("(%p,%p)\n",iface,pClassID);
@ -245,7 +158,7 @@ HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
/****************************************************************************** /******************************************************************************
* ItemMoniker_IsDirty * 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 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
method in the OLE-provided moniker interfaces always return S_FALSE because method in the OLE-provided moniker interfaces always return S_FALSE because
@ -259,7 +172,7 @@ HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface)
/****************************************************************************** /******************************************************************************
* ItemMoniker_Load * ItemMoniker_Load
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm) static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -328,9 +241,9 @@ HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
/****************************************************************************** /******************************************************************************
* ItemMoniker_Save * ItemMoniker_Save
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
IStream* pStm,/* pointer to the stream where the object is to be saved */ IStream* pStm,/* pointer to the stream where the object is to be saved */
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */ BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
HRESULT res; HRESULT res;
@ -364,8 +277,8 @@ HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_GetSizeMax * ItemMoniker_GetSizeMax
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */ ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1; DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1;
@ -388,67 +301,14 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
return S_OK; 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 * ItemMoniker_BindToObject
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
IBindCtx* pbc, IBindCtx* pbc,
IMoniker* pmkToLeft, IMoniker* pmkToLeft,
REFIID riid, REFIID riid,
VOID** ppvResult) VOID** ppvResult)
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -481,11 +341,11 @@ HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_BindToStorage * ItemMoniker_BindToStorage
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
IBindCtx* pbc, IBindCtx* pbc,
IMoniker* pmkToLeft, IMoniker* pmkToLeft,
REFIID riid, REFIID riid,
VOID** ppvResult) VOID** ppvResult)
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -514,11 +374,11 @@ HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_Reduce * ItemMoniker_Reduce
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
IBindCtx* pbc, IBindCtx* pbc,
DWORD dwReduceHowFar, DWORD dwReduceHowFar,
IMoniker** ppmkToLeft, IMoniker** ppmkToLeft,
IMoniker** ppmkReduced) IMoniker** ppmkReduced)
{ {
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,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 * ItemMoniker_ComposeWith
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
IMoniker* pmkRight, IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric, BOOL fOnlyIfNotGeneric,
IMoniker** ppmkComposite) IMoniker** ppmkComposite)
{ {
HRESULT res=S_OK; HRESULT res=S_OK;
DWORD mkSys,mkSys2; DWORD mkSys,mkSys2;
@ -609,7 +469,7 @@ HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_Enum * 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); TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
@ -624,7 +484,7 @@ HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker*
/****************************************************************************** /******************************************************************************
* ItemMoniker_IsEqual * ItemMoniker_IsEqual
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{ {
CLSID clsid; CLSID clsid;
@ -657,7 +517,7 @@ HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker
/****************************************************************************** /******************************************************************************
* ItemMoniker_Hash * ItemMoniker_Hash
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
DWORD h = 0; DWORD h = 0;
@ -682,10 +542,10 @@ HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
/****************************************************************************** /******************************************************************************
* ItemMoniker_IsRunning * ItemMoniker_IsRunning
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
IBindCtx* pbc, IBindCtx* pbc,
IMoniker* pmkToLeft, IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning) IMoniker* pmkNewlyRunning)
{ {
IRunningObjectTable* rot; IRunningObjectTable* rot;
HRESULT res; HRESULT res;
@ -701,7 +561,7 @@ HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
return S_OK; return S_OK;
else { else {
if (pbc==NULL) if (pbc==NULL)
return E_POINTER; return E_INVALIDARG;
res=IBindCtx_GetRunningObjectTable(pbc,&rot); res=IBindCtx_GetRunningObjectTable(pbc,&rot);
@ -734,10 +594,10 @@ HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_GetTimeOfLastChange * ItemMoniker_GetTimeOfLastChange
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
IBindCtx* pbc, IBindCtx* pbc,
IMoniker* pmkToLeft, IMoniker* pmkToLeft,
FILETIME* pItemTime) FILETIME* pItemTime)
{ {
IRunningObjectTable* rot; IRunningObjectTable* rot;
HRESULT res; HRESULT res;
@ -775,7 +635,7 @@ HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_Inverse * 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); TRACE("(%p,%p)\n",iface,ppmk);
@ -788,7 +648,7 @@ HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
/****************************************************************************** /******************************************************************************
* ItemMoniker_CommonPrefixWith * 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; DWORD mkSys;
@ -815,7 +675,7 @@ HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOth
/****************************************************************************** /******************************************************************************
* ItemMoniker_RelativePathTo * 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); TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
@ -830,10 +690,10 @@ HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther,
/****************************************************************************** /******************************************************************************
* ItemMoniker_GetDisplayName * ItemMoniker_GetDisplayName
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
IBindCtx* pbc, IBindCtx* pbc,
IMoniker* pmkToLeft, IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName) LPOLESTR *ppszDisplayName)
{ {
ItemMonikerImpl *This = (ItemMonikerImpl *)iface; ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
@ -862,12 +722,12 @@ HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_ParseDisplayName * ItemMoniker_ParseDisplayName
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface, static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
IBindCtx* pbc, IBindCtx* pbc,
IMoniker* pmkToLeft, IMoniker* pmkToLeft,
LPOLESTR pszDisplayName, LPOLESTR pszDisplayName,
ULONG* pchEaten, ULONG* pchEaten,
IMoniker** ppmkOut) IMoniker** ppmkOut)
{ {
IOleItemContainer* poic=0; IOleItemContainer* poic=0;
IParseDisplayName* ppdn=0; IParseDisplayName* ppdn=0;
@ -906,7 +766,7 @@ HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
/****************************************************************************** /******************************************************************************
* ItemMoniker_IsSystemMoniker * 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); TRACE("(%p,%p)\n",iface,pwdMksys);
@ -921,7 +781,7 @@ HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
/******************************************************************************* /*******************************************************************************
* ItemMonikerIROTData_QueryInterface * 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); IMoniker *This = impl_from_IROTData(iface);
@ -934,7 +794,7 @@ HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid
/*********************************************************************** /***********************************************************************
* ItemMonikerIROTData_AddRef * ItemMonikerIROTData_AddRef
*/ */
ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface) static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
{ {
IMoniker *This = impl_from_IROTData(iface); IMoniker *This = impl_from_IROTData(iface);
@ -946,7 +806,7 @@ ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface)
/*********************************************************************** /***********************************************************************
* ItemMonikerIROTData_Release * ItemMonikerIROTData_Release
*/ */
ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface) static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
{ {
IMoniker *This = impl_from_IROTData(iface); IMoniker *This = impl_from_IROTData(iface);
@ -958,10 +818,10 @@ ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
/****************************************************************************** /******************************************************************************
* ItemMonikerIROTData_GetComparisonData * ItemMonikerIROTData_GetComparisonData
******************************************************************************/ ******************************************************************************/
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface, static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData, BYTE* pbData,
ULONG cbMax, ULONG cbMax,
ULONG* pcbData) ULONG* pcbData)
{ {
IMoniker *This = impl_from_IROTData(iface); IMoniker *This = impl_from_IROTData(iface);
ItemMonikerImpl *This1 = (ItemMonikerImpl *)This; ItemMonikerImpl *This1 = (ItemMonikerImpl *)This;
@ -989,6 +849,99 @@ HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
return S_OK; 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.@] * CreateItemMoniker [OLE32.@]
******************************************************************************/ ******************************************************************************/

View file

@ -553,9 +553,9 @@ static HRESULT WINAPI ProxyCliSec_SetBlanket(IClientSecurity *iface,
void *pAuthInfo, void *pAuthInfo,
DWORD Capabilities) DWORD Capabilities)
{ {
FIXME("(%p, %d, %d, %s, %d, %d, %p, 0x%x): stub\n", pProxy, AuthnSvc, FIXME("(%p, %d, %d, %s, %d, %d, %p, 0x%x): stub\n", pProxy, AuthnSvc, AuthzSvc,
AuthzSvc, debugstr_w(pServerPrincName), AuthnLevel, ImpLevel, pServerPrincName == COLE_DEFAULT_PRINCIPAL ? "<default principal>" : debugstr_w(pServerPrincName),
pAuthInfo, Capabilities); AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
return E_NOTIMPL; 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? */ /* unref the ifstub. FIXME: only do this on success? */
if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid)) 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); stub_manager_int_release(stubmgr);
return hres; return hres;

View file

@ -124,30 +124,18 @@ static BOOL start_rpcss(void)
{ {
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFOW si; STARTUPINFOW si;
static WCHAR cmd[6]; WCHAR cmd[MAX_PATH];
static const WCHAR rpcss[] = {'r','p','c','s','s',0}; static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0};
BOOL rslt; BOOL rslt;
TRACE("\n"); TRACE("\n");
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFOA)); ZeroMemory(&si, sizeof(STARTUPINFOA));
si.cb = sizeof(STARTUPINFOA); si.cb = sizeof(STARTUPINFOA);
GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) );
strcatW( cmd, rpcss );
memcpy(cmd, rpcss, sizeof(rpcss)); rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
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 */
);
if (rslt) if (rslt)
{ {

View file

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

View file

@ -70,7 +70,7 @@
@ stdcall CoRevokeClassObject(long) @ stdcall CoRevokeClassObject(long)
@ stdcall CoRevokeInitializeSpy(double) @ stdcall CoRevokeInitializeSpy(double)
@ stdcall CoRevokeMallocSpy() @ 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 CoSetState(ptr)
@ stdcall CoSuspendClassObjects() @ stdcall CoSuspendClassObjects()
@ stdcall CoSwitchCallContext(ptr ptr) @ stdcall CoSwitchCallContext(ptr ptr)

View file

@ -23,7 +23,10 @@
#include "winuser.h" #include "winuser.h"
#include "winnls.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, * Everything that does not depend on language,
@ -44,12 +47,3 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/* @makedep: drag_link.cur */ /* @makedep: drag_link.cur */
3 CURSOR 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 WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
{ {
HRESULT hr;
*ppv = NULL; *ppv = NULL;
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&( if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IClassFactory) ||
@ -70,5 +72,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr)) if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr))
return ComCatCF_Create(iid, ppv); 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 = { static GUID const CLSID_PackagerMoniker = {
0x00000308, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; 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_Metafile;
extern GUID const CLSID_Picture_Dib; extern GUID const CLSID_Picture_Dib;
@ -510,42 +507,35 @@ static struct regsvr_coclass const coclass_list[] = {
* interface list * interface list
*/ */
#define INTERFACE_ENTRY(interface, base, clsid32) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), NULL, clsid32 } #define INTERFACE_ENTRY(interface, base) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), NULL, NULL }
#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)
static const struct regsvr_interface interface_list[] = { static const struct regsvr_interface interface_list[] = {
LCL_INTERFACE_ENTRY(IUnknown), INTERFACE_ENTRY( IUnknown, NULL ),
LCL_INTERFACE_ENTRY(IMalloc), INTERFACE_ENTRY( IMalloc, NULL ),
LCL_INTERFACE_ENTRY(IMarshal), INTERFACE_ENTRY( IMarshal, NULL ),
BAS_INTERFACE_ENTRY(IMoniker, IPersistStream), INTERFACE_ENTRY( IMoniker, &IID_IPersistStream ),
LCL_INTERFACE_ENTRY(IMessageFilter), INTERFACE_ENTRY( IMessageFilter, NULL ),
LCL_INTERFACE_ENTRY(IStdMarshalInfo), INTERFACE_ENTRY( IStdMarshalInfo, NULL ),
LCL_INTERFACE_ENTRY(IExternalConnection), INTERFACE_ENTRY( IExternalConnection, NULL ),
LCL_INTERFACE_ENTRY(IMallocSpy), INTERFACE_ENTRY( IMallocSpy, NULL ),
LCL_INTERFACE_ENTRY(IMultiQI), INTERFACE_ENTRY( IMultiQI, NULL ),
BAS_INTERFACE_ENTRY(IPersistStream, IPersist), INTERFACE_ENTRY( IPersistStream, &IID_IPersist ),
BAS_INTERFACE_ENTRY(IPersistStorage, IPersist), INTERFACE_ENTRY( IPersistStorage, &IID_IPersist ),
BAS_INTERFACE_ENTRY(IPersistFile, IPersist), INTERFACE_ENTRY( IPersistFile, &IID_IPersist ),
LCL_INTERFACE_ENTRY(IDataAdviseHolder), INTERFACE_ENTRY( IDataAdviseHolder, NULL ),
LCL_INTERFACE_ENTRY(IOleAdviseHolder), INTERFACE_ENTRY( IOleAdviseHolder, NULL ),
BAS_INTERFACE_ENTRY(IOleInPlaceObject, IOleWindow), INTERFACE_ENTRY( IOleInPlaceObject, &IID_IOleWindow ),
BAS_INTERFACE_ENTRY(IOleInPlaceUIWindow, IOleWindow), INTERFACE_ENTRY( IOleInPlaceUIWindow, &IID_IOleWindow ),
BAS_INTERFACE_ENTRY(IOleInPlaceActiveObject, IOleWindow), INTERFACE_ENTRY( IOleInPlaceActiveObject, &IID_IOleWindow ),
BAS_INTERFACE_ENTRY(IOleInPlaceSite, IOleWindow), INTERFACE_ENTRY( IOleInPlaceSite, &IID_IOleWindow ),
BAS_INTERFACE_ENTRY(IOleContainer, IParseDisplayName), INTERFACE_ENTRY( IOleContainer, &IID_IParseDisplayName ),
BAS_INTERFACE_ENTRY(IOleItemContainer, IOleContainer), INTERFACE_ENTRY( IOleItemContainer, &IID_IOleContainer ),
LCL_INTERFACE_ENTRY(IDropSource), INTERFACE_ENTRY( IDropSource, NULL ),
BAS_INTERFACE_ENTRY(IAdviseSink2, IAdviseSink), INTERFACE_ENTRY( IAdviseSink2, &IID_IAdviseSink ),
BAS_INTERFACE_ENTRY(IViewObject2, IViewObject), INTERFACE_ENTRY( IViewObject2, &IID_IViewObject ),
BAS_INTERFACE_ENTRY(IOleCache2, IOleCache), INTERFACE_ENTRY( IOleCache2, &IID_IOleCache ),
LCL_INTERFACE_ENTRY(IClientSecurity), INTERFACE_ENTRY( IClientSecurity, NULL ),
LCL_INTERFACE_ENTRY(IServerSecurity), INTERFACE_ENTRY( IServerSecurity, NULL ),
ACTX_INTERFACE_ENTRY(IEnumGUID),
ACTX_INTERFACE_ENTRY(IEnumCATEGORYINFO),
ACTX_INTERFACE_ENTRY(ICatRegister),
ACTX_INTERFACE_ENTRY(ICatInformation),
{ NULL } /* list terminator */ { NULL } /* list terminator */
}; };

View file

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

View file

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

View file

@ -74,21 +74,6 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This)
This->parentStorage = 0; 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. * Finally, free the memory used-up by the class.
*/ */
@ -179,73 +164,6 @@ static ULONG WINAPI StgStreamImpl_Release(
return ref; 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. * This method is part of the ISequentialStream interface.
* *
@ -264,7 +182,6 @@ static HRESULT WINAPI StgStreamImpl_Read(
StgStreamImpl* const This=(StgStreamImpl*)iface; StgStreamImpl* const This=(StgStreamImpl*)iface;
ULONG bytesReadBuffer; ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
HRESULT res; HRESULT res;
TRACE("(%p, %p, %d, %p)\n", TRACE("(%p, %p, %d, %p)\n",
@ -283,60 +200,21 @@ static HRESULT WINAPI StgStreamImpl_Read(
if (pcbRead==0) if (pcbRead==0)
pcbRead = &bytesReadBuffer; pcbRead = &bytesReadBuffer;
/* res = StorageBaseImpl_StreamReadAt(This->parentStorage,
* Using the known size of the stream, calculate the number of bytes This->dirEntry,
* to read from the block chain This->currentPosition,
*/ cb,
bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); pv,
pcbRead);
/*
* 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;
}
if (SUCCEEDED(res)) if (SUCCEEDED(res))
{ {
/* /*
* We should always be able to read the proper amount of data from the * Advance the pointer for the number of positions read.
* chain. */
*/ This->currentPosition.u.LowPart += *pcbRead;
assert(bytesToReadFromBuffer == *pcbRead);
/*
* Advance the pointer for the number of positions read.
*/
This->currentPosition.u.LowPart += *pcbRead;
} }
end:
TRACE("<-- %08x\n", res); TRACE("<-- %08x\n", res);
return res; return res;
} }
@ -359,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write(
{ {
StgStreamImpl* const This=(StgStreamImpl*)iface; StgStreamImpl* const This=(StgStreamImpl*)iface;
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0; ULONG bytesWritten = 0;
HRESULT res; HRESULT res;
@ -405,51 +282,13 @@ static HRESULT WINAPI StgStreamImpl_Write(
TRACE("<-- S_OK, written 0\n"); TRACE("<-- S_OK, written 0\n");
return S_OK; return S_OK;
} }
else
{
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
}
/* res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
* Verify if we need to grow the stream This->dirEntry,
*/ This->currentPosition,
if (newSize.u.LowPart > This->streamSize.u.LowPart) cb,
{ pv,
/* grow stream */ pcbWritten);
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;
}
/* /*
* Advance the position pointer for the number of positions written. * Advance the position pointer for the number of positions written.
@ -477,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek(
StgStreamImpl* const This=(StgStreamImpl*)iface; StgStreamImpl* const This=(StgStreamImpl*)iface;
ULARGE_INTEGER newPosition; ULARGE_INTEGER newPosition;
DirEntry currentEntry;
HRESULT hr;
TRACE("(%p, %d, %d, %p)\n", TRACE("(%p, %d, %d, %p)\n",
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition); iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
@ -515,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek(
*plibNewPosition = This->currentPosition; *plibNewPosition = This->currentPosition;
break; break;
case STREAM_SEEK_END: case STREAM_SEEK_END:
*plibNewPosition = This->streamSize; hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, &currentEntry);
if (FAILED(hr)) return hr;
*plibNewPosition = currentEntry.size;
break; break;
default: default:
WARN("invalid dwOrigin %d\n", dwOrigin); WARN("invalid dwOrigin %d\n", dwOrigin);
@ -545,8 +388,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
{ {
StgStreamImpl* const This=(StgStreamImpl*)iface; StgStreamImpl* const This=(StgStreamImpl*)iface;
StgProperty curProperty; HRESULT hr;
BOOL Success;
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart); TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
@ -574,99 +416,8 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
return STG_E_ACCESSDENIED; return STG_E_ACCESSDENIED;
} }
/* In simple mode keep the stream size above the small block limit */ hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize);
if (This->parentStorage->ancestorStorage->base.openFlags & STGM_SIMPLE) return hr;
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;
} }
/*** /***
@ -834,8 +585,8 @@ static HRESULT WINAPI StgStreamImpl_Stat(
{ {
StgStreamImpl* const This=(StgStreamImpl*)iface; StgStreamImpl* const This=(StgStreamImpl*)iface;
StgProperty curProperty; DirEntry currentEntry;
BOOL readSuccessful; HRESULT hr;
TRACE("%p %p %d\n", This, pstatstg, grfStatFlag); 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, hr = StorageBaseImpl_ReadDirEntry(This->parentStorage,
This->ownerProperty, This->dirEntry,
&curProperty); &currentEntry);
if (readSuccessful) if (SUCCEEDED(hr))
{ {
StorageImpl *root = This->parentStorage->ancestorStorage; StorageUtl_CopyDirEntryToSTATSTG(This->parentStorage,
pstatstg,
StorageUtl_CopyPropertyToSTATSTG(pstatstg, &currentEntry,
&curProperty,
grfStatFlag); grfStatFlag);
pstatstg->grfMode = This->grfMode; pstatstg->grfMode = This->grfMode;
/* In simple create mode cbSize is the current pos */ /* 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; pstatstg->cbSize = This->currentPosition;
return S_OK; return S_OK;
} }
WARN("failed to read properties\n"); WARN("failed to read entry\n");
return E_FAIL; return hr;
} }
/*** /***
@ -910,7 +660,7 @@ static HRESULT WINAPI StgStreamImpl_Clone(
if ( ppstm == 0 ) if ( ppstm == 0 )
return STG_E_INVALIDPOINTER; 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) if (!new_stream)
return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */ return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */
@ -957,12 +707,12 @@ static const IStreamVtbl StgStreamImpl_Vtbl =
* *
* Params: * Params:
* parentStorage - Pointer to the storage that contains the stream to open * 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( StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage, StorageBaseImpl* parentStorage,
DWORD grfMode, DWORD grfMode,
ULONG ownerProperty) DirRef dirEntry)
{ {
StgStreamImpl* newStream; StgStreamImpl* newStream;
@ -991,7 +741,7 @@ StgStreamImpl* StgStreamImpl_Construct(
*/ */
newStream->grfMode = grfMode; newStream->grfMode = grfMode;
newStream->ownerProperty = ownerProperty; newStream->dirEntry = dirEntry;
/* /*
* Start the stream at the beginning. * Start the stream at the beginning.
@ -999,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct(
newStream->currentPosition.u.HighPart = 0; newStream->currentPosition.u.HighPart = 0;
newStream->currentPosition.u.LowPart = 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 */ /* add us to the storage's list of active streams */
StorageBaseImpl_AddStream(parentStorage, newStream); 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_BBDEPOTSTART = 0x0000004C;
static const ULONG OFFSET_PS_NAME = 0x00000000; static const ULONG OFFSET_PS_NAME = 0x00000000;
static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040; static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040;
static const ULONG OFFSET_PS_PROPERTYTYPE = 0x00000042; static const ULONG OFFSET_PS_STGTYPE = 0x00000042;
static const ULONG OFFSET_PS_PREVIOUSPROP = 0x00000044; static const ULONG OFFSET_PS_LEFTCHILD = 0x00000044;
static const ULONG OFFSET_PS_NEXTPROP = 0x00000048; static const ULONG OFFSET_PS_RIGHTCHILD = 0x00000048;
static const ULONG OFFSET_PS_DIRPROP = 0x0000004C; static const ULONG OFFSET_PS_DIRROOT = 0x0000004C;
static const ULONG OFFSET_PS_GUID = 0x00000050; static const ULONG OFFSET_PS_GUID = 0x00000050;
static const ULONG OFFSET_PS_TSS1 = 0x00000064; static const ULONG OFFSET_PS_CTIMELOW = 0x00000064;
static const ULONG OFFSET_PS_TSD1 = 0x00000068; static const ULONG OFFSET_PS_CTIMEHIGH = 0x00000068;
static const ULONG OFFSET_PS_TSS2 = 0x0000006C; static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C;
static const ULONG OFFSET_PS_TSD2 = 0x00000070; static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070;
static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074; static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074;
static const ULONG OFFSET_PS_SIZE = 0x00000078; static const ULONG OFFSET_PS_SIZE = 0x00000078;
static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009; 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_SPECIAL = 0xFFFFFFFD;
static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE; static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE;
static const ULONG BLOCK_UNUSED = 0xFFFFFFFF; 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 DIRENTRY_NAME_MAX_LEN 0x20
#define PROPERTY_NAME_BUFFER_LEN 0x40 #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 DIRENTRY_RELATION_PREVIOUS 0
#define PROPERTY_RELATION_NEXT 1 #define DIRENTRY_RELATION_NEXT 1
#define PROPERTY_RELATION_DIR 2 #define DIRENTRY_RELATION_DIR 2
/* /*
* Property type constants * type constant used in files for the root storage
*/ */
#define PROPTYPE_STORAGE 0x01 #define STGTY_ROOT 0x05
#define PROPTYPE_STREAM 0x02
#define PROPTYPE_ROOT 0x05
/* /*
* These defines assume a hardcoded blocksize. The code will assert * These defines assume a hardcoded blocksize. The code will assert
@ -116,30 +114,34 @@ static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
* module. * module.
*/ */
typedef struct StorageBaseImpl StorageBaseImpl; typedef struct StorageBaseImpl StorageBaseImpl;
typedef struct StorageBaseImplVtbl StorageBaseImplVtbl;
typedef struct StorageImpl StorageImpl; typedef struct StorageImpl StorageImpl;
typedef struct BlockChainStream BlockChainStream; typedef struct BlockChainStream BlockChainStream;
typedef struct SmallBlockChainStream SmallBlockChainStream; typedef struct SmallBlockChainStream SmallBlockChainStream;
typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl; typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
typedef struct StgProperty StgProperty; typedef struct DirEntry DirEntry;
typedef struct StgStreamImpl StgStreamImpl; typedef struct StgStreamImpl StgStreamImpl;
/* /*
* This utility structure is used to read/write the information in a storage * A reference to a directory entry in the file or a transacted cache.
* property.
*/ */
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; WORD sizeOfNameString;
BYTE propertyType; BYTE stgType;
ULONG previousProperty; DirRef leftChild;
ULONG nextProperty; DirRef rightChild;
ULONG dirProperty; DirRef dirRootEntry;
GUID propertyUniqueID; GUID clsid;
ULONG timeStampS1; FILETIME ctime;
ULONG timeStampD1; FILETIME mtime;
ULONG timeStampS2;
ULONG timeStampD2;
ULONG startingBlock; ULONG startingBlock;
ULARGE_INTEGER size; ULARGE_INTEGER size;
}; };
@ -178,6 +180,7 @@ HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void OLECONVERT_CreateOleStream(LPSTORAGE pStorage); void OLECONVERT_CreateOleStream(LPSTORAGE pStorage);
HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName); HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName);
/**************************************************************************** /****************************************************************************
* Storage32BaseImpl definitions. * Storage32BaseImpl definitions.
* *
@ -200,26 +203,30 @@ struct StorageBaseImpl
struct list strmHead; struct list strmHead;
/*
* Storage tracking list
*/
struct list storageHead;
/* /*
* Reference count of this object * Reference count of this object
*/ */
LONG ref; 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 * Index of the directory entry of this storage
* 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 * 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 * State bits appear to only be preserved while running. No in the stream
*/ */
DWORD stateBits; 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 * StorageBaseImpl stream list handlers
*/ */
@ -239,6 +325,9 @@ struct StorageBaseImpl
void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm); void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm);
void StorageBaseImpl_RemoveStream(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. * Storage32Impl definitions.
* *
@ -255,11 +344,6 @@ struct StorageImpl
*/ */
HANDLE hFile; /* Physical support for the Docfile */ HANDLE hFile; /* Physical support for the Docfile */
LPOLESTR pwcsName; /* Full path of the document file */ 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 * File header
@ -286,21 +370,39 @@ struct StorageImpl
BlockChainStream* smallBlockDepotChain; BlockChainStream* smallBlockDepotChain;
BlockChainStream* smallBlockRootChain; 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 * Pointer to the big block file abstraction
*/ */
BigBlockFile* bigBlockFile; BigBlockFile* bigBlockFile;
}; };
BOOL StorageImpl_ReadProperty( HRESULT StorageImpl_ReadRawDirEntry(
StorageImpl* This, StorageImpl *This,
ULONG index, ULONG index,
StgProperty* buffer); 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, StorageImpl* This,
ULONG index, DirRef index,
const StgProperty* buffer); const DirEntry* buffer);
BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
StorageImpl* This, StorageImpl* This,
@ -343,27 +445,14 @@ struct StgStreamImpl
DWORD grfMode; 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; DirRef dirEntry;
/*
* Helper variable that contains the size of the stream
*/
ULARGE_INTEGER streamSize;
/* /*
* This is the current position of the cursor in the stream * This is the current position of the cursor in the stream
*/ */
ULARGE_INTEGER currentPosition; 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( StgStreamImpl* StgStreamImpl_Construct(
StorageBaseImpl* parentStorage, StorageBaseImpl* parentStorage,
DWORD grfMode, DWORD grfMode,
ULONG ownerProperty); DirRef dirEntry);
/****************************************************************************** /******************************************************************************
@ -409,8 +498,8 @@ void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
const ULARGE_INTEGER *value); const ULARGE_INTEGER *value);
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value); void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value); void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination, const StgProperty* source, void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination,
int statFlags); const DirEntry* source, int statFlags);
/**************************************************************************** /****************************************************************************
* BlockChainStream definitions. * BlockChainStream definitions.
@ -422,7 +511,7 @@ struct BlockChainStream
{ {
StorageImpl* parentStorage; StorageImpl* parentStorage;
ULONG* headOfStreamPlaceHolder; ULONG* headOfStreamPlaceHolder;
ULONG ownerPropertyIndex; DirRef ownerDirEntry;
ULONG lastBlockNoInSequence; ULONG lastBlockNoInSequence;
ULONG lastBlockNoInSequenceIndex; ULONG lastBlockNoInSequenceIndex;
ULONG tailIndex; ULONG tailIndex;
@ -435,7 +524,7 @@ struct BlockChainStream
BlockChainStream* BlockChainStream_Construct( BlockChainStream* BlockChainStream_Construct(
StorageImpl* parentStorage, StorageImpl* parentStorage,
ULONG* headOfStreamPlaceHolder, ULONG* headOfStreamPlaceHolder,
ULONG propertyIndex); DirRef dirEntry);
void BlockChainStream_Destroy( void BlockChainStream_Destroy(
BlockChainStream* This); BlockChainStream* This);
@ -467,7 +556,7 @@ BOOL BlockChainStream_SetSize(
struct SmallBlockChainStream struct SmallBlockChainStream
{ {
StorageImpl* parentStorage; StorageImpl* parentStorage;
ULONG ownerPropertyIndex; DirRef ownerDirEntry;
ULONG* headOfStreamPlaceHolder; ULONG* headOfStreamPlaceHolder;
}; };
@ -477,7 +566,7 @@ struct SmallBlockChainStream
SmallBlockChainStream* SmallBlockChainStream_Construct( SmallBlockChainStream* SmallBlockChainStream_Construct(
StorageImpl* parentStorage, StorageImpl* parentStorage,
ULONG* headOfStreamPlaceHolder, ULONG* headOfStreamPlaceHolder,
ULONG propertyIndex); DirRef dirEntry);
void SmallBlockChainStream_Destroy( void SmallBlockChainStream_Destroy(
SmallBlockChainStream* This); 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); rc = (m->extrefs -= refs);
if (tableweak) if (tableweak)
rc += --m->weakrefs; --m->weakrefs;
if (!last_unlock_releases)
rc += m->weakrefs;
LeaveCriticalSection(&m->lock); LeaveCriticalSection(&m->lock);
TRACE("removed %u refs from %p (oid %s), rc is now %u\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 && last_unlock_releases) if (rc == 0)
stub_manager_int_release(m); stub_manager_int_release(m);
return rc; 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) else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
refs = 1; refs = 1;
stub_manager_ext_release(m, refs, tableweak, TRUE); stub_manager_ext_release(m, refs, tableweak, FALSE);
} }
/* is an ifstub table marshaled? */ /* is an ifstub table marshaled? */

View file

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