diff options
Diffstat (limited to '3rdparty/lua/src/modules/lua-winreg/src/winreg.c')
-rw-r--r-- | 3rdparty/lua/src/modules/lua-winreg/src/winreg.c | 1392 |
1 files changed, 696 insertions, 696 deletions
diff --git a/3rdparty/lua/src/modules/lua-winreg/src/winreg.c b/3rdparty/lua/src/modules/lua-winreg/src/winreg.c index 363c1c2..87b518a 100644 --- a/3rdparty/lua/src/modules/lua-winreg/src/winreg.c +++ b/3rdparty/lua/src/modules/lua-winreg/src/winreg.c @@ -1,697 +1,697 @@ -#ifdef _LUAMSVC -# include <luamsvc.h> -#endif - -#include <assert.h> -#ifndef lua_assert -#define lua_assert assert -#endif - -#include <lua.h> -#include <lualib.h> -#include <lauxlib.h> -#include "l52util.h" - -#include "stdmacro.h" -#include "luamacro.h" -#include "luawinmacro.h" - -#include "lua_tstring.h" -#include "lua_int64.h" -#include "lua_mtutil.h" -#include "luawin_dllerror.h" - -#include "win_trace.h" -#include "win_privileges.h" -#include "win_registry.h" - -#define LUA_REG_DEFINE_EXTERNS -#include "luareg.h" - -#define lua_error_invalid_option(L, i) luaL_argerror(L, (i), "invalid option") -#define lrk_hkey "{afx/hkey}" - -#ifndef HKEY_PERFORMANCE_TEXT -#define HKEY_PERFORMANCE_TEXT (( HKEY )((LONG)0x80000050) ) -#define HKEY_PERFORMANCE_NLSTEXT (( HKEY )((LONG)0x80000060) ) -#endif -#ifndef REG_QWORD -#define REG_QWORD ( 11 ) // 64-bit number -#endif - -#ifndef LUA_REG_NO_DLL -BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ - UNUSED(hModule); - UNUSED(lpReserved); - UNUSED(ul_reason_for_call); - return TRUE; -} - -__declspec(dllexport) -#endif -int luaopen_winreg(lua_State *L){ - luaL_register(L, "winreg", lreg_reglib); - return 1; -} -#define reg_aux_gethkey(L,index) (*((PHKEY)luaL_checkudata(L, index, lrk_hkey))) -#define reg_aux_getphkey(L,index) ((PHKEY)luaL_checkudata(L, index, lrk_hkey)) - -typedef struct HKEY_DATA{ - HKEY hkey; - DWORD opt; -} HKEY_DATA, *PHKEY_DATA; - -int reg_aux_newhkey(lua_State *L, PHKEY pHKey){ - PHKEY phKey = (PHKEY)lua_newuserdatamt(L, sizeof(HKEY), lrk_hkey, lreg_regobj); - return phKey && pHKey && (NULL != (*phKey = *pHKey)); -} - -int reg_aux_newkey(lua_State *L, HKEY HKey, LPCTSTR szKey, LPCTSTR szClass, REGSAM samDesired, BOOL bCreate){ - DWORD dwDis = (bCreate==FALSE) ? REG_OPENED_EXISTING_KEY : 0; - HKEY hKey = NULL; - LONG ret = (bCreate - ? RegCreateKeyEx(HKey, szKey, 0, (PTSTR)szClass, 0, samDesired, NULL, &hKey, &dwDis) - : RegOpenKeyEx(HKey, szKey, 0, samDesired, &hKey) - ); - //WIN_TRACET(_T("%hs: hkey<%x>, sub<%s>, cls<%s>, acc<%d>;"), bCreate?"createkey":"openkey", HKey, szKey, szClass, samDesired); - - if(ret == ERROR_SUCCESS){ - reg_aux_newhkey(L, &hKey); - return dwDis; - }else{ - // if we're opening a key, dont shout the error - // just return nil - // this will test if the key exist - if(bCreate){ - LUA_CHECK_DLL_ERROR(L,ret); - } - lua_pushnil(L); - return 0; - } -} - -REGSAM reg_aux_getaccess(lua_State *L, int i){ - REGSAM acc = 0; - if(lua_isnumber(L, i) || lua_isnoneornil(L, i)){ - acc = lua_optint(L, i, KEY_ALL_ACCESS); - }else{ - const char * psz = lua_checkstring(L, i); - for(;*psz;psz++){ - switch(*psz){ - case 'w': acc |= KEY_WRITE; break; - case 'r': acc |= KEY_READ ; break; - case 'a': acc |= KEY_ALL_ACCESS ; break; -#ifdef KEY_WOW64_64KEY - case '6': if(*++psz == '4') { - // Access a 64-bit key from either a 32-bit or 64-bit application - acc |= KEY_WOW64_64KEY; - break; - } -#endif -#ifdef KEY_WOW64_32KEY - case '3': if(*++psz == '2') { - // Access a 64-bit key from either a 32-bit or 64-bit application - acc |= KEY_WOW64_32KEY; - break; - } -#endif - default : lua_error_invalid_option(L, i); - } - } - } - return acc; -} - -typedef struct KVDATA{ - const char * name; - size_t data; -} KVDATA, *PKVDATA; - -HKEY reg_aux_strtohkey(lua_State *L, const char * psz){ - static KVDATA ph[] = { - {"HKEY_CLASSES_ROOT", (size_t)HKEY_CLASSES_ROOT}, - {"HKEY_CURRENT_USER", (size_t)HKEY_CURRENT_USER}, - {"HKEY_LOCAL_MACHINE", (size_t)HKEY_LOCAL_MACHINE}, - {"HKEY_USERS", (size_t)HKEY_USERS}, - {"HKEY_PERFORMANCE_DATA", (size_t)HKEY_PERFORMANCE_DATA}, - {"HKEY_PERFORMANCE_TEXT", (size_t)HKEY_PERFORMANCE_TEXT}, - {"HKEY_PERFORMANCE_NLSTEXT", (size_t)HKEY_PERFORMANCE_NLSTEXT}, - {"HKEY_CURRENT_CONFIG", (size_t)HKEY_CURRENT_CONFIG}, - {"HKEY_DYN_DATA", (size_t)HKEY_DYN_DATA}, - {"HKCR", (size_t)HKEY_CLASSES_ROOT}, - {"HKCU", (size_t)HKEY_CURRENT_USER}, - {"HKLM", (size_t)HKEY_LOCAL_MACHINE}, - {"HKU", (size_t)HKEY_USERS}, - {"HKPD", (size_t)HKEY_PERFORMANCE_DATA}, - {"HKPT", (size_t)HKEY_PERFORMANCE_TEXT}, - {"HKPN", (size_t)HKEY_PERFORMANCE_NLSTEXT}, - {"HKCC", (size_t)HKEY_CURRENT_CONFIG}, - {"HKDD", (size_t)HKEY_DYN_DATA}, - {0,0} - }; - PKVDATA pph; - INT64 x; - if(atoINT64(psz, &x)){ - WIN_TRACEA("DIGIT ROOTKEY %s", psz); - return (HKEY)(size_t)x; - }else{ - for(pph = ph; pph->name && _stricmp(psz, pph->name); pph++); - if(!pph->data)luaL_error(L, "invalid prefix key '%s'", psz); - return (HKEY)pph->data; - } -} - - -void reg_aux_splitkey(lua_State *L, const char * psz){ - const char * szpre; - // skip space - while(*psz && ISSPACE(*psz))psz++; - // remember prefix - szpre = psz; - // skip prefix - while(*psz && *psz != '\\')psz++; - lua_pushlstring(L, szpre, (int)(psz - szpre)); //@ -2 (rootkey) - while(*psz && *psz == '\\')psz++; - lua_pushstring(L, psz); //@ -1 (subkey) -} -//docok -int reglib_createkey(lua_State *L){//reglib.createkey - //reglib.createkey("<ROOT>\\SUBKEY","access","class") - HKEY hkey = NULL; - const char * szPath = lua_checkstring(L, 1); - REGSAM Access = reg_aux_getaccess(L, 2); - const TCHAR * pszCls = lua_opttstring(L, 3, NULL); - const TCHAR * pszSubKey; - const char * pszRootKey; - reg_aux_splitkey(L, szPath); - pszSubKey = lua_totstring(L,-1); - pszRootKey = lua_tostring(L,-2); - // get hkey of root-key-string - hkey = reg_aux_strtohkey(L, pszRootKey); - reg_aux_newkey(L, hkey, pszSubKey, pszCls, Access, TRUE); - return 1; -} -//docok -int reglib_openkey(lua_State *L){//reglib.openkey - HKEY hkey = NULL; - LONG ret = 0; - const char * szPath = lua_checkstring(L, 1); - REGSAM Access = reg_aux_getaccess(L, 2); - - if(ISSLASH(szPath[0]) && ISSLASH(szPath[1])){ - HKEY HKey = NULL; - const TCHAR * pszMachine; - const char * pszRootKey; - // \\computer_name\hkxx - while(szPath[0] && ISSLASH(szPath[0]) )szPath++;// skip the begining slashes - reg_aux_splitkey(L, szPath); - pszMachine = lua_totstring(L,-1); - pszRootKey = lua_tostring(L,-2); - - hkey = reg_aux_strtohkey(L, pszRootKey); - if((ret = RegConnectRegistry(pszMachine, hkey, &HKey)) == ERROR_SUCCESS){ - reg_aux_newhkey(L, &HKey); - }else{ - lua_pushnil(L); - LUA_CHECK_DLL_ERROR(L, ret); - } - }else{ - const TCHAR * pszSubKey; - const char * pszRootKey; - reg_aux_splitkey(L, szPath); - pszSubKey = lua_totstring(L,-1); - pszRootKey = lua_tostring(L,-2); - hkey = reg_aux_strtohkey(L, pszRootKey); - reg_aux_newkey(L, hkey, pszSubKey, NULL, Access, FALSE); - } - return 1; -} -static const KVDATA reg_type_table[] = { - {"none", REG_NONE}, - {"sz", REG_SZ }, - {"expand_sz", REG_EXPAND_SZ}, - {"binary", REG_BINARY}, - {"dword", REG_DWORD}, - {"dword_big_endian", REG_DWORD_BIG_ENDIAN}, - {"link", REG_LINK}, - {"multi_sz", REG_MULTI_SZ}, - {"resource_list", REG_RESOURCE_LIST}, - {"full_resource_descriptor", REG_FULL_RESOURCE_DESCRIPTOR}, - {"resource_requirements_list", REG_RESOURCE_REQUIREMENTS_LIST}, - {"qword", REG_QWORD}, - {0,0} -}; -void reg_aux_pushdatatype(lua_State *L, DWORD dwType){ -/* const KVDATA * pkvd; - for(pkvd = ®_type_table[0]; pkvd->name && pkvd->data != dwType; pkvd++); - if(pkvd->name){ - lua_pushstring(L, pkvd->name); - }else*/{ - lua_pushint(L, dwType); - } -} - -int reg_aux_getdatatype(lua_State *L, int i){ - if(lua_isrealstring(L, i)){ - const KVDATA * pkvd; - const char * psz = lua_tostring(L, i); - for(pkvd = ®_type_table[0]; pkvd->name && strcmp(psz, pkvd->name); pkvd++); - return (pkvd->name)?(int)pkvd->data:-1; - }else{ - return lua_optint(L, i, -1); - } -} - -BOOL reg_aux_setvalue(lua_State *L, HKEY hKey, const TCHAR * pszVal, int type, int i){ - PBYTE pdata = NULL; - size_t cdata = 0; - LONG ret = ERROR_SUCCESS; - DWORD32 dw32; - DWORD64 dw64; - - if(type < 0){ - switch(lua_type(L, i)){ - break;case LUA_TTABLE :type = REG_MULTI_SZ; - break;case LUA_TNUMBER:type = REG_DWORD; - break;case LUA_TSTRING:type = REG_SZ; - } - } - WIN_TRACEA("reg_aux_setvalue val<%s> type<%d>", pszVal, type); - switch(type){ - case REG_DWORD: case REG_DWORD_BIG_ENDIAN:{ - dw32 = lua_checkDWORD(L, i); - pdata = (PBYTE)&dw32; - cdata = sizeof(DWORD32); - } - break; case REG_QWORD:{ - if(lua_isuserdata(L, i)){ - memcpy(&dw64, lua_touserdata(L, i), sizeof(DWORD64)); - }else{ - dw64 = lua_checkUINT64(L, i); - } - pdata = (PBYTE)&dw64; - cdata = sizeof(DWORD64); - } - break; case REG_MULTI_SZ:{ - size_t len = 0; - luaL_Buffer B; - luaL_buffinit(L, &B); - if(lua_istable(L, i)){ - int n; - int last = lua_objlen(L, i); - for (n = 1; n <= last; n++) { - lua_rawgeti(L, i, n); - luaL_addstring(&B, lua_checkstring(L, -1)); - luaL_addchar(&B, 0); - } - }else{ - luaL_checktype(L, i, LUA_TSTRING); - lua_pushvalue(L, i); - luaL_addvalue(&B); - luaL_addchar(&B, 0); - } - luaL_addchar(&B, 0); - luaL_pushresult(&B); - pdata = (PBYTE)lua_checkltstring(L, -1, &len); - cdata = len*sizeof(TCHAR); - } - break; case REG_SZ: case REG_EXPAND_SZ:{ - pdata = (PBYTE)lua_checkltstring(L, i, &cdata); - cdata = (cdata+1)*sizeof(TCHAR); - } - break; default: -#if LUA_VERSION_NUM >= 501 - if(lua_isfulluserdata(L, i)){ - pdata = (PBYTE)lua_touserdata(L, i); - cdata = lua_objlen(L, i); - }else -#endif - { - pdata = (PBYTE)luaL_checklstring(L, i, &cdata); - } - } - ret = RegSetValueEx(hKey, pszVal, 0, type, pdata, (DWORD)cdata); - LUA_CHECK_DLL_ERROR(L, ret); - return ERROR_SUCCESS == ret; -} -void reg_aux_pusheregstrdata(lua_State *L, PVOID pdata, size_t cdata, DWORD dwType, int expand){ - if(pdata == NULL){lua_pushnil(L);return;} - switch(dwType){ - case REG_DWORD: case REG_DWORD_BIG_ENDIAN: case REG_QWORD: - { - char buf[24]; - DWORD64 n; - if(dwType == REG_QWORD){ - n = *((PDWORD64)pdata); - }else{ - n = (DWORD64)(*((PDWORD32)pdata)); - } - if(_ui64toa_s(n, buf, _countof(buf), 10)){ - lua_pushnil(L); - return; - }else{ - lua_pushstring(L, buf); - } - - } - break; case REG_MULTI_SZ: - { - lua_pushltstring(L, (const TCHAR *)pdata, cdata); - } - break; case REG_EXPAND_SZ: case REG_SZ: - { - DWORD dwLen; - PTSTR pbuf; - if( dwType == REG_EXPAND_SZ && expand - && (dwLen = ExpandEnvironmentStrings((const TCHAR *)pdata, NULL, 0)) > 0 - && NULL != (pbuf = lua_alloc_tchar(L, ++dwLen)) - && (dwLen = ExpandEnvironmentStrings((const TCHAR *)pdata, pbuf, dwLen)) > 0){ - lua_pushtstring(L, pbuf); - }else{ - lua_pushtstring(L, (const TCHAR *)pdata); - } - } - break;default: - lua_pushlstring(L, (const char *)pdata, cdata); - } -} - -void reg_aux_pusheregluadata(lua_State *L, PVOID pdata, size_t cdata, DWORD dwType){ - if(pdata == NULL){lua_pushnil(L);return;} - switch(dwType){ - case REG_DWORD: case REG_DWORD_BIG_ENDIAN: - lua_pushnumber(L, *((PDWORD32)pdata)); - break; case REG_QWORD: - lua_pushUINT64(L, *((PDWORD64)pdata)); - break; case REG_MULTI_SZ: - { - int c = 1; - lua_newtable(L); - DZTS_ITER_INIT(PTSTR, ptoken, (PTSTR)pdata) - lua_pushinteger(L, c); - lua_pushtstring(L, ptoken);//TCHAR!! - lua_rawset(L, -3); - c++; - DZTS_ITER_CONT(ptoken) - } - break; case REG_SZ: case REG_EXPAND_SZ: - lua_pushtstring(L, (const TCHAR *)pdata); - break;default: - lua_pushlstring(L, (const char *)pdata, cdata); - } -} -typedef struct _REG_ENUM_TAG { // rc - HKEY hKey; - DWORD dwIndex; - PTSTR buffer; - DWORD bchlen; -} REG_ENUM_TAG; -#define REG_ENUM_MINBUFLEN ((LUAL_BUFFERSIZE-sizeof(REG_ENUM_TAG))/sizeof(TCHAR)) -#define REG_ENUM_DATALEN(n) (sizeof(REG_ENUM_TAG)+((n)*sizeof(TCHAR))) - -int reg_aux_enumkey_closure(lua_State *L){ - REG_ENUM_TAG* pret = (REG_ENUM_TAG*)lua_touserdata(L, lua_upvalueindex(1)); - if(pret){ - DWORD dwcbSubKey = pret->bchlen; - PTSTR pszSubKey = pret->buffer; - LONG ret = RegEnumKeyEx(pret->hKey, pret->dwIndex, pszSubKey, &dwcbSubKey, 0, NULL, NULL, NULL); - - if(ERROR_SUCCESS == ret ){ - lua_pushtstring(L, pszSubKey); - pret->dwIndex++; - return 1; - } - if(ret != ERROR_NO_MORE_ITEMS){ - WIN_TRACEA("pret->bchlen=%d,dwcbSubKey=%d,Subkey='%s'", pret->bchlen, dwcbSubKey, pszSubKey); - LUA_CHECK_DLL_ERROR(L, ret); - } - } - lua_pushnil(L); - return 1; -} -int reg_aux_enumvalue_closure(lua_State *L){ - REG_ENUM_TAG* pret = (REG_ENUM_TAG*)lua_touserdata(L, lua_upvalueindex(1)); - if(pret){ - LONG ret = 0; - DWORD dwType = 0; - DWORD dwccValue = pret->bchlen; - PTSTR pszValue = pret->buffer; - - ret = RegEnumValue(pret->hKey, pret->dwIndex, pszValue, &dwccValue, 0, &dwType, NULL, NULL); - - if(ERROR_SUCCESS == ret ){ - lua_pushtstring(L, pszValue); - reg_aux_pushdatatype(L, dwType); - pret->dwIndex++; - return 2; - } - if(ret != ERROR_NO_MORE_ITEMS){ - LUA_CHECK_DLL_ERROR(L, ret); - } - } - lua_pushnil(L); - return 1; -} -//docok -int reg_close(lua_State *L){//regobj.__gc, regobj.close - PHKEY phKey = (PHKEY)lua_touserdata(L, 1); - lua_assert(phKey); - //WIN_TRACEA("reg_close<%x>;", *phKey); - if(phKey && *phKey){ - LUA_CHECK_DLL_ERROR(L, RegCloseKey(*phKey)); - *phKey = NULL; - } - return 0; -} -//docok -int reg_createkey(lua_State *L){//regobj.createkey - reg_aux_newkey(L, reg_aux_gethkey(L, 1), - lua_checktstring(L, 2), (PTSTR)lua_opttstring(L, 4, NULL), reg_aux_getaccess(L, 3), TRUE); - return 1; -} -//docok -int reg_deletekey(lua_State *L){//regobj.deletekey - LONG ret = win_reg_deltree(reg_aux_gethkey(L,1), lua_checktstring(L, 2)); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -//docok -int reg_deletevalue(lua_State *L){//regobj.deletevalue - LONG ret = RegDeleteValue(reg_aux_gethkey(L,1), lua_checktstring(L, 2)); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -//docok -int reg_enumkey(lua_State *L){//regobj.enumkey - HKEY hKey = reg_aux_gethkey(L, 1); - DWORD dwNameLen = 0; - REG_ENUM_TAG* pret; - LONG ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &dwNameLen, NULL, NULL, NULL, NULL, NULL, NULL); - dwNameLen = max(REG_ENUM_MINBUFLEN,dwNameLen+1); - pret = (REG_ENUM_TAG*)lua_newuserdata(L,REG_ENUM_DATALEN(dwNameLen)); - - pret->hKey = hKey; - pret->dwIndex = 0; - pret->bchlen = dwNameLen; - pret->buffer = (PTSTR)(&pret[1]); - - WIN_TRACEA("reg_enumkey bchlen=%d datlen=%d", pret->bchlen, REG_ENUM_DATALEN(dwNameLen)); - LUA_CHECK_DLL_ERROR(L, ret); - lua_pushcclosure(L, reg_aux_enumkey_closure, 1); - return 1; -} -//docok -int reg_enumvalue(lua_State *L){//regobj.enumvalue - HKEY hKey = reg_aux_gethkey(L, 1); - REG_ENUM_TAG* pret; - DWORD dwNameLen = 0; - LONG ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwNameLen, NULL, NULL, NULL); - dwNameLen = max(REG_ENUM_MINBUFLEN,dwNameLen+1); - pret = (REG_ENUM_TAG*)lua_newuserdata(L,REG_ENUM_DATALEN(dwNameLen)); - - pret->hKey = hKey; - pret->dwIndex = 0; - pret->bchlen = dwNameLen; - pret->buffer = (PTSTR)(&pret[1]); - - WIN_TRACEA("reg_enumkey bchlen=%d datlen=%d", pret->bchlen, REG_ENUM_DATALEN(dwNameLen)); - LUA_CHECK_DLL_ERROR(L, ret); - - lua_pushcclosure(L, reg_aux_enumvalue_closure, 1); - return 1; -} -//docok -int reg_flushkey(lua_State *L){//"regobj.flushkey" - LONG ret = RegFlushKey(reg_aux_gethkey(L, 1)); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -//docok -int reg_getinfo(lua_State *L){//regobj.getinfo - HKEY hKey = reg_aux_gethkey(L,1); - FILETIME ftLastWriteTime = {0,}; - DWORD dwcbClass = 64, dwcSubKeys = 0, dwcbMaxSubKeyLen = 0, dwcbMaxClassLen = 0, dwcValues = 0, dwcbMaxValueNameLen = 0, dwcbMaxValueLen = 0, dwcbSecurityDescriptor = 0; - LONG ret = RegQueryInfoKey (hKey, NULL, NULL, NULL, &dwcSubKeys, &dwcbMaxSubKeyLen, &dwcbMaxClassLen, &dwcValues, &dwcbMaxValueNameLen, &dwcbMaxValueLen, &dwcbSecurityDescriptor, &ftLastWriteTime); - PTSTR psz = lua_alloc_tchar(L, ++dwcbClass); - - if(ERROR_MORE_DATA == RegQueryInfoKey(hKey, psz, &dwcbClass, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) ){ - psz = lua_alloc_tchar(L, ++dwcbClass); - RegQueryInfoKey(hKey, psz, &dwcbClass, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - } - - LUA_CHECK_DLL_ERROR(L, ret); - if(ret == ERROR_SUCCESS){ - lua_newtable(L); - lua_rawset_st(L, -3, "class",psz); - lua_rawset_sn(L, -3, "subkeys",dwcSubKeys); - lua_rawset_sn(L, -3, "values",dwcValues); - lua_rawset_sn(L, -3, "maxsubkeylen",dwcbMaxSubKeyLen); - lua_rawset_sn(L, -3, "maxclasslen",dwcbMaxClassLen); - lua_rawset_sn(L, -3, "maxvaluelen",dwcbMaxValueLen); - lua_rawset_sn(L, -3, "maxvaluenamelen",dwcbMaxValueNameLen); - lua_rawset_sn(L, -3, "maxsecuritydescriptor",dwcbSecurityDescriptor); - //lua_pushstring(L, "lastwritetime"); - //aux_pushftime(L, &ftLastWriteTime); - //lua_rawset(L, -3); - }else{ - lua_pushnil(L); - } - return 1; -} -//docok -int reg_getvalue(lua_State *L){//regobj.getvalue - HKEY hKey = reg_aux_gethkey(L, 1); - const TCHAR * pszVal = lua_opttstring(L, 2, NULL); - DWORD dwType = 0; - DWORD dwLen = 0; - PVOID pvd = 0; - LONG ret = ERROR_SUCCESS; - // open the key - if( ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, NULL, &dwLen)) - // alloc - && (pvd = lua_newuserdata(L, dwLen)) != NULL - // query a-again - && ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, pvd, &dwLen)) - ){ - reg_aux_pusheregluadata(L, pvd, dwLen, dwType); - reg_aux_pushdatatype(L, dwType); - }else{ - lua_pushnil(L); - lua_pushnil(L); - //LUA_CHECK_DLL_ERROR(L, ret); - } - return 2; -} -#ifndef LUA_REG_NO_HIVEOPS -//docok -int reg_loadkey(lua_State *L){//regobj.load - LONG ret; - win_setprivilege(SE_RESTORE_NAME, 1, NULL); - ret = RegLoadKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), lua_checktstring(L, 3)); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -#endif // LUA_REG_NO_HIVEOPS -//docok -int reg_openkey(lua_State *L){//regobj.openkey - reg_aux_newkey(L, reg_aux_gethkey(L, 1), - lua_checktstring(L, 2), NULL, reg_aux_getaccess(L, 3), FALSE); - return 1; -} -#ifndef LUA_REG_NO_HIVEOPS -//docok -int reg_replacekey(lua_State *L){//regobj.replace - LONG ret; - win_setprivilege(SE_RESTORE_NAME, 1, NULL); - ret = RegReplaceKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), lua_checktstring(L, 3), lua_checktstring(L, 4)); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -//docok -int reg_restorekey(lua_State *L){//regobj.restore - LONG ret; - DWORD dwFlags = 0; - win_setprivilege(SE_RESTORE_NAME, 1, NULL); - if(lua_isboolean(L,3)){ - dwFlags = lua_toboolean(L,3)?REG_WHOLE_HIVE_VOLATILE:0; - }else{ - dwFlags = lua_optDWORD(L, 3, 0); - } - ret = RegRestoreKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), dwFlags); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -//docok -int reg_savekey(lua_State *L){//regobj.save - LONG ret; - win_setprivilege(SE_BACKUP_NAME, 1, NULL); - ret = RegSaveKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), NULL); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -#endif // LUA_REG_NO_HIVEOPS -//docok -int reg_setvalue(lua_State *L){//regobj.setvalue - LUA_CHECK_RETURN_OBJECT(L, - reg_aux_setvalue(L, reg_aux_gethkey(L, 1), lua_opttstring(L, 2, NULL), reg_aux_getdatatype(L, 4), 3) - ); -} -#ifndef LUA_REG_NO_HIVEOPS -//docok -int reg_unloadkey(lua_State *L){//regobj.unload - LONG ret; - win_setprivilege(SE_RESTORE_NAME, 1, NULL); - ret = RegUnLoadKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2)); - LUA_CHECK_DLL_ERROR(L, ret); - LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS); -} -#endif // LUA_REG_NO_HIVEOPS - -int reg_handle(lua_State *L){//regobj.handle - HKEY hKey = reg_aux_gethkey(L, 1); - lua_pushlightuserdata(L, hKey); - return 1; -} - -int reg_detach(lua_State *L){//regobj.detach - PHKEY phKey = reg_aux_getphkey(L, 1); - lua_pushlightuserdata(L, *phKey); - *phKey = NULL; - return 1; -} - -int reg_getstrval(lua_State *L){//regobj.getstrval - HKEY hKey = reg_aux_gethkey(L, 1); - const TCHAR * pszVal = lua_opttstring(L, 2, NULL); - int expand = lua_optbool(L,3,1); - DWORD dwType = 0; - DWORD dwLen = 0; - PVOID pvd = 0; - LONG ret = ERROR_SUCCESS; - // open the key - if( ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, NULL, &dwLen)) - // alloc - && (pvd = lua_newuserdata(L, dwLen)) != NULL - // query a-again - && ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, pvd, &dwLen)) - ){ - reg_aux_pusheregstrdata(L, pvd, dwLen, dwType, expand); - }else{ - lua_pushnil(L); - } - return 1; -} - -int reg_getvaltype(lua_State *L){//regobj.getvaltype - HKEY hKey = reg_aux_gethkey(L, 1); - const TCHAR * pszVal = lua_opttstring(L, 2, NULL); - DWORD dwType = 0; - LONG ret = ERROR_SUCCESS; - if(ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, NULL, NULL)) ){ - reg_aux_pushdatatype(L, dwType); - }else{ - // value does not exist! - lua_pushnil(L); - } - return 1; +#ifdef _LUAMSVC
+# include <luamsvc.h>
+#endif
+
+#include <assert.h>
+#ifndef lua_assert
+#define lua_assert assert
+#endif
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include "l52util.h"
+
+#include "stdmacro.h"
+#include "luamacro.h"
+#include "luawinmacro.h"
+
+#include "lua_tstring.h"
+#include "lua_int64.h"
+#include "lua_mtutil.h"
+#include "luawin_dllerror.h"
+
+#include "win_trace.h"
+#include "win_privileges.h"
+#include "win_registry.h"
+
+#define LUA_REG_DEFINE_EXTERNS
+#include "luareg.h"
+
+#define lua_error_invalid_option(L, i) luaL_argerror(L, (i), "invalid option")
+#define lrk_hkey "{afx/hkey}"
+
+#ifndef HKEY_PERFORMANCE_TEXT
+#define HKEY_PERFORMANCE_TEXT (( HKEY )((LONG)0x80000050) )
+#define HKEY_PERFORMANCE_NLSTEXT (( HKEY )((LONG)0x80000060) )
+#endif
+#ifndef REG_QWORD
+#define REG_QWORD ( 11 ) // 64-bit number
+#endif
+
+#ifndef LUA_REG_NO_DLL
+BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){
+ UNUSED(hModule);
+ UNUSED(lpReserved);
+ UNUSED(ul_reason_for_call);
+ return TRUE;
+}
+
+__declspec(dllexport)
+#endif
+int luaopen_winreg(lua_State *L){
+ luaL_register(L, "winreg", lreg_reglib);
+ return 1;
+}
+#define reg_aux_gethkey(L,index) (*((PHKEY)luaL_checkudata(L, index, lrk_hkey)))
+#define reg_aux_getphkey(L,index) ((PHKEY)luaL_checkudata(L, index, lrk_hkey))
+
+typedef struct HKEY_DATA{
+ HKEY hkey;
+ DWORD opt;
+} HKEY_DATA, *PHKEY_DATA;
+
+int reg_aux_newhkey(lua_State *L, PHKEY pHKey){
+ PHKEY phKey = (PHKEY)lua_newuserdatamt(L, sizeof(HKEY), lrk_hkey, lreg_regobj);
+ return phKey && pHKey && (NULL != (*phKey = *pHKey));
+}
+
+int reg_aux_newkey(lua_State *L, HKEY HKey, LPCTSTR szKey, LPCTSTR szClass, REGSAM samDesired, BOOL bCreate){
+ DWORD dwDis = (bCreate==FALSE) ? REG_OPENED_EXISTING_KEY : 0;
+ HKEY hKey = NULL;
+ LONG ret = (bCreate
+ ? RegCreateKeyEx(HKey, szKey, 0, (PTSTR)szClass, 0, samDesired, NULL, &hKey, &dwDis)
+ : RegOpenKeyEx(HKey, szKey, 0, samDesired, &hKey)
+ );
+ //WIN_TRACET(_T("%hs: hkey<%x>, sub<%s>, cls<%s>, acc<%d>;"), bCreate?"createkey":"openkey", HKey, szKey, szClass, samDesired);
+
+ if(ret == ERROR_SUCCESS){
+ reg_aux_newhkey(L, &hKey);
+ return dwDis;
+ }else{
+ // if we're opening a key, dont shout the error
+ // just return nil
+ // this will test if the key exist
+ if(bCreate){
+ LUA_CHECK_DLL_ERROR(L,ret);
+ }
+ lua_pushnil(L);
+ return 0;
+ }
+}
+
+REGSAM reg_aux_getaccess(lua_State *L, int i){
+ REGSAM acc = 0;
+ if(lua_isnumber(L, i) || lua_isnoneornil(L, i)){
+ acc = lua_optint(L, i, KEY_ALL_ACCESS);
+ }else{
+ const char * psz = lua_checkstring(L, i);
+ for(;*psz;psz++){
+ switch(*psz){
+ case 'w': acc |= KEY_WRITE; break;
+ case 'r': acc |= KEY_READ ; break;
+ case 'a': acc |= KEY_ALL_ACCESS ; break;
+#ifdef KEY_WOW64_64KEY
+ case '6': if(*++psz == '4') {
+ // Access a 64-bit key from either a 32-bit or 64-bit application
+ acc |= KEY_WOW64_64KEY;
+ break;
+ }
+#endif
+#ifdef KEY_WOW64_32KEY
+ case '3': if(*++psz == '2') {
+ // Access a 64-bit key from either a 32-bit or 64-bit application
+ acc |= KEY_WOW64_32KEY;
+ break;
+ }
+#endif
+ default : lua_error_invalid_option(L, i);
+ }
+ }
+ }
+ return acc;
+}
+
+typedef struct KVDATA{
+ const char * name;
+ size_t data;
+} KVDATA, *PKVDATA;
+
+HKEY reg_aux_strtohkey(lua_State *L, const char * psz){
+ static KVDATA ph[] = {
+ {"HKEY_CLASSES_ROOT", (size_t)HKEY_CLASSES_ROOT},
+ {"HKEY_CURRENT_USER", (size_t)HKEY_CURRENT_USER},
+ {"HKEY_LOCAL_MACHINE", (size_t)HKEY_LOCAL_MACHINE},
+ {"HKEY_USERS", (size_t)HKEY_USERS},
+ {"HKEY_PERFORMANCE_DATA", (size_t)HKEY_PERFORMANCE_DATA},
+ {"HKEY_PERFORMANCE_TEXT", (size_t)HKEY_PERFORMANCE_TEXT},
+ {"HKEY_PERFORMANCE_NLSTEXT", (size_t)HKEY_PERFORMANCE_NLSTEXT},
+ {"HKEY_CURRENT_CONFIG", (size_t)HKEY_CURRENT_CONFIG},
+ {"HKEY_DYN_DATA", (size_t)HKEY_DYN_DATA},
+ {"HKCR", (size_t)HKEY_CLASSES_ROOT},
+ {"HKCU", (size_t)HKEY_CURRENT_USER},
+ {"HKLM", (size_t)HKEY_LOCAL_MACHINE},
+ {"HKU", (size_t)HKEY_USERS},
+ {"HKPD", (size_t)HKEY_PERFORMANCE_DATA},
+ {"HKPT", (size_t)HKEY_PERFORMANCE_TEXT},
+ {"HKPN", (size_t)HKEY_PERFORMANCE_NLSTEXT},
+ {"HKCC", (size_t)HKEY_CURRENT_CONFIG},
+ {"HKDD", (size_t)HKEY_DYN_DATA},
+ {0,0}
+ };
+ PKVDATA pph;
+ INT64 x;
+ if(atoINT64(psz, &x)){
+ WIN_TRACEA("DIGIT ROOTKEY %s", psz);
+ return (HKEY)(size_t)x;
+ }else{
+ for(pph = ph; pph->name && _stricmp(psz, pph->name); pph++);
+ if(!pph->data)luaL_error(L, "invalid prefix key '%s'", psz);
+ return (HKEY)pph->data;
+ }
+}
+
+
+void reg_aux_splitkey(lua_State *L, const char * psz){
+ const char * szpre;
+ // skip space
+ while(*psz && ISSPACE(*psz))psz++;
+ // remember prefix
+ szpre = psz;
+ // skip prefix
+ while(*psz && *psz != '\\')psz++;
+ lua_pushlstring(L, szpre, (int)(psz - szpre)); //@ -2 (rootkey)
+ while(*psz && *psz == '\\')psz++;
+ lua_pushstring(L, psz); //@ -1 (subkey)
+}
+//docok
+int reglib_createkey(lua_State *L){//reglib.createkey
+ //reglib.createkey("<ROOT>\\SUBKEY","access","class")
+ HKEY hkey = NULL;
+ const char * szPath = lua_checkstring(L, 1);
+ REGSAM Access = reg_aux_getaccess(L, 2);
+ const TCHAR * pszCls = lua_opttstring(L, 3, NULL);
+ const TCHAR * pszSubKey;
+ const char * pszRootKey;
+ reg_aux_splitkey(L, szPath);
+ pszSubKey = lua_totstring(L,-1);
+ pszRootKey = lua_tostring(L,-2);
+ // get hkey of root-key-string
+ hkey = reg_aux_strtohkey(L, pszRootKey);
+ reg_aux_newkey(L, hkey, pszSubKey, pszCls, Access, TRUE);
+ return 1;
+}
+//docok
+int reglib_openkey(lua_State *L){//reglib.openkey
+ HKEY hkey = NULL;
+ LONG ret = 0;
+ const char * szPath = lua_checkstring(L, 1);
+ REGSAM Access = reg_aux_getaccess(L, 2);
+
+ if(ISSLASH(szPath[0]) && ISSLASH(szPath[1])){
+ HKEY HKey = NULL;
+ const TCHAR * pszMachine;
+ const char * pszRootKey;
+ // \\computer_name\hkxx
+ while(szPath[0] && ISSLASH(szPath[0]) )szPath++;// skip the begining slashes
+ reg_aux_splitkey(L, szPath);
+ pszMachine = lua_totstring(L,-1);
+ pszRootKey = lua_tostring(L,-2);
+
+ hkey = reg_aux_strtohkey(L, pszRootKey);
+ if((ret = RegConnectRegistry(pszMachine, hkey, &HKey)) == ERROR_SUCCESS){
+ reg_aux_newhkey(L, &HKey);
+ }else{
+ lua_pushnil(L);
+ LUA_CHECK_DLL_ERROR(L, ret);
+ }
+ }else{
+ const TCHAR * pszSubKey;
+ const char * pszRootKey;
+ reg_aux_splitkey(L, szPath);
+ pszSubKey = lua_totstring(L,-1);
+ pszRootKey = lua_tostring(L,-2);
+ hkey = reg_aux_strtohkey(L, pszRootKey);
+ reg_aux_newkey(L, hkey, pszSubKey, NULL, Access, FALSE);
+ }
+ return 1;
+}
+static const KVDATA reg_type_table[] = {
+ {"none", REG_NONE},
+ {"sz", REG_SZ },
+ {"expand_sz", REG_EXPAND_SZ},
+ {"binary", REG_BINARY},
+ {"dword", REG_DWORD},
+ {"dword_big_endian", REG_DWORD_BIG_ENDIAN},
+ {"link", REG_LINK},
+ {"multi_sz", REG_MULTI_SZ},
+ {"resource_list", REG_RESOURCE_LIST},
+ {"full_resource_descriptor", REG_FULL_RESOURCE_DESCRIPTOR},
+ {"resource_requirements_list", REG_RESOURCE_REQUIREMENTS_LIST},
+ {"qword", REG_QWORD},
+ {0,0}
+};
+void reg_aux_pushdatatype(lua_State *L, DWORD dwType){
+/* const KVDATA * pkvd;
+ for(pkvd = ®_type_table[0]; pkvd->name && pkvd->data != dwType; pkvd++);
+ if(pkvd->name){
+ lua_pushstring(L, pkvd->name);
+ }else*/{
+ lua_pushint(L, dwType);
+ }
+}
+
+int reg_aux_getdatatype(lua_State *L, int i){
+ if(lua_isrealstring(L, i)){
+ const KVDATA * pkvd;
+ const char * psz = lua_tostring(L, i);
+ for(pkvd = ®_type_table[0]; pkvd->name && strcmp(psz, pkvd->name); pkvd++);
+ return (pkvd->name)?(int)pkvd->data:-1;
+ }else{
+ return lua_optint(L, i, -1);
+ }
+}
+
+BOOL reg_aux_setvalue(lua_State *L, HKEY hKey, const TCHAR * pszVal, int type, int i){
+ PBYTE pdata = NULL;
+ size_t cdata = 0;
+ LONG ret = ERROR_SUCCESS;
+ DWORD32 dw32;
+ DWORD64 dw64;
+
+ if(type < 0){
+ switch(lua_type(L, i)){
+ break;case LUA_TTABLE :type = REG_MULTI_SZ;
+ break;case LUA_TNUMBER:type = REG_DWORD;
+ break;case LUA_TSTRING:type = REG_SZ;
+ }
+ }
+ WIN_TRACEA("reg_aux_setvalue val<%s> type<%d>", pszVal, type);
+ switch(type){
+ case REG_DWORD: case REG_DWORD_BIG_ENDIAN:{
+ dw32 = lua_checkDWORD(L, i);
+ pdata = (PBYTE)&dw32;
+ cdata = sizeof(DWORD32);
+ }
+ break; case REG_QWORD:{
+ if(lua_isuserdata(L, i)){
+ memcpy(&dw64, lua_touserdata(L, i), sizeof(DWORD64));
+ }else{
+ dw64 = lua_checkUINT64(L, i);
+ }
+ pdata = (PBYTE)&dw64;
+ cdata = sizeof(DWORD64);
+ }
+ break; case REG_MULTI_SZ:{
+ size_t len = 0;
+ luaL_Buffer B;
+ luaL_buffinit(L, &B);
+ if(lua_istable(L, i)){
+ int n;
+ int last = lua_objlen(L, i);
+ for (n = 1; n <= last; n++) {
+ lua_rawgeti(L, i, n);
+ luaL_addstring(&B, lua_checkstring(L, -1));
+ luaL_addchar(&B, 0);
+ }
+ }else{
+ luaL_checktype(L, i, LUA_TSTRING);
+ lua_pushvalue(L, i);
+ luaL_addvalue(&B);
+ luaL_addchar(&B, 0);
+ }
+ luaL_addchar(&B, 0);
+ luaL_pushresult(&B);
+ pdata = (PBYTE)lua_checkltstring(L, -1, &len);
+ cdata = len*sizeof(TCHAR);
+ }
+ break; case REG_SZ: case REG_EXPAND_SZ:{
+ pdata = (PBYTE)lua_checkltstring(L, i, &cdata);
+ cdata = (cdata+1)*sizeof(TCHAR);
+ }
+ break; default:
+#if LUA_VERSION_NUM >= 501
+ if(lua_isfulluserdata(L, i)){
+ pdata = (PBYTE)lua_touserdata(L, i);
+ cdata = lua_objlen(L, i);
+ }else
+#endif
+ {
+ pdata = (PBYTE)luaL_checklstring(L, i, &cdata);
+ }
+ }
+ ret = RegSetValueEx(hKey, pszVal, 0, type, pdata, (DWORD)cdata);
+ LUA_CHECK_DLL_ERROR(L, ret);
+ return ERROR_SUCCESS == ret;
+}
+void reg_aux_pusheregstrdata(lua_State *L, PVOID pdata, size_t cdata, DWORD dwType, int expand){
+ if(pdata == NULL){lua_pushnil(L);return;}
+ switch(dwType){
+ case REG_DWORD: case REG_DWORD_BIG_ENDIAN: case REG_QWORD:
+ {
+ char buf[24];
+ DWORD64 n;
+ if(dwType == REG_QWORD){
+ n = *((PDWORD64)pdata);
+ }else{
+ n = (DWORD64)(*((PDWORD32)pdata));
+ }
+ if(_ui64toa_s(n, buf, _countof(buf), 10)){
+ lua_pushnil(L);
+ return;
+ }else{
+ lua_pushstring(L, buf);
+ }
+
+ }
+ break; case REG_MULTI_SZ:
+ {
+ lua_pushltstring(L, (const TCHAR *)pdata, cdata);
+ }
+ break; case REG_EXPAND_SZ: case REG_SZ:
+ {
+ DWORD dwLen;
+ PTSTR pbuf;
+ if( dwType == REG_EXPAND_SZ && expand
+ && (dwLen = ExpandEnvironmentStrings((const TCHAR *)pdata, NULL, 0)) > 0
+ && NULL != (pbuf = lua_alloc_tchar(L, ++dwLen))
+ && (dwLen = ExpandEnvironmentStrings((const TCHAR *)pdata, pbuf, dwLen)) > 0){
+ lua_pushtstring(L, pbuf);
+ }else{
+ lua_pushtstring(L, (const TCHAR *)pdata);
+ }
+ }
+ break;default:
+ lua_pushlstring(L, (const char *)pdata, cdata);
+ }
+}
+
+void reg_aux_pusheregluadata(lua_State *L, PVOID pdata, size_t cdata, DWORD dwType){
+ if(pdata == NULL){lua_pushnil(L);return;}
+ switch(dwType){
+ case REG_DWORD: case REG_DWORD_BIG_ENDIAN:
+ lua_pushnumber(L, *((PDWORD32)pdata));
+ break; case REG_QWORD:
+ lua_pushUINT64(L, *((PDWORD64)pdata));
+ break; case REG_MULTI_SZ:
+ {
+ int c = 1;
+ lua_newtable(L);
+ DZTS_ITER_INIT(PTSTR, ptoken, (PTSTR)pdata)
+ lua_pushinteger(L, c);
+ lua_pushtstring(L, ptoken);//TCHAR!!
+ lua_rawset(L, -3);
+ c++;
+ DZTS_ITER_CONT(ptoken)
+ }
+ break; case REG_SZ: case REG_EXPAND_SZ:
+ lua_pushtstring(L, (const TCHAR *)pdata);
+ break;default:
+ lua_pushlstring(L, (const char *)pdata, cdata);
+ }
+}
+typedef struct _REG_ENUM_TAG { // rc
+ HKEY hKey;
+ DWORD dwIndex;
+ PTSTR buffer;
+ DWORD bchlen;
+} REG_ENUM_TAG;
+#define REG_ENUM_MINBUFLEN ((LUAL_BUFFERSIZE-sizeof(REG_ENUM_TAG))/sizeof(TCHAR))
+#define REG_ENUM_DATALEN(n) (sizeof(REG_ENUM_TAG)+((n)*sizeof(TCHAR)))
+
+int reg_aux_enumkey_closure(lua_State *L){
+ REG_ENUM_TAG* pret = (REG_ENUM_TAG*)lua_touserdata(L, lua_upvalueindex(1));
+ if(pret){
+ DWORD dwcbSubKey = pret->bchlen;
+ PTSTR pszSubKey = pret->buffer;
+ LONG ret = RegEnumKeyEx(pret->hKey, pret->dwIndex, pszSubKey, &dwcbSubKey, 0, NULL, NULL, NULL);
+
+ if(ERROR_SUCCESS == ret ){
+ lua_pushtstring(L, pszSubKey);
+ pret->dwIndex++;
+ return 1;
+ }
+ if(ret != ERROR_NO_MORE_ITEMS){
+ WIN_TRACEA("pret->bchlen=%d,dwcbSubKey=%d,Subkey='%s'", pret->bchlen, dwcbSubKey, pszSubKey);
+ LUA_CHECK_DLL_ERROR(L, ret);
+ }
+ }
+ lua_pushnil(L);
+ return 1;
+}
+int reg_aux_enumvalue_closure(lua_State *L){
+ REG_ENUM_TAG* pret = (REG_ENUM_TAG*)lua_touserdata(L, lua_upvalueindex(1));
+ if(pret){
+ LONG ret = 0;
+ DWORD dwType = 0;
+ DWORD dwccValue = pret->bchlen;
+ PTSTR pszValue = pret->buffer;
+
+ ret = RegEnumValue(pret->hKey, pret->dwIndex, pszValue, &dwccValue, 0, &dwType, NULL, NULL);
+
+ if(ERROR_SUCCESS == ret ){
+ lua_pushtstring(L, pszValue);
+ reg_aux_pushdatatype(L, dwType);
+ pret->dwIndex++;
+ return 2;
+ }
+ if(ret != ERROR_NO_MORE_ITEMS){
+ LUA_CHECK_DLL_ERROR(L, ret);
+ }
+ }
+ lua_pushnil(L);
+ return 1;
+}
+//docok
+int reg_close(lua_State *L){//regobj.__gc, regobj.close
+ PHKEY phKey = (PHKEY)lua_touserdata(L, 1);
+ lua_assert(phKey);
+ //WIN_TRACEA("reg_close<%x>;", *phKey);
+ if(phKey && *phKey){
+ LUA_CHECK_DLL_ERROR(L, RegCloseKey(*phKey));
+ *phKey = NULL;
+ }
+ return 0;
+}
+//docok
+int reg_createkey(lua_State *L){//regobj.createkey
+ reg_aux_newkey(L, reg_aux_gethkey(L, 1),
+ lua_checktstring(L, 2), (PTSTR)lua_opttstring(L, 4, NULL), reg_aux_getaccess(L, 3), TRUE);
+ return 1;
+}
+//docok
+int reg_deletekey(lua_State *L){//regobj.deletekey
+ LONG ret = win_reg_deltree(reg_aux_gethkey(L,1), lua_checktstring(L, 2));
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+//docok
+int reg_deletevalue(lua_State *L){//regobj.deletevalue
+ LONG ret = RegDeleteValue(reg_aux_gethkey(L,1), lua_checktstring(L, 2));
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+//docok
+int reg_enumkey(lua_State *L){//regobj.enumkey
+ HKEY hKey = reg_aux_gethkey(L, 1);
+ DWORD dwNameLen = 0;
+ REG_ENUM_TAG* pret;
+ LONG ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &dwNameLen, NULL, NULL, NULL, NULL, NULL, NULL);
+ dwNameLen = max(REG_ENUM_MINBUFLEN,dwNameLen+1);
+ pret = (REG_ENUM_TAG*)lua_newuserdata(L,REG_ENUM_DATALEN(dwNameLen));
+
+ pret->hKey = hKey;
+ pret->dwIndex = 0;
+ pret->bchlen = dwNameLen;
+ pret->buffer = (PTSTR)(&pret[1]);
+
+ WIN_TRACEA("reg_enumkey bchlen=%d datlen=%d", pret->bchlen, REG_ENUM_DATALEN(dwNameLen));
+ LUA_CHECK_DLL_ERROR(L, ret);
+ lua_pushcclosure(L, reg_aux_enumkey_closure, 1);
+ return 1;
+}
+//docok
+int reg_enumvalue(lua_State *L){//regobj.enumvalue
+ HKEY hKey = reg_aux_gethkey(L, 1);
+ REG_ENUM_TAG* pret;
+ DWORD dwNameLen = 0;
+ LONG ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwNameLen, NULL, NULL, NULL);
+ dwNameLen = max(REG_ENUM_MINBUFLEN,dwNameLen+1);
+ pret = (REG_ENUM_TAG*)lua_newuserdata(L,REG_ENUM_DATALEN(dwNameLen));
+
+ pret->hKey = hKey;
+ pret->dwIndex = 0;
+ pret->bchlen = dwNameLen;
+ pret->buffer = (PTSTR)(&pret[1]);
+
+ WIN_TRACEA("reg_enumkey bchlen=%d datlen=%d", pret->bchlen, REG_ENUM_DATALEN(dwNameLen));
+ LUA_CHECK_DLL_ERROR(L, ret);
+
+ lua_pushcclosure(L, reg_aux_enumvalue_closure, 1);
+ return 1;
+}
+//docok
+int reg_flushkey(lua_State *L){//"regobj.flushkey"
+ LONG ret = RegFlushKey(reg_aux_gethkey(L, 1));
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+//docok
+int reg_getinfo(lua_State *L){//regobj.getinfo
+ HKEY hKey = reg_aux_gethkey(L,1);
+ FILETIME ftLastWriteTime = {0,};
+ DWORD dwcbClass = 64, dwcSubKeys = 0, dwcbMaxSubKeyLen = 0, dwcbMaxClassLen = 0, dwcValues = 0, dwcbMaxValueNameLen = 0, dwcbMaxValueLen = 0, dwcbSecurityDescriptor = 0;
+ LONG ret = RegQueryInfoKey (hKey, NULL, NULL, NULL, &dwcSubKeys, &dwcbMaxSubKeyLen, &dwcbMaxClassLen, &dwcValues, &dwcbMaxValueNameLen, &dwcbMaxValueLen, &dwcbSecurityDescriptor, &ftLastWriteTime);
+ PTSTR psz = lua_alloc_tchar(L, ++dwcbClass);
+
+ if(ERROR_MORE_DATA == RegQueryInfoKey(hKey, psz, &dwcbClass, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) ){
+ psz = lua_alloc_tchar(L, ++dwcbClass);
+ RegQueryInfoKey(hKey, psz, &dwcbClass, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+
+ LUA_CHECK_DLL_ERROR(L, ret);
+ if(ret == ERROR_SUCCESS){
+ lua_newtable(L);
+ lua_rawset_st(L, -3, "class",psz);
+ lua_rawset_sn(L, -3, "subkeys",dwcSubKeys);
+ lua_rawset_sn(L, -3, "values",dwcValues);
+ lua_rawset_sn(L, -3, "maxsubkeylen",dwcbMaxSubKeyLen);
+ lua_rawset_sn(L, -3, "maxclasslen",dwcbMaxClassLen);
+ lua_rawset_sn(L, -3, "maxvaluelen",dwcbMaxValueLen);
+ lua_rawset_sn(L, -3, "maxvaluenamelen",dwcbMaxValueNameLen);
+ lua_rawset_sn(L, -3, "maxsecuritydescriptor",dwcbSecurityDescriptor);
+ //lua_pushstring(L, "lastwritetime");
+ //aux_pushftime(L, &ftLastWriteTime);
+ //lua_rawset(L, -3);
+ }else{
+ lua_pushnil(L);
+ }
+ return 1;
+}
+//docok
+int reg_getvalue(lua_State *L){//regobj.getvalue
+ HKEY hKey = reg_aux_gethkey(L, 1);
+ const TCHAR * pszVal = lua_opttstring(L, 2, NULL);
+ DWORD dwType = 0;
+ DWORD dwLen = 0;
+ PVOID pvd = 0;
+ LONG ret = ERROR_SUCCESS;
+ // open the key
+ if( ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, NULL, &dwLen))
+ // alloc
+ && (pvd = lua_newuserdata(L, dwLen)) != NULL
+ // query a-again
+ && ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, pvd, &dwLen))
+ ){
+ reg_aux_pusheregluadata(L, pvd, dwLen, dwType);
+ reg_aux_pushdatatype(L, dwType);
+ }else{
+ lua_pushnil(L);
+ lua_pushnil(L);
+ //LUA_CHECK_DLL_ERROR(L, ret);
+ }
+ return 2;
+}
+#ifndef LUA_REG_NO_HIVEOPS
+//docok
+int reg_loadkey(lua_State *L){//regobj.load
+ LONG ret;
+ win_setprivilege(SE_RESTORE_NAME, 1, NULL);
+ ret = RegLoadKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), lua_checktstring(L, 3));
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+#endif // LUA_REG_NO_HIVEOPS
+//docok
+int reg_openkey(lua_State *L){//regobj.openkey
+ reg_aux_newkey(L, reg_aux_gethkey(L, 1),
+ lua_checktstring(L, 2), NULL, reg_aux_getaccess(L, 3), FALSE);
+ return 1;
+}
+#ifndef LUA_REG_NO_HIVEOPS
+//docok
+int reg_replacekey(lua_State *L){//regobj.replace
+ LONG ret;
+ win_setprivilege(SE_RESTORE_NAME, 1, NULL);
+ ret = RegReplaceKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), lua_checktstring(L, 3), lua_checktstring(L, 4));
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+//docok
+int reg_restorekey(lua_State *L){//regobj.restore
+ LONG ret;
+ DWORD dwFlags = 0;
+ win_setprivilege(SE_RESTORE_NAME, 1, NULL);
+ if(lua_isboolean(L,3)){
+ dwFlags = lua_toboolean(L,3)?REG_WHOLE_HIVE_VOLATILE:0;
+ }else{
+ dwFlags = lua_optDWORD(L, 3, 0);
+ }
+ ret = RegRestoreKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), dwFlags);
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+//docok
+int reg_savekey(lua_State *L){//regobj.save
+ LONG ret;
+ win_setprivilege(SE_BACKUP_NAME, 1, NULL);
+ ret = RegSaveKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2), NULL);
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+#endif // LUA_REG_NO_HIVEOPS
+//docok
+int reg_setvalue(lua_State *L){//regobj.setvalue
+ LUA_CHECK_RETURN_OBJECT(L,
+ reg_aux_setvalue(L, reg_aux_gethkey(L, 1), lua_opttstring(L, 2, NULL), reg_aux_getdatatype(L, 4), 3)
+ );
+}
+#ifndef LUA_REG_NO_HIVEOPS
+//docok
+int reg_unloadkey(lua_State *L){//regobj.unload
+ LONG ret;
+ win_setprivilege(SE_RESTORE_NAME, 1, NULL);
+ ret = RegUnLoadKey(reg_aux_gethkey(L,1), lua_checktstring(L, 2));
+ LUA_CHECK_DLL_ERROR(L, ret);
+ LUA_CHECK_RETURN_OBJECT(L, ret == ERROR_SUCCESS);
+}
+#endif // LUA_REG_NO_HIVEOPS
+
+int reg_handle(lua_State *L){//regobj.handle
+ HKEY hKey = reg_aux_gethkey(L, 1);
+ lua_pushlightuserdata(L, hKey);
+ return 1;
+}
+
+int reg_detach(lua_State *L){//regobj.detach
+ PHKEY phKey = reg_aux_getphkey(L, 1);
+ lua_pushlightuserdata(L, *phKey);
+ *phKey = NULL;
+ return 1;
+}
+
+int reg_getstrval(lua_State *L){//regobj.getstrval
+ HKEY hKey = reg_aux_gethkey(L, 1);
+ const TCHAR * pszVal = lua_opttstring(L, 2, NULL);
+ int expand = lua_optbool(L,3,1);
+ DWORD dwType = 0;
+ DWORD dwLen = 0;
+ PVOID pvd = 0;
+ LONG ret = ERROR_SUCCESS;
+ // open the key
+ if( ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, NULL, &dwLen))
+ // alloc
+ && (pvd = lua_newuserdata(L, dwLen)) != NULL
+ // query a-again
+ && ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, pvd, &dwLen))
+ ){
+ reg_aux_pusheregstrdata(L, pvd, dwLen, dwType, expand);
+ }else{
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
+int reg_getvaltype(lua_State *L){//regobj.getvaltype
+ HKEY hKey = reg_aux_gethkey(L, 1);
+ const TCHAR * pszVal = lua_opttstring(L, 2, NULL);
+ DWORD dwType = 0;
+ LONG ret = ERROR_SUCCESS;
+ if(ERROR_SUCCESS == (ret = RegQueryValueEx(hKey, pszVal, NULL, &dwType, NULL, NULL)) ){
+ reg_aux_pushdatatype(L, dwType);
+ }else{
+ // value does not exist!
+ lua_pushnil(L);
+ }
+ return 1;
}
\ No newline at end of file |