diff options
| author | ruki <[email protected]> | 2017-05-30 23:14:27 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-05-30 23:14:27 +0800 |
| commit | f01d5364141a3e2a965bd9d46e65a2bd851e27ec (patch) | |
| tree | 6d56fb256655efa493021ee1a340368407c2c7c2 | |
| parent | af5040e4c197ce261062b925743201358dc5e43c (diff) | |
add winreg.query and improve program
| -rw-r--r-- | core/pkg/base.pkg/xmake.lua | 2 | ||||
| -rw-r--r-- | core/src/xmake/machine.c | 19 | ||||
| -rw-r--r-- | core/src/xmake/makefile | 1 | ||||
| -rw-r--r-- | core/src/xmake/winreg/prefix.h | 39 | ||||
| -rw-r--r-- | core/src/xmake/winreg/query.c | 235 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/lib/detect/find_program.lua | 46 | ||||
| -rw-r--r-- | xmake/modules/detect/tool/find_ollydbg.lua | 18 | ||||
| -rw-r--r-- | xmake/modules/detect/tool/find_vsjitdebugger.lua | 18 | ||||
| -rw-r--r-- | xmake/modules/detect/tool/find_windbg.lua | 18 | ||||
| -rw-r--r-- | xmake/modules/detect/tool/find_x64dbg.lua | 18 | ||||
| -rw-r--r-- | xmake/platforms/windows/check.lua | 59 |
11 files changed, 357 insertions, 116 deletions
diff --git a/core/pkg/base.pkg/xmake.lua b/core/pkg/base.pkg/xmake.lua index db521e677..92d1ced6d 100644 --- a/core/pkg/base.pkg/xmake.lua +++ b/core/pkg/base.pkg/xmake.lua @@ -5,7 +5,7 @@ option("base") set_category("package") -- add links - if is_os("windows") then add_links("ws2_32") + if is_os("windows") then add_links("ws2_32", "Advapi32") elseif is_os("android") then add_links("m", "c") else add_links("pthread", "dl", "m", "c") end diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c index 0281f0a2c..e1638e1ab 100644 --- a/core/src/xmake/machine.c +++ b/core/src/xmake/machine.c @@ -93,6 +93,11 @@ tb_int_t xm_path_absolute(lua_State* lua); tb_int_t xm_path_translate(lua_State* lua); tb_int_t xm_path_is_absolute(lua_State* lua); +// the winreg functions +#ifdef TB_CONFIG_OS_WINDOWS +tb_int_t xm_winreg_query(lua_State* lua); +#endif + // the string functions tb_int_t xm_string_strcmp(lua_State* lua); tb_int_t xm_string_endswith(lua_State* lua); @@ -173,6 +178,15 @@ static luaL_Reg const g_string_functions[] = , { tb_null, tb_null } }; +#ifdef TB_CONFIG_OS_WINDOWS +// the winreg functions +static luaL_Reg const g_winreg_functions[] = +{ + { "query", xm_winreg_query } +, { tb_null, tb_null } +}; +#endif + // the process functions static luaL_Reg const g_process_functions[] = { @@ -419,6 +433,11 @@ xm_machine_ref_t xm_machine_init() // bind sandbox functions luaL_register(impl->lua, "sandbox", g_sandbox_functions); + // bind winreg functions +#ifdef TB_CONFIG_OS_WINDOWS + luaL_register(impl->lua, "winreg", g_winreg_functions); +#endif + #ifdef XM_CONFIG_API_HAVE_READLINE // bind readline functions luaL_register(impl->lua, "readline", g_readline_functions); diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile index c7b1ffc29..efc32d94d 100644 --- a/core/src/xmake/makefile +++ b/core/src/xmake/makefile @@ -44,6 +44,7 @@ xmake_C_FILES += \ path/absolute \ path/translate \ path/is_absolute \ + winreg/query \ string/strcmp \ string/endswith \ string/startswith \ diff --git a/core/src/xmake/winreg/prefix.h b/core/src/xmake/winreg/prefix.h new file mode 100644 index 000000000..45fe6f42c --- /dev/null +++ b/core/src/xmake/winreg/prefix.h @@ -0,0 +1,39 @@ +/*!The Make-like Build Utility based on Lua + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 - 2017, TBOOX Open Source Group. + * + * @author TitanSnow + * @file prefix.h + * + */ +#ifndef XM_WINREG_PREFIX_H +#define XM_WINREG_PREFIX_H + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "../prefix.h" +#ifdef TB_CONFIG_OS_WINDOWS +#include <windows.h> +#endif + + +#endif + + diff --git a/core/src/xmake/winreg/query.c b/core/src/xmake/winreg/query.c new file mode 100644 index 000000000..036d4a7c3 --- /dev/null +++ b/core/src/xmake/winreg/query.c @@ -0,0 +1,235 @@ +/*!The Make-like Build Utility based on Lua + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 - 2017, TBOOX Open Source Group. + * + * @author TitanSnow, ruki + * @file query.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "query" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * types + */ +#ifdef TB_CONFIG_OS_WINDOWS +// the RegGetValueA func type +typedef BOOL (WINAPI* xm_RegGetValueA_t)(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData); +#endif + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ + +#ifdef TB_CONFIG_OS_WINDOWS + +/* query registry + * + * local value, errors = winreg.query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger") + */ +tb_int_t xm_winreg_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); + + // query key-value + tb_bool_t ok = tb_false; + HKEY key = NULL; + HKEY keynew = NULL; + tb_char_t pathbuf[TB_PATH_MAXN]; + 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'; + } + if (!valuename) + { + lua_pushnil(lua); + lua_pushfstring(lua, "parse value name failed: %s", path); + break; + } + + // trace + tb_trace_d("key: %s, subkey: %s, name: %s", pathkey, pathsubkey, valuename); + + // 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; + else + { + lua_pushnil(lua); + lua_pushfstring(lua, "invalid registry path: %s", path); + 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, pathsubkey, valuename, RRF_RT_ANY, 0, tb_null, &valuesize) != ERROR_SUCCESS) + { + lua_pushnil(lua); + lua_pushfstring(lua, "get registry value size failed: %s", path); + break; + } + + // make value buffer + value = (tb_char_t*)tb_malloc0(valuesize); + tb_assert_and_check_break(value); + + // get value result + type = 0; + if (s_RegGetValueA(key, pathsubkey, valuename, RRF_RT_ANY, &type, (PVOID)value, &valuesize) != ERROR_SUCCESS) + { + lua_pushnil(lua); + lua_pushfstring(lua, "get registry value failed: %s", path); + break; + } + } + else + { + // open registry key + if (RegOpenKeyExA(key, pathsubkey, 0, KEY_QUERY_VALUE, &keynew) != ERROR_SUCCESS && keynew) + { + lua_pushnil(lua); + lua_pushfstring(lua, "open registry key failed: %s", path); + break; + } + + // get registry value size + DWORD valuesize = 0; + if (RegQueryValueEx(keynew, valuename, tb_null, tb_null, tb_null, &valuesize) != ERROR_SUCCESS) + { + lua_pushnil(lua); + lua_pushfstring(lua, "get registry value size failed: %s", path); + break; + } + + // make value buffer + value = (tb_char_t*)tb_malloc0(valuesize); + tb_assert_and_check_break(value); + + // get value result + type = 0; + if (RegQueryValueEx(keynew, valuename, tb_null, &type, (LPBYTE)value, &valuesize) != ERROR_SUCCESS) + { + lua_pushnil(lua); + lua_pushfstring(lua, "get registry value failed: %s", path); + 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 != NULL) + RegCloseKey(keynew); + keynew = NULL; + + // exit value + if (value) tb_free(value); + value = tb_null; + + // ok? + return ok? 1 : 2; +} +#endif diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua index 2f6f8b2ab..7ee0fb5a9 100644 --- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua +++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua @@ -63,7 +63,7 @@ function sandbox_lib_detect_find_program._check(program, check) end -- find program -function sandbox_lib_detect_find_program._find(name, dirs, check) +function sandbox_lib_detect_find_program._find(name, pathes, check) -- attempt to check it directly in current environment if sandbox_lib_detect_find_program._check(name, check) then @@ -72,14 +72,36 @@ function sandbox_lib_detect_find_program._find(name, dirs, check) -- attempt to check it from the given directories if not path.is_absolute(name) then - for _, dir in ipairs(table.wrap(dirs)) do + for _, _path in ipairs(table.wrap(pathes)) do - -- TODO - -- dir is registry path? + -- handle winreg value .e.g [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name]\\dir\\file + _path = _path:gsub("%[(.*)%]", function (regpath) + + -- get registry value + local value, errors = winreg.query(regpath) + if not value then + raise(errors) + end + + -- file path not exists? attempt to parse path from `"path" xxx` + if not os.exists(value) then + value = value:match("\"(.-)\"") + end + + -- ok + return value + end) + + -- get program path + local program_path = nil + if os.isfile(_path) then + program_path = _path + elseif os.isdir(_path) then + program_path = path.join(_path, name) + end -- the program path - local program_path = path.join(dir, name) - if os.isexec(program_path) then + if program_path and os.isexec(program_path) then -- check it if sandbox_lib_detect_find_program._check(program_path, check) then return program_path @@ -105,11 +127,11 @@ end -- find program -- --- @param name the program name --- @param dirs the program directories --- @param check the check script or command +-- @param name the program name +-- @param pathes the program pathes (.e.g dirs, pathes, winreg pathes) +-- @param check the check script or command -- --- @return the program name or path +-- @return the program name or path -- -- @code -- @@ -120,7 +142,7 @@ end -- -- @endcode -- -function sandbox_lib_detect_find_program.main(name, dirs, check) +function sandbox_lib_detect_find_program.main(name, pathes, check) -- get detect cache local detectcache = cache(utils.ifelse(os.isfile(project.file()), "local.detect", "memory.detect")) @@ -133,7 +155,7 @@ function sandbox_lib_detect_find_program.main(name, dirs, check) end -- find executable program - result = sandbox_lib_detect_find_program._find(name, dirs, check) + result = sandbox_lib_detect_find_program._find(name, pathes, check) -- cache result cacheinfo[name] = utils.ifelse(result, result, false) diff --git a/xmake/modules/detect/tool/find_ollydbg.lua b/xmake/modules/detect/tool/find_ollydbg.lua index 0075e9eb8..3afd51276 100644 --- a/xmake/modules/detect/tool/find_ollydbg.lua +++ b/xmake/modules/detect/tool/find_ollydbg.lua @@ -46,16 +46,12 @@ function main(opt) if os.host() ~= "windows" then return end - - -- find program, TODO from winreg - local program = find_program(opt.program or "ollydbg", {}) - - -- find program version - local version = nil - if program and opt and opt.version then - version = find_programver(program) - end - -- ok? - return program, version + -- init options + opt = opt or {} + + -- find program + return find_program(opt.program or "ollydbg", {"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]"} + , function (program) if not os.isfile(program) then raise() end end) end diff --git a/xmake/modules/detect/tool/find_vsjitdebugger.lua b/xmake/modules/detect/tool/find_vsjitdebugger.lua index bc7b12144..0d3368c72 100644 --- a/xmake/modules/detect/tool/find_vsjitdebugger.lua +++ b/xmake/modules/detect/tool/find_vsjitdebugger.lua @@ -46,16 +46,12 @@ function main(opt) if os.host() ~= "windows" then return end - - -- find program, TODO from winreg - local program = find_program(opt.program or "vsjitdebugger", {}) - - -- find program version - local version = nil - if program and opt and opt.version then - version = find_programver(program) - end - -- ok? - return program, version + -- init options + opt = opt or {} + + -- find program + return find_program(opt.program or "vsjitdebugger", {"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]"} + , function (program) if not os.isfile(program) then raise() end end) end diff --git a/xmake/modules/detect/tool/find_windbg.lua b/xmake/modules/detect/tool/find_windbg.lua index 89d9e2563..f42469698 100644 --- a/xmake/modules/detect/tool/find_windbg.lua +++ b/xmake/modules/detect/tool/find_windbg.lua @@ -47,15 +47,11 @@ function main(opt) return end - -- find program, TODO from winreg - local program = find_program(opt.program or "windbg", {}) - - -- find program version - local version = nil - if program and opt and opt.version then - version = find_programver(program) - end - - -- ok? - return program, version + -- init options + opt = opt or {} + + -- find program + return find_program(opt.program or "windbg", {"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]"} + , function (program) if not os.isfile(program) then raise() end end) end diff --git a/xmake/modules/detect/tool/find_x64dbg.lua b/xmake/modules/detect/tool/find_x64dbg.lua index be6c73155..38b8a5004 100644 --- a/xmake/modules/detect/tool/find_x64dbg.lua +++ b/xmake/modules/detect/tool/find_x64dbg.lua @@ -46,16 +46,12 @@ function main(opt) if os.host() ~= "windows" then return end - - -- find program, TODO from winreg - local program = find_program(opt.program or "x64dbg", {}) - - -- find program version - local version = nil - if program and opt and opt.version then - version = find_programver(program) - end - -- ok? - return program, version + -- init options + opt = opt or {} + + -- find program + return find_program(opt.program or "x64dbg", {"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger]"} + , function (program) if not os.isfile(program) then raise() end end) end diff --git a/xmake/platforms/windows/check.lua b/xmake/platforms/windows/check.lua index cb7e78eb1..8a442a0fe 100644 --- a/xmake/platforms/windows/check.lua +++ b/xmake/platforms/windows/check.lua @@ -199,64 +199,6 @@ function _check_vs(config) end end --- check the debugger -function _check_debugger(config) - - -- get debugger - local debugger = config.get("dg") - if debugger then - return - end - - -- query the debugger info for x64 - local info = try - { - function () - return os.iorun("reg query \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\" /v Debugger") - end - } - -- query the debugger info for x86 - if not info then - info = try - { - function () - return os.iorun("reg query \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\" /v Debugger") - end - } - end - - -- parse the debugger path - -- - -- ! REG.EXE VERSION 3.0 - -- - -- HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug - -- Debugger REG_SZ "C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld - if info then - debugger = info:match("Debugger%s+REG_SZ%s+\"(.+)\"") - if debugger then - debugger = debugger:trim() - end - end - - -- this debugger exists? - if debugger and path.is_absolute(debugger) and not os.isfile(debugger) then - debugger = nil - end - - -- check ok? update it - if debugger then - - -- save it - config.set("dg", debugger) - - -- trace - print("checking for the debugger ... %s", path.filename(debugger)) - else - -- failed - print("checking for the debugger ... no") - end -end - -- get toolchains function _toolchains(config) @@ -350,7 +292,6 @@ function main(kind, toolkind) { { checker.check_arch, "x86" } , _check_vs - , _check_debugger } -- init the check list of global |
