From: Jonathan Vollebregt Subject: [PATCH 5/5] reg.exe: Implement query functionality Message-Id: <1409576734-9289-5-git-send-email-jnvsor@gmail.com> Date: Mon, 1 Sep 2014 15:05:34 +0200 --- programs/reg/reg.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 212 insertions(+), 8 deletions(-) diff --git a/programs/reg/reg.c b/programs/reg/reg.c index ad8582a..ad6adbd 100644 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -20,7 +20,9 @@ #include #include "reg.h" +#define MAX_KEY_LENGTH 256 #define MAX_ROOT_KEY_NAME_LENGTH 20 +#define MAX_VALUE_NAME 16384 #define MAX_TYPE_LENGTH 32 static const WCHAR short_HKEY_name[][5] = { @@ -315,6 +317,166 @@ static LPBYTE wchar_get_data(const WCHAR * input, const DWORD type, WCHAR sepera return output; } +static void print_key(WCHAR * path, WCHAR * subkey) +{ + WCHAR print_keyname[]={'%','s','\\','%','s','\\','%','s','\n',0}; + + if(subkey == NULL) + { + reg_printfW(&print_keyname[3],path_get_rootkey_name(path),strchrW(path,'\\')+1); + } + else + { + reg_printfW(print_keyname,path_get_rootkey_name(path),strchrW(path,'\\')+1,subkey); + } +} + +static DWORD print_value(HKEY hkey, WCHAR *value_name) +{ + DWORD rc; + DWORD type; + + BYTE* data=NULL; + DWORD data_size; + WCHAR *out_data=NULL; + + WCHAR default_value_name[]={'(','N','O',' ','N','A','M','E',')',0}; + WCHAR print_value[]={' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s','\n','\0'}; + + rc = RegGetValueW(hkey, NULL, value_name, RRF_RT_ANY | RRF_NOEXPAND, &type, + NULL, &data_size); + + if (rc != ERROR_SUCCESS) + { + return 1; + } + + data=HeapAlloc(GetProcessHeap(),0,data_size); + + rc = RegGetValueW(hkey, NULL, value_name, RRF_RT_ANY, NULL, + data, &data_size); + + if (rc != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(),0,data); + return 1; + } + + out_data = data_get_wchar(data, data_size, type); + + if (value_name==NULL) + reg_printfW(print_value, default_value_name, type_get_wchar(type), out_data); + else + reg_printfW(print_value, value_name, type_get_wchar(type), out_data); + + HeapFree(GetProcessHeap(),0,data); + HeapFree(GetProcessHeap(),0,out_data); + return 0; +} + +static DWORD print_all_values(HKEY hkey, WCHAR *key_name, BOOL recurse) +{ + LONG rc; + DWORD i=0; + DWORD num_subkeys=0; + DWORD num_values=0; + + WCHAR value_name[MAX_VALUE_NAME]; + DWORD value_name_length; + + WCHAR subkey_name[MAX_KEY_LENGTH]; + DWORD subkey_length; + LPWSTR subkey_path=NULL; + DWORD subkey_path_length; + HKEY subkey; + + WCHAR format_subkey_path[]={'%','s','\\','%','s',0}; + + rc = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, + &num_values, NULL, NULL, NULL, NULL); + + if (rc != ERROR_SUCCESS) + { + return 1; + } + + print_key(key_name,NULL); + + /*enumerate values*/ + for (i=0; i= subkey_path_length) + { + return 1; + } + + subkey = path_get_key(subkey_path); + if (!subkey) + { + return 1; + } + + if(print_all_values(subkey, subkey_path, recurse)) + { + return 1; + } + RegCloseKey(subkey); + HeapFree(GetProcessHeap(),0,subkey_path); + } + return 0; +} + static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, WCHAR *type, WCHAR separator, WCHAR *data, BOOL force) { @@ -456,13 +618,55 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, } static int reg_query(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, - BOOL subkey) + BOOL recurse) { - static const WCHAR stubW[] = {'S','T','U','B',' ','Q','U','E','R','Y',' ', - '-',' ','%','s',' ','%','s',' ','%','d',' ','%','d','\n',0}; - reg_printfW(stubW, key_name, value_name, value_empty, subkey); + HKEY key = path_get_key(key_name); + + WCHAR newline[]={'\n',0}; + reg_printfW(newline); + + if (value_name && value_empty) + { + reg_message(STRING_INVALID_CMDLINE); + return 1; + } - return 1; + if(!key) + { + return 1; + } + + if (value_name) + { + if (print_value(key, value_name)!=0) + { + RegCloseKey(key); + reg_message(STRING_CANNOT_FIND); + return 1; + } + } + else if (value_empty) + { + if (print_value(key, NULL)!=0) + { + RegCloseKey(key); + reg_message(STRING_CANNOT_FIND); + return 1; + } + } + else + { + if (print_all_values(key, key_name, recurse)!=0) + { + RegCloseKey(key); + reg_message(STRING_CANNOT_FIND); + return 1; + } + } + + RegCloseKey(key); + + return 0; } int wmain(int argc, WCHAR *argvW[]) @@ -559,7 +763,7 @@ int wmain(int argc, WCHAR *argvW[]) else if (!lstrcmpiW(argvW[1], queryW)) { WCHAR *key_name, *value_name = NULL; - BOOL value_empty = FALSE, subkey = FALSE; + BOOL value_empty = FALSE, recurse = FALSE; if (argc < 3) { @@ -581,9 +785,9 @@ int wmain(int argc, WCHAR *argvW[]) else if (!lstrcmpiW(argvW[i], slashVEW)) value_empty = TRUE; else if (!lstrcmpiW(argvW[i], slashSW)) - subkey = TRUE; + recurse = TRUE; } - return reg_query(key_name, value_name, value_empty, subkey); + return reg_query(key_name, value_name, value_empty, recurse); } else { -- 2.1.0