diff options
| author | ruki <[email protected]> | 2020-12-26 00:43:58 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-12-26 00:43:58 +0800 |
| commit | 9dd609f518388f7c62e241e7f1d5813df0ada6b1 (patch) | |
| tree | 7b48cd4dadc2d756b562ac94fa1c98b8f7f1bb84 | |
| parent | d9fb6826a45caafc94772ba63c87a3d2f023867e (diff) | |
improve registry
| -rw-r--r-- | core/src/xmake/winos/registry_query.c | 88 | ||||
| -rw-r--r-- | xmake/core/base/winos.lua | 91 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/interpreter/winos.lua | 8 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/winos.lua | 28 |
4 files changed, 146 insertions, 69 deletions
diff --git a/core/src/xmake/winos/registry_query.c b/core/src/xmake/winos/registry_query.c index a9d968539..f507bbaab 100644 --- a/core/src/xmake/winos/registry_query.c +++ b/core/src/xmake/winos/registry_query.c @@ -42,74 +42,36 @@ typedef BOOL (WINAPI* xm_RegGetValueA_t)(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpVa /* query registry * - * local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger") + * local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", "Debugger") */ tb_int_t xm_winos_registry_query(lua_State* lua) { // check tb_assert_and_check_return_val(lua, 0); - // get the path - tb_char_t const* path = luaL_checkstring(lua, 1); - tb_check_return_val(path, 0); + // get the arguments + tb_char_t const* rootkey = luaL_checkstring(lua, 1); + tb_char_t const* rootdir = luaL_checkstring(lua, 2); + tb_char_t const* valuename = luaL_checkstring(lua, 3); + tb_check_return_val(rootkey && rootdir && valuename, 0); // query key-value tb_bool_t ok = tb_false; - HKEY key = NULL; - HKEY keynew = NULL; - tb_char_t pathbuf[TB_PATH_MAXN]; + HKEY key = tb_null; + HKEY keynew = tb_null; tb_char_t* value = tb_null; do { - // copy path - tb_size_t size = tb_strlcpy(pathbuf, path, sizeof(pathbuf)); - if (size >= sizeof(pathbuf)) - { - lua_pushnil(lua); - lua_pushfstring(lua, "too long path: %s", path); - break; - } - - // parse path key and subkey - tb_char_t* pathkey = tb_null; - tb_char_t* pathsubkey = tb_null; - tb_char_t* p = pathbuf; - for (; *p && *p != '\\'; p++) ; - if (*p == '\\') - { - *p = '\0'; - pathkey = pathbuf; - pathsubkey = p + 1; - } - if (!pathkey || !pathsubkey) - { - lua_pushnil(lua); - lua_pushfstring(lua, "parse pathkey and pathsubkey failed: %s", path); - break; - } - - // parse value name - tb_char_t* valuename = tb_null; - for (p = pathbuf + size - 1; p >= pathbuf && *p && *p != ';'; p--) ; - if (p >= pathbuf && *p == ';') - { - valuename = p + 1; - *p = '\0'; - } - - // trace - tb_trace_d("key: %s, subkey: %s, name: %s", pathkey, pathsubkey, valuename? valuename : "(default)"); - - // get registry key - if (!tb_strcmp(pathkey, "HKEY_CLASSES_ROOT")) key = HKEY_CLASSES_ROOT; - else if (!tb_strcmp(pathkey, "HKEY_CURRENT_CONFIG")) key = HKEY_CURRENT_CONFIG; - else if (!tb_strcmp(pathkey, "HKEY_CURRENT_USER")) key = HKEY_CURRENT_USER; - else if (!tb_strcmp(pathkey, "HKEY_LOCAL_MACHINE")) key = HKEY_LOCAL_MACHINE; - else if (!tb_strcmp(pathkey, "HKEY_USERS")) key = HKEY_USERS; + // get registry rootkey + if (!tb_strcmp(rootkey, "HKEY_CLASSES_ROOT")) key = HKEY_CLASSES_ROOT; + else if (!tb_strcmp(rootkey, "HKEY_CURRENT_CONFIG")) key = HKEY_CURRENT_CONFIG; + else if (!tb_strcmp(rootkey, "HKEY_CURRENT_USER")) key = HKEY_CURRENT_USER; + else if (!tb_strcmp(rootkey, "HKEY_LOCAL_MACHINE")) key = HKEY_LOCAL_MACHINE; + else if (!tb_strcmp(rootkey, "HKEY_USERS")) key = HKEY_USERS; else { lua_pushnil(lua); - lua_pushfstring(lua, "invalid registry path: %s", path); + lua_pushfstring(lua, "invalid registry rootkey: %s", rootkey); break; } @@ -129,10 +91,10 @@ tb_int_t xm_winos_registry_query(lua_State* lua) { // get registry value size DWORD valuesize = 0; - if (s_RegGetValueA(key, pathsubkey, valuename, RRF_RT_ANY, 0, tb_null, &valuesize) != ERROR_SUCCESS) + if (s_RegGetValueA(key, rootdir, valuename, RRF_RT_ANY, 0, tb_null, &valuesize) != ERROR_SUCCESS) { lua_pushnil(lua); - lua_pushfstring(lua, "get registry value size failed: %s", path); + lua_pushfstring(lua, "get registry value size failed: %s\\%s;%s", rootkey, rootdir, valuename); break; } @@ -142,20 +104,20 @@ tb_int_t xm_winos_registry_query(lua_State* lua) // get value result type = 0; - if (s_RegGetValueA(key, pathsubkey, valuename, RRF_RT_ANY, &type, (PVOID)value, &valuesize) != ERROR_SUCCESS) + if (s_RegGetValueA(key, rootdir, valuename, RRF_RT_ANY, &type, (PVOID)value, &valuesize) != ERROR_SUCCESS) { lua_pushnil(lua); - lua_pushfstring(lua, "get registry value failed: %s", path); + lua_pushfstring(lua, "get registry value failed: %s\\%s;%s", rootkey, rootdir, valuename); break; } } else { // open registry key - if (RegOpenKeyExA(key, pathsubkey, 0, KEY_QUERY_VALUE, &keynew) != ERROR_SUCCESS && keynew) + if (RegOpenKeyExA(key, rootdir, 0, KEY_QUERY_VALUE, &keynew) != ERROR_SUCCESS && keynew) { lua_pushnil(lua); - lua_pushfstring(lua, "open registry key failed: %s", path); + lua_pushfstring(lua, "open registry key failed: %s\\%s", rootkey, rootdir); break; } @@ -164,7 +126,7 @@ tb_int_t xm_winos_registry_query(lua_State* lua) if (RegQueryValueExA(keynew, valuename, tb_null, tb_null, tb_null, &valuesize) != ERROR_SUCCESS) { lua_pushnil(lua); - lua_pushfstring(lua, "get registry value size failed: %s", path); + lua_pushfstring(lua, "get registry value size failed: %s\\%s;%s", rootkey, rootdir, valuename); break; } @@ -177,7 +139,7 @@ tb_int_t xm_winos_registry_query(lua_State* lua) if (RegQueryValueExA(keynew, valuename, tb_null, &type, (LPBYTE)value, &valuesize) != ERROR_SUCCESS) { lua_pushnil(lua); - lua_pushfstring(lua, "get registry value failed: %s", path); + lua_pushfstring(lua, "get registry value failed: %s\\%s;%s", rootkey, rootdir, valuename); break; } } @@ -207,9 +169,9 @@ tb_int_t xm_winos_registry_query(lua_State* lua) } while (0); // exit registry key - if (keynew != NULL) + if (keynew) RegCloseKey(keynew); - keynew = NULL; + keynew = tb_null; // exit value if (value) tb_free(value); diff --git a/xmake/core/base/winos.lua b/xmake/core/base/winos.lua index e50b79a92..a6498458a 100644 --- a/xmake/core/base/winos.lua +++ b/xmake/core/base/winos.lua @@ -23,10 +23,13 @@ local winos = winos or {} -- load modules local os = require("base/os") +local path = require("base/path") local semver = require("base/semver") -winos._ansi_cp = winos._ansi_cp or winos.ansi_cp -winos._oem_cp = winos._oem_cp or winos.oem_cp +winos._ansi_cp = winos._ansi_cp or winos.ansi_cp +winos._oem_cp = winos._oem_cp or winos.oem_cp +winos._registry_query = winos._registry_query or winos.registry_query +winos._registry_keys = winos._registry_keys or winos.registry_keys function winos.ansi_cp() if not winos._ANSI_CP then @@ -178,5 +181,89 @@ function winos.cmdargv(argv, key) return argv end +-- query registry value +-- +-- @param keypath the key path +-- @return the value and errors +-- +-- @code +-- local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug") +-- local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger") +-- @endcode +-- +function winos.registry_query(keypath) + + -- get value name + local splitinfo = keypath:split(';', {plain = true}) + local valuename = splitinfo[2] or "(Default)" + keypath = splitinfo[1] + + -- get rootkey, e.g. HKEY_LOCAL_MACHINE + local rootkey + local p = keypath:find("\\", 1, true) + if p then + rootkey = keypath:sub(1, p - 1) + end + if not rootkey then + return nil, "root key not found!" + end + + -- get the root directory + local rootdir = keypath:sub(p + 1) + + -- query value + return winos._registry_query(rootkey, rootdir, valuename) +end + +-- get registry key paths +-- +-- @param pattern the search pattern +-- uses "*" to match any part of a key path, +-- uses "**" to recurse into subkey paths. +-- @return the result array and errors +-- +-- @code +-- local keypaths, errors = winos.registry_keys("HKEY_LOCAL_MACHINE\\SOFTWARE\\*\\Windows NT\\*\\CurrentVersion\\AeDebug") +-- local keypaths, errors = winos.registry_keys("HKEY_LOCAL_MACHINE\\SOFTWARE\\**") +-- @endcode +-- +function winos.registry_keys(pattern) + + -- get rootkey, e.g. HKEY_LOCAL_MACHINE + local rootkey + local p = pattern:find("\\", 1, true) + if p then + rootkey = pattern:sub(1, p - 1) + end + if not rootkey then + return + end + + -- get the root directory + local rootdir = pattern:sub(p + 1) + p = rootdir:find("*", 1, true) + if p then + rootdir = path.directory(rootdir:sub(1, p - 1)) + end + + -- convert pattern to a lua pattern + pattern = path.pattern(pattern) + + -- find keys + return winos._registry_keys(rootkey, rootdir, pattern) +end + +-- get registry values from the given key path +-- +-- @param keypath the key path +-- @return the values array and errors +-- +-- @code +-- local values, errors = winos.registry_values("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug") +-- @endcode +-- +function winos.registry_values(keypath) +end + -- return module: winos return winos diff --git a/xmake/core/sandbox/modules/interpreter/winos.lua b/xmake/core/sandbox/modules/interpreter/winos.lua index 6787d9a3f..2a470c7fd 100644 --- a/xmake/core/sandbox/modules/interpreter/winos.lua +++ b/xmake/core/sandbox/modules/interpreter/winos.lua @@ -25,9 +25,11 @@ local winos = require("base/winos") local sandbox_winos = sandbox_winos or {} -- export some readonly interfaces -sandbox_winos.registry_query = winos.registry_query -sandbox_winos.logical_drives = winos.logical_drives -sandbox_winos.version = winos.version +sandbox_winos.registry_query = winos.registry_query +sandbox_winos.registry_keys = winos.registry_keys +sandbox_winos.registry_values = winos.registry_values +sandbox_winos.logical_drives = winos.logical_drives +sandbox_winos.version = winos.version -- return module return sandbox_winos diff --git a/xmake/core/sandbox/modules/winos.lua b/xmake/core/sandbox/modules/winos.lua index 1726897f8..0a8058a75 100644 --- a/xmake/core/sandbox/modules/winos.lua +++ b/xmake/core/sandbox/modules/winos.lua @@ -31,7 +31,6 @@ sandbox_winos.ansi_cp = winos.ansi_cp sandbox_winos.cp_info = winos.cp_info sandbox_winos.console_cp = winos.console_cp sandbox_winos.console_output_cp = winos.console_output_cp -sandbox_winos.registry_query = winos.registry_query sandbox_winos.logical_drives = winos.logical_drives sandbox_winos.cmdargv = winos.cmdargv @@ -44,6 +43,33 @@ function sandbox_winos.version() return winver end +-- query registry value +function sandbox_winos.registry_query(keypath) + local value, errors = winos.registry_query(keypath) + if not value then + raise(errors) + end + return value +end + +-- get registry keys +function sandbox_winos.registry_keys(pattern) + local keypaths, errors = winos.registry_keys(pattern) + if not keypaths then + raise(errors) + end + return keypaths +end + +-- get registry values +function sandbox_winos.registry_values(keypath) + local values, errors = winos.registry_values(keypath) + if not values then + raise(errors) + end + return values +end + -- return module return sandbox_winos |
