1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[misc] fix an issue with Far Manager

* Closes #161
* Also fix a couple warnings from MinGW and VS
This commit is contained in:
Pete Batard 2014-05-27 02:02:50 +01:00
parent 70d2784165
commit ae08fe3ac2
11 changed files with 263 additions and 45 deletions

85
res/hogger/hogger.asm Normal file
View file

@ -0,0 +1,85 @@
; Rufus: The Reliable USB Formatting Utility
; Commandline hogger, assembly version (NASM)
; Copyright © 2014 Pete Batard <pete@akeo.ie>
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
global _main
extern _GetStdHandle@4
extern _OpenMutexA@12
extern _WaitForSingleObject@8
extern _WriteFile@20
extern _ExitProcess@4
section .text
_main:
; DWORD size;
mov ebp, esp
sub esp, 4
; register HANDLE mutex [-> ecx], stdout [-> ebx];
; stdout = GetStdHandle(STD_OUTPUT_HANDLE);
push -11
call _GetStdHandle@4
mov ebx, eax
; mutex = OpenMutexA(SYNCHRONIZE, FALSE, "Global/Rufus_CmdLine");
push mutex_name
push 0
push 1048576 ; 0x00100000
call _OpenMutexA@12
mov ecx, eax
; if (mutex == NULL)
test eax, eax
; goto error
je error
; WaitForSingleObject(mutex, INFINITE);
push -1
push ecx
call _WaitForSingleObject@8
; goto out;
jmp out;
; error:
error:
; WriteFile(stdout, error_msg, sizeof(error_msg), &size, 0);
push 0
lea eax, [ebp-4]
push eax
push (error_msg_end - error_msg)
push error_msg
push ebx
call _WriteFile@20
; out:
out:
; ExitProcess(0)
push 0
call _ExitProcess@4
; Just in case...
hlt
mutex_name:
db "Global/Rufus_CmdLine",0
error_msg:
db "Unable to synchronize with GUI application.",0
error_msg_end:

40
res/hogger/hogger.c Normal file
View file

@ -0,0 +1,40 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Commandline hogger, C version
* Copyright © 2014 Pete Batard <pete@akeo.ie>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
const char error_msg[] = "Unable to synchronize with UI application.";
int __cdecl main(int argc_ansi, char** argv_ansi)
{
DWORD size;
register HANDLE mutex, stdout;
stdout = GetStdHandle(STD_OUTPUT_HANDLE);
mutex = OpenMutexA(SYNCHRONIZE, FALSE, "Global/Rufus_CmdLine");
if (mutex == NULL)
goto error;
WaitForSingleObject(mutex, INFINITE);
goto out;
error:
WriteFile(stdout, error_msg, sizeof(error_msg), &size, 0);
out:
ExitProcess(0);
}

BIN
res/hogger/hogger.exe Normal file

Binary file not shown.

69
res/hogger/readme.txt Normal file
View file

@ -0,0 +1,69 @@
Rufus: The Reliable USB Formatting Utility - Commandline hogger
# Description
This little utility is intended to solve the issue of Windows applications not
being able to be BOTH console and GUI [1], leading to all kind of annoyances [2].
The basic problem is as follows:
1. You have an awesome Windows UI application that you want your users to be
able to start from the commandline (to provide parameters, etc.)
2. If an application is set to operate in UI mode, then when you launch it from
the command line, you will NOT get a command prompt freeze until it exits, as
you'd expect from any console app, but instead the prompt will return to the
user right away.
3. This means that any message that you try to output from your app to the
console will appear as ugly as:
C:\Some\Directory> Some Application Message
4. Another unfortunate effect is that, when users exit your app, they might
continue to wait for the prompt to come back, when it is already available
whilst polluted by output that looks out of place => Your user experience is
now subpar...
5. To compensate for this, you might try to be (somewhat) clever, through the
simulating an <Enter> keypress when your app exit, but lo and behold, soon
enough you start receiving complaints left and right from Far Manager [3]
users, due to the fact that this application uses the <Enter> keypress as an
"I want to launch the currently selected app" event.
6. HEY, MICROSOFT, THIS SUPER-SUCKS!!!!
# Primer
So, how far do we need to go to address this?
1. We'll create a console hogger application, that does just what you'd expect
a regular commandline app to do (hog the console prompt until the app exits)
and wait for a signal (Mutex) from the UI app to indicate that it is closed.
2. We'll embed this console hogger as a resource in our app, to be extracted
and run in the current directory whenever we detect that our UI app has
been launched from the commandline
3. Because we want this annoyance to have the least impact possible, we'll
make sure that it is AS SMALL AS POSSIBLE, by writing it in pure assembly
so that we can compile it with NASM and linking it with WDK, leaving us
with a 2 KB executable (that will further be compressed to about 1/4th of
this size through UPX/LZMA).
# Drawbacks
The one annoyance with this workaround is that our 'hogger' will appear in the
command history (doskey). This means that when when a user wants to navigate
back to the command they launched, they need to skip through an extra entry,
which they probably have no idea about. And of course, doskey does not provide
the ability to suppress this last entry.
Oh, and you also need to release the mutex so that you can delete the file
before you exit, though that's not a big deal...
# Compilation
; From a WDK command prompt
nasm -fwin32 hogger.asm
link /subsystem:console /nodefaultlib /entry:main hogger.obj %SDK_LIB_DEST%\i386\kernel32.lib
# Links
[1] http://blogs.msdn.com/b/oldnewthing/archive/2009/01/01/9259142.aspx
[2] https://github.com/pbatard/rufus/issues/161
[3] http://www.farmanager.com/