[PATCH 01/10] d3dx9: Fix handling of includes in D3DXCreateEffectFromFileExW().

Matteo Bruni mbruni at codeweavers.com
Thu Mar 22 15:43:04 CDT 2018


Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
For bug 43863 (Rollcage Redux).

 dlls/d3dx9_36/d3dx9_private.h |  8 ++++++++
 dlls/d3dx9_36/effect.c        | 37 ++++++++++++++++++++++++++++++-------
 dlls/d3dx9_36/shader.c        | 38 +++++++++++++++++---------------------
 3 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
index 2044b2af448..6cc1126c80f 100644
--- a/dlls/d3dx9_36/d3dx9_private.h
+++ b/dlls/d3dx9_36/d3dx9_private.h
@@ -69,6 +69,14 @@ struct pixel_format_desc {
     void (*to_rgba)(const struct vec4 *src, struct vec4 *dst, const PALETTEENTRY *palette);
 };
 
+struct d3dx_include_from_file
+{
+    ID3DXInclude ID3DXInclude_iface;
+};
+
+extern CRITICAL_SECTION from_file_mutex DECLSPEC_HIDDEN;
+extern const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl DECLSPEC_HIDDEN;
+
 static inline BOOL is_conversion_from_supported(const struct pixel_format_desc *format)
 {
     if (format->type == FORMAT_ARGB || format->type == FORMAT_ARGBF16
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 33e0fc4cdae..7675f17e403 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -6664,8 +6664,10 @@ static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base,
 #endif
     unsigned int i, j;
 
-    TRACE("base %p, data %p, data_size %lu, effect %p, pool %p, skip_constants %s.\n",
-            base, data, data_size, effect, pool, debugstr_a(skip_constants_string));
+    TRACE("base %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, errors %p, "
+            "effect %p, pool %p, skip_constants %s.\n",
+            base, data, data_size, defines, include, eflags, errors, effect, pool,
+            debugstr_a(skip_constants_string));
 
     base->effect = effect;
     base->pool = pool;
@@ -7041,9 +7043,11 @@ HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, cons
         const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
         struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
 {
-    void *buffer;
+    struct d3dx_include_from_file include_from_file;
+    const void *buffer;
+    unsigned int size;
+    char *filename_a;
     HRESULT ret;
-    DWORD size;
 
     TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
             "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
@@ -7053,14 +7057,33 @@ HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, cons
     if (!device || !srcfile)
         return D3DERR_INVALIDCALL;
 
-    ret = map_view_of_file(srcfile, &buffer, &size);
+    if (!include)
+    {
+        include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
+        include = &include_from_file.ID3DXInclude_iface;
+    }
 
+    size = WideCharToMultiByte(CP_ACP, 0, srcfile, -1, NULL, 0, NULL, NULL);
+    filename_a = heap_alloc(size);
+    if (!filename_a)
+        return E_OUTOFMEMORY;
+    WideCharToMultiByte(CP_ACP, 0, srcfile, -1, filename_a, size, NULL, NULL);
+
+    EnterCriticalSection(&from_file_mutex);
+    ret = ID3DXInclude_Open(include, D3DXINC_LOCAL, filename_a, NULL, &buffer, &size);
     if (FAILED(ret))
+    {
+        LeaveCriticalSection(&from_file_mutex);
+        heap_free(filename_a);
         return D3DXERR_INVALIDDATA;
+    }
 
-    ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
-    UnmapViewOfFile(buffer);
+    ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool,
+            effect, compilationerrors);
 
+    ID3DXInclude_Close(include, buffer);
+    LeaveCriticalSection(&from_file_mutex);
+    heap_free(filename_a);
     return ret;
 }
 
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index f3724947601..acbbf0718ad 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -214,7 +214,6 @@ HRESULT WINAPI D3DXAssembleShader(const char *data, UINT data_len, const D3DXMAC
 
 static const void *main_file_data;
 
-static CRITICAL_SECTION from_file_mutex;
 static CRITICAL_SECTION_DEBUG from_file_mutex_debug =
 {
     0, 0, &from_file_mutex,
@@ -224,14 +223,14 @@ static CRITICAL_SECTION_DEBUG from_file_mutex_debug =
     },
     0, 0, {(DWORD_PTR)(__FILE__ ": from_file_mutex")}
 };
-static CRITICAL_SECTION from_file_mutex = {&from_file_mutex_debug, -1, 0, 0, 0, 0};
+CRITICAL_SECTION from_file_mutex = {&from_file_mutex_debug, -1, 0, 0, 0, 0};
 
 /* D3DXInclude private implementation, used to implement
  * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
 /* To be able to correctly resolve include search paths we have to store the
  * pathname of each include file. We store the pathname pointer right before
  * the file data. */
-static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE include_type,
+static HRESULT WINAPI d3dx_include_from_file_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE include_type,
         const char *filename, const void *parent_data, const void **data, UINT *bytes)
 {
     const char *p, *parent_name = "";
@@ -250,7 +249,7 @@ static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_T
             parent_name = *((const char **)main_file_data - 1);
     }
 
