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'.