Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
Access mask used originally is invalid to begin with.
dlls/ole32/filemoniker.c | 46 +++++++++++++++---------------- dlls/ole32/tests/moniker.c | 55 +++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 26 deletions(-)
diff --git a/dlls/ole32/filemoniker.c b/dlls/ole32/filemoniker.c index d8c401c8978..d7c2a5a5ea7 100644 --- a/dlls/ole32/filemoniker.c +++ b/dlls/ole32/filemoniker.c @@ -583,41 +583,37 @@ FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft */ static HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, - REFIID riid, VOID** ppvObject) + REFIID riid, void **object) { - LPOLESTR filePath=0; - IStorage *pstg=0; - HRESULT res; - - TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject); - - if (pmkToLeft==NULL){ + FileMonikerImpl *moniker = impl_from_IMoniker(iface); + BIND_OPTS bind_opts; + HRESULT hr;
- if (IsEqualIID(&IID_IStorage, riid)){ + TRACE("(%p,%p,%p,%s,%p)\n", iface, pbc, pmkToLeft, debugstr_guid(riid), object);
- /* get the file name */ - IMoniker_GetDisplayName(iface,pbc,pmkToLeft,&filePath); - - res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg); + if (!pbc) + return E_INVALIDARG;
- if (SUCCEEDED(res)) - *ppvObject=pstg; + bind_opts.cbStruct = sizeof(bind_opts); + hr = IBindCtx_GetBindOptions(pbc, &bind_opts); + if (FAILED(hr)) + return hr;
- CoTaskMemFree(filePath); + if (!pmkToLeft) + { + if (IsEqualIID(&IID_IStorage, riid)) + { + return StgOpenStorage(moniker->filePathName, NULL, bind_opts.grfMode, NULL, 0, (IStorage **)object); } + else if ((IsEqualIID(&IID_IStream, riid)) || (IsEqualIID(&IID_ILockBytes, riid))) + return E_FAIL; else - if ( (IsEqualIID(&IID_IStream, riid)) || (IsEqualIID(&IID_ILockBytes, riid)) ) - return E_FAIL; - else - return E_NOINTERFACE; + return E_NOINTERFACE; } - else {
- FIXME("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject); + FIXME("(%p,%p,%p,%s,%p)\n", iface, pbc, pmkToLeft, debugstr_guid(riid), object);
- return E_NOTIMPL; - } - return res; + return E_NOTIMPL; }
/****************************************************************************** diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 6be75f75c28..8d9c0678436 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -1980,7 +1980,13 @@ static void test_file_monikers(void) */ {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0}, }; - + WCHAR filename[MAX_PATH], path[MAX_PATH]; + BIND_OPTS bind_opts; + IMoniker *moniker; + IStorage *storage; + IBindCtx *bindctx; + STATSTG statstg; + HRESULT hr; int i;
trace("ACP is %u\n", GetACP()); @@ -2004,6 +2010,53 @@ static void test_file_monikers(void) test_file_moniker(wszFile[i]); } } + + /* BindToStorage() */ + GetTempPathW(MAX_PATH, path); + GetTempFileNameW(path, L"stg", 1, filename); + + hr = StgCreateStorageEx(filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, STGFMT_STORAGE, + 0, NULL, NULL, &IID_IStorage, (void **)&storage); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IStorage_Release(storage); + + hr = CreateFileMoniker(filename, &moniker); + ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr); + + hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IStorage, (void **)&storage); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = CreateBindCtx(0, &bindctx); + ok(hr == S_OK, "Failed to create bind context, hr %#x.\n", hr); + + hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IStorage, (void **)&storage); + ok(hr == STG_E_INVALIDFLAG, "Unexpected hr %#x.\n", hr); + + bind_opts.cbStruct = sizeof(bind_opts); + bind_opts.grfMode = STGM_READWRITE | STGM_SHARE_DENY_WRITE; + hr = IBindCtx_SetBindOptions(bindctx, &bind_opts); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IStorage, (void **)&storage); + ok(hr == STG_E_INVALIDFLAG, "Unexpected hr %#x.\n", hr); + + bind_opts.grfMode = STGM_READ | STGM_SHARE_DENY_WRITE; + hr = IBindCtx_SetBindOptions(bindctx, &bind_opts); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IStorage, (void **)&storage); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + memset(&statstg, 0, sizeof(statstg)); + hr = IStorage_Stat(storage, &statstg, STATFLAG_NONAME); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(statstg.grfMode == (STGM_READ | STGM_SHARE_DENY_WRITE), "Unexpected mode %#x.\n", statstg.grfMode); + + IStorage_Release(storage); + IBindCtx_Release(bindctx); + IMoniker_Release(moniker); + + DeleteFileW(filename); }
static void test_item_moniker(void)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ole32/filemoniker.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-)
diff --git a/dlls/ole32/filemoniker.c b/dlls/ole32/filemoniker.c index d7c2a5a5ea7..d3940a9365f 100644 --- a/dlls/ole32/filemoniker.c +++ b/dlls/ole32/filemoniker.c @@ -59,7 +59,6 @@ static inline FileMonikerImpl *impl_from_IROTData(IROTData *iface)
/* Local function used by filemoniker implementation */ static HRESULT FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName); -static HRESULT FileMonikerImpl_Destroy(FileMonikerImpl* iface);
/******************************************************************************* * FileMoniker_QueryInterface @@ -116,21 +115,19 @@ FileMonikerImpl_AddRef(IMoniker* iface) return InterlockedIncrement(&This->ref); }
-/****************************************************************************** - * FileMoniker_Release - */ -static ULONG WINAPI -FileMonikerImpl_Release(IMoniker* iface) +static ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface) { - FileMonikerImpl *This = impl_from_IMoniker(iface); - ULONG ref; - - TRACE("(%p)\n",iface); + FileMonikerImpl *moniker = impl_from_IMoniker(iface); + ULONG ref = InterlockedDecrement(&moniker->ref);
- ref = InterlockedDecrement(&This->ref); + TRACE("(%p, refcount %d)\n", iface, ref);
- /* destroy the object if there are no more references to it */ - if (ref == 0) FileMonikerImpl_Destroy(This); + if (!ref) + { + if (moniker->pMarshal) IUnknown_Release(moniker->pMarshal); + HeapFree(GetProcessHeap(), 0, moniker->filePathName); + HeapFree(GetProcessHeap(), 0, moniker); + }
return ref; } @@ -452,20 +449,6 @@ FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize) return S_OK; }
-/****************************************************************************** - * FileMoniker_Destroy (local function) - *******************************************************************************/ -HRESULT FileMonikerImpl_Destroy(FileMonikerImpl* This) -{ - TRACE("(%p)\n",This); - - if (This->pMarshal) IUnknown_Release(This->pMarshal); - HeapFree(GetProcessHeap(),0,This->filePathName); - HeapFree(GetProcessHeap(),0,This); - - return S_OK; -} - /****************************************************************************** * FileMoniker_BindToObject */
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
Implementation should not depend on what public methods return, when testing for same moniker class. In continuation of cleanup that was started in 2019.
dlls/ole32/filemoniker.c | 45 ++++++++++++++------------------------ dlls/ole32/tests/moniker.c | 18 ++++++++++++++- 2 files changed, 34 insertions(+), 29 deletions(-)
diff --git a/dlls/ole32/filemoniker.c b/dlls/ole32/filemoniker.c index d3940a9365f..f52881108c7 100644 --- a/dlls/ole32/filemoniker.c +++ b/dlls/ole32/filemoniker.c @@ -57,6 +57,15 @@ static inline FileMonikerImpl *impl_from_IROTData(IROTData *iface) return CONTAINING_RECORD(iface, FileMonikerImpl, IROTData_iface); }
+static const IMonikerVtbl VT_FileMonikerImpl; + +static FileMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface) +{ + if (iface->lpVtbl != &VT_FileMonikerImpl) + return NULL; + return CONTAINING_RECORD(iface, FileMonikerImpl, IMoniker_iface); +} + /* Local function used by filemoniker implementation */ static HRESULT FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
@@ -735,40 +744,20 @@ FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker return S_OK; }
-/****************************************************************************** - * FileMoniker_IsEqual - */ -static HRESULT WINAPI -FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +static HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker *iface, IMoniker *other) { - FileMonikerImpl *This = impl_from_IMoniker(iface); - CLSID clsid; - LPOLESTR filePath; - IBindCtx* bind; - HRESULT res; - - TRACE("(%p,%p)\n",iface,pmkOtherMoniker); + FileMonikerImpl *moniker = impl_from_IMoniker(iface), *other_moniker;
- if (pmkOtherMoniker==NULL) - return S_FALSE; + TRACE("%p, %p.\n", iface, other);
- IMoniker_GetClassID(pmkOtherMoniker,&clsid); + if (!other) + return E_INVALIDARG;
- if (!IsEqualCLSID(&clsid,&CLSID_FileMoniker)) + other_moniker = unsafe_impl_from_IMoniker(other); + if (!other_moniker) return S_FALSE;
- res = CreateBindCtx(0,&bind); - if (FAILED(res)) return res; - - res = S_FALSE; - if (SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath))) { - if (!lstrcmpiW(filePath, This->filePathName)) - res = S_OK; - CoTaskMemFree(filePath); - } - - IBindCtx_Release(bind); - return res; + return !wcsicmp(moniker->filePathName, other_moniker->filePathName) ? S_OK : S_FALSE; }
/****************************************************************************** diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index 8d9c0678436..d8d52295ff2 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -1981,8 +1981,8 @@ static void test_file_monikers(void) {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0}, }; WCHAR filename[MAX_PATH], path[MAX_PATH]; + IMoniker *moniker, *moniker2; BIND_OPTS bind_opts; - IMoniker *moniker; IStorage *storage; IBindCtx *bindctx; STATSTG statstg; @@ -2057,6 +2057,22 @@ static void test_file_monikers(void) IMoniker_Release(moniker);
DeleteFileW(filename); + + /* IsEqual() */ + hr = CreateFileMoniker(L"test.bmp", &moniker); + ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr); + + hr = CreateFileMoniker(L"TEST.bmp", &moniker2); + ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr); + + hr = IMoniker_IsEqual(moniker, moniker2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_IsEqual(moniker, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + IMoniker_Release(moniker2); + IMoniker_Release(moniker); }
static void test_item_moniker(void)