diff options
Diffstat (limited to 'jam-files/engine/w32_getreg.c')
-rw-r--r-- | jam-files/engine/w32_getreg.c | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/jam-files/engine/w32_getreg.c b/jam-files/engine/w32_getreg.c new file mode 100644 index 00000000..5a06f43e --- /dev/null +++ b/jam-files/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 |