Cannot launch program from folder named with semicolon

Please report only one bug per message!

Moderators: white, Hacker, petermad, Stefan2

Post Reply
MarekKnapek
Junior Member
Junior Member
Posts: 7
Joined: 2019-09-07, 06:08 UTC

Cannot launch program from folder named with semicolon

Post by *MarekKnapek »

Hi,

Recently I discovered weird behavior when using Total Commander. I'm not able to execute some programs if they are located inside path containing semicolon. Symptoms: Double click on executable from Total Commander will bring system message box about missing DLL up. Double click on the same executable in the same path but from Widows File Explorer runs the program just fine.

My system is: Windows 7 x64, Total Commander x64 9.22a.

After digging for a while I discovered that the missing DLL is always some "local to the application" DLL, never a system one. Steps to reproduce: Locate some application in your computer that statically depends on some DLL that is located in the same directory as the EXE. I use VLC media player downloaded from their web site, the portable edition one (distributed in 7zip archive). Copy the entire application to some path containing semicolon in its name. I use c:\temp\semicolon-bug\a;b\vlc-3.0.8\, in this path is vlc.exe and its dependency libvlc.dll. In Total Commander navigate to that folder and double click on the application. System dialog about missing DLL appears. Do the same in Windows File Explorer and VLC runs just fine.

So it seemed as a Total Commander bug for me. But I kept digging for a little bit more.

If you have Debugging Tools for Windows installed you can turn on Loader Snaps for VLC.exe using GFlags application. We need a debugger to be able to see the snaps. Steps I did to see what the loader does: Start 32bit version of Total Commander under debugger or attach debugger to already running TC (I use Visual Studio). Put break point to CreateProcessW function. Navigate to VLC folder in TC and double click on vlc.exe. Break point is hit. Open memory view and go to stack ($esp). Now we want to change dwCreationFlags, the sixth parameter going to CreateProcessW function. In my case it is stored on the stack and has value of 0x04080410. We want to OR it with CREATE_SUSPENDED, so change the value of dwCreationFlags from 0x04080410 to 0x04080414. Press run in debugger. Now vlc.exe process exists but does nothing not even loading its dependent DLLs, it is suspended. Attach debugger to this newly created process. In my case loading dependent DLLs starts after attaching debugger, but you might want to resume the process from some task manager (use Process Explorer or Process Hacker). In debugger output [1] we see that the loader failed to find libvlc.dll. Upon closer examination of the Loader Snaps, we see that Windows loader has some problems with path containing semicolon, not Total Commander. It tries to locate the libvlc.dll from C:\temp\semicolon-bug\a\libvlc.dll and from b\vlc-3.0.8\libvlc.dll, but in reality the file is located at c:\temp\semicolon-bug\a;b\vlc-3.0.8\libvlc.dll.

After gaining this knowledge we can reproduce this problem even simpler. Open cmd.exe and enter "cd c:\temp\semicolon-bug\a;b" command, now run VLC by executing "vlc-3.0.8\vlc.exe" command, Windows fails to find the dependent DLL. Execute "cd vlc-3.0.8" and ".\vlc.exe" commands and everything works fine. I was not able to debug why Windows Explorer succeeds to launch VLC because I don't understand x64 ABI and calling conventions good enough.

So, this seems as Windows Loader bug, not TC bug. But TC is affected by it and works differently (worse) than File Explorer. Do you think it is worth fixing? Fix should be easy: Change current working directory before launching any executable.

Best regards,
Marek Knápek


[1]

Code: Select all

