diff --git a/programs/reg/import.c b/programs/reg/import.c index 654235b0561..c4879244c39 100644 --- a/programs/reg/import.c +++ b/programs/reg/import.c @@ -66,6 +66,7 @@ enum parser_state PARSE_WIN31_LINE, /* parsing a Windows 3.1 registry line */ LINE_START, /* at the beginning of a registry line */ KEY_NAME, /* parsing a key name */ + DELETE_KEY, /* deleting a registry key */ DEFAULT_VALUE_NAME, /* parsing a default value name */ QUOTED_VALUE_NAME, /* parsing a double-quoted value name */ DATA_START, /* preparing for data parsing operations */ @@ -105,6 +106,7 @@ static WCHAR *header_state(struct parser *parser, WCHAR *pos); static WCHAR *parse_win31_line_state(struct parser *parser, WCHAR *pos); static WCHAR *line_start_state(struct parser *parser, WCHAR *pos); static WCHAR *key_name_state(struct parser *parser, WCHAR *pos); +static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos); static WCHAR *default_value_name_state(struct parser *parser, WCHAR *pos); static WCHAR *quoted_value_name_state(struct parser *parser, WCHAR *pos); static WCHAR *data_start_state(struct parser *parser, WCHAR *pos); @@ -124,6 +126,7 @@ static const parser_state_func parser_funcs[NB_PARSER_STATES] = parse_win31_line_state, /* PARSE_WIN31_LINE */ line_start_state, /* LINE_START */ key_name_state, /* KEY_NAME */ + delete_key_state, /* DELETE_KEY */ default_value_name_state, /* DEFAULT_VALUE_NAME */ quoted_value_name_state, /* QUOTED_VALUE_NAME */ data_start_state, /* DATA_START */ @@ -581,8 +584,8 @@ static WCHAR *key_name_state(struct parser *parser, WCHAR *pos) if (*p == '-') { - FIXME("key deletion not yet implemented\n"); - goto done; + set_state(parser, DELETE_KEY); + return p + 1; } else if (open_key(parser, p) != ERROR_SUCCESS) output_message(STRING_OPEN_KEY_FAILED, p); @@ -592,6 +595,26 @@ done: return p; } +/* handler for parser DELETE_KEY state */ +static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos) +{ + WCHAR *p = pos; + + if (*p == 'H' || *p == 'h') + { + HKEY root; + WCHAR *path; + + root = parse_key_name(p, &path); + + if (root && path && *path) + RegDeleteTreeW(root, path); + } + + set_state(parser, LINE_START); + return p; +} + /* handler for parser DEFAULT_VALUE_NAME state */ static WCHAR *default_value_name_state(struct parser *parser, WCHAR *pos) { diff --git a/programs/reg/tests/reg.c b/programs/reg/tests/reg.c index 8ddeabc34ba..64091960765 100644 --- a/programs/reg/tests/reg.c +++ b/programs/reg/tests/reg.c @@ -1713,8 +1713,8 @@ static void test_import(void) "[-HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey2a]\n\n" "[-HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey2b]\n\n", &r); todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_key_nonexist(hkey, "Subkey2a"); - todo_wine verify_key_nonexist(hkey, "Subkey2b"); + verify_key_nonexist(hkey, "Subkey2a"); + verify_key_nonexist(hkey, "Subkey2b"); /* Test case sensitivity when creating and deleting registry keys. */ test_import_str("REGEDIT4\n\n" @@ -1728,8 +1728,8 @@ static void test_import(void) "[-HKEY_current_USER\\" KEY_BASE "\\sUBKEY3A]\n\n" "[-hKeY_cUrReNt_UsEr\\" KEY_BASE "\\sUbKeY3B]\n\n", &r); todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_key_nonexist(hkey, "Subkey3a"); - todo_wine verify_key_nonexist(hkey, "Subkey3b"); + verify_key_nonexist(hkey, "Subkey3a"); + verify_key_nonexist(hkey, "Subkey3b"); /* Test value deletion. We start by creating some registry values. */ test_import_str("REGEDIT4\n\n" @@ -2278,7 +2278,7 @@ static void test_import(void) ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - todo_wine ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); } static void test_unicode_import(void) @@ -2330,39 +2330,39 @@ static void test_unicode_import(void) "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"Test1\"=\"Value\"\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_reg_nonexist(hkey, "Test1"); + verify_reg_nonexist(hkey, "Test1"); test_import_wstr("\xef\xbb\xbfregedit4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"Test2\"=\"Value\"\n", &r); ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS) /* WinXP */, "got exit code %d, expected 1\n", r); - todo_wine verify_reg_nonexist(hkey, "Test2"); + verify_reg_nonexist(hkey, "Test2"); test_import_wstr("\xef\xbb\xbfRegedit4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"Test3\"=\"Value\"\n", &r); ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS) /* WinXP */, "got exit code %d, expected 1\n", r); - todo_wine verify_reg_nonexist(hkey, "Test3"); + verify_reg_nonexist(hkey, "Test3"); test_import_wstr("\xef\xbb\xbfREGEDIT 4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"Test4\"=\"Value\"\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_reg_nonexist(hkey, "Test4"); + verify_reg_nonexist(hkey, "Test4"); test_import_wstr("\xef\xbb\xbfREGEDIT4FOO\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"Test5\"=\"Value\"\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_reg_nonexist(hkey, "Test5"); + verify_reg_nonexist(hkey, "Test5"); test_import_wstr("\xef\xbb\xbfREGEDIT4 FOO\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"Test6\"=\"Value\"\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_reg_nonexist(hkey, "Test6"); + verify_reg_nonexist(hkey, "Test6"); test_import_wstr("\xef\xbb\xbfREGEDIT5\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -3169,8 +3169,8 @@ static void test_unicode_import(void) "[-HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey2a]\n\n" "[-HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey2b]\n\n", &r); todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_key_nonexist(hkey, "Subkey2a"); - todo_wine verify_key_nonexist(hkey, "Subkey2b"); + verify_key_nonexist(hkey, "Subkey2a"); + verify_key_nonexist(hkey, "Subkey2b"); /* Test case sensitivity when creating and deleting registry keys. */ test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" @@ -3184,8 +3184,8 @@ static void test_unicode_import(void) "[-HKEY_current_USER\\" KEY_BASE "\\sUBKEY3A]\n\n" "[-hKeY_cUrReNt_UsEr\\" KEY_BASE "\\sUbKeY3B]\n\n", &r); todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - todo_wine verify_key_nonexist(hkey, "Subkey3a"); - todo_wine verify_key_nonexist(hkey, "Subkey3b"); + verify_key_nonexist(hkey, "Subkey3a"); + verify_key_nonexist(hkey, "Subkey3b"); /* Test value deletion. We start by creating some registry values. */ test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" @@ -3744,7 +3744,7 @@ static void test_unicode_import(void) ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - todo_wine ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); } static void test_import_with_whitespace(void) @@ -3891,7 +3891,7 @@ static void test_import_with_whitespace(void) ok(err == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", err); err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - todo_wine ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %d, expected 0\n", err); + ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %d, expected 0\n", err); } static void test_unicode_import_with_whitespace(void) @@ -4038,7 +4038,7 @@ static void test_unicode_import_with_whitespace(void) ok(err == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", err); err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - todo_wine ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %d, expected 0\n", err); + ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %d, expected 0\n", err); } static void test_import_31(void)