From ac0eef4019baefc758a06d21ccaa5aaa7dadf1c2 Mon Sep 17 00:00:00 2001 From: Jonathan Vollebregt Date: Wed, 14 Jan 2015 18:12:24 +0100 Subject: reg: Add path/key conversion functions --- programs/reg/reg.c | 150 ++++++++++++++++++++++++++--------------------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/programs/reg/reg.c b/programs/reg/reg.c index f0c0b2e..e9b5b68 100755 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -20,8 +20,38 @@ #include #include "reg.h" +#define ARRAY_SIZE(A) (sizeof(A)/sizeof(*A)) + #define ERROR_NO_REMOTE 20000 +static const WCHAR empty_wstr[] = {0}; + +static const WCHAR short_hklm[] = {'H','K','L','M',0}; +static const WCHAR short_hkcu[] = {'H','K','C','U',0}; +static const WCHAR short_hkcr[] = {'H','K','C','R',0}; +static const WCHAR short_hku[] = {'H','K','U',0}; +static const WCHAR short_hkcc[] = {'H','K','C','C',0}; +static const WCHAR long_hklm[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0}; +static const WCHAR long_hkcu[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0}; +static const WCHAR long_hkcr[] = {'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0}; +static const WCHAR long_hku[] = {'H','K','E','Y','_','U','S','E','R','S',0}; +static const WCHAR long_hkcc[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0}; + +static const struct +{ + HKEY key; + const WCHAR *short_name; + const WCHAR *long_name; +} +root_rels[] = +{ + {HKEY_LOCAL_MACHINE, short_hklm, long_hklm}, + {HKEY_CURRENT_USER, short_hkcu, long_hkcu}, + {HKEY_CLASSES_ROOT, short_hkcr, long_hkcr}, + {HKEY_USERS, short_hku, long_hku}, + {HKEY_CURRENT_CONFIG, short_hkcc, long_hkcc}, +}; + static int reg_printfW(const WCHAR *msg, ...) { va_list va_args; @@ -84,6 +114,9 @@ static void reg_print_error(LSTATUS error_code) case ERROR_NO_REMOTE: reg_message(STRING_NO_REMOTE); return; + case ERROR_FILE_NOT_FOUND: + reg_message(STRING_CANNOT_FIND); + return; default: { static const WCHAR error_string[] = {'%','0','5','d',':',' ','%','s',0}; @@ -99,51 +132,40 @@ static void reg_print_error(LSTATUS error_code) } } -static int reg_StrCmpNIW(LPCWSTR str, LPCWSTR comp, int len) +static inline BOOL path_rootname_cmp(const WCHAR *input_path, const WCHAR *rootkey_name) { - int i; + DWORD length = strlenW(rootkey_name); + + return (!strncmpiW(input_path, rootkey_name, length) && + (input_path[length] == 0 || input_path[length] == '\\')); +} - for (i = 0; i < len; i++) +static HKEY path_get_rootkey(const WCHAR *path) +{ + DWORD i; + + for (i = 0; i < ARRAY_SIZE(root_rels); i++) { - if (!str[i]) - { - len = i + 1; - break; - } + if (path_rootname_cmp(path, root_rels[i].short_name) || + path_rootname_cmp(path, root_rels[i].long_name)) + return root_rels[i].key; } - return CompareStringW(CP_ACP, NORM_IGNORECASE, str, len, comp, len) - CSTR_EQUAL; + return NULL; } -static HKEY get_rootkey(LPWSTR key) +static LSTATUS path_open(const WCHAR *path, HKEY *out, BOOL create) { - static const WCHAR szHKLM[] = {'H','K','L','M',0}; - static const WCHAR szHKEY_LOCAL_MACHINE[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0}; - static const WCHAR szHKCU[] = {'H','K','C','U',0}; - static const WCHAR szHKEY_CURRENT_USER[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0}; - static const WCHAR szHKCR[] = {'H','K','C','R',0}; - static const WCHAR szHKEY_CLASSES_ROOT[] = {'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0}; - static const WCHAR szHKU[] = {'H','K','U',0}; - static const WCHAR szHKEY_USERS[] = {'H','K','E','Y','_','U','S','E','R','S',0}; - static const WCHAR szHKCC[] = {'H','K','C','C',0}; - static const WCHAR szHKEY_CURRENT_CONFIG[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0}; - - if (!reg_StrCmpNIW(key, szHKLM, 4) || - !reg_StrCmpNIW(key, szHKEY_LOCAL_MACHINE, 18)) - return HKEY_LOCAL_MACHINE; - else if (!reg_StrCmpNIW(key, szHKCU, 4) || - !reg_StrCmpNIW(key, szHKEY_CURRENT_USER, 17)) - return HKEY_CURRENT_USER; - else if (!reg_StrCmpNIW(key, szHKCR, 4) || - !reg_StrCmpNIW(key, szHKEY_CLASSES_ROOT, 17)) - return HKEY_CLASSES_ROOT; - else if (!reg_StrCmpNIW(key, szHKU, 3) || - !reg_StrCmpNIW(key, szHKEY_USERS, 10)) - return HKEY_USERS; - else if (!reg_StrCmpNIW(key, szHKCC, 4) || - !reg_StrCmpNIW(key, szHKEY_CURRENT_CONFIG, 19)) - return HKEY_CURRENT_CONFIG; - else return NULL; + *out = path_get_rootkey(path); + + path = strchrW(path, '\\'); + if (path) + path++; + + if (create) + return RegCreateKeyW(*out, path, out); + else + return RegOpenKeyW(*out, path, out); } static DWORD get_regtype(LPWSTR type) @@ -229,8 +251,7 @@ static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, { static const WCHAR stubW[] = {'A','D','D',' ','-',' ','%','s', ' ','%','s',' ','%','d',' ','%','s',' ','%','s',' ','%','d','\n',0}; - LPWSTR p; - HKEY root,subkey; + HKEY subkey; LONG err; reg_printfW(stubW, key_name, value_name, value_empty, type, data, force); @@ -242,22 +263,8 @@ static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, return 1; } - p = strchrW(key_name,'\\'); - if (!p) - { - reg_message(STRING_INVALID_KEY); - return 1; - } - p++; - - root = get_rootkey(key_name); - if (!root) - { - reg_message(STRING_INVALID_KEY); - return 1; - } - - if(RegCreateKeyW(root,p,&subkey)!=ERROR_SUCCESS) + err = path_open(key_name, &subkey, TRUE); + if (err != ERROR_SUCCESS) { reg_message(STRING_INVALID_KEY); return 1; @@ -301,8 +308,7 @@ static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL value_all, BOOL force) { - LPWSTR p; - HKEY root,subkey; + HKEY subkey; LONG err; static const WCHAR stubW[] = {'D','E','L','E','T','E', @@ -317,16 +323,8 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, return 1; } - p = strchrW(key_name,'\\'); - if (!p) - { - reg_message(STRING_INVALID_KEY); - return 1; - } - p++; - - root = get_rootkey(key_name); - if (!root) + err = path_open(key_name, &subkey, FALSE); + if (err != ERROR_SUCCESS) { reg_message(STRING_INVALID_KEY); return 1; @@ -352,21 +350,23 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, /* Delete subtree only if no /v* option is given */ if (!value_name && !value_empty && !value_all) { - if (RegDeleteTreeW(root,p)!=ERROR_SUCCESS) + err = RegDeleteTreeW(subkey, NULL); + if (err != ERROR_SUCCESS) { - reg_message(STRING_CANNOT_FIND); + reg_print_error(err); + return 1; + } + + err = RegDeleteKeyW(subkey, empty_wstr); + if (err != ERROR_SUCCESS) + { + reg_print_error(err); return 1; } reg_message(STRING_SUCCESS); return 0; } - if(RegOpenKeyW(root,p,&subkey)!=ERROR_SUCCESS) - { - reg_message(STRING_CANNOT_FIND); - return 1; - } - if (value_all) { LPWSTR szValue; -- 2.2.2