[cmd] add -g option to disable the commandline hogger (rufus.com)

* This can be useful when launching Rufus from the commandline or a batch file with 'start /wait'
* Also fix a crash when specifying an unknown commandline option
* Also fix the commandline usage help
This commit is contained in:
Pete Batard 2015-02-22 01:14:00 +00:00
parent fe55f30277
commit 821a9df1c8
3 changed files with 88 additions and 49 deletions

View File

@ -72,6 +72,7 @@ static htab_table htab_loc = HTAB_EMPTY;
int loc_line_nr;
struct list_head locale_list = {NULL, NULL};
char *loc_filename = NULL, *embedded_loc_filename = "embedded.loc";
static BOOL localization_initialized = FALSE;
/* Message table */
char* default_msg_table[MSG_MAX-MSG_000] = {"%s", 0};
@ -188,9 +189,12 @@ void _init_localization(BOOL reinit) {
if (!reinit)
list_init(&locale_list);
htab_create(LOC_HTAB_SIZE, &htab_loc);
localization_initialized = TRUE;
}
void _exit_localization(BOOL reinit) {
if (!localization_initialized)
return;
if (!reinit) {
free_locale_list();
if (loc_filename != embedded_loc_filename)

View File

@ -90,6 +90,7 @@ PF_DECL(ImageList_ReplaceIcon);
PF_TYPE_DECL(WINAPI, BOOL, SHChangeNotifyDeregister, (ULONG));
PF_TYPE_DECL(WINAPI, ULONG, SHChangeNotifyRegister, (HWND, int, LONG, UINT, int, const MY_SHChangeNotifyEntry*));
const char* cmdline_hogger = "rufus.com";
const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT", "ReFS" };
// Number of steps for each FS for FCC_STRUCTURE_PROGRESS
const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 };
@ -2407,16 +2408,65 @@ static void PrintUsage(char* appname)
char fname[_MAX_FNAME];
_splitpath(appname, NULL, NULL, fname, NULL);
printf("\nUsage: %s [-h] [-i PATH] [-w TIMEOUT]\n", fname);
printf("\nUsage: %s [-f] [-g] [-h] [-i PATH] [-l LOCALE] [-w TIMEOUT]\n", fname);
printf(" -f, --fixed\n");
printf(" Enable the listing of fixed/HDD USB drives\n");
printf(" -g, --gui\n");
printf(" Start in GUI mode (disable the 'rufus.com' commandline hogger)\n");
printf(" -i PATH, --iso=PATH\n");
printf(" Select the ISO image pointed by PATH to be used on startup\n");
printf(" -l LOCALE, --locale=LOCALE\n");
printf(" Select the locale to be used on startup\n");
printf(" -w TIMEOUT, --wait=TIMEOUT\n");
printf(" Wait TIMEOUT tens of a second for the global application mutex to be released.\n");
printf(" Wait TIMEOUT tens of seconds for the global application mutex to be released.\n");
printf(" Used when launching a newer version of " APPLICATION_NAME " from a running application.\n");
printf(" -h, --help\n");
printf(" This usage guide.\n");
}
static HANDLE SetHogger(BOOL attached_console, BOOL disable_hogger)
{
INPUT* input;
BYTE* hog_data;
DWORD hog_size, Size;
HANDLE hogmutex = NULL, hFile = NULL;
int i;
if (!attached_console)
return NULL;
hog_data = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_XT_HOGGER),
_RT_RCDATA, cmdline_hogger, &hog_size, FALSE);
if ((hog_data != NULL) && (!disable_hogger)) {
// Create our synchronisation mutex
hogmutex = CreateMutexA(NULL, TRUE, "Global/Rufus_CmdLine");
// Extract the hogger resource
hFile = CreateFileA(cmdline_hogger, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
// coverity[check_return]
WriteFile(hFile, hog_data, hog_size, &Size, NULL);
}
safe_closehandle(hFile);
// Now launch the file from the commandline, by simulating keypresses
input = (INPUT*)calloc(strlen(cmdline_hogger)+1, sizeof(INPUT));
for (i=0; i<(int)strlen(cmdline_hogger); i++) {
input[i].type = INPUT_KEYBOARD;
input[i].ki.dwFlags = KEYEVENTF_UNICODE;
input[i].ki.wScan = (wchar_t)cmdline_hogger[i];
}
input[i].type = INPUT_KEYBOARD;
input[i].ki.wVk = VK_RETURN;
SendInput(i+1, input, sizeof(INPUT));
safe_free(input);
}
if (hogmutex != NULL)
Sleep(200); // Need to add a delay, otherwise we may get some printout before the hogger
return hogmutex;
}
/*
* Application Entrypoint
*/
@ -2426,14 +2476,12 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
#endif
{
const char* old_wait_option = "/W";
const char* rufus_loc = "rufus.loc";
const char* cmdline_hogger = "rufus.com";
int i, opt, option_index = 0, argc = 0, si = 0, lcid = GetUserDefaultUILanguage();
FILE* fd;
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount;
BYTE *loc_data, *hog_data;
DWORD loc_size, hog_size, Size;
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount, disable_hogger = FALSE;
BYTE *loc_data;
DWORD loc_size, Size;
char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH], ini_flags[] = "rb";
char *tmp, *locale_name = NULL, **argv = NULL;
wchar_t **wenv, **wargv;
@ -2443,8 +2491,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
MSG msg;
int wait_for_mutex = 0;
struct option long_options[] = {
{"fixed", no_argument, NULL, 'f'},
{"gui", no_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'},
{"iso", required_argument, NULL, 'i'},
{"locale", required_argument, NULL, 'l'},
{"wait", required_argument, NULL, 'w'},
{0, 0, NULL, 0}
};
@ -2453,41 +2504,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// Reattach the console, if we were started from commandline
if (AttachConsole(ATTACH_PARENT_PROCESS) != 0) {
INPUT* input;
attached_console = TRUE;
IGNORE_RETVAL(freopen("CONIN$", "r", stdin));
IGNORE_RETVAL(freopen("CONOUT$", "w", stdout));
IGNORE_RETVAL(freopen("CONOUT$", "w", stderr));
_flushall();
hog_data = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_XT_HOGGER),
_RT_RCDATA, cmdline_hogger, &hog_size, FALSE);
if (hog_data != NULL) {
// Create our synchronisation mutex
hogmutex = CreateMutexA(NULL, TRUE, "Global/Rufus_CmdLine");
// Extract the hogger resource
hFile = CreateFileA(cmdline_hogger, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
// coverity[check_return]
WriteFile(hFile, hog_data, hog_size, &Size, NULL);
}
safe_closehandle(hFile);
// Now launch the file from the commandline, by simulating keypresses
input = (INPUT*)calloc(strlen(cmdline_hogger)+1, sizeof(INPUT));
for (i=0; i<(int)strlen(cmdline_hogger); i++) {
input[i].type = INPUT_KEYBOARD;
input[i].ki.dwFlags = KEYEVENTF_UNICODE;
input[i].ki.wScan = (wchar_t)cmdline_hogger[i];
}
input[i].type = INPUT_KEYBOARD;
input[i].ki.wVk = VK_RETURN;
SendInput(i+1, input, sizeof(INPUT));
safe_free(input);
}
}
// We have to process the arguments before we acquire the lock and process the locale
@ -2495,25 +2516,39 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
if (pf__wgetmainargs != NULL) {
pf__wgetmainargs(&argc, &wargv, &wenv, 1, &si);
argv = (char**)calloc(argc, sizeof(char*));
// Non getopt parameter check
for (i=0; i<argc; i++) {
argv[i] = wchar_to_utf8(wargv[i]);
// Check for "/W" (wait for mutex release for pre 1.3.3 versions)
if (safe_strcmp(argv[i], old_wait_option) == 0)
// Check for " /W" (wait for mutex release for pre 1.3.3 versions)
if (strcmp(argv[i], "/W") == 0)
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
// We need to find if we need to disable the hogger BEFORE we start
// processing arguments with getopt, as we may want to print messages
// on the commandline then, which the hogger makes more intuitive.
if ((strcmp(argv[i], "-g") == 0) || (strcmp(argv[i], "--gui") == 0))
disable_hogger = TRUE;
}
// If our application name contains a 'p' (for "portable") create a 'rufus.ini'
// NB: argv[0] is populated in the previous loop
tmp = &argv[0][strlen(argv[0]) -1];
while ((((uintptr_t)tmp)>((uintptr_t)argv[0])) && (*tmp != '\\'))
tmp--;
if (strchr(tmp, 'p') != NULL)
ini_flags[0] = 'a';
while ((opt = getopt_long(argc, argv, "?fhi:w:l:", long_options, &option_index)) != EOF)
// Now enable the hogger before processing the rest of the arguments
hogmutex = SetHogger(attached_console, disable_hogger);
while ((opt = getopt_long(argc, argv, "?fghi:w:l:", long_options, &option_index)) != EOF)
switch (opt) {
case 'f':
enable_HDDs = TRUE;
break;
case 'g':
// No need to reprocess that option
break;
case 'i':
if (_access(optarg, 0) != -1) {
image_path = safe_strdup(optarg);
@ -2821,7 +2856,7 @@ relaunch:
out:
// Destroy the hogger mutex first, so that the cmdline app can exit and we can delete it
if (attached_console) {
if (attached_console && !disable_hogger) {
ReleaseMutex(hogmutex);
safe_closehandle(hogmutex);
}

View File

@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.0.629"
CAPTION "Rufus 2.0.630"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -157,7 +157,7 @@ END
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.0.629"
CAPTION "Rufus 2.0.630"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -283,7 +283,7 @@ END
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 2.0.629"
CAPTION "Rufus 2.0.630"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -415,7 +415,7 @@ END
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 2.0.629"
CAPTION "Rufus 2.0.630"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -671,8 +671,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,0,629,0
PRODUCTVERSION 2,0,629,0
FILEVERSION 2,0,630,0
PRODUCTVERSION 2,0,630,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -689,13 +689,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "2.0.629"
VALUE "FileVersion", "2.0.630"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "2.0.629"
VALUE "ProductVersion", "2.0.630"
END
END
BLOCK "VarFileInfo"