Skip to content

Commit

Permalink
d3d9-nine: introduce forwarder DLL
Browse files Browse the repository at this point in the history
Because Wine appears to ignore override settings for .dll.so libraries,
introduce a forwarding DLL that will always be identified as native.

Fixes #150
  • Loading branch information
9ary committed Mar 18, 2023
1 parent dea89dc commit d8539b2
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 4 deletions.
Binary file added d3d9-nine/d3d9-nine-forwarder.dll
Binary file not shown.
15 changes: 15 additions & 0 deletions d3d9-nine/d3d9-nine-forwarder.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
@ stdcall Direct3DShaderValidatorCreate9() d3d9-nine.Direct3DShaderValidatorCreate9
@ stdcall PSGPError() d3d9-nine.PSGPError
@ stdcall PSGPSampleTexture() d3d9-nine.PSGPSampleTexture
@ stdcall D3DPERF_BeginEvent(long wstr) d3d9-nine.D3DPERF_BeginEvent
@ stdcall D3DPERF_EndEvent() d3d9-nine.D3DPERF_EndEvent
@ stdcall D3DPERF_GetStatus() d3d9-nine.D3DPERF_GetStatus
@ stdcall D3DPERF_QueryRepeatFrame() d3d9-nine.D3DPERF_QueryRepeatFrame
@ stdcall D3DPERF_SetMarker(long wstr) d3d9-nine.D3DPERF_SetMarker
@ stdcall D3DPERF_SetOptions(long) d3d9-nine.D3DPERF_SetOptions
@ stdcall D3DPERF_SetRegion(long wstr) d3d9-nine.D3DPERF_SetRegion
@ stdcall DebugSetLevel() d3d9-nine.DebugSetLevel
@ stdcall DebugSetMute() d3d9-nine.DebugSetMute
@ stdcall Direct3DCreate9(long) d3d9-nine.Direct3DCreate9
@ stdcall Direct3DCreate9Ex(long ptr) d3d9-nine.Direct3DCreate9Ex
43 changes: 43 additions & 0 deletions d3d9-nine/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,46 @@ custom_target(
'@OUTPUT@',
],
)

if wine_version.version_compare('>= 7.3')
d3d9_forwarder_builtin = shared_library(
'd3d9-nine-forwarder',
[
d3d9_res,
],
name_prefix : '',
name_suffix : 'dll.builtin',
install : false,
vs_module_defs : 'd3d9-nine-forwarder.spec',
objects : 'd3d9-nine-forwarder.spec',
link_args : [
'-Wb,--data-only',
'-Wb,--filename=d3d9',
],
)

# Wine checks for a string in the header to identify builtin DLLs.
# Work around this with a simple substitution.
d3d9_forwarder = custom_target(
'd3d9-nine-forwarder.dll',
input : d3d9_forwarder_builtin,
output : 'd3d9-nine-forwarder.dll',
install : true,
install_dir : pe_dir,
command : [
sed,
'-e', 's|Wine builtin DLL|Nine forwarder |',
'@INPUT@',
],
capture : true,
)
else
# Support for building data-only modules was added in wine 7.3.
# For binary releases, use a prebuilt version (without resources).
# This is a small (8KiB) and reproducible file that contains
# no executable code, so it shouldn't be a problem.
install_data(
'd3d9-nine-forwarder.dll',
install_dir : pe_dir,
)
endif
10 changes: 10 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ wrc = [
'-o', '@OUTPUT@',
]

wine_version = run_command(
[
find_program('winebuild'),
'--version',
],
check : true,
).stdout().split()[-1]

sed = find_program('sed')

if cc.has_function('dlopen')
dep_dl = null_dep
else
Expand Down
9 changes: 5 additions & 4 deletions ninewinecfg/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "resource.h"

static const char * const fn_nine_dll = "d3d9-nine.dll";
static const char * const fn_forwarder_dll = "d3d9-nine-forwarder.dll";
static const char * const fn_backup_dll = "d3d9-nine.bak";
static const char * const fn_d3d9_dll = "d3d9.dll";
static const char * const fn_nine_exe = "ninewinecfg.exe";
Expand Down Expand Up @@ -253,11 +254,11 @@ static BOOL is_nine_symlink(LPCSTR filename)
return FALSE;

ret = readlink(fn, buf, sizeof(buf));
if ((ret < strlen(fn_nine_dll)) || (ret == sizeof(buf)))
if ((ret < strlen(fn_forwarder_dll)) || (ret == sizeof(buf)))
return FALSE;

buf[ret] = 0;
return !strcmp(buf + ret - strlen(fn_nine_dll), fn_nine_dll);
return !strcmp(buf + ret - strlen(fn_forwarder_dll), fn_forwarder_dll);
}

static BOOL nine_get_system_path(CHAR *pOut, DWORD SizeOut)
Expand Down Expand Up @@ -397,7 +398,7 @@ static void nine_set(BOOL status, BOOL NoOtherArch)
remove_file(dst);
}

hmod = LoadLibraryExA(fn_nine_dll, NULL, DONT_RESOLVE_DLL_REFERENCES);
hmod = LoadLibraryExA(fn_forwarder_dll, NULL, DONT_RESOLVE_DLL_REFERENCES);
if (hmod)
{
Dl_info info;
Expand All @@ -410,7 +411,7 @@ static void nine_set(BOOL status, BOOL NoOtherArch)
FreeLibrary(hmod);
} else {
LPWSTR msg = load_message(GetLastError());
ERR("Couldn't load %s: %s\n", fn_nine_dll, nine_dbgstr_w(msg));
ERR("Couldn't load %s: %s\n", fn_forwarder_dll, nine_dbgstr_w(msg));
LocalFree(msg);
}
} else {
Expand Down
2 changes: 2 additions & 0 deletions tools/nine-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ DST=$(wine winepath -u 'c:\windows\system32')
echo "installing 32bit binaries to $DST"
pe_dir='i386-windows'
so_dir='i386-unix'
ln -sf "$BASE/wine/$pe_dir/d3d9-nine-forwarder.dll" "$DST/"
ln -sf "$BASE/wine/$so_dir/d3d9-nine.dll.so" "$DST/d3d9-nine.dll"
ln -sf "$BASE/wine/$so_dir/ninewinecfg.exe.so" "$DST/ninewinecfg.exe"

Expand All @@ -31,6 +32,7 @@ DST=$(wine64 winepath -u 'c:\windows\system32')
echo "installing 64bit binaries to $DST"
pe_dir='x86_64-windows'
so_dir='x86_64-unix'
ln -sf "$BASE/wine/$pe_dir/d3d9-nine-forwarder.dll" "$DST/"
ln -sf "$BASE/wine/$so_dir/d3d9-nine.dll.so" "$DST/d3d9-nine.dll"
ln -sf "$BASE/wine/$so_dir/ninewinecfg.exe.so" "$DST/ninewinecfg.exe"

Expand Down

0 comments on commit d8539b2

Please sign in to comment.