-    TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename), debugstr_a(parent_name));
+    TRACE("Looking up include file %s, parent %s.\n", debugstr_a(filename), debugstr_a(parent_name));
 
     if ((p = strrchr(parent_name, '\\')))
         ++p;
@@ -301,7 +300,7 @@ error:
     return HRESULT_FROM_WIN32(GetLastError());
 }
 
-static HRESULT WINAPI d3dincludefromfile_close(ID3DXInclude *iface, const void *data)
+static HRESULT WINAPI d3dx_include_from_file_close(ID3DXInclude *iface, const void *data)
 {
     HeapFree(GetProcessHeap(), 0, *((char **)data - 1));
     HeapFree(GetProcessHeap(), 0, (char **)data - 1);
@@ -310,13 +309,10 @@ static HRESULT WINAPI d3dincludefromfile_close(ID3DXInclude *iface, const void *
     return S_OK;
 }
 
-static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl = {
-    d3dincludefromfile_open,
-    d3dincludefromfile_close
-};
-
-struct D3DXIncludeImpl {
-    ID3DXInclude ID3DXInclude_iface;
+const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl =
+{
+    d3dx_include_from_file_open,
+    d3dx_include_from_file_close
 };
 
 HRESULT WINAPI D3DXAssembleShaderFromFileA(const char *filename, const D3DXMACRO *defines,
@@ -348,7 +344,7 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
     const void *buffer;
     DWORD len;
     HRESULT hr;
-    struct D3DXIncludeImpl includefromfile;
+    struct d3dx_include_from_file include_from_file;
     char *filename_a;
 
     TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
@@ -356,8 +352,8 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
 
     if(!include)
     {
-        includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
-        include = &includefromfile.ID3DXInclude_iface;
+        include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
+        include = &include_from_file.ID3DXInclude_iface;
     }
 
     len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
@@ -481,7 +477,7 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
     const void *buffer;
     DWORD len, filename_len;
     HRESULT hr;
-    struct D3DXIncludeImpl includefromfile;
+    struct d3dx_include_from_file include_from_file;
     char *filename_a;
 
     TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
@@ -491,8 +487,8 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
 
     if (!include)
     {
-        includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
-        include = &includefromfile.ID3DXInclude_iface;
+        include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
+        include = &include_from_file.ID3DXInclude_iface;
     }
 
     filename_len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
@@ -606,7 +602,7 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
     const void *buffer;
     DWORD len;
     HRESULT hr;
-    struct D3DXIncludeImpl includefromfile;
+    struct d3dx_include_from_file include_from_file;
     char *filename_a;
 
     TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
@@ -614,8 +610,8 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
 
     if (!include)
     {
-        includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
-        include = &includefromfile.ID3DXInclude_iface;
+        include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
+        include = &include_from_file.ID3DXInclude_iface;
     }
 
     len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
-- 
2.13.6




More information about the wine-devel mailing list