https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d9daaed32569901d53e78390f8b595468670eb51

commit d9daaed32569901d53e78390f8b595468670eb51
Author:     William Kent <[email protected]>
AuthorDate: Mon Aug 19 18:29:58 2019 -0400
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Tue Aug 20 00:29:58 2019 +0200

    Add support for save and restore reg.exe subcommands (#1565)
    
    * [REG] Add save and restore help strings
    * [REG] Implement REG SAVE
    * [REG] Assert the BACKUP privilege
    With this change applied, reg.exe correctly saves a key on Windows 10.
    * [REG] Use RegSaveKeyEx()
    * [REG] Implement REG RESTORE
    * [REG] Close the process token
    * [REG] Remove duplicate string
    * [REG] Add missing comma
    * [REG] Copy new strings into translation files
    * [REG] Update STRING_USAGE translations
    "Should be submitted to wine" (tm)
---
 base/applications/cmdutils/reg/lang/bg-BG.rc |   4 +-
 base/applications/cmdutils/reg/lang/cs-CZ.rc |   4 +-
 base/applications/cmdutils/reg/lang/da-DK.rc |   4 +-
 base/applications/cmdutils/reg/lang/de-DE.rc |   4 +-
 base/applications/cmdutils/reg/lang/en-US.rc |   4 +-
 base/applications/cmdutils/reg/lang/es-ES.rc |   4 +-
 base/applications/cmdutils/reg/lang/fr-FR.rc |   4 +-
 base/applications/cmdutils/reg/lang/it-IT.rc |   4 +-
 base/applications/cmdutils/reg/lang/ja-JP.rc |   4 +-
 base/applications/cmdutils/reg/lang/ko-KR.rc |   4 +-
 base/applications/cmdutils/reg/lang/lt-LT.rc |   4 +-
 base/applications/cmdutils/reg/lang/nl-NL.rc |   4 +-
 base/applications/cmdutils/reg/lang/no-NO.rc |   4 +-
 base/applications/cmdutils/reg/lang/pl-PL.rc |   4 +-
 base/applications/cmdutils/reg/lang/pt-PT.rc |   4 +-
 base/applications/cmdutils/reg/lang/ro-RO.rc |   4 +-
 base/applications/cmdutils/reg/lang/ru-RU.rc |   4 +-
 base/applications/cmdutils/reg/lang/sl-SI.rc |   4 +-
 base/applications/cmdutils/reg/lang/sq-AL.rc |   4 +-
 base/applications/cmdutils/reg/lang/sv-SE.rc |   4 +-
 base/applications/cmdutils/reg/lang/tr-TR.rc |   4 +-
 base/applications/cmdutils/reg/lang/uk-UA.rc |   4 +-
 base/applications/cmdutils/reg/lang/zh-CN.rc |   4 +-
 base/applications/cmdutils/reg/lang/zh-TW.rc |   4 +-
 base/applications/cmdutils/reg/reg.c         | 164 +++++++++++++++++++++++++++
 base/applications/cmdutils/reg/resource.h    |   2 +
 26 files changed, 238 insertions(+), 24 deletions(-)

diff --git a/base/applications/cmdutils/reg/lang/bg-BG.rc 
b/base/applications/cmdutils/reg/lang/bg-BG.rc
index 51303d004cb..0ea098c3a44 100644
--- a/base/applications/cmdutils/reg/lang/bg-BG.rc
+++ b/base/applications/cmdutils/reg/lang/bg-BG.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD ключ_име [/v стойност_име | /ve] [/t вид] [/s 
разделител] [/d данни] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE ключ_име [/v стойност_име | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY ключ_име [/v стойност_име | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/cs-CZ.rc 
b/base/applications/cmdutils/reg/lang/cs-CZ.rc
index 3b5e7a17548..e4413cbce02 100644
--- a/base/applications/cmdutils/reg/lang/cs-CZ.rc
+++ b/base/applications/cmdutils/reg/lang/cs-CZ.rc
@@ -7,7 +7,7 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD název_klíče [/v název_hodnoty | /ve] [/t type] 
[/s oddělovač] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE název_klíče [/v název_hodnoty | /ve | 
/va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY název_klíče [/v název_hodnoty | /ve] [/s]\n"
@@ -45,4 +45,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/da-DK.rc 
b/base/applications/cmdutils/reg/lang/da-DK.rc
index b4c34686842..a7bf9e9361a 100644
--- a/base/applications/cmdutils/reg/lang/da-DK.rc
+++ b/base/applications/cmdutils/reg/lang/da-DK.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nøgle_navn [/v værdi | /ve] [/t type] [/s 
separator] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nøgle_navn [/v værdi | /ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nøgle_navn [/v værdi | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/de-DE.rc 
b/base/applications/cmdutils/reg/lang/de-DE.rc
index 927e7ba48c8..dba7ed54791 100644
--- a/base/applications/cmdutils/reg/lang/de-DE.rc
+++ b/base/applications/cmdutils/reg/lang/de-DE.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD Schlüssel [/v Wert | /ve] [/t Typ] [/s Trenner] 
[/d Daten] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE Schlüssel [/v Wert | /ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY Schlüssel [/v Wert | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/en-US.rc 
b/base/applications/cmdutils/reg/lang/en-US.rc
index 26ce1697f08..65c37f1a803 100644
--- a/base/applications/cmdutils/reg/lang/en-US.rc
+++ b/base/applications/cmdutils/reg/lang/en-US.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD key_name [/v value_name | /ve] [/t type] [/s 
separator] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE key_name [/v value_name | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY key_name [/v value_name | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/es-ES.rc 
b/base/applications/cmdutils/reg/lang/es-ES.rc
index ad2b984e411..5e6d9ed4cd5 100644
--- a/base/applications/cmdutils/reg/lang/es-ES.rc
+++ b/base/applications/cmdutils/reg/lang/es-ES.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nombre_clave [/v nombre_valor | /ve] [/t tipo] 
[/s separador] [/d datos] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nombre_clave [/v nombre_valor | /ve | 
/va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nombre_clave [/v nombre_valor | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/fr-FR.rc 
b/base/applications/cmdutils/reg/lang/fr-FR.rc
index 757169f1636..0419d350e80 100644
--- a/base/applications/cmdutils/reg/lang/fr-FR.rc
+++ b/base/applications/cmdutils/reg/lang/fr-FR.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nom_de_clé [/v nom_de_valeur | /ve] [/t type] 
[/s séparateur] [/d données] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nom_de_clé [/v nom_de_valeur | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nom_de_clé [/v nom_de_valeur | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/it-IT.rc 
b/base/applications/cmdutils/reg/lang/it-IT.rc
index ed268d36989..84417873ed1 100644
--- a/base/applications/cmdutils/reg/lang/it-IT.rc
+++ b/base/applications/cmdutils/reg/lang/it-IT.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nome_della_chiave [/v nome_del_valore | /ve] 
[/t tipo] [/s separatore] [/d dati] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nome_della_chiave [/v nome_del_valore | 
/ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nome_della_chiave [/v nome_del_valore | 
/ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/ja-JP.rc 
b/base/applications/cmdutils/reg/lang/ja-JP.rc
index 3dc044cf0d2..cbaeb46f7fd 100644
--- a/base/applications/cmdutils/reg/lang/ja-JP.rc
+++ b/base/applications/cmdutils/reg/lang/ja-JP.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD キー名 [/v 値名 | /ve] [/t type] [/s セパレータ] [/d データ] 
[/f]\n"
     STRING_DELETE_USAGE, "REG DELETE キー名 [/v 値名 | /ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY キー名 [/v 値名 | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/ko-KR.rc 
b/base/applications/cmdutils/reg/lang/ko-KR.rc
index 552a031c9ce..1ba6c381f31 100644
--- a/base/applications/cmdutils/reg/lang/ko-KR.rc
+++ b/base/applications/cmdutils/reg/lang/ko-KR.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD 값 [/v 값 | /ve] [/t 형식] [/s 분리기호] [/d 데이타] 
[/f]\n"
     STRING_DELETE_USAGE, "REG DELETE 키 이름 [/v 값 | /ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY 키 이름 [/v 값| /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/lt-LT.rc 
b/base/applications/cmdutils/reg/lang/lt-LT.rc
index 70f2786b67b..48e96d23c97 100644
--- a/base/applications/cmdutils/reg/lang/lt-LT.rc
+++ b/base/applications/cmdutils/reg/lang/lt-LT.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD rakto_vardas [/v reikšmės_vardas | /ve] [/t 
tipas] [/s skirtukas] [/d duomenys] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE rakto_vardas [/v reikšmės_vardas | /ve | 
/va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY rakto_vardas [/v reikšmės_vardas | /ve] 
[/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/nl-NL.rc 
b/base/applications/cmdutils/reg/lang/nl-NL.rc
index a24806ef3ec..1cf44949866 100644
--- a/base/applications/cmdutils/reg/lang/nl-NL.rc
+++ b/base/applications/cmdutils/reg/lang/nl-NL.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD sleutel_naam [/v waarde_naam | /ve] [/t type] 
[/s scheidingsteken] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE sleutel_naam [/v waarde_naam | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY sleutel_naam [/v waarde_naam | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/no-NO.rc 
b/base/applications/cmdutils/reg/lang/no-NO.rc
index cfef4d43233..2046fad5278 100644
--- a/base/applications/cmdutils/reg/lang/no-NO.rc
+++ b/base/applications/cmdutils/reg/lang/no-NO.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nøkkelnavn [/v verdi | /ve] [/t type] [/s 
separator] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nøkkelnavn [/v verdi | /ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nøkkelnavn [/v verdi | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/pl-PL.rc 
b/base/applications/cmdutils/reg/lang/pl-PL.rc
index 3f587fc57c6..c8d9768df0b 100644
--- a/base/applications/cmdutils/reg/lang/pl-PL.rc
+++ b/base/applications/cmdutils/reg/lang/pl-PL.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Sposób użycia:\n  REG [operacja] [parametry]\n\nWspierane 
operacje:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nAby uzyskać pomoc 
dotyczącą określonej operacji, wpisz:\n  REG [operacja] /?\n\n"
+    STRING_USAGE, "Sposób użycia:\n  REG [operacja] [parametry]\n\nWspierane 
operacje:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nAby 
uzyskać pomoc dotyczącą określonej operacji, wpisz:\n  REG [operacja] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nazwa_klucza [/v nazwa_wartości | /ve] [/t typ] 
[/s separator] [/d dane] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nazwa_klucza [/v nazwa_wartości | /ve | 
/va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nazwa_klucza [/v nazwa_wartości | /ve] 
[/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT nazwa_klucza plik.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Nieprawidłowy klucz systemowy [%1]\n"
     STRING_OVERWRITE_FILE, "Plik '%1' już istnieje. Czy chcesz go zastąpić?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/pt-PT.rc 
b/base/applications/cmdutils/reg/lang/pt-PT.rc
index 5e3d477e334..58e8752324e 100644
--- a/base/applications/cmdutils/reg/lang/pt-PT.rc
+++ b/base/applications/cmdutils/reg/lang/pt-PT.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nome_chave [/v nome_valor | /ve] [/t tipo] [/s 
separador] [/d dados] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nome_chave [/v nome_valor | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nome_chave [/v nome_valor | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/ro-RO.rc 
b/base/applications/cmdutils/reg/lang/ro-RO.rc
index d2405ab2ea5..3ee1f903895 100644
--- a/base/applications/cmdutils/reg/lang/ro-RO.rc
+++ b/base/applications/cmdutils/reg/lang/ro-RO.rc
@@ -8,7 +8,7 @@ LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Sintaxa comenzii:\n  REG [operație] [parametri]\n\nOperații 
disponibile:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nPentru informații 
despre o anume operație, tastați:\n  REG [operație] /?\n\n"
+    STRING_USAGE, "Sintaxa comenzii:\n  REG [operație] [parametri]\n\nOperații 
disponibile:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | 
RESTORE\n\nPentru informații despre o anume operație, tastați:\n  REG 
[operație] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nume_cheie [/v nume_valoare | /ve] [/t tip] [/s 
separator] [/d date] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nume_cheie [/v nume_valoare | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nume_cheie [/v nume_valoare | /ve] [/s]\n"
@@ -46,4 +46,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT nume_cheie fișier.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Cheia de sistem [%1] nu este una 
validă.\n"
     STRING_OVERWRITE_FILE, "Fișierul «%1» deja există. Doriți suprascrierea 
lui?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/ru-RU.rc 
b/base/applications/cmdutils/reg/lang/ru-RU.rc
index e75ad5c0a79..757926b9b68 100644
--- a/base/applications/cmdutils/reg/lang/ru-RU.rc
+++ b/base/applications/cmdutils/reg/lang/ru-RU.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD <имя_раздела> [/v <имя_параметра> | /ve] [/t 
<тип>] [/s <разделитель>] [/d <данные>] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE <имя_раздела> [/v <имя_параметра> | /ve | 
/va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY <имя_раздела> [/v [имя_параметра] | /ve] 
[/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/sl-SI.rc 
b/base/applications/cmdutils/reg/lang/sl-SI.rc
index 134a398ec04..d0f4b37e82c 100644
--- a/base/applications/cmdutils/reg/lang/sl-SI.rc
+++ b/base/applications/cmdutils/reg/lang/sl-SI.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD ime_ključa [/v ime_vrednosti | /ve] [/t vrsta] 
[/s ločilo] [/d podatki] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE ime_ključa [/v ime_vrednosti | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY ime_ključa [/v ime_vrednosti | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/sq-AL.rc 
b/base/applications/cmdutils/reg/lang/sq-AL.rc
index ed63303e4cd..a94677b8c6c 100644
--- a/base/applications/cmdutils/reg/lang/sq-AL.rc
+++ b/base/applications/cmdutils/reg/lang/sq-AL.rc
@@ -6,7 +6,7 @@ LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD emri_çelsit [/v value_name | /ve] [/t tipi] [/s 
ndares] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE emri_çelsit [/v value_name | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY emri_çelsit [/v value_name | /ve] [/s]\n"
@@ -44,4 +44,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/sv-SE.rc 
b/base/applications/cmdutils/reg/lang/sv-SE.rc
index 70b59a2775f..c015bd9d6f9 100644
--- a/base/applications/cmdutils/reg/lang/sv-SE.rc
+++ b/base/applications/cmdutils/reg/lang/sv-SE.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD nyckelnamn [/v värdenamn | /ve] [/t typ] [/s 
separator] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE nyckelnamn [/v värdenamn | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY nyckelnamn [/v värdenamn | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/tr-TR.rc 
b/base/applications/cmdutils/reg/lang/tr-TR.rc
index 742923183b2..47abfc54bf8 100644
--- a/base/applications/cmdutils/reg/lang/tr-TR.rc
+++ b/base/applications/cmdutils/reg/lang/tr-TR.rc
@@ -4,7 +4,7 @@ LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD dizin adı [/v değer adı | /ve] [/t tür] [/s 
ayırıcı] [/d veri] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE dizin adı [/v değer adı | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY dizin adı [/v değer adı | /ve] [/s]\n"
@@ -42,4 +42,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/uk-UA.rc 
b/base/applications/cmdutils/reg/lang/uk-UA.rc
index a2c2b6a3736..f2fff4f5e67 100644
--- a/base/applications/cmdutils/reg/lang/uk-UA.rc
+++ b/base/applications/cmdutils/reg/lang/uk-UA.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD <ключ> [/v <параметр> | /ve] [/t <тип>] [/s 
<розділювач>] [/d дані] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE <ключ> [/v <параметр> | /ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY <ключ> [/v <параметр> | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/zh-CN.rc 
b/base/applications/cmdutils/reg/lang/zh-CN.rc
index 4c65c03424f..08f92516977 100644
--- a/base/applications/cmdutils/reg/lang/zh-CN.rc
+++ b/base/applications/cmdutils/reg/lang/zh-CN.rc
@@ -2,7 +2,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD key_name [/v value_name | /ve] [/t type] [/s 
separator] [/d data] [/f]\n"
     STRING_DELETE_USAGE, "REG DELETE key_name [/v value_name | /ve | /va] 
[/f]\n"
     STRING_QUERY_USAGE, "REG QUERY key_name [/v value_name | /ve] [/s]\n"
@@ -40,4 +40,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: 无效的系统键 [%1]\n"
     STRING_OVERWRITE_FILE, "文件 '%1' 已经存在。您是否要覆盖它?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/lang/zh-TW.rc 
b/base/applications/cmdutils/reg/lang/zh-TW.rc
index 1dbd4d0f349..7771b9ea401 100644
--- a/base/applications/cmdutils/reg/lang/zh-TW.rc
+++ b/base/applications/cmdutils/reg/lang/zh-TW.rc
@@ -4,7 +4,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
 
 STRINGTABLE
 {
-    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY\n\nFor help on a specific 
operation, type:\n  REG [operation] /?\n\n"
+    STRING_USAGE, "Usage:\n  REG [operation] [parameters]\n\nSupported 
operations:\n  ADD | DELETE | IMPORT | EXPORT | QUERY | SAVE | RESTORE\n\nFor 
help on a specific operation, type:\n  REG [operation] /?\n\n"
     STRING_ADD_USAGE, "REG ADD 金鑰名稱 [/v 值名稱 | /ve] [/t 類型] [/s 分隔符] [/d 資料] 
[/f]\n"
     STRING_DELETE_USAGE, "REG DELETE 金鑰名稱 [/v 值名稱 | /ve | /va] [/f]\n"
     STRING_QUERY_USAGE, "REG QUERY 金鑰名稱 [/v 值名稱 | /ve] [/s]\n"
@@ -42,4 +42,6 @@ STRINGTABLE
     STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
     STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
     STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to 
overwrite it?"
+    STRING_SAVE_USAGE, "REG SAVE key_name file_name [/y]"
+    STRING_RESTORE_USAGE, "REG RESTORE key_name file_name"
 }
diff --git a/base/applications/cmdutils/reg/reg.c 
b/base/applications/cmdutils/reg/reg.c
index 455d3dd96a4..5e65aee269b 100644
--- a/base/applications/cmdutils/reg/reg.c
+++ b/base/applications/cmdutils/reg/reg.c
@@ -144,6 +144,23 @@ static void output_formatstring(const WCHAR *fmt, 
__ms_va_list va_args)
     LocalFree(str);
 }
 
+static void output_error(LSTATUS status)
+{
+    WCHAR* str;
+    DWORD len;
+
+    SetLastError(NO_ERROR);
+    len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | 
FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, status, 0, (WCHAR*)&str, 0, NULL);
+    if (len == 0 && GetLastError() != NO_ERROR)
+    {
+        WINE_FIXME("Could not format error code: le=%u, error=%u", 
GetLastError(), status);
+        return;
+    }
+
+    output_writeconsole(str, len);
+    LocalFree(str);
+}
+
 void WINAPIV output_message(unsigned int id, ...)
 {
     WCHAR fmt[1024];
@@ -892,6 +909,141 @@ static BOOL is_switch(const WCHAR *s, const WCHAR c)
     return FALSE;
 }
 
+static BOOL set_privilege(LPCWSTR privilegeName, BOOL enabled)
+{
+    HANDLE hToken = INVALID_HANDLE_VALUE;
+    TOKEN_PRIVILEGES tp;
+    DWORD error = ERROR_SUCCESS;
+
+    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, 
&hToken))
+    {
+        tp.PrivilegeCount = 1;
+        tp.Privileges[0].Attributes = (enabled ? SE_PRIVILEGE_ENABLED : 0);
+
+        if (LookupPrivilegeValueW(NULL, privilegeName, &tp.Privileges[0].Luid))
+        {
+            if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
+            {
+                if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
+                {
+                    error = ERROR_NOT_ALL_ASSIGNED;
+                    goto fail;
+                }
+            }
+            else
+            {
+                error = GetLastError();
+                goto fail;
+            }
+        }
+        else
+        {
+            error = GetLastError();
+            goto fail;
+        }
+    }
+    else
+    {
+        error = GetLastError();
+        goto fail;
+    }
+
+    CloseHandle(hToken);
+    return TRUE;
+
+fail:
+    // Don't allow a success error to be printed, as that would confuse the 
user.
+    // "Access denied" seems like a reasonable default.
+    if (error == ERROR_SUCCESS) error = ERROR_ACCESS_DENIED;
+    if (hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);
+
+    output_error(error);
+    return FALSE;
+}
+
+static int reg_save(int argc, WCHAR* argv[]) {
+    HKEY root, hkey;
+    LSTATUS status;
+    WCHAR* path, *long_key;
+
+    if (argc < 4 || argc > 5) goto error;
+
+    if (!parse_registry_key(argv[2], &root, &path, &long_key))
+        return 1;
+
+    if (GetFileAttributes(argv[3]) != INVALID_FILE_ATTRIBUTES)
+    {
+        if (argc == 5 && !strcmpiW(argv[4], L"/y"))
+        {
+            DeleteFile(argv[3]);
+        }
+        else
+        {
+            if (ask_confirm(STRING_OVERWRITE_FILE, argv[3]))
+                DeleteFile(argv[3]);
+        }
+    }
+
+    if (RegOpenKeyExW(root, path, 0, KEY_READ, &hkey))
+    {
+        output_message(STRING_INVALID_KEY);
+        return 1;
+    }
+
+    if (!set_privilege(SE_BACKUP_NAME, TRUE)) return 1; 
+
+    status = RegSaveKeyExW(hkey, argv[3], NULL, REG_LATEST_FORMAT);
+    RegCloseKey(hkey);
+
+    if (status != ERROR_SUCCESS) {
+        output_error(status);
+        return 1;
+    }
+
+    return 0;
+
+error:
+    output_message(STRING_INVALID_SYNTAX);
+    output_message(STRING_FUNC_HELP, struprW(argv[1]));
+    return 1;
+}
+
+static int reg_restore(int argc, WCHAR* argv[])
+{
+    HKEY root, hkey;
+    LSTATUS status;
+    WCHAR* path, * long_key;
+
+    if (argc != 4) goto error;
+
+    if (!parse_registry_key(argv[2], &root, &path, &long_key))
+        return 1;
+
+    if (RegOpenKeyExW(root, path, 0, KEY_READ, &hkey))
+    {
+        output_message(STRING_INVALID_KEY);
+        return 1;
+    }
+
+    if (!set_privilege(SE_BACKUP_NAME, TRUE)) return 1;
+    if (!set_privilege(SE_RESTORE_NAME, TRUE)) return 1;
+
+    status = RegRestoreKeyW(hkey, argv[3], 0);
+    RegCloseKey(hkey);
+
+    if (status != ERROR_SUCCESS) {
+        output_error(status);
+        return 1;
+    }
+
+    return 0;
+
+error:
+    output_message(STRING_INVALID_SYNTAX);
+    output_message(STRING_FUNC_HELP, struprW(argv[1]));
+    return 1;
+}
+
 static BOOL is_help_switch(const WCHAR *s)
 {
     if (is_switch(s, '?') || is_switch(s, 'h'))
@@ -906,6 +1058,8 @@ enum operations {
     REG_IMPORT,
     REG_EXPORT,
     REG_QUERY,
+    REG_SAVE,
+    REG_RESTORE,
     REG_INVALID
 };
 
@@ -918,6 +1072,8 @@ static enum operations get_operation(const WCHAR *str, int 
*op_help)
     static const WCHAR import[] = {'i','m','p','o','r','t',0};
     static const WCHAR export[] = {'e','x','p','o','r','t',0};
     static const WCHAR query[] = {'q','u','e','r','y',0};
+    static const WCHAR save[] = L"save";
+    static const WCHAR restore[] = L"restore";
 
     static const struct op_info op_array[] =
     {
@@ -926,6 +1082,8 @@ static enum operations get_operation(const WCHAR *str, int 
*op_help)
         { import,  REG_IMPORT,  STRING_IMPORT_USAGE },
         { export,  REG_EXPORT,  STRING_EXPORT_USAGE },
         { query,   REG_QUERY,   STRING_QUERY_USAGE },
+        { save,    REG_SAVE,    STRING_SAVE_USAGE },
+        { restore, REG_RESTORE, STRING_RESTORE_USAGE },
         { NULL,    -1,          0 }
     };
 
@@ -996,6 +1154,12 @@ int wmain(int argc, WCHAR *argvW[])
     if (op == REG_EXPORT)
         return reg_export(argc, argvW);
 
+    if (op == REG_SAVE)
+        return reg_save(argc, argvW);
+
+    if (op == REG_RESTORE)
+        return reg_restore(argc, argvW);
+
     if (!parse_registry_key(argvW[2], &root, &path, &key_name))
         return 1;
 
diff --git a/base/applications/cmdutils/reg/resource.h 
b/base/applications/cmdutils/reg/resource.h
index 3658adc1556..06848ca4eca 100644
--- a/base/applications/cmdutils/reg/resource.h
+++ b/base/applications/cmdutils/reg/resource.h
@@ -61,3 +61,5 @@
 #define STRING_EXPORT_USAGE           136
 #define STRING_INVALID_SYSTEM_KEY     137
 #define STRING_OVERWRITE_FILE         138
+#define STRING_SAVE_USAGE             139
+#define STRING_RESTORE_USAGE          140

Reply via email to