summaryrefslogtreecommitdiff
path: root/tools/build/v2/engine/w32_getreg.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/build/v2/engine/w32_getreg.c')
-rw-r--r--tools/build/v2/engine/w32_getreg.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/tools/build/v2/engine/w32_getreg.c b/tools/build/v2/engine/w32_getreg.c
new file mode 100644
index 0000000000..5a06f43e92
--- /dev/null
+++ b/tools/build/v2/engine/w32_getreg.c
@@ -0,0 +1,207 @@
+/*
+Copyright Paul Lin 2003. Copyright 2006 Bojan Resnik.
+Distributed under the Boost Software License, Version 1.0. (See accompanying
+file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+# include "jam.h"
+
+# if defined( OS_NT ) || defined( OS_CYGWIN )
+
+# include "lists.h"
+# include "newstr.h"
+# include "parse.h"
+# include "frames.h"
+# include "strings.h"
+
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+# define MAX_REGISTRY_DATA_LENGTH 4096
+# define MAX_REGISTRY_KEYNAME_LENGTH 256
+# define MAX_REGISTRY_VALUENAME_LENGTH 16384
+
+typedef struct
+{
+ LPCSTR name;
+ HKEY value;
+} KeyMap;
+
+static const KeyMap dlRootKeys[] = {
+ { "HKLM", HKEY_LOCAL_MACHINE },
+ { "HKCU", HKEY_CURRENT_USER },
+ { "HKCR", HKEY_CLASSES_ROOT },
+ { "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE },
+ { "HKEY_CURRENT_USER", HKEY_CURRENT_USER },
+ { "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT },
+ { 0, 0 }
+};
+
+static HKEY get_key(char const** path)
+{
+ const KeyMap *p;
+
+ for (p = dlRootKeys; p->name; ++p)
+ {
+ int n = strlen(p->name);
+ if (!strncmp(*path,p->name,n))
+ {
+ if ((*path)[n] == '\\' || (*path)[n] == 0)
+ {
+ *path += n + 1;
+ break;
+ }
+ }
+ }
+
+ return p->value;
+}
+
+LIST*
+builtin_system_registry(
+ PARSE *parse,
+ FRAME *frame )
+{
+ char const* path = lol_get(frame->args, 0)->string;
+ LIST* result = L0;
+ HKEY key = get_key(&path);
+
+ if (
+ key != 0
+ && ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key)
+ )
+ {
+ DWORD type;
+ BYTE data[MAX_REGISTRY_DATA_LENGTH];
+ DWORD len = sizeof(data);
+ LIST const* const field = lol_get(frame->args, 1);
+
+ if ( ERROR_SUCCESS ==
+ RegQueryValueEx(key, field ? field->string : 0, 0, &type, data, &len) )
+ {
+ switch (type)
+ {
+
+ case REG_EXPAND_SZ:
+ {
+ long len;
+ string expanded[1];
+ string_new(expanded);
+
+ while (
+ (len = ExpandEnvironmentStrings(
+ (LPCSTR)data, expanded->value, expanded->capacity))
+ > expanded->capacity
+ )
+ string_reserve(expanded, len);
+
+ expanded->size = len - 1;
+
+ result = list_new( result, newstr(expanded->value) );
+ string_free( expanded );
+ }
+ break;
+
+ case REG_MULTI_SZ:
+ {
+ char* s;
+
+ for (s = (char*)data; *s; s += strlen(s) + 1)
+ result = list_new( result, newstr(s) );
+
+ }
+ break;
+
+ case REG_DWORD:
+ {
+ char buf[100];
+ sprintf( buf, "%u", *(PDWORD)data );
+ result = list_new( result, newstr(buf) );
+ }
+ break;
+
+ case REG_SZ:
+ result = list_new( result, newstr((char*)data) );
+ break;
+ }
+ }
+ RegCloseKey(key);
+ }
+ return result;
+}
+
+static LIST* get_subkey_names(HKEY key, char const* path)
+{
+ LIST* result = 0;
+
+ if ( ERROR_SUCCESS ==
+ RegOpenKeyEx(key, path, 0, KEY_ENUMERATE_SUB_KEYS, &key)
+ )
+ {
+ char name[MAX_REGISTRY_KEYNAME_LENGTH];
+ DWORD name_size = sizeof(name);
+ DWORD index;
+ FILETIME last_write_time;
+
+ for ( index = 0;
+ ERROR_SUCCESS == RegEnumKeyEx(
+ key, index, name, &name_size, 0, 0, 0, &last_write_time);
+ ++index,
+ name_size = sizeof(name)
+ )
+ {
+ name[name_size] = 0;
+ result = list_append(result, list_new(0, newstr(name)));
+ }
+
+ RegCloseKey(key);
+ }
+
+ return result;
+}
+
+static LIST* get_value_names(HKEY key, char const* path)
+{
+ LIST* result = 0;
+
+ if ( ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key) )
+ {
+ char name[MAX_REGISTRY_VALUENAME_LENGTH];
+ DWORD name_size = sizeof(name);
+ DWORD index;
+
+ for ( index = 0;
+ ERROR_SUCCESS == RegEnumValue(
+ key, index, name, &name_size, 0, 0, 0, 0);
+ ++index,
+ name_size = sizeof(name)
+ )
+ {
+ name[name_size] = 0;
+ result = list_append(result, list_new(0, newstr(name)));
+ }
+
+ RegCloseKey(key);
+ }
+
+ return result;
+}
+
+LIST*
+builtin_system_registry_names(
+ PARSE *parse,
+ FRAME *frame )
+{
+ char const* path = lol_get(frame->args, 0)->string;
+ char const* result_type = lol_get(frame->args, 1)->string;
+
+ HKEY key = get_key(&path);
+
+ if ( !strcmp(result_type, "subkeys") )
+ return get_subkey_names(key, path);
+ if ( !strcmp(result_type, "values") )
+ return get_value_names(key, path);
+ return 0;
+}
+
+# endif