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 | 97 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/programs/reg/add.c b/programs/reg/add.c index 269fa30e5e1..f3998554980 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: + { + LPWSTR 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..dbe5fc4fa88 100644 --- a/programs/reg/tests/add.c +++ b/programs/reg/tests/add.c @@ -764,6 +764,102 @@ static void test_reg_dword_big_endian(void) delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); }
+static void test_reg_qword(void) +{ + DWORD r, type, size; + UINT64 qword; + HKEY hkey; + LONG err; + + 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; + if (r == REG_EXIT_SUCCESS) + verify_reg(hkey, "", REG_QWORD, &qword, sizeof(qword), 0); + else + win_skip("broken reg.exe detected\n"); + + 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); + + 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); + + 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); + size = sizeof(qword); + err = RegQueryValueExA(hkey, "qword6", NULL, &type, (BYTE *)&qword, &size); + ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %ld\n", err); + ok(type == REG_QWORD, "got wrong type %ld, expected %d\n", type, REG_DWORD); + ok(size == sizeof(qword), "got wrong size %ld, expected %d\n", size, (int)sizeof(DWORD)); + ok(qword == 123, "got wrong data %I64d, expected 123\n", qword); + + 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); + + 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 +1084,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 */