From a6791b3bc71156fa02d93cf519c7f169893f1b1b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 3 Feb 2015 15:14:57 +0000 Subject: [PATCH] * 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. --- winsup/utils/ChangeLog | 12 ++++++++ winsup/utils/regtool.cc | 66 ++++++++++++++++++++++++----------------- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index a0dc739c8..a86aa55e9 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,15 @@ +2015-02-03 Corinna Vinschen + + * 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 * setfacl.c (action_t): Add DeleteDef value. diff --git a/winsup/utils/regtool.cc b/winsup/utils/regtool.cc index 86f2bb61f..c24ec3cef 100644 --- a/winsup/utils/regtool.cc +++ b/winsup/utils/regtool.cc @@ -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, --key-separator[=] set key-value separator to 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;