[PATCH v3 6/8] reg.exe: Implement query functionality
Jonathan Vollebregt
jnvsor at gmail.com
Sat Sep 6 11:05:21 CDT 2014
---
programs/reg/reg.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 200 insertions(+), 9 deletions(-)
diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index a0ea6a8..9b2d46b 100644
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -20,6 +20,8 @@
#include <wine/unicode.h>
#include "reg.h"
+#define MAX_VALUE_NAME 16384
+#define MAX_KEY_LENGTH 256
#define MAX_ROOT_KEY_NAME_LENGTH 20
#define NUM_ROOT_KEYS 5
#define MAX_TYPE_LENGTH 21
@@ -376,6 +378,165 @@ static BYTE *wchar_get_data(const WCHAR *input, const DWORD type,
}
}
+static void print_key(const WCHAR *path, const WCHAR *subkey)
+{
+ static const WCHAR part[] = {'\\','%','s',0};
+ static const WCHAR newline[] = {'\n',0};
+
+ reg_printfW(&part[1], path_get_rootkey_name(path));
+
+ if (path_get_key(path) != path_get_rootkey(path))
+ reg_printfW(part, strchrW(path, '\\') + 1);
+ if(subkey)
+ reg_printfW(part, subkey);
+
+ reg_printfW(newline);
+}
+
+static DWORD print_value(const HKEY hkey, const WCHAR *value_name)
+{
+ static const WCHAR default_value_name[] = {'(','N','O',' ','N','A','M','E',')',0};
+ static const WCHAR print_value[] = {' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s',' ',' ',' ',' ','%','s','\n',0};
+ DWORD rc, type, data_size;
+ WCHAR *out_data = NULL;
+ BYTE* data = NULL;
+
+ rc = RegQueryValueExW(hkey, value_name, NULL, &type, NULL, &data_size);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ reg_message(STRING_CANNOT_FIND);
+ return 1;
+ }
+
+ data = HeapAlloc(GetProcessHeap(), 0, data_size);
+
+ if (!data)
+ {
+ reg_message(STRING_ERROR);
+ return 1;
+ }
+
+ rc = RegQueryValueExW(hkey, value_name, NULL, NULL, data, &data_size);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ reg_message(STRING_ERROR);
+ HeapFree(GetProcessHeap(), 0, data);
+ return 1;
+ }
+
+ out_data = data_get_wchar(data, data_size, type);
+
+ if (!value_name || !value_name[0])
+ 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(const HKEY hkey, const WCHAR *key_name, const BOOL recurse)
+{
+ static const WCHAR format_subkey_path[] = {'%','s','\\','%','s',0};
+ static const WCHAR newline[] = {'\n',0};
+ WCHAR value_name[MAX_VALUE_NAME];
+ WCHAR subkey_name[MAX_KEY_LENGTH];
+ WCHAR *subkey_path = NULL;
+ LONG rc;
+ DWORD i, length, subkey_length, num_subkeys, num_values;
+ HKEY subkey;
+
+ rc = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL,
+ &num_values, NULL, NULL, NULL, NULL);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ reg_message(STRING_CANNOT_FIND);
+ return 1;
+ }
+
+ print_key(key_name, NULL);
+
+ for (i = 0; i < num_values; i++)
+ {
+ length = MAX_VALUE_NAME;
+
+ rc = RegEnumValueW(hkey, i, value_name, &length, NULL, NULL, NULL, NULL);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ reg_message(STRING_ERROR);
+ return 1;
+ }
+
+ if (!value_name[0])
+ print_value(hkey, NULL);
+ else
+ print_value(hkey, value_name);
+ }
+
+ if (num_subkeys)
+ reg_printfW(newline);
+
+ for (i = 0; i < num_subkeys; i++)
+ {
+ length = MAX_KEY_LENGTH;
+
+ rc = RegEnumKeyExW(hkey, i, subkey_name, &length, NULL, NULL, NULL, NULL);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ reg_message(STRING_ERROR);
+ return 1;
+ }
+
+ if (!recurse)
+ {
+ print_key(key_name, subkey_name);
+ continue;
+ }
+
+ subkey_length = strlenW(key_name) + length + 2;
+ subkey_path = HeapAlloc(GetProcessHeap(), 0, subkey_length * sizeof(WCHAR));
+
+ if (!subkey_path)
+ {
+ reg_message(STRING_ERROR);
+ return 1;
+ }
+
+ rc = snprintfW(subkey_path, subkey_length, format_subkey_path, key_name, subkey_name);
+
+ if (rc < 0 || rc >= subkey_length)
+ {
+ reg_message(STRING_ERROR);
+ HeapFree(GetProcessHeap(), 0, subkey_path);
+ return 1;
+ }
+
+ subkey = path_get_key(subkey_path);
+ if (!subkey)
+ {
+ HeapFree(GetProcessHeap(), 0, subkey_path);
+ return 1;
+ }
+
+ if (print_all_values(subkey, subkey_path, recurse))
+ {
+ RegCloseKey(subkey);
+ HeapFree(GetProcessHeap(), 0, subkey_path);
+ 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)
{
@@ -536,14 +697,44 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
return 0;
}
-static int reg_query(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
- BOOL subkey)
+static int reg_query( const WCHAR *key_name, const WCHAR *value_name,
+ const BOOL value_empty, const 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);
+ static const WCHAR newline[] = {'\n',0};
+ HKEY key;
- return 1;
+ reg_printfW(newline);
+
+ if (value_name && value_empty)
+ {
+ reg_message(STRING_INVALID_CMDLINE);
+ return 1;
+ }
+
+ key = path_get_key(key_name);
+
+ if (!key)
+ return 1;
+
+ if (value_empty || value_name)
+ {
+ if (value_name && !value_name[0])
+ value_name = NULL;
+
+ if (print_value(key, value_name))
+ {
+ RegCloseKey(key);
+ return 1;
+ }
+ }
+ else if (print_all_values(key, key_name, recurse))
+ {
+ RegCloseKey(key);
+ return 1;
+ }
+
+ RegCloseKey(key);
+ return 0;
}
int wmain(int argc, WCHAR *argvW[])
@@ -653,7 +844,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)
{
@@ -675,9 +866,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
More information about the wine-patches
mailing list