Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve registry #2222

Merged
merged 9 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/src/xmake/winos/registry_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,13 @@ tb_int_t xm_winos_registry_keys(lua_State* lua)
{
// get registry rootkey
if (!tb_strcmp(rootkey, "HKEY_CLASSES_ROOT")) key = HKEY_CLASSES_ROOT;
else if (!tb_strcmp(rootkey, "HKCR")) key = HKEY_CLASSES_ROOT;
else if (!tb_strcmp(rootkey, "HKEY_CURRENT_CONFIG")) key = HKEY_CURRENT_CONFIG;
else if (!tb_strcmp(rootkey, "HKCC")) key = HKEY_CURRENT_CONFIG;
else if (!tb_strcmp(rootkey, "HKEY_CURRENT_USER")) key = HKEY_CURRENT_USER;
else if (!tb_strcmp(rootkey, "HKCU")) key = HKEY_CURRENT_USER;
else if (!tb_strcmp(rootkey, "HKEY_LOCAL_MACHINE")) key = HKEY_LOCAL_MACHINE;
else if (!tb_strcmp(rootkey, "HKLM")) key = HKEY_LOCAL_MACHINE;
else if (!tb_strcmp(rootkey, "HKEY_USERS")) key = HKEY_USERS;
else
{
Expand Down
84 changes: 66 additions & 18 deletions core/src/xmake/winos/registry_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
/* //////////////////////////////////////////////////////////////////////////////////////
* 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);
// the RegGetValueW func type
typedef BOOL (WINAPI* xm_RegGetValueW_t)(HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);

/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
Expand All @@ -60,13 +60,19 @@ tb_int_t xm_winos_registry_query(lua_State* lua)
HKEY key = tb_null;
HKEY keynew = tb_null;
tb_char_t* value = tb_null;
tb_wchar_t* value_w = tb_null;
tb_size_t value_n = (tb_size_t)-1;
shuax marked this conversation as resolved.
Show resolved Hide resolved
do
{
// get registry rootkey
if (!tb_strcmp(rootkey, "HKEY_CLASSES_ROOT")) key = HKEY_CLASSES_ROOT;
else if (!tb_strcmp(rootkey, "HKCR")) key = HKEY_CLASSES_ROOT;
else if (!tb_strcmp(rootkey, "HKEY_CURRENT_CONFIG")) key = HKEY_CURRENT_CONFIG;
else if (!tb_strcmp(rootkey, "HKCC")) key = HKEY_CURRENT_CONFIG;
else if (!tb_strcmp(rootkey, "HKEY_CURRENT_USER")) key = HKEY_CURRENT_USER;
else if (!tb_strcmp(rootkey, "HKCU")) key = HKEY_CURRENT_USER;
else if (!tb_strcmp(rootkey, "HKEY_LOCAL_MACHINE")) key = HKEY_LOCAL_MACHINE;
else if (!tb_strcmp(rootkey, "HKLM")) key = HKEY_LOCAL_MACHINE;
else if (!tb_strcmp(rootkey, "HKEY_USERS")) key = HKEY_USERS;
else
{
Expand All @@ -75,82 +81,122 @@ tb_int_t xm_winos_registry_query(lua_State* lua)
break;
}

// attempt to load RegGetValueA
static xm_RegGetValueA_t s_RegGetValueA = tb_null;
if (!s_RegGetValueA)
// convert rootdir to wide characters
tb_wchar_t rootdir_w[TB_PATH_MAXN];
if (tb_atow(rootdir_w, rootdir, TB_PATH_MAXN) == (tb_size_t)-1)
{
lua_pushnil(lua);
lua_pushfstring(lua, "invalid registry rootkey:: %s", rootdir);
break;
}

// convert valuename to wide characters
tb_wchar_t valuename_w[TB_PATH_MAXN];
if (tb_atow(valuename_w, valuename, TB_PATH_MAXN) == (tb_size_t)-1)
{
lua_pushnil(lua);
lua_pushfstring(lua, "invalid registry valuename: %s", valuename);
break;
}

// attempt to load RegGetValueW
static xm_RegGetValueW_t s_RegGetValueW = tb_null;
if (!s_RegGetValueW)
{
// 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");
if (module) s_RegGetValueW = (xm_RegGetValueW_t)tb_dynamic_func(module, "RegGetValueW");
}

// get registry value
DWORD type = 0;
if (s_RegGetValueA)
if (s_RegGetValueW)
{
// get registry value size
DWORD valuesize = 0;
if (s_RegGetValueA(key, rootdir, valuename, RRF_RT_ANY, 0, tb_null, &valuesize) != ERROR_SUCCESS)
DWORD valuesize_w = 0;
if (s_RegGetValueW(key, rootdir_w, valuename_w, RRF_RT_ANY, 0, tb_null, &valuesize_w) != 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);
DWORD valuesize = valuesize_w * 2;
value = (tb_char_t*)tb_malloc0(valuesize);
tb_assert_and_check_break(value);
value_w = (tb_wchar_t*)tb_malloc0(valuesize_w);
tb_assert_and_check_break(value_w);

// get value result, we attempt to do not expand value if get failed
type = 0;
if (s_RegGetValueA(key, rootdir, valuename, RRF_RT_ANY, &type, (PVOID)value, &valuesize) != ERROR_SUCCESS &&
s_RegGetValueA(key, rootdir, valuename, RRF_RT_ANY | RRF_NOEXPAND, &type, (PVOID)value, &valuesize) != ERROR_SUCCESS)
if (s_RegGetValueW(key, rootdir_w, valuename_w, RRF_RT_ANY, &type, (PVOID)value_w, &valuesize_w) != ERROR_SUCCESS &&
s_RegGetValueW(key, rootdir_w, valuename_w, RRF_RT_ANY | RRF_NOEXPAND, &type, (PVOID)value_w, &valuesize_w) != ERROR_SUCCESS)
{
lua_pushnil(lua);
lua_pushfstring(lua, "get registry value failed: %s\\%s;%s", rootkey, rootdir, valuename);
break;
}

value_n = tb_wtoa(value, value_w, valuesize);
if (value_n == (tb_size_t)-1)
{
lua_pushnil(lua);
lua_pushfstring(lua, "wtoa 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)
if (RegOpenKeyExW(key, rootdir_w, 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)
DWORD valuesize_w = 0;
if (RegQueryValueExW(keynew, valuename_w, tb_null, tb_null, tb_null, &valuesize_w) != 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);
DWORD valuesize = valuesize_w * 2;
value = (tb_char_t*)tb_malloc0(valuesize);
tb_assert_and_check_break(value);
value_w = (tb_wchar_t*)tb_malloc0(valuesize_w);
tb_assert_and_check_break(value_w);

// get value result
type = 0;
if (RegQueryValueExA(keynew, valuename, tb_null, &type, (LPBYTE)value, &valuesize) != ERROR_SUCCESS)
if (RegQueryValueExW(keynew, valuename_w, tb_null, &type, (LPBYTE)value_w, &valuesize_w) != ERROR_SUCCESS)
{
lua_pushnil(lua);
lua_pushfstring(lua, "get registry value failed: %s\\%s;%s", rootkey, rootdir, valuename);
break;
}

value_n = tb_wtoa(value, value_w, valuesize);
if (value_n == (tb_size_t)-1)
{
lua_pushnil(lua);
lua_pushfstring(lua, "wtoa 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);
lua_pushlstring(lua, value, value_n);
ok = tb_true;
break;
case REG_DWORD:
Expand All @@ -177,6 +223,8 @@ tb_int_t xm_winos_registry_query(lua_State* lua)
// exit value
if (value) tb_free(value);
value = tb_null;
if (value_w) tb_free(value_w);
value_w = tb_null;

// ok?
return ok? 1 : 2;
Expand Down
4 changes: 4 additions & 0 deletions core/src/xmake/winos/registry_values.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,13 @@ tb_int_t xm_winos_registry_values(lua_State* lua)
{
// get registry rootkey
if (!tb_strcmp(rootkey, "HKEY_CLASSES_ROOT")) key = HKEY_CLASSES_ROOT;
else if (!tb_strcmp(rootkey, "HKCR")) key = HKEY_CLASSES_ROOT;
else if (!tb_strcmp(rootkey, "HKEY_CURRENT_CONFIG")) key = HKEY_CURRENT_CONFIG;
else if (!tb_strcmp(rootkey, "HKCC")) key = HKEY_CURRENT_CONFIG;
else if (!tb_strcmp(rootkey, "HKEY_CURRENT_USER")) key = HKEY_CURRENT_USER;
else if (!tb_strcmp(rootkey, "HKCU")) key = HKEY_CURRENT_USER;
else if (!tb_strcmp(rootkey, "HKEY_LOCAL_MACHINE")) key = HKEY_LOCAL_MACHINE;
else if (!tb_strcmp(rootkey, "HKLM")) key = HKEY_LOCAL_MACHINE;
else if (!tb_strcmp(rootkey, "HKEY_USERS")) key = HKEY_USERS;
else
{
Expand Down