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:
		
							parent
							
								
									70d2784165
								
							
						
					
					
						commit
						ae08fe3ac2
					
				
					 11 changed files with 263 additions and 45 deletions
				
			
		
							
								
								
									
										85
									
								
								res/hogger/hogger.asm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								res/hogger/hogger.asm
									
										
									
									
									
										Normal 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
									
								
							
							
						
						
									
										40
									
								
								res/hogger/hogger.c
									
										
									
									
									
										Normal 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
									
								
							
							
						
						
									
										
											BIN
										
									
								
								res/hogger/hogger.exe
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										69
									
								
								res/hogger/readme.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								res/hogger/readme.txt
									
										
									
									
									
										Normal 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/ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue