summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-05-30 23:14:27 +0800
committerruki <[email protected]>2017-05-30 23:14:27 +0800
commitf01d5364141a3e2a965bd9d46e65a2bd851e27ec (patch)
tree6d56fb256655efa493021ee1a340368407c2c7c2
parentaf5040e4c197ce261062b925743201358dc5e43c (diff)
add winreg.query and improve program
-rw-r--r--core/pkg/base.pkg/xmake.lua2
-rw-r--r--core/src/xmake/machine.c19
-rw-r--r--core/src/xmake/makefile1
-rw-r--r--core/src/xmake/winreg/prefix.h39
-rw-r--r--core/src/xmake/winreg/query.c235
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_program.lua46
-rw-r--r--xmake/modules/detect/tool/find_ollydbg.lua18
-rw-r--r--xmake/modules/detect/tool/find_vsjitdebugger.lua18
-rw-r--r--xmake/modules/detect/tool/find_windbg.lua18
-rw-r--r--xmake/modules/detect/tool/find_x64dbg.lua18
-rw-r--r--xmake/platforms/windows/check.lua59
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