1f1c:0b0c @ 375170813 - LdrpHandleOneOldFormatImportDescriptor - INFO: DLL "C:\temp\semicolon-bug\a;b\vlc-3.0.8\vlc.exe" imports "libvlc.dll"
1f1c:0b0c @ 375170813 - LdrpLoadImportModule - ENTER: DLL name: libvlc.dll DLL path: C:\temp\semicolon-bug\a;b\vlc-3.0.8;;C:\Windows\system32;C:\Windows\system;C:\Windows;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\
1f1c:0b0c @ 375170813 - LdrpFindOrMapDll - ENTER: DLL name: libvlc.dll DLL path: C:\temp\semicolon-bug\a;b\vlc-3.0.8;;C:\Windows\system32;C:\Windows\system;C:\Windows;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\Syst
1f1c:0b0c @ 375170813 - LdrpFindKnownDll - ENTER: DLL name: libvlc.dll
1f1c:0b0c @ 375170813 - LdrpFindKnownDll - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpSearchPath - ENTER: DLL name: libvlc.dll DLL path: C:\temp\semicolon-bug\a;b\vlc-3.0.8;;C:\Windows\system32;C:\Windows\system;C:\Windows;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\temp\semicolon-bug\a\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: b\vlc-3.0.8\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system32\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files (x86)\Common Files\Oracle\Java\javapath\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files (x86)\AMD APP\bin\x86_64\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files (x86)\AMD APP\bin\x86\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\ProgramData\Oracle\Java\javapath\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system32\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\Wbem\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170813 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\WindowsPowerShell\v1.0\libvlc.dll
1f1c:0b0c @ 375170813 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\libvlc.dll
1f1c:0b0c @ 375170829 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\libvlc.dll
1f1c:0b0c @ 375170829 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\WindowsPowerShell\v1.0\libvlc.dll
1f1c:0b0c @ 375170829 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Modules\TShell\TShell\libvlc.dll
1f1c:0b0c @ 375170829 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\WindowsPowerShell\v1.0\libvlc.dll
1f1c:0b0c @ 375170829 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files\dotnet\libvlc.dll
1f1c:0b0c @ 375170829 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\WindowsPowerShell\v1.0\libvlc.dll
1f1c:0b0c @ 375170829 - LdrpResolveFileName - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpSearchPath - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpFindOrMapDll - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375170829 - LdrpLoadImportModule - ERROR: Loading DLL libvlc.dll from path C:\temp\semicolon-bug\a;b\vlc-3.0.8;;C:\Windows\system32;C:\Windows\system;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Window
The thread 0x4f50 has exited with code 0 (0x0).
1f1c:0b0c @ 375176882 - LdrpLoadImportModule - RETURN: Status: 0xc0000135
1f1c:0b0c @ 375176882 - LdrpHandleOneOldFormatImportDescriptor - ERROR: Loading "?????" from the import table of DLL "C:\temp\semicolon-bug\a;b\vlc-3.0.8\vlc.exe" failed with status 0xc0000135
1f1c:0b0c @ 375176882 - LdrpInitializeProcess - ERROR: Walking the import tables of the executable and its static imports failed with status 0xc0000135
1f1c:0b0c @ 375176882 - _LdrpInitialize - ERROR: Process initialization failed with status 0xc0000135
1f1c:0b0c @ 375176882 - LdrpInitializationFailure - ERROR: Process initialization failed with status 0xc0000135
The thread 0xb0c has exited with code -1073741515 (0xc0000135).
The program '[0x1F1C] vlc.exe' has exited with code -1073741515 (0xc0000135) 'A dependent dll was not found'.
User avatar
Dalai
Power Member
Power Member
Posts: 9352
Joined: 2005-01-28, 22:17 UTC
Location: Meiningen (Südthüringen)

Re: Cannot launch program from folder named with semicolon

Post by *Dalai »

I can confirm the problem. If you launch the EXE via context menu (so it's launched by Explorer) it works fine (which is expected), but the funny thing is that afterwards double-clicking the EXE in TC might work as well! It does for me as long as the first process is still running, but it might work only once or twice, depending on the program used and if the DLL has already been unloaded - DLLs are shared among several processes after all. At least that's true for my tests with DOSBox (depends on SDL.dll and SDL_net.dll) and OpenSSL (depends on ssleay32.dll).

My guess is that it doesn't work properly because semicolon is a separator for the PATH environment variable.

Regards
Dalai
#101164 Personal licence
Ryzen 5 2600, 16 GiB RAM, ASUS Prime X370-A, Win7 x64

Plugins: Services2, Startups, CertificateInfo, SignatureInfo, LineBreakInfo - Download-Mirror
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48005
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Cannot launch program from folder named with semicolon

Post by *ghisler(Author) »

Strange, I don't have this problem with Windows 10, I tried with various programs including VLC, WinRAR and PFE (Editor). So it's probably a bug in Windows 7?
Author of Total Commander
https://www.ghisler.com
MarekKnapek
Junior Member
Junior Member
Posts: 7
Joined: 2019-09-07, 06:08 UTC

Re: Cannot launch program from folder named with semicolon

Post by *MarekKnapek »

Sorry, I didn't mention this. It works correctly on Windows 10 and buggy on Windows 7.
User avatar
DrShark
Power Member
Power Member
Posts: 1872
Joined: 2006-11-03, 22:26 UTC
Location: Kyiv, 68/262
Contact:

Re: Cannot launch program from folder named with semicolon

Post by *DrShark »

I can confirm the issue on Vista 32-bit, it is still not fixed as of TC 9.50 beta 5.
MarekKnapek wrote: 2019-09-07, 07:26 UTCFix should be easy: Change current working directory before launching any executable.
At least on OS where 8.3 names are enabled, and a folder with semicolon has 8.3 alias, TC could pass this alias as working directory. It should work in most cases because by default Windows replaces ; in long name with _ in 8.3 name.
Edit: the path to exe should also be passed using 8.3 names, otherwise an exe still will show error about missing dll, e.g. for in a button:

Code: Select all

TOTALCMD#BAR#DATA
"c:\totalcmd\test\; semicolon dir test\vlc.exe"

c:\totalcmd\test\; semicolon dir test\vlc.exe
vlc
"c:\totalcmd\test\_semic~1\"

-1
in the Command: fiel the path should also be replaced to "c:\totalcmd\test\_semic~1\vlc.exe" to make an app start without errors.
Donate for Ukraine to help stop Russian invasion!
Ukraine's National Bank special bank account:
UA843000010000000047330992708
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48005
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: Cannot launch program from folder named with semicolon

Post by *ghisler(Author) »

Currently it's not planned to change this, sorry. Too much work for too little gain.
Author of Total Commander
https://www.ghisler.com
Post Reply