lutris / lutris

Lutris desktop client
https://lutris.net
GNU General Public License v3.0
7.88k stars 691 forks source link

Wine runner arguments are split incorrectly and/or quotes are removed. #4018

Open luluco250 opened 2 years ago

luluco250 commented 2 years ago

Bug description

It seems Lutris removes quotes from command line arguments passed to a Wine game (and maybe with other runners too? I haven't tested it). This causes issues with quoted arguments that would normally be interpreted as a single, whole argument.

Many Deus Ex mods require passing arguments to specify ini files, which can involve paths with spaces in them, for example:

-hax0r INI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.ini" USERINI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini" log=TNM.log

These arguments are passed by the shortcut of The Nameless Mod, which points to C:\GOG Games\Deus Ex GOTY\System\TNM.exe. This results in the following error message:

image

Launching the .lnk shortcut created by the mod directly works flawlessly, as does a batch file like the following:

@echo off
TNM.exe -hax0r INI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.ini" USERINI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini" log=TNM.log

Taking a look at the log shows that the launch command removed the quotes:

Started initial process 31623 from gamemoderun /home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/bin/wine /home/lucas/Games/deus-ex-tnm/drive_c/GOG Games/Deus Ex GOTY/System/TNM.exe -hax0r INI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.iniUSERINI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini log=TNM.log

So at some point along the launch process it appears to remove quotes from the arguments or launch string, which will obviously cause the game to parse the previously quoted arguments as multiple separate ones.

How to Reproduce

Steps to reproduce the behavior:

  1. Install a game or mod that requires command line arguments (examples: GMDX, The Nameless Mod etc).
  2. Take the command line arguments required by the game and add them to the Lutris configuration (can be obtained by the shortcut created by the game or mod).
  3. Add command line arguments to a Wine game, ensuring at least one of them has a space in it (surrounded by quotes, such as a path).
  4. Run the game.
  5. Expect issues such as error messages or missing the installed mod.
  6. Create a batch file that runs the game with the exact same arguments.
  7. Point the Lutris configuration to it (and remove the arguments from Lutris).
  8. Run the game.
  9. Game/mod works normally.

Expected behavior

Lutris passes the arguments in the same way as the Windows/Wine command line, working exactly the same as a batch file or .lnk shortcut.

Log output

2022-01-27 18:52:30,525: Magic not available. Unable to automatically find game executables. Pleaseinstall python-magic
2022-01-27 18:52:30,556: Starting Lutris 0.5.9.1
2022-01-27 18:52:30,576: No cores found
2022-01-27 18:52:32,265: Failed to read content length on response from https://api.github.com/repos/lutris/dxvk/releases
2022-01-27 18:52:33,144: Startup complete
INFO     2022-01-27 18:52:33,145 [startup.check_driver:61]:Running AMD Mesa driver 21.3.4 on AMD Radeon RX 560 Series (POLARIS11, DRM 3.44.0, 5.16.2-zen1-1-zen, LLVM 13.0.0) (0x67ef)
INFO     2022-01-27 18:52:33,145 [startup.check_driver:73]:GPU: 1002:67EF 1458:230A (amdgpu drivers)
DEBUG    2022-01-27 18:52:33,339 [lutriswindow.update_store:451]:Showing 20 games
DEBUG    2022-01-27 18:52:37,940 [grid.on_item_activated:57]:Item activated: 27
DEBUG    2022-01-27 18:52:37,941 [lutriswindow.on_game_activated:833]:No service for view
DEBUG    2022-01-27 18:52:38,114 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/dxgi.dll with DXVK version
DEBUG    2022-01-27 18:52:38,115 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3d11.dll with DXVK version
DEBUG    2022-01-27 18:52:38,115 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3d10core.dll with DXVK version
DEBUG    2022-01-27 18:52:38,117 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3d9.dll with DXVK version
DEBUG    2022-01-27 18:52:38,118 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dcompiler_42.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,119 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dcompiler_43.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,119 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dcompiler_46.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,119 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dcompiler_47.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,119 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_33.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,119 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_34.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,119 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_35.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_36.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_37.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_38.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_39.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_40.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_41.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_42.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10_43.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx10.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx11_42.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,120 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx11_43.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_24.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_25.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_26.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_27.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_28.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_29.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_30.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_31.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_32.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_33.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_34.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,121 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_35.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_36.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_37.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_38.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_39.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_40.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_41.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_42.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,122 [dll_manager.enable_dll:131]:Replacing /home/lucas/Games/deus-ex-tnm/drive_c/windows/system32/d3dx9_43.dll with D3D Extras version
DEBUG    2022-01-27 18:52:38,146 [xrandr._get_vidmodes:14]:Retrieving video modes from XrandR
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:DISABLE_LAYER_AMD_SWITCHABLE_GRAPHICS_1="1"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:SDL_VIDEO_FULLSCREEN_DISPLAY="off"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:DRI_PRIME="1"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:LD_LIBRARY_PATH="/home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/lib:/home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/lib64:/usr/lib:/usr/lib32:/usr/lib/openmpi:/usr/lib/opencollada:/usr/lib/libfakeroot:/usr/lib64:/home/lucas/.local/share/lutris/runtime/Ubuntu-18.04-i686:/home/lucas/.local/share/lutris/runtime/steam/i386/lib/i386-linux-gnu:/home/lucas/.local/share/lutris/runtime/steam/i386/lib:/home/lucas/.local/share/lutris/runtime/steam/i386/usr/lib/i386-linux-gnu:/home/lucas/.local/share/lutris/runtime/steam/i386/usr/lib:/home/lucas/.local/share/lutris/runtime/Ubuntu-18.04-x86_64:/home/lucas/.local/share/lutris/runtime/steam/amd64/lib/x86_64-linux-gnu:/home/lucas/.local/share/lutris/runtime/steam/amd64/lib:/home/lucas/.local/share/lutris/runtime/steam/amd64/usr/lib/x86_64-linux-gnu:/home/lucas/.local/share/lutris/runtime/steam/amd64/usr/lib:$LD_LIBRARY_PATH"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINEDEBUG="-all"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINEARCH="win32"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINE="/home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/bin/wine"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:GST_PLUGIN_SYSTEM_PATH_1_0="/home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/lib64/gstreamer-1.0/:/home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/lib/gstreamer-1.0/"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINEPREFIX="/home/lucas/Games/deus-ex-tnm"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINEESYNC="1"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINEFSYNC="1"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINEDLLOVERRIDES="d3d10core,d3d11,d3d9,d3dcompiler_42,d3dcompiler_43,d3dcompiler_46,d3dcompiler_47,d3dx10,d3dx10_33,d3dx10_34,d3dx10_35,d3dx10_36,d3dx10_37,d3dx10_38,d3dx10_39,d3dx10_40,d3dx10_41,d3dx10_42,d3dx10_43,d3dx11_42,d3dx11_43,d3dx9_24,d3dx9_25,d3dx9_26,d3dx9_27,d3dx9_28,d3dx9_29,d3dx9_30,d3dx9_31,d3dx9_32,d3dx9_33,d3dx9_34,d3dx9_35,d3dx9_36,d3dx9_37,d3dx9_38,d3dx9_39,d3dx9_40,d3dx9_41,d3dx9_42,d3dx9_43,dxgi=n;winemenubuilder="
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:WINE_LARGE_ADDRESS_AWARE="1"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:game_name="Deus Ex: The Nameless Mod"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:PYTHONPATH="/usr/lib/lutris:/usr/bin:/usr/lib/python310.zip:/usr/lib/python3.10:/usr/lib/python3.10/lib-dynload:/usr/lib/python3.10/site-packages"
DEBUG    2022-01-27 18:52:38,156 [command.start:139]:LUTRIS_GAME_UUID="c5f22edd-49e6-4cbb-8b9e-056469d36018"
lutris-wrapper: Deus Ex: The Nameless Mod
Started initial process 31623 from gamemoderun /home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/bin/wine /home/lucas/Games/deus-ex-tnm/drive_c/GOG Games/Deus Ex GOTY/System/TNM.exe -hax0r INI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.iniUSERINI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini log=TNM.log
Start monitoring process.
gamemodeauto:
fsync: up and running.
Monitored process exited.
Initial process has exited (return code: 256)
Exit with return code 256
DEBUG    2022-01-27 18:52:41,524 [command.on_stop:193]:Process 31618 has terminated with code 256
DEBUG    2022-01-27 18:52:48,185 [game.beat:588]:Game thread stopped
WARNING  2022-01-27 18:52:48,185 [game.on_game_quit:614]:Game still running (state: running)
INFO     2022-01-27 18:52:48,185 [game.stop:599]:Stopping Deus Ex: The Nameless Mod (wine)
DEBUG    2022-01-27 18:52:48,186 [game.stop_game:554]:Deus Ex: The Nameless Mod (wine) has run for 10 seconds
DEBUG    2022-01-27 18:52:48,209 [game.on_game_quit:632]:Deus Ex: The Nameless Mod stopped at qui, 27 jan 2022 18:52:48
DEBUG    2022-01-27 18:52:48,209 [game.save:257]:Saving Deus Ex: The Nameless Mod (wine) with config ID deus-ex-the-nameless-mod-1643239720
INFO     2022-01-27 18:52:48,263 [application.do_shutdown:631]:Shutting down Lutris

System Information

[System]
OS:              Arch Linux rolling n/a
Arch:            x86_64
Kernel:          5.16.2-zen1-1-zen
Desktop:         KDE
Display Server:  x11

[CPU]
Vendor:          AuthenticAMD
Model:           AMD Ryzen 7 3800X 8-Core Processor
Physical cores:  8
Logical cores:   16

[Memory]
RAM:             15.6 GB
Swap:            16.0 GB

[Graphics]
Vendor:          AMD
OpenGL Renderer: AMD Radeon RX 560 Series (POLARIS11, DRM 3.44.0, 5.16.2-zen1-1-zen, LLVM 13.0.0)
OpenGL Version:  4.6 (Compatibility Profile) Mesa 21.3.4
OpenGL Core:     4.6 (Core Profile) Mesa 21.3.4
OpenGL ES:       OpenGL ES 3.2 Mesa 21.3.4
Vulkan:          Supported

Media (optional)

No response

Checklist:

danieljohnson2 commented 2 years ago

Does this still reproduce if you turn off 'Enable Feral GameMode'?

I looked at this code and it appears to me that the log message does not put quotes in there, but the arguments are still being separated correctly in the actual execution.

It's possible that something is going wrong in Feral GameMode, maybe. So maybe without it, things will start to work.

luluco250 commented 2 years ago

Unfortunately the error still occurs even if I disable Feral Game Mode, all it does is remove gamemoderun from the launch string, the parameters remain de-quoted. image

lutris-wrapper: Deus Ex: The Nameless Mod
Started initial process 7107 from /home/lucas/.local/share/lutris/runners/wine/lutris-fshack-6.21-6-x86_64/bin/wine /home/lucas/Games/deus-ex-tnm/drive_c/GOG Games/Deus Ex GOTY/System/DeusEx.exe -hax0r INI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.ini USERINI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini log=TNM.log -skipdialog
Start monitoring process.
fsync: up and running.
Monitored process exited.
Initial process has exited (return code: 256)
Exit with return code 256

I figured out I can just use a relative path since there are no spaces in the folders inside the game's folder, but it's probably gonna be an issue in other cases (specially when a relative path is not applicable or there are still spaces in the paths).

danieljohnson2 commented 2 years ago

I think I see it. But I think this may not be so easy to fix without breaking lots of existing game installs.

I think you can work around this by quoting more- like this: -hax0r 'INI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.ini"' 'USERINI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini"' log=TNM.log

That's single-quotes around the arguments that contain double quotes to protect them. Note that the stuff like INI= goes inside these quotes. Try that and let us know if that works.

I think the thing that is happening here is like this: Lutris must parse the arguments into separate argument strings to pass them to the game (or to Game-Mode or whatever). It does this using shlex.split in POSIX mode. In this mode this function removes internal quotes. INI="A B" becomes the string 'INI=A B' which is not so great.

In non-POSIX mode, shlex.split does the right thing here: you get 'INI="A B"'as expected and the quotes survive. But this mode changes quite a lot, described here: Parsing Rules

I can't believe changing all that is safe; surely existing installed games will be using backslash-escaping or somethings. Yet it seems like non-POSIX mode is better for WINE, since Windows is anything but POSIX in its command line handling.

luluco250 commented 2 years ago

I think you can work around this by quoting more- like this: -hax0r 'INI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.ini"' 'USERINI="C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini"' log=TNM.log

I just tried that and got a very strange error, it seems to have passed the argument literally (with the double quotes) to the program and made it unable to handle the path string.

I say that because it:

Screenshot ![image](https://user-images.githubusercontent.com/18670927/151786586-3686051d-56f3-4547-9f25-6ce93bfafbe2.png)

Out of curiosity I've also tried 'INI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNM.ini' 'USERINI=C:\GOG Games\Deus Ex GOTY\TNM\System\TNMUser.ini' but it again had the issue of splitting arguments (probably the same dequoting problem).

Using both quotes around the arguments ('"INI=..."') also didn't work.

I can't believe changing all that is safe; surely existing installed games will be using backslash-escaping or somethings. Yet it seems like non-POSIX mode is better for WINE, since Windows is anything but POSIX in its command line handling.

While kind of an ugly workaround, perhaps introducing an option to switch between the two modes would be ok? If it were a system option it also could be set globally by users.

danieljohnson2 commented 2 years ago

Nuts. I'll have to get off my lazy butt and install the nameless mod.

I don't think we want a mode switch, since unPOSIX-mode is weird and incompatible and does not seem like it would even work for you (since the workaround did not). So no point there.

I spoke to @strycore and he does not seem worried about the compatibility issue, but thinks that we should transfer the arguments into the game faithfully- ideally with no processing. I haven't found a way to do that, but maybe we can get by with minimal processing on the args.

strycore commented 2 years ago

I don't see another way of fixing this other than creating a subclass of shlex that has the correct behavior and doesn't strip quotes.

danieljohnson2 commented 2 years ago

I don't think anything like that can work.

The fundamental problem is in WINE. The issue is in the function build_command_line() in /dlls/ntdll/unix/env.c: env.c

I've been trying to find a way to bypass that, but it looks like it's going to be invoked no matter what we do.

What it does is encode the Unix command like args (argc/argv) into a Windows command line (that is, one big string). The strange algorithm there is Microsoft's, and Win32's CommandLineToArgv() function will parse that mess.

That algorithm turns INI="C:..." into INI=\"C:..\", and CommandLineToArgv() turns it back. But nothing compels a Windows program to use CommandLineToArgv(), and I think this one expects the quotes to be un-escaped instead.

You can see what this looks like in WINE's notepad, which does its own command line parsing and does not know about backslash escaping: WINE Notepad's main.c

I haven't yet proved the The Nameless Mod does anything odd here, but that's my theory. I need to research that next.

danieljohnson2 commented 2 years ago

It's not looking too good. The TNM source does not include this and Unreal 1's source hasn't been released, and the Unreal docs I can find don't document this. But when I modify the .BAT file above to include backslashes, it fails.

If I am right, there's no way to pass command line arguments that would work- anything we pass gets munged. We could work around this only by avoiding the WINE command line. We could write a BAT file and have WINE run that, say. But that seems awfully ugly to me.

What we really want is some sort of WINE command line option to take the argument list as a single string and not molest it at all. But I'm now pretty sure WINE has not got that option.

luluco250 commented 2 years ago

It's not looking too good. The TNM source does not include this and Unreal 1's source hasn't been released, and the Unreal docs I can find don't document this.

If you'd like I can compile a test Win32 application to check how the arguments are actually passed.

PS: GMDX will also work to test this if you have that/its source.

danieljohnson2 commented 2 years ago

I don't think I need a custom Win32 test harness, thanks.

I have been testing with TNM to see what works for it, and using WINE's notepad clone to see what WINE is giving us. WINE notepad gives an error message for file-not-found that gives the path it sees, so that confirmed that WINE is indeed escaping quotes with backslashes, which is what its source code says it does.

I don't think I can get the Unreal 1 source code. But I can see through testing that it does not like those backslashes.

danieljohnson2 commented 2 years ago

Well, I see no fix with WINE as it is that's better than writing out a .bat file and running that. We'd surely want to detect the quoting problem and do this only when necessary.

But my word, that's ugly as sin. I don't want to do it. I think we should treat this as a WONTFIX until WINE provides a way to pass that argument string without WINE escaping it.

I've been poking around, and WINE does not seem to even have a feature-request process. Dunno what's going on with that.

luluco250 commented 2 years ago

I think we should treat this as a WONTFIX until WINE provides a way to pass that argument string without WINE escaping it.

That's fair, I'll just stick to the .bat for now, it works well enough. Thanks for looking into it though!

Feel free to close the issue.

danieljohnson2 commented 2 years ago

I'm just a random contributor. I can't close your issues.

On the other hand, just because I don't want to fix this, does not mean that nobody will do so.

luluco250 commented 2 years ago

Oh I see. I'll just leave it open then in case anyone else wants to chip in.

strycore commented 2 years ago

Has anyone even tried reproducing this with the bash option?

Using -b script.sh on the command line will create a script for a given game that is able to run a game without lutris.

danieljohnson2 commented 2 years ago

I have no longer got the Nameless Mod installed, but I did a quick check using wine notepad and WINE seems to still be escaping quotes as before, so I'd expect this to fail the same way.

strycore commented 2 years ago

I tried with notepad and I can open a file with or without quotes

https://user-images.githubusercontent.com/280336/152898041-fbc991c6-e54b-4421-996a-8f9466f03633.mp4

danieljohnson2 commented 2 years ago

Oh my, the background music!

But your " quotes are removed by shlex, and WINE just replaces them to protect the space in the path. No backslashes, so wine notepad removes these quotes and is done.

The MS quoting rules are complicated. The backslashes are for quotes within arguments, not around them.

Try the argument: 'INI="path"'

The outer ' quotes are for shlex, so that it does not remove the " quotes. Those quotes are within the argument, and they get backslash-escaped by WINE. WINE is trying to preserve them, but (I think) The Nameless Mod wants the quotes literally.

wine notepad does not use the standard Win32 API (I checked) so you can see the command line text WINE has given you, more or less. That lets you see the fnords backslashes.

danieljohnson2 commented 2 years ago

I had a brief idea that moving the quotes around would help, and suggested the @luluco250 try it.

But no, TNM can't be using the Win32 API here or the original command line would have worked- POSIX and Win32 actually agree about what unescaped quotes within arguments do, or close enough.

Since the original command line does not work, TNM must not agree with this system, so it must not be using the Win32 API for this. It needs the quotes to survive, without backslashes, in the right places and not around the whole argument instead.

Sigh. Sometimes I'm like the Sherlock Holmes of failure, you know? I can deduce why nothing will ever work.