Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v2: reg: Add REG_QWORD support to 'add'.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- programs/reg/add.c | 16 +++++++ programs/reg/reg.c | 1 + programs/reg/reg.h | 2 +- programs/reg/reg.rc | 2 +- programs/reg/tests/add.c | 95 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 2 deletions(-)
diff --git a/programs/reg/add.c b/programs/reg/add.c index 269fa30e5e1..e0cd0373339 100644 --- a/programs/reg/add.c +++ b/programs/reg/add.c @@ -84,6 +84,22 @@ static BOOL get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, *(DWORD *)*data_bytes = val; break; } + case REG_QWORD: + { + WCHAR *rest; + UINT64 val; + + val = _wcstoui64(data, &rest, (towlower(data[1]) == 'x') ? 16 : 10); + if (*rest || (val == ~0ull && errno == ERANGE)) + { + output_message(STRING_MISSING_NUMBER); + return FALSE; + } + *size_bytes = sizeof(val); + *data_bytes = malloc(*size_bytes); + *(UINT64 *)*data_bytes = val; + break; + } case REG_BINARY: { BYTE hex0, hex1, *ptr; diff --git a/programs/reg/reg.c b/programs/reg/reg.c index 4fd374579e9..5753b99bdf4 100644 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -46,6 +46,7 @@ const struct reg_type_rels type_rels[] = {REG_DWORD, L"REG_DWORD"}, {REG_DWORD_LITTLE_ENDIAN, L"REG_DWORD_LITTLE_ENDIAN"}, {REG_DWORD_BIG_ENDIAN, L"REG_DWORD_BIG_ENDIAN"}, + {REG_QWORD, L"REG_QWORD"}, {REG_MULTI_SZ, L"REG_MULTI_SZ"}, };
diff --git a/programs/reg/reg.h b/programs/reg/reg.h index 67b49b7797f..4ac54dcecaf 100644 --- a/programs/reg/reg.h +++ b/programs/reg/reg.h @@ -31,7 +31,7 @@ struct reg_type_rels { const WCHAR *name; };
-extern const struct reg_type_rels type_rels[8]; +extern const struct reg_type_rels type_rels[9];
void output_writeconsole(const WCHAR *str, DWORD wlen); void WINAPIV output_message(unsigned int id, ...); diff --git a/programs/reg/reg.rc b/programs/reg/reg.rc index a3c53cf41b4..45acb993add 100644 --- a/programs/reg/reg.rc +++ b/programs/reg/reg.rc @@ -55,7 +55,7 @@ STRINGTABLE \ The type of data to add to the registry. If [/t] is specified,\n\ \ <type> must be one of the following:\n\n\ \ REG_SZ | REG_MULTI_SZ | REG_EXPAND_SZ\n\ -\ REG_DWORD | REG_BINARY | REG_NONE\n\n\ +\ REG_DWORD | REG_QWORD | REG_BINARY | REG_NONE\n\n\ \ If [/t] is not specified, the default data type is REG_SZ.\n\n\ \ /s <separator>\n\ \ The character used to separate strings in REG_MULTI_SZ data.\n\ diff --git a/programs/reg/tests/add.c b/programs/reg/tests/add.c index 0d213414443..ae9c79b07ec 100644 --- a/programs/reg/tests/add.c +++ b/programs/reg/tests/add.c @@ -764,6 +764,100 @@ static void test_reg_dword_big_endian(void) delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); }
+static void test_reg_qword(void) +{ + UINT64 qword; + HKEY hkey; + DWORD r; + + add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); + + run_reg_exe("reg add HKCU\" KEY_BASE " /t REG_QWORD /f /d 0x123456789abcdef", &r); + ok(r == REG_EXIT_SUCCESS, "Unexpected exit code %ld.\n", r); + qword = 0x123456789abcdef; + verify_reg(hkey, "", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /ve /t REG_QWORD /f", &r); + ok(r == REG_EXIT_SUCCESS, "Unexpected exit code %ld.\n", r); + qword = 0; + verify_reg(hkey, "", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword0 /t REG_QWORD /f /d", &r); + ok(r == REG_EXIT_FAILURE, "Unexpected exit code %lu.\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword1 /t REG_QWORD /f", &r); + ok(r == REG_EXIT_SUCCESS, "Unexpected exit code %ld.\n", r); + qword = 0; + verify_reg(hkey, "qword1", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword2 /t REG_QWORD /d zzz /f", &r); + ok(r == REG_EXIT_FAILURE, "Unexpected exit code %lu.\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword3 /t REG_QWORD /d deadbeef /f", &r); + ok(r == REG_EXIT_FAILURE, "Unexpected exit code %lu.\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword4 /t REG_QWORD /d 123xyz /f", &r); + ok(r == REG_EXIT_FAILURE, "Unexpected exit code %lu.\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword5 /t reg_qword /d 12345678 /f", &r); + ok(r == REG_EXIT_SUCCESS, "Unexpected exit code %ld.\n", r); + qword = 12345678; + verify_reg(hkey, "qword5", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword6 /t REG_QWORD /D 0123 /f", &r); + ok(r == REG_EXIT_SUCCESS, "Unexpected exit code %ld.\n", r); + qword = 123; + verify_reg(hkey, "qword6", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword7 /t reg_qword /d 0xabcdefg /f", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %ld, expected 1\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword8 /t REG_qword /d 0xdeadbeef /f", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %ld, expected 0\n", r); + qword = 0xdeadbeef; + verify_reg(hkey, "qword8", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /t REG_QWORD /v qword9 /f /d -1", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %ld, expected 0\n", r); + qword = ~0ull; + verify_reg(hkey, "qword9", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /t REG_QWORD /v qword10 /f /d -0x1", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %lu, expected 1\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword11 /t REG_qword /d 0x01ffffffffffffffff /f", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %ld, expected 1\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword12 /t REG_QWORD /d 0xffffffffffffffff /f", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %ld, expected 0\n", r); + qword = ~0ull; + verify_reg(hkey, "qword12", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword13 /t REG_QWORD /d 00x123 /f", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %ld, expected 1\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword14 /t REG_QWORD /d 0X123 /f", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %ld, expected 0\n", r); + qword = 0x123; + verify_reg(hkey, "qword14", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword15 /t REG_QWORD /d 18446744073709551616 /f", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %lu, expected 1\n", r); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword16 /t REG_QWORD /d 456 /f", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %ld, expected 0\n", r); + qword = 456; + verify_reg(hkey, "qword16", REG_QWORD, &qword, sizeof(qword), 0); + + run_reg_exe("reg add HKCU\" KEY_BASE " /v qword17 /t REG_QWORD /d 0x456 /f", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %ld, expected 0\n", r); + qword = 0x456; + verify_reg(hkey, "qword17", REG_QWORD, &qword, sizeof(qword), 0); + + close_key(hkey); + delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); +} + static void test_reg_multi_sz(void) { HKEY hkey; @@ -988,6 +1082,7 @@ START_TEST(add) test_reg_binary(); test_reg_dword(); test_reg_dword_big_endian(); + test_reg_qword(); test_reg_multi_sz();
/* Check if reg.exe is running with elevated privileges */
On Fri Jun 24 12:47:38 2022 +0000, Hugh McMaster wrote:
I think we all prefer `WCHAR *` for new code. You can also just use `QWORD` for `UINT64`, although the latter is probably more readable at a glance.
QWORD is not universally available afaict, it's used for some multimedia API, and some other headers redefine it as well. I pushed update addressing your comments, thank you.