diff options
| author | ruki <[email protected]> | 2020-12-26 17:12:03 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-12-26 17:12:03 +0800 |
| commit | 796cea61e572315240b42ef0a5328b113b8c44bb (patch) | |
| tree | 0c784b9125508c74917344898d50a231aa93fa35 /core/src | |
| parent | 0ffe195f2b6caaee85c3ca3ac7fc5444fdafbbbc (diff) | |
impl registry_keys
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/winos/registry_keys.c | 205 | ||||
| -rw-r--r-- | core/src/xmake/winos/registry_values.c | 3 |
2 files changed, 135 insertions, 73 deletions
diff --git a/core/src/xmake/winos/registry_keys.c b/core/src/xmake/winos/registry_keys.c index 42ad24f98..234cdf035 100644 --- a/core/src/xmake/winos/registry_keys.c +++ b/core/src/xmake/winos/registry_keys.c @@ -31,124 +31,114 @@ #include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// - * private implementation + * types */ -/* ////////////////////////////////////////////////////////////////////////////////////// - * implementation - */ - -/* get registry keys - * - * local count, errors = winos.registry_keys("HKEY_LOCAL_MACHINE", - * "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", - * function (key_path) - * return true -- continue or break - * end) - */ -tb_int_t xm_winos_registry_keys(lua_State* lua) +// the enum info type +typedef struct __xm_winos_registry_enum_info_t { - // check - tb_assert_and_check_return_val(lua, 0); + lua_State* lua; + HKEY key; + tb_int_t ok; + tb_char_t const* error; + tb_int_t count; + tb_wchar_t key_name[1024]; + tb_char_t key_path_a[TB_PATH_MAXN]; - // get the arguments - tb_char_t const* rootkey = luaL_checkstring(lua, 1); - tb_char_t const* rootdir = luaL_checkstring(lua, 2); - tb_bool_t is_function = lua_isfunction(lua, 3); - tb_check_return_val(rootkey && rootdir && is_function, 0); +}xm_winos_registry_enum_info_t; - // query key-value - tb_bool_t ok = tb_false; - tb_int_t count = 0; - HKEY key = tb_null; +/* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ +static tb_void_t xm_winos_registry_enum_keys(xm_winos_registry_enum_info_t* info, tb_wchar_t const* rootdir, tb_long_t recursion) +{ + // enum keys HKEY keynew = tb_null; - tb_char_t* value = tb_null; + lua_State* lua = info->lua; + tb_wchar_t* key_path = tb_null; + tb_size_t key_path_maxn = TB_PATH_MAXN; 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 + // open registry key + if (RegOpenKeyExW(info->key, rootdir, 0, KEY_READ, &keynew) != ERROR_SUCCESS && keynew) { - lua_pushnil(lua); - lua_pushfstring(lua, "invalid registry rootkey: %s", rootkey); + info->ok = -1; + info->error = "open registry key failed"; break; } - // open registry key - if (RegOpenKeyExA(key, rootdir, 0, KEY_READ, &keynew) != ERROR_SUCCESS && keynew) + // query keys + DWORD key_name_num = 0; + DWORD key_name_maxn = 0; + if (RegQueryInfoKeyW(keynew, tb_null, tb_null, tb_null, &key_name_num, &key_name_maxn, tb_null, tb_null, tb_null, tb_null, tb_null, tb_null) != ERROR_SUCCESS) { - lua_pushnil(lua); - lua_pushfstring(lua, "open registry key failed: %s\\%s", rootkey, rootdir); + // cannot query this key, we ignore it break; } + key_name_maxn++; // add `\0` - // query keys - DWORD key_path_num = 0; - DWORD key_path_maxn = 0; - if (RegQueryInfoKeyW(keynew, tb_null, tb_null, tb_null, &key_path_num, &key_path_maxn, tb_null, tb_null, tb_null, tb_null, tb_null, tb_null) != ERROR_SUCCESS) + // ensure enough key path buffer + if (key_name_maxn > tb_arrayn(info->key_name)) { - lua_pushnil(lua); - lua_pushfstring(lua, "query registry info failed: %s\\%s", rootkey, rootdir); + info->ok = -1; + info->error = "no enough key path buffer"; break; } - key_path_maxn++; // add `\0` - // ensure enough key path buffer - tb_wchar_t key_path[TB_PATH_MAXN]; - if (key_path_maxn > tb_arrayn(key_path)) + // init key path + key_path = (tb_wchar_t*)tb_malloc(key_path_maxn * sizeof(tb_wchar_t)); + if (!key_path) { - lua_pushnil(lua); - lua_pushfstring(lua, "no enough key path buffer: %s\\%s", rootkey, rootdir); + info->ok = -1; + info->error = "no enough key path buffer"; break; } // get all keys DWORD i = 0; - tb_char_t key_path_a[TB_PATH_MAXN]; - for (i = 0; i < key_path_num; i++) + for (i = 0; i < key_name_num && info->ok > 0; i++) { - // get key path - key_path[0] = L'\0'; - DWORD key_path_size = tb_arrayn(key_path); - if (RegEnumKeyExW(keynew, i, key_path, &key_path_size, tb_null, tb_null, tb_null, tb_null) != ERROR_SUCCESS) + // get key name + info->key_name[0] = L'\0'; + DWORD key_name_size = tb_arrayn(info->key_name); + if (RegEnumKeyExW(keynew, i, info->key_name, &key_name_size, tb_null, tb_null, tb_null, tb_null) != ERROR_SUCCESS) { - lua_pushnil(lua); - lua_pushfstring(lua, "get registry key path(%d) failed: %s\\%s", i, rootkey, rootdir); + info->ok = -1; + info->error = "get registry key failed"; break; } + // get key path + tb_swprintf(key_path, key_path_maxn, L"%s\\%s", rootdir, info->key_name); + // get key path (mbs) - tb_size_t key_path_a_size = tb_wtoa(key_path_a, key_path, sizeof(key_path_a)); + tb_size_t key_path_a_size = tb_wtoa(info->key_path_a, key_path, sizeof(info->key_path_a)); if (key_path_a_size == -1) { - lua_pushnil(lua); - lua_pushfstring(lua, "convert registry key path(%d) failed: %s\\%s", i, rootkey, rootdir); + info->ok = -1; + info->error = "convert registry key path failed"; break; } - // do callback(key_path) - lua_pushvalue(lua, 3); - lua_pushlstring(lua, key_path_a, key_path_a_size); + // do callback(key_name) + lua_pushvalue(lua, 4); + lua_pushlstring(lua, info->key_path_a, key_path_a_size); lua_call(lua, 1, 1); - count++; + info->count++; // is continue? tb_bool_t is_continue = lua_toboolean(lua, -1); lua_pop(lua, 1); if (!is_continue) { - ok = tb_true; + info->ok = 0; break; } - } - // ok - if (i == key_path_num) - ok = tb_true; + // enum all subkeys + if (recursion > 0 || recursion < 0) + xm_winos_registry_enum_keys(info, key_path, recursion > 0? recursion - 1 : recursion); + } } while (0); @@ -157,6 +147,79 @@ tb_int_t xm_winos_registry_keys(lua_State* lua) RegCloseKey(keynew); keynew = tb_null; + // free key path + if (key_path) tb_free(key_path); + key_path = tb_null; +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ + +/* get registry keys + * + * local count, errors = winos.registry_keys("HKEY_LOCAL_MACHINE", + * "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", + * function (key_path) + * return true -- continue or break + * end) + */ +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_long_t recursion = lua_tointeger(lua, 3); + tb_bool_t is_function = lua_isfunction(lua, 4); + tb_check_return_val(rootkey && rootdir && is_function, 0); + + // enum keys + tb_bool_t ok = tb_false; + tb_int_t count = 0; + HKEY key = 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; + } + + // do enum + tb_wchar_t rootdir_w[TB_PATH_MAXN]; + if (tb_atow(rootdir_w, rootdir, TB_PATH_MAXN) == -1) + { + lua_pushnil(lua); + lua_pushfstring(lua, "rootdir is too long: %s", rootdir); + break; + } + xm_winos_registry_enum_info_t info; + info.lua = lua; + info.key = key; + info.count = 0; + info.ok = tb_true; + info.error = tb_null; + xm_winos_registry_enum_keys(&info, rootdir_w, recursion); + count = info.count; + ok = info.ok >= 0; + if (!ok) + { + lua_pushnil(lua); + lua_pushfstring(lua, "%s: %s\\%s", info.error? info.error : "enum registry keys failed", rootkey, rootdir); + } + + } while (0); + // ok? if (ok) { diff --git a/core/src/xmake/winos/registry_values.c b/core/src/xmake/winos/registry_values.c index 7a9211007..17aefef6e 100644 --- a/core/src/xmake/winos/registry_values.c +++ b/core/src/xmake/winos/registry_values.c @@ -53,12 +53,11 @@ tb_int_t xm_winos_registry_values(lua_State* lua) tb_bool_t is_function = lua_isfunction(lua, 3); tb_check_return_val(rootkey && rootdir && is_function, 0); - // query key-value + // enum values tb_bool_t ok = tb_false; tb_int_t count = 0; HKEY key = tb_null; HKEY keynew = tb_null; - tb_char_t* value = tb_null; do { // get registry rootkey |
