summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-12-26 00:43:58 +0800
committerruki <[email protected]>2020-12-26 00:43:58 +0800
commit9dd609f518388f7c62e241e7f1d5813df0ada6b1 (patch)
tree7b48cd4dadc2d756b562ac94fa1c98b8f7f1bb84
parentd9fb6826a45caafc94772ba63c87a3d2f023867e (diff)
improve registry
-rw-r--r--core/src/xmake/winos/registry_query.c88
-rw-r--r--xmake/core/base/winos.lua91
-rw-r--r--xmake/core/sandbox/modules/interpreter/winos.lua8
-rw-r--r--xmake/core/sandbox/modules/winos.lua28
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