Installer is sometimes unable to find running TC instances

Bug reports will be moved here when the described bug has been fixed

Moderators: white, Hacker, petermad, Stefan2

Post Reply
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Installer is sometimes unable to find running TC instances

Post by *MarcinW »

There are some scenarios, in which TC installer is unable to find running TC instances.

Steps to reproduce (1):
1) Launch TC installer and install TC to "c:\Total Commander" (exactly to this path!)
2) Launch cmd.exe and execute: c:\totalc~1\totalcmd.exe (most probably, short name for "Total Commander" folder will be "totalc~1"; you may try also with "totalc~2" in case of failure)
3) Launch TC installer and install TC to "c:\Total Commander" - installer will not be able to find the running TC instance, so it will fail when overwriting files

Steps to reproduce (2):
1) Launch TC installer and install TC to "c:\Total Commander" (exactly to this path!)
2) Launch cmd.exe and execute: "c:\Total Commander\totalcmd.exe" (with double quotes!)
3) Launch TC installer and install TC to c:\totalc~1 - installer will not be able to find the running TC instance, so it will fail when overwriting files


Solution: It seems that calling GetLongPathName API for both paths being compared (i.e. for the installation path and for the running executable path) should help.


Additional improvement, to make the algorithm even more robust: The current algorithm in the installer, when obtaining an executable path from a process ID, is:

1) call OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, .. ,ProcessID)
2) if failed then exit
3) try with GetModuleFileNameExA
4) if failed then try with QueryFullProcessImageNameA

Calling OpenProcess for GetModuleFileNameExA requires more access rights than calling OpenProcess for QueryFullProcessImageNameA. So a better algorithm would be:

1) call OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, .. ,ProcessID)
1b) if failed then OpenProcess(PROCESS_QUERY_INFORMATION, .. ,ProcessID)
1c) if failed then OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, .. ,ProcessID)

2) if failed then exit
3) try with GetModuleFileNameExA
4) if failed then try with QueryFullProcessImageNameA

For a process handle opened with PROCESS_QUERY_INFORMATION or with PROCESS_QUERY_LIMITED_INFORMATION, GetModuleFileNameExA call will always fail, but QueryFullProcessImageNameA should succeed.


Regards
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48021
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Currently the installer does not handle short names. But you will get an error when overwrite fails, so you can close the program manually.
Author of Total Commander
https://www.ghisler.com
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

Ok, my examples were a bit artificial...

But I had similar problems sometimes, even without using short names (at least intentionally). I was not able to reproduce the problem, but I suppose that it might be due to the code that I described above.

Please consider improving it - adding two OpenProcess calls and two GetLongPathName calls should be a two-minute work.

Regards
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48021
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

I prefer not to use GetLongPathName, because it will access the file system and go through all parts of the path. TC checks all running process locations, and it could cause a lot of problems and slow speed.
Author of Total Commander
https://www.ghisler.com
siealex
Senior Member
Senior Member
Posts: 278
Joined: 2009-03-22, 16:36 UTC

Post by *siealex »

Or add a prompt to close TC manually (instead of an error message) if the installer cannot overwrite TC files.
We are not so S.M.A.R.T. as we imagine...
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

Well, it's not so bad...

TC installer enumerates all top-level windows on the desktop - but only for those windows, that have class names and titles like TC, installer performs further actions - i.e. checks for the window executable's path.

So, in practice, this gives one GetLongPathName call per every running TC instance, plus one initial call for the installer's destination path, that has been entered by the user. In practice - ein Augenblick ;)
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48021
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

OK, I have added it now for test purposes to beta 2. If anyone encounters a problem with the installer now, please let me know!
Author of Total Commander
https://www.ghisler.com
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

Original problem solved - thanks!

But... I found, that in a 64-bit installer (not 32-bit or 32/64-bit), there is a missing call to QueryFullProcessImageNameA. There should be a call to GetModuleFileNameExA, and - if failed - to QueryFullProcessImageNameA, like in a 32-bit installer.

Regards
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48021
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

I'm only calling QueryFullProcessImageNameA in 32-bit. Why? GetModuleFileNameExA does not work for 64-bit modules accessed from a 32-bit program. However, the reverse works: A 64-bit program can actually see the name of a 32-bit process with GetModuleFileNameExA.

Why should the 64-bit installer call QueryFullProcessImageNameA? Is there a specific case where this is needed?
Author of Total Commander
https://www.ghisler.com
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

There is one case, where QueryFullProcessImageNameA may be helpful - if OpenProcess failed with PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, but then succeeded with PROCESS_QUERY_INFORMATION or with PROCESS_QUERY_LIMITED_INFORMATION.

GetModuleFileNameExA will fail in the latter two cases, but QueryFullProcessImageNameA will do the work.

Regards
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48021
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

In which case would it fail with PROCESS_QUERY_INFORMATION + PROCESS_VM_READ? The installer is always run elevated.
Author of Total Commander
https://www.ghisler.com
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

Well, to be honest - I don't know... But there is a trend towards decreasing privileges as low as possible.

Since Vista, PROCESS_QUERY_LIMITED_INFORMATION has been introduced, since even PROCESS_QUERY_INFORMATION may be denied for some operations, under some circumstances...
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48021
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

OK, I have added this call to beta 3 64-bit now...
Author of Total Commander
https://www.ghisler.com
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

I can confirm that the installer does now everything that can be done :)

Fully fixed.
Post Reply