summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-12-26 00:48:22 +0800
committerruki <[email protected]>2020-12-26 00:48:22 +0800
commite291913e1e1479acb9894bca364ac18948c609f5 (patch)
treec1719903a7069e872740e7ade6141a65b388393b
parent9045f4cd312de04cdfc316ba18094a036702bdfc (diff)
add stub registry keys and values
-rw-r--r--core/src/xmake/engine.c4
-rw-r--r--core/src/xmake/winos/registry_keys.c182
-rw-r--r--core/src/xmake/winos/registry_values.c182
-rw-r--r--xmake/core/base/winos.lua9
4 files changed, 373 insertions, 4 deletions
diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c
index b4d2b7101..71b202689 100644
--- a/core/src/xmake/engine.c
+++ b/core/src/xmake/engine.c
@@ -185,6 +185,8 @@ tb_int_t xm_winos_ansi_cp(lua_State* lua);
tb_int_t xm_winos_oem_cp(lua_State* lua);
tb_int_t xm_winos_logical_drives(lua_State* lua);
tb_int_t xm_winos_registry_query(lua_State* lua);
+tb_int_t xm_winos_registry_keys(lua_State* lua);
+tb_int_t xm_winos_registry_values(lua_State* lua);
#endif
// the string functions
@@ -287,6 +289,8 @@ static luaL_Reg const g_winos_functions[] =
, { "ansi_cp", xm_winos_ansi_cp }
, { "logical_drives", xm_winos_logical_drives }
, { "registry_query", xm_winos_registry_query }
+, { "registry_keys", xm_winos_registry_keys }
+, { "registry_values", xm_winos_registry_values }
, { tb_null, tb_null }
};
#endif
diff --git a/core/src/xmake/winos/registry_keys.c b/core/src/xmake/winos/registry_keys.c
new file mode 100644
index 000000000..3f70c29cd
--- /dev/null
+++ b/core/src/xmake/winos/registry_keys.c
@@ -0,0 +1,182 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file registry_keys.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "registry_keys"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * types
+ */
+// the RegGetValueA func type
+typedef BOOL (WINAPI* xm_RegGetValueA_t)(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/* get registry keys
+ *
+ * local value, errors = winos.registry_keys("HKEY_LOCAL_MACHINE", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", "Debugger")
+ */
+tb_int_t xm_winos_registry_keys(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 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 = tb_null;
+ HKEY keynew = tb_null;
+ tb_char_t* value = tb_null;
+ do
+ {
+ // 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 rootkey: %s", rootkey);
+ break;
+ }
+
+ // attempt to load RegGetValueA
+ static xm_RegGetValueA_t s_RegGetValueA = tb_null;
+ if (!s_RegGetValueA)
+ {
+ // load the advapi32 module
+ tb_dynamic_ref_t module = (tb_dynamic_ref_t)GetModuleHandleA("advapi32.dll");
+ if (!module) module = tb_dynamic_init("advapi32.dll");
+ if (module) s_RegGetValueA = (xm_RegGetValueA_t)tb_dynamic_func(module, "RegGetValueA");
+ }
+
+ // get registry value
+ DWORD type = 0;
+ if (s_RegGetValueA)
+ {
+ // get registry value size
+ DWORD valuesize = 0;
+ 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\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+
+ // make value buffer
+ value = (tb_char_t*)tb_malloc0(valuesize + 1);
+ tb_assert_and_check_break(value);
+
+ // get value result
+ type = 0;
+ 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\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+ }
+ else
+ {
+ // open registry key
+ if (RegOpenKeyExA(key, rootdir, 0, KEY_QUERY_VALUE, &keynew) != ERROR_SUCCESS && keynew)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "open registry key failed: %s\\%s", rootkey, rootdir);
+ break;
+ }
+
+ // get registry value size
+ DWORD valuesize = 0;
+ 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\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+
+ // make value buffer
+ value = (tb_char_t*)tb_malloc0(valuesize + 1);
+ tb_assert_and_check_break(value);
+
+ // get value result
+ type = 0;
+ if (RegQueryValueExA(keynew, valuename, tb_null, &type, (LPBYTE)value, &valuesize) != ERROR_SUCCESS)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "get registry value failed: %s\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+ }
+
+ // save result
+ switch (type)
+ {
+ case REG_SZ:
+ case REG_EXPAND_SZ:
+ lua_pushstring(lua, value);
+ ok = tb_true;
+ break;
+ case REG_DWORD:
+ lua_pushfstring(lua, "%d", *((tb_int_t*)value));
+ ok = tb_true;
+ break;
+ case REG_QWORD:
+ lua_pushfstring(lua, "%lld", *((tb_int64_t*)value));
+ ok = tb_true;
+ break;
+ default:
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "unsupported registry value type: %d", type);
+ break;
+ }
+
+ } while (0);
+
+ // exit registry key
+ if (keynew)
+ RegCloseKey(keynew);
+ keynew = tb_null;
+
+ // exit value
+ if (value) tb_free(value);
+ value = tb_null;
+
+ // ok?
+ return ok? 1 : 2;
+}
diff --git a/core/src/xmake/winos/registry_values.c b/core/src/xmake/winos/registry_values.c
new file mode 100644
index 000000000..f52357c94
--- /dev/null
+++ b/core/src/xmake/winos/registry_values.c
@@ -0,0 +1,182 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file registry_values.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "registry_values"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * types
+ */
+// the RegGetValueA func type
+typedef BOOL (WINAPI* xm_RegGetValueA_t)(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/* get registry values
+ *
+ * local value, errors = winos.registry_values("HKEY_LOCAL_MACHINE", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", "Debugger")
+ */
+tb_int_t xm_winos_registry_values(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 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 = tb_null;
+ HKEY keynew = tb_null;
+ tb_char_t* value = tb_null;
+ do
+ {
+ // 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 rootkey: %s", rootkey);
+ break;
+ }
+
+ // attempt to load RegGetValueA
+ static xm_RegGetValueA_t s_RegGetValueA = tb_null;
+ if (!s_RegGetValueA)
+ {
+ // load the advapi32 module
+ tb_dynamic_ref_t module = (tb_dynamic_ref_t)GetModuleHandleA("advapi32.dll");
+ if (!module) module = tb_dynamic_init("advapi32.dll");
+ if (module) s_RegGetValueA = (xm_RegGetValueA_t)tb_dynamic_func(module, "RegGetValueA");
+ }
+
+ // get registry value
+ DWORD type = 0;
+ if (s_RegGetValueA)
+ {
+ // get registry value size
+ DWORD valuesize = 0;
+ 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\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+
+ // make value buffer
+ value = (tb_char_t*)tb_malloc0(valuesize + 1);
+ tb_assert_and_check_break(value);
+
+ // get value result
+ type = 0;
+ 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\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+ }
+ else
+ {
+ // open registry key
+ if (RegOpenKeyExA(key, rootdir, 0, KEY_QUERY_VALUE, &keynew) != ERROR_SUCCESS && keynew)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "open registry key failed: %s\\%s", rootkey, rootdir);
+ break;
+ }
+
+ // get registry value size
+ DWORD valuesize = 0;
+ 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\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+
+ // make value buffer
+ value = (tb_char_t*)tb_malloc0(valuesize + 1);
+ tb_assert_and_check_break(value);
+
+ // get value result
+ type = 0;
+ if (RegQueryValueExA(keynew, valuename, tb_null, &type, (LPBYTE)value, &valuesize) != ERROR_SUCCESS)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "get registry value failed: %s\\%s;%s", rootkey, rootdir, valuename);
+ break;
+ }
+ }
+
+ // save result
+ switch (type)
+ {
+ case REG_SZ:
+ case REG_EXPAND_SZ:
+ lua_pushstring(lua, value);
+ ok = tb_true;
+ break;
+ case REG_DWORD:
+ lua_pushfstring(lua, "%d", *((tb_int_t*)value));
+ ok = tb_true;
+ break;
+ case REG_QWORD:
+ lua_pushfstring(lua, "%lld", *((tb_int64_t*)value));
+ ok = tb_true;
+ break;
+ default:
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "unsupported registry value type: %d", type);
+ break;
+ }
+
+ } while (0);
+
+ // exit registry key
+ if (keynew)
+ RegCloseKey(keynew);
+ keynew = tb_null;
+
+ // exit value
+ if (value) tb_free(value);
+ value = tb_null;
+
+ // ok?
+ return ok? 1 : 2;
+}
diff --git a/xmake/core/base/winos.lua b/xmake/core/base/winos.lua
index 2492dc76d..483dbbd9f 100644
--- a/xmake/core/base/winos.lua
+++ b/xmake/core/base/winos.lua
@@ -26,10 +26,11 @@ 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._registry_query = winos._registry_query or winos.registry_query
-winos._registry_keys = winos._registry_keys or winos.registry_keys
+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
+winos._registry_values = winos._registry_values or winos.registry_values
function winos.ansi_cp()
if not winos._ANSI_CP then