* regtool.cc (longopts): Add --force option.

(opts): Add -f option.
	(restore_flags): New variable.
	(usage): Clarify working of save action.  Add restore action.  Add
	description for -f/--force option.
	(set_privilege): Drop function.  The Cygwin DLL is doing that anyway.
	(cmd_save): Drop call to set_privilege.
	(cmd_restore): New function.
	(main): Handle -f/--force option.
This commit is contained in:
Corinna Vinschen 2015-02-03 15:14:57 +00:00
parent db9a8c9983
commit a6791b3bc7
2 changed files with 51 additions and 27 deletions

View File

@ -1,3 +1,15 @@
2015-02-03 Corinna Vinschen <corinna@vinschen.de>
* regtool.cc (longopts): Add --force option.
(opts): Add -f option.
(restore_flags): New variable.
(usage): Clarify working of save action. Add restore action. Add
description for -f/--force option.
(set_privilege): Drop function. The Cygwin DLL is doing that anyway.
(cmd_save): Drop call to set_privilege.
(cmd_restore): New function.
(main): Handle -f/--force option.
2014-12-15 Corinna Vinschen <corinna@vinschen.de>
* setfacl.c (action_t): Add DeleteDef value.

View File

@ -1,7 +1,7 @@
/* regtool.cc
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011 Red Hat Inc.
2009, 2010, 2011, 2015 Red Hat Inc.
This file is part of Cygwin.
@ -42,6 +42,7 @@ static struct option longopts[] =
{"dword", no_argument, NULL, 'd' },
{"dword-be", no_argument, NULL, 'D' },
{"expand-string", no_argument, NULL, 'e' },
{"force", no_argument, NULL, 'f' },
{"help", no_argument, NULL, 'h' },
{"integer", no_argument, NULL, 'i' },
{"keys", no_argument, NULL, 'k'},
@ -61,7 +62,7 @@ static struct option longopts[] =
{NULL, 0, NULL, 0}
};
static char opts[] = "bdDehiklmnpqQsvVwWxK:";
static char opts[] = "bdDefhiklmnpqQsvVwWxK:";
const char *types[] =
{
@ -85,6 +86,7 @@ int verbose = 0;
int quiet = 0;
int hex = 0;
DWORD wow64 = 0;
DWORD restore_flags = 0;
char **argv;
HKEY key;
@ -112,22 +114,23 @@ usage (FILE *where = stderr)
" unset KEY\\VALUE removes VALUE from KEY\n"
" load KEY\\SUBKEY PATH load hive from PATH into new SUBKEY\n"
" unload KEY\\SUBKEY unload hive and remove SUBKEY\n"
" save KEY\\SUBKEY PATH save SUBKEY into new hive PATH\n"
" save KEY\\SUBKEY PATH save SUBKEY into new file PATH\n"
" restore KEY\\SUBKEY PATH restore SUBKEY from file PATH\n"
"\n");
fprintf (where, ""
"Options for 'list' Action:\n"
"Options for 'list' action:\n"
"\n"
" -k, --keys print only KEYs\n"
" -l, --list print only VALUEs\n"
" -p, --postfix like ls -p, appends '\\' postfix to KEY names\n"
"\n"
"Options for 'get' Action:\n"
"Options for 'get' action:\n"
"\n"
" -b, --binary print data as printable hex bytes\n"
" -n, --none print data as stream of bytes as stored in registry\n"
" -x, --hex print numerical data as hex numbers\n"
"\n"
"Options for 'set' Action:\n"
"Options for 'set' action:\n"
"\n"
" -b, --binary set type to REG_BINARY (hex args or '-')\n"
" -d, --dword set type to REG_DWORD\n"
@ -143,6 +146,11 @@ usage (FILE *where = stderr)
"\n"
" -K<c>, --key-separator[=]<c> set key-value separator to <c> instead of '\\'\n"
"\n"
"Options for 'restore' action:\n"
"\n"
" -f, --force restore even if open handles exist at or beneath the location\n"
" in the registry hierarchy to which KEY\\SUBKEY points\n"
"\n"
"Other Options:\n"
"\n"
" -h, --help output usage information and exit\n"
@ -838,25 +846,6 @@ cmd_unload ()
return 0;
}
DWORD
set_privilege (const char *name)
{
TOKEN_PRIVILEGES tp;
if (!LookupPrivilegeValue (NULL, name, &tp.Privileges[0].Luid))
return GetLastError ();
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
HANDLE t;
/* OpenProcessToken does not work here, because main thread has its own
impersonation token */
if (!OpenThreadToken (GetCurrentThread (), TOKEN_ADJUST_PRIVILEGES, FALSE, &t))
return GetLastError ();
AdjustTokenPrivileges (t, FALSE, &tp, 0, NULL, NULL);
DWORD rv = GetLastError ();
CloseHandle (t);
return rv;
}
int
cmd_save ()
{
@ -865,8 +854,6 @@ cmd_save ()
usage ();
return 1;
}
/* try to set SeBackupPrivilege, let RegSaveKey report the error */
set_privilege (SE_BACKUP_NAME);
/* REG_OPTION_BACKUP_RESTORE is necessary to save /HKLM/SECURITY */
find_key (1, KEY_QUERY_VALUE, REG_OPTION_BACKUP_RESTORE);
ssize_t len = cygwin_conv_path (CCP_POSIX_TO_WIN_W, argv[1], NULL, 0);
@ -880,6 +867,27 @@ cmd_save ()
return 0;
}
int
cmd_restore ()
{
if (!argv[1])
{
usage ();
return 1;
}
/* REG_OPTION_BACKUP_RESTORE is necessary to restore /HKLM/SECURITY */
find_key (1, KEY_ALL_ACCESS, REG_OPTION_BACKUP_RESTORE);
ssize_t len = cygwin_conv_path (CCP_POSIX_TO_WIN_W, argv[1], NULL, 0);
wchar_t win32_path[len];
cygwin_conv_path (CCP_POSIX_TO_WIN_W, argv[1], win32_path, len);
DWORD rv = RegRestoreKeyW (key, win32_path, restore_flags);
if (rv != ERROR_SUCCESS)
Fail (rv);
if (verbose)
printf ("key saved to %ls\n", win32_path);
return 0;
}
static struct
{
const char *name;
@ -896,6 +904,7 @@ static struct
{"load", cmd_load},
{"unload", cmd_unload},
{"save", cmd_save},
{"restore", cmd_restore},
{0, 0}
};
@ -923,6 +932,9 @@ main (int argc, char **_argv)
case 'e':
value_type = REG_EXPAND_SZ;
break;
case 'f':
restore_flags = REG_FORCE_RESTORE;
break;
case 'k':
listwhat |= LIST_KEYS;
break;