Jacek Caban : mscoree: Added CreateConfigStream implementation.

Alexandre Julliard julliard at winehq.org
Wed Sep 27 17:54:50 CDT 2017


Module: wine
Branch: master
Commit: 8fff6813b11387c68e0b949e2c482c5dd4d9765d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8fff6813b11387c68e0b949e2c482c5dd4d9765d

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep 26 18:09:52 2017 +0200

mscoree: Added CreateConfigStream implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 a52a521..af2ccf2 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 2c5d2cb..9561405 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 abe105d..63517dc 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);
 }




More information about the wine-cvs mailing list