如果你不是开发人员,不关心代码层面的细节,请看这篇教程:https://hu60.cn/q.php/bbs.topic.103014.html
Wine函数库顶替的“原生”选项不加载由Wine源代码编译出来的内建DLL,原因是Wine在DLL的开头放了字符串“Wine builtin DLL”作为标记。加载时只要检测到这个字符串,Wine就会认为它是内建DLL,如果你设置函数库顶替为“原生”,就会报告DLL找不到。
用 strings xxx.dll | grep DLL
可以显示出这个字符串标记。
相关检测代码在dlls/ntdll/loader.c
中。
所以要让Wine把内建DLL视为原生也很简单,编译Wine时把字符串Wine builtin DLL
批量替换一下,比如替换成Wine native DLL
。这样编译出来的DLL就没有Wine builtin DLL
标记了(变成了Wine native DLL
标记),放进其他Wine创建的前缀里,就会被视为原生DLL正常加载了。同理,你修改后的Wine也会把任何其他Wine的DLL视为原生DLL(因为它现在把带有Wine native DLL
标记的DLL视为内建DLL,但其他Wine的DLL并没有这个标记)。
Wine游戏助手的START云游戏安装脚本就使用了上述方法得到可以被作为原生DLL加载的修改版dwmapi.dll
,从而绕过了START的DWM功能检测。
如果你的DLL已经编译好了,也可以直接使用十六进制编辑器修改开头的“Wine builtin DLL”,把它改成别的就能作为原生DLL加载了。
游戏是通过调用dwmapi.dll
的DwmIsCompositionEnabled
函数来检测DWM功能是否打开的,所以只要该函数始终报告“DWM已打开”,就可以绕过游戏的DWM功能检测。
dlls/dwmapi/dwmapi_main.c
,把DwmIsCompositionEnabled
函数修改成这样:HRESULT WINAPI DwmIsCompositionEnabled(BOOL *enabled)
{
TRACE("%p\n", enabled);
if (!enabled)
return E_INVALIDARG;
*enabled = TRUE;
return S_OK;
}
在源代码里把字符串Wine builtin DLL
批量替换一下,比如替换成Wine native DLL
。
编译项目,得到可作为原生DLL加载的dwmapi.dll
。
把dwmapi.dll
放进其他Wine创建的前缀/drive_c/windows/system32
或前缀/drive_c/windows/syswow64
文件夹,然后设置函数库顶替:dwmapi
=原生,就能生效。
编译好的修改版dwmapi.dll
,可作为原生DLL加载:
修改后的源代码:https://gitee.com/winegame/wine/commits/7.7-dwm-enabled