diff options
| author | ruki <[email protected]> | 2020-12-26 00:48:22 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-12-26 00:48:22 +0800 |
| commit | e291913e1e1479acb9894bca364ac18948c609f5 (patch) | |
| tree | c1719903a7069e872740e7ade6141a65b388393b | |
| parent | 9045f4cd312de04cdfc316ba18094a036702bdfc (diff) | |
add stub registry keys and values
| -rw-r--r-- | core/src/xmake/engine.c | 4 | ||||
| -rw-r--r-- | core/src/xmake/winos/registry_keys.c | 182 | ||||
| -rw-r--r-- | core/src/xmake/winos/registry_values.c | 182 | ||||
| -rw-r--r-- | xmake/core/base/winos.lua | 9 |
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 |
