#include #include #include #include #include #include #include "_whelk.h" #define WHELK_KEYHANDLE "HKEY" #define whelk_checkkeyptr(L,n) ((HKEY *)luaL_checkudata(L,n,WHELK_KEYHANDLE)) static HKEY whelk_checkkey(lua_State *L,int n) { HKEY *key=whelk_checkkeyptr(L,n); if (*key==INVALID_HANDLE_VALUE) luaL_error(L,"attempt to use a closed WIN32 registry key"); return *key; } static HKEY *newkey(lua_State *L) { HKEY *key=(HKEY *)lua_newuserdata(L,sizeof(HKEY)); *key=INVALID_HANDLE_VALUE; luaL_getmetatable(L,WHELK_KEYHANDLE); lua_setmetatable(L,-2); return key; } static int get_value(lua_State *L) { DWORD type,nb; HRESULT result; int retval=1; void *data; HKEY key=whelk_checkkey(L,1); const char *subkey=luaL_checkstring(L,2); const char *value=luaL_checkstring(L,3); result=whelk_reg_get_value(key,subkey,value,&type,&data,&nb); if (result!=ERROR_SUCCESS) { lua_pushnil(L); lua_pushfstring(L,"%s: Failed to get value",value); lua_pushinteger(L,result); retval=3; } else switch(type) { case REG_SZ: case REG_EXPAND_SZ: lua_pushstring(L,(char *)data); break; case REG_DWORD: lua_pushnumber(L,*(DWORD *)data); break; default: lua_pushnil(L); lua_pushfstring(L,"%s: Data is not a string or number",value); lua_pushinteger(L,ERROR_INVALID_PARAMETER); retval=3; } free(data); return retval; } static int set_value(lua_State *L) { DWORD type; int nb; HRESULT result; lua_Number number; DWORD d; const void *data; HKEY key=whelk_checkkey(L,1); const char *subkey=luaL_checkstring(L,2); const char *value=luaL_checkstring(L,3); switch(lua_type(L,4)) { case LUA_TSTRING: data=lua_tostring(L,4); type=REG_SZ; nb=-1; break; case LUA_TNUMBER: number=lua_tonumber(L,4); d=(DWORD)number; if ((lua_Number)d!=number) { lua_pushnil(L); lua_pushfstring(L,"%s: Data is not storable as DWORD",value); lua_pushinteger(L,ERROR_INVALID_PARAMETER); } data=&d; type=REG_DWORD; nb=sizeof(d); break; case LUA_TNIL: data=NULL; type=REG_NONE; nb=0; break; default: lua_pushnil(L); lua_pushfstring(L,"%s: Data is not a string or number",value); lua_pushinteger(L,ERROR_INVALID_PARAMETER); return 3; } result=whelk_reg_set_value(key,subkey,value,type,data,nb); if (result!=ERROR_SUCCESS) { lua_pushnil(L); lua_pushfstring(L,"%s: Failed to set value",value); lua_pushinteger(L,result); return 3; } return 1; } static int delete_key(lua_State *L) { HRESULT result; HKEY key=whelk_checkkey(L,1); const char *subkey=luaL_checkstring(L,2); result=whelk_reg_delete_key(key,subkey); if (result!=ERROR_SUCCESS) { lua_pushnil(L); lua_pushfstring(L,"%s: Failed to delete key",subkey); lua_pushinteger(L,result); return 3; } return 1; } static int reg_gc(lua_State *L) { HKEY key=*whelk_checkkeyptr(L,1); if (key!=INVALID_HANDLE_VALUE) (void)whelk_reg_close_key(key); return 0; } static const luaL_Reg reg_methods[]={ { "GetValue",get_value }, { "SetValue",set_value }, { "DeleteKey",delete_key }, { "__gc",reg_gc }, { NULL } }; static void create_predefined_key(lua_State *L,HKEY key,const char *name) { *newkey(L)=key; lua_setfield(L,-3,name); } void whelk_open_reg_keys(lua_State *L) { luaL_newmetatable(L,WHELK_KEYHANDLE); lua_pushvalue(L,-1); lua_setfield(L,-2,"__index"); luaL_register(L,NULL,reg_methods); create_predefined_key(L,HKEY_CLASSES_ROOT,"KEY_CLASSES_ROOT"); create_predefined_key(L,HKEY_CURRENT_CONFIG,"KEY_CURRENT_CONFIG"); create_predefined_key(L,HKEY_CURRENT_USER,"KEY_CURRENT_USER"); create_predefined_key(L,HKEY_LOCAL_MACHINE,"KEY_LOCAL_MACHINE"); create_predefined_key(L,HKEY_USERS,"KEY_USERS"); lua_pop(L,1); }