From: Jacek Caban Subject: [PATCH 1/2] mscoree: Added CreateConfigStream implementation. Message-Id: Date: Tue, 26 Sep 2017 18:09:52 +0200 Fixes regression from bug 43776. Signed-off-by: Jacek Caban --- dlls/mscoree/config.c | 187 +++++++++++++++++++++++++++++++++++++++++++ dlls/mscoree/mscoree_main.c | 6 -- dlls/mscoree/tests/mscoree.c | 27 ++++--- 3 files changed, 203 insertions(+), 17 deletions(-) diff --git a/dlls/mscoree/config.c b/dlls/mscoree/config.c index a52a521794..af2ccf243f 100644 --- a/dlls/mscoree/config.c +++ b/dlls/mscoree/config.c @@ -29,6 +29,7 @@ #include "msxml2.h" #include "mscoree.h" #include "corhdr.h" +#include "corerror.h" #include "metahost.h" #include "cordebug.h" #include "wine/list.h" @@ -60,6 +61,192 @@ typedef struct ConfigFileHandler parsed_config_file *result; } ConfigFileHandler; +typedef struct +{ + IStream IStream_iface; + LONG ref; + HANDLE file; +} ConfigStream; + +static inline ConfigStream *impl_from_IStream(IStream *iface) +{ + return CONTAINING_RECORD(iface, ConfigStream, IStream_iface); +} + +static HRESULT WINAPI ConfigStream_QueryInterface(IStream *iface, REFIID riid, void **ppv) +{ + ConfigStream *This = impl_from_IStream(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IStream)) + *ppv = &This->IStream_iface; + else + { + WARN("Not supported iface %s\n", debugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI ConfigStream_AddRef(IStream *iface) +{ + ConfigStream *This = impl_from_IStream(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%u\n", This, ref); + + return ref; +} + +static ULONG WINAPI ConfigStream_Release(IStream *iface) +{ + ConfigStream *This = impl_from_IStream(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%u\n",This, ref); + + if (!ref) + { + CloseHandle(This->file); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI ConfigStream_Read(IStream *iface, void *buf, ULONG size, ULONG *ret_read) +{ + ConfigStream *This = impl_from_IStream(iface); + DWORD read = 0; + + TRACE("(%p)->(%p %u %p)\n", This, buf, size, ret_read); + + if (!ReadFile(This->file, buf, size, &read, NULL)) + { + WARN("error %d reading file\n", GetLastError()); + return HRESULT_FROM_WIN32(GetLastError()); + } + + if (ret_read) *ret_read = read; + return S_OK; +} + +static HRESULT WINAPI ConfigStream_Write(IStream *iface, const void *buf, ULONG size, ULONG *written) +{ + ConfigStream *This = impl_from_IStream(iface); + TRACE("(%p)->(%p %u %p)\n", This, buf, size, written); + return E_FAIL; +} + +static HRESULT WINAPI ConfigStream_Seek(IStream *iface, LARGE_INTEGER dlibMove, + DWORD dwOrigin, ULARGE_INTEGER *pNewPos) +{ + ConfigStream *This = impl_from_IStream(iface); + TRACE("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, pNewPos); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConfigStream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize) +{ + ConfigStream *This = impl_from_IStream(iface); + TRACE("(%p)->(%d)\n", This, libNewSize.u.LowPart); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConfigStream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER size, + ULARGE_INTEGER *read, ULARGE_INTEGER *written) +{ + ConfigStream *This = impl_from_IStream(iface); + FIXME("(%p)->(%p %d %p %p)\n", This, stream, size.u.LowPart, read, written); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConfigStream_Commit(IStream *iface, DWORD flags) +{ + ConfigStream *This = impl_from_IStream(iface); + FIXME("(%p,%d)\n", This, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConfigStream_Revert(IStream *iface) +{ + ConfigStream *This = impl_from_IStream(iface); + TRACE("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConfigStream_LockUnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, DWORD dwLockType) +{ + ConfigStream *This = impl_from_IStream(iface); + TRACE("(%p,%d,%d,%d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConfigStream_Stat(IStream *iface, STATSTG *lpStat, DWORD grfStatFlag) +{ + ConfigStream *This = impl_from_IStream(iface); + FIXME("(%p,%p,%d)\n", This, lpStat, grfStatFlag); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConfigStream_Clone(IStream *iface, IStream **ppstm) +{ + ConfigStream *This = impl_from_IStream(iface); + TRACE("(%p)\n",This); + return E_NOTIMPL; +} + +static const IStreamVtbl ConfigStreamVtbl = { + ConfigStream_QueryInterface, + ConfigStream_AddRef, + ConfigStream_Release, + ConfigStream_Read, + ConfigStream_Write, + ConfigStream_Seek, + ConfigStream_SetSize, + ConfigStream_CopyTo, + ConfigStream_Commit, + ConfigStream_Revert, + ConfigStream_LockUnlockRegion, + ConfigStream_LockUnlockRegion, + ConfigStream_Stat, + ConfigStream_Clone +}; + +HRESULT WINAPI CreateConfigStream(const WCHAR *filename, IStream **stream) +{ + ConfigStream *config_stream; + HANDLE file; + + TRACE("(%s, %p)\n", debugstr_w(filename), stream); + + if (!stream) + return COR_E_NULLREFERENCE; + + file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + if (file == INVALID_HANDLE_VALUE) + return GetLastError() == ERROR_FILE_NOT_FOUND ? COR_E_FILENOTFOUND : E_FAIL; + + config_stream = HeapAlloc(GetProcessHeap(), 0, sizeof(*config_stream)); + if (!config_stream) + { + CloseHandle(file); + return E_OUTOFMEMORY; + } + + config_stream->IStream_iface.lpVtbl = &ConfigStreamVtbl; + config_stream->ref = 1; + config_stream->file = file; + + *stream = &config_stream->IStream_iface; + return S_OK; +} + static inline ConfigFileHandler *impl_from_ISAXContentHandler(ISAXContentHandler *iface) { return CONTAINING_RECORD(iface, ConfigFileHandler, ISAXContentHandler_iface); diff --git a/dlls/mscoree/mscoree_main.c b/dlls/mscoree/mscoree_main.c index 2c5d2cbd6c..9561405608 100644 --- a/dlls/mscoree/mscoree_main.c +++ b/dlls/mscoree/mscoree_main.c @@ -551,12 +551,6 @@ BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerifi return FALSE; } -HRESULT WINAPI CreateConfigStream(LPCWSTR filename, IStream **stream) -{ - FIXME("(%s, %p): stub\n", debugstr_w(filename), stream); - return E_NOTIMPL; -} - HRESULT WINAPI CreateDebuggingInterfaceFromVersion(int nDebugVersion, LPCWSTR version, IUnknown **ppv) { const WCHAR v2_0[] = {'v','2','.','0','.','5','0','7','2','7',0}; diff --git a/dlls/mscoree/tests/mscoree.c b/dlls/mscoree/tests/mscoree.c index abe105d5b2..63517dc79b 100644 --- a/dlls/mscoree/tests/mscoree.c +++ b/dlls/mscoree/tests/mscoree.c @@ -437,24 +437,24 @@ static void test_createconfigstream(void) GetFullPathNameW(file, MAX_PATH, path, NULL); hr = pCreateConfigStream(NULL, &stream); - todo_wine ok(hr == E_FAIL || - broken(hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND)) || /* some WinXP, Win2K3 and Win7 */ - broken(hr == S_OK && !stream), /* some Win2K3 */ - "CreateConfigStream returned %x\n", hr); + ok(hr == E_FAIL || + broken(hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND)) || /* some WinXP, Win2K3 and Win7 */ + broken(hr == S_OK && !stream), /* some Win2K3 */ + "CreateConfigStream returned %x\n", hr); hr = pCreateConfigStream(path, NULL); - todo_wine ok(hr == COR_E_NULLREFERENCE, "CreateConfigStream returned %x\n", hr); + ok(hr == COR_E_NULLREFERENCE, "CreateConfigStream returned %x\n", hr); hr = pCreateConfigStream(NULL, NULL); - todo_wine ok(hr == COR_E_NULLREFERENCE, "CreateConfigStream returned %x\n", hr); + ok(hr == COR_E_NULLREFERENCE, "CreateConfigStream returned %x\n", hr); hr = pCreateConfigStream(nonexistent, &stream); - todo_wine ok(hr == COR_E_FILENOTFOUND, "CreateConfigStream returned %x\n", hr); + ok(hr == COR_E_FILENOTFOUND, "CreateConfigStream returned %x\n", hr); ok(stream == NULL, "Expected stream to be NULL\n"); hr = pCreateConfigStream(path, &stream); - todo_wine ok(hr == S_OK, "CreateConfigStream failed, hr=%x\n", hr); - todo_wine ok(stream != NULL, "Expected non-NULL stream\n"); + ok(hr == S_OK, "CreateConfigStream failed, hr=%x\n", hr); + ok(stream != NULL, "Expected non-NULL stream\n"); if (stream) { @@ -462,12 +462,17 @@ static void test_createconfigstream(void) LARGE_INTEGER pos; ULARGE_INTEGER size; IStream *stream2 = NULL; + ULONG ref; hr = IStream_Read(stream, buffer, strlen(xmldata), &count); ok(hr == S_OK, "IStream_Read failed, hr=%x\n", hr); ok(count == strlen(xmldata), "wrong count: %u\n", count); ok(!strcmp(buffer, xmldata), "Strings do not match\n"); + hr = IStream_Read(stream, buffer, sizeof(buffer), &count); + ok(hr == S_OK, "IStream_Read failed, hr=%x\n", hr); + ok(!count, "wrong count: %u\n", count); + hr = IStream_Write(stream, xmldata, strlen(xmldata), &count); ok(hr == E_FAIL, "IStream_Write returned hr=%x\n", hr); @@ -488,8 +493,8 @@ static void test_createconfigstream(void) hr = IStream_Revert(stream); ok(hr == E_NOTIMPL, "IStream_Revert returned hr=%x\n", hr); - hr = IStream_Release(stream); - ok(hr == S_OK, "IStream_Release returned hr=%x\n", hr); + ref = IStream_Release(stream); + ok(!ref, "IStream_Release returned %u\n", ref); } DeleteFileW(file); }