whelk/reg_keys.c
changeset 0 8525965e930d
child 10 9ae1a7880142
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/whelk/reg_keys.c	Thu Jul 09 08:52:03 2009 +0100
     1.3 @@ -0,0 +1,168 @@
     1.4 +#include <stdlib.h>
     1.5 +#include <errno.h>
     1.6 +#include <windows.h>
     1.7 +#include <lua.h>
     1.8 +#include <lualib.h>
     1.9 +#include <lauxlib.h>
    1.10 +#include "_whelk.h"
    1.11 +
    1.12 +#define WHELK_KEYHANDLE		"HKEY"
    1.13 +#define whelk_checkkeyptr(L,n)	((HKEY *)luaL_checkudata(L,n,WHELK_KEYHANDLE))
    1.14 +
    1.15 +static HKEY whelk_checkkey(lua_State *L,int n)
    1.16 +{
    1.17 +    HKEY *key=whelk_checkkeyptr(L,n);
    1.18 +    if (*key==INVALID_HANDLE_VALUE)
    1.19 +	luaL_error(L,"attempt to use a closed WIN32 registry key");
    1.20 +    return *key;
    1.21 +}
    1.22 +
    1.23 +static HKEY *newkey(lua_State *L)
    1.24 +{
    1.25 +    HKEY *key=(HKEY *)lua_newuserdata(L,sizeof(HKEY));
    1.26 +    *key=INVALID_HANDLE_VALUE;
    1.27 +    luaL_getmetatable(L,WHELK_KEYHANDLE);
    1.28 +    lua_setmetatable(L,-2);
    1.29 +    return key;
    1.30 +}
    1.31 +
    1.32 +static int get_value(lua_State *L)
    1.33 +{
    1.34 +    DWORD type,nb;
    1.35 +    HRESULT result;
    1.36 +    int retval=1;
    1.37 +    void *data;
    1.38 +    HKEY key=whelk_checkkey(L,1);
    1.39 +    const char *subkey=luaL_checkstring(L,2);
    1.40 +    const char *value=luaL_checkstring(L,3);
    1.41 +    result=whelk_reg_get_value(key,subkey,value,&type,&data,&nb);
    1.42 +    if (result!=ERROR_SUCCESS)
    1.43 +    {
    1.44 +	lua_pushnil(L);
    1.45 +	lua_pushfstring(L,"%s: Failed to get value",value);
    1.46 +	lua_pushinteger(L,result);
    1.47 +	retval=3;
    1.48 +    }
    1.49 +    else
    1.50 +	switch(type)
    1.51 +	{
    1.52 +	    case REG_SZ:
    1.53 +	    case REG_EXPAND_SZ:
    1.54 +		lua_pushstring(L,(char *)data);
    1.55 +		break;
    1.56 +	    case REG_DWORD:
    1.57 +		lua_pushnumber(L,*(DWORD *)data);
    1.58 +		break;
    1.59 +	    default:
    1.60 +		lua_pushnil(L);
    1.61 +		lua_pushfstring(L,"%s: Data is not a string or number",value);
    1.62 +		lua_pushinteger(L,ERROR_INVALID_PARAMETER);
    1.63 +		retval=3;
    1.64 +	}
    1.65 +    free(data);
    1.66 +    return retval;
    1.67 +}
    1.68 +
    1.69 +static int set_value(lua_State *L)
    1.70 +{
    1.71 +    DWORD type;
    1.72 +    int nb;
    1.73 +    HRESULT result;
    1.74 +    lua_Number number;
    1.75 +    DWORD d;
    1.76 +    const void *data;
    1.77 +    HKEY key=whelk_checkkey(L,1);
    1.78 +    const char *subkey=luaL_checkstring(L,2);
    1.79 +    const char *value=luaL_checkstring(L,3);
    1.80 +    switch(lua_type(L,4))
    1.81 +    {
    1.82 +	case LUA_TSTRING:
    1.83 +	    data=lua_tostring(L,4);
    1.84 +	    type=REG_SZ;
    1.85 +	    nb=-1;
    1.86 +	    break;
    1.87 +	case LUA_TNUMBER:
    1.88 +	    number=lua_tonumber(L,4);
    1.89 +	    d=(DWORD)number;
    1.90 +	    if ((lua_Number)d!=number)
    1.91 +	    {
    1.92 +		lua_pushnil(L);
    1.93 +		lua_pushfstring(L,"%s: Data is not storable as DWORD",value);
    1.94 +		lua_pushinteger(L,ERROR_INVALID_PARAMETER);
    1.95 +	    }
    1.96 +	    data=&d;
    1.97 +	    type=REG_DWORD;
    1.98 +	    nb=sizeof(d);
    1.99 +	    break;
   1.100 +	case LUA_TNIL:
   1.101 +	    data=NULL;
   1.102 +	    type=REG_NONE;
   1.103 +	    nb=0;
   1.104 +	    break;
   1.105 +	default:
   1.106 +	    lua_pushnil(L);
   1.107 +	    lua_pushfstring(L,"%s: Data is not a string or number",value);
   1.108 +	    lua_pushinteger(L,ERROR_INVALID_PARAMETER);
   1.109 +	    return 3;
   1.110 +    }
   1.111 +    result=whelk_reg_set_value(key,subkey,value,type,data,nb);
   1.112 +    if (result!=ERROR_SUCCESS)
   1.113 +    {
   1.114 +	lua_pushnil(L);
   1.115 +	lua_pushfstring(L,"%s: Failed to set value",value);
   1.116 +	lua_pushinteger(L,result);
   1.117 +	return 3;
   1.118 +    }
   1.119 +    return 1;
   1.120 +}
   1.121 +
   1.122 +static int delete_key(lua_State *L)
   1.123 +{
   1.124 +    HRESULT result;
   1.125 +    HKEY key=whelk_checkkey(L,1);
   1.126 +    const char *subkey=luaL_checkstring(L,2);
   1.127 +    result=whelk_reg_delete_key(key,subkey);
   1.128 +    if (result!=ERROR_SUCCESS)
   1.129 +    {
   1.130 +	lua_pushnil(L);
   1.131 +	lua_pushfstring(L,"%s: Failed to delete key",subkey);
   1.132 +	lua_pushinteger(L,result);
   1.133 +	return 3;
   1.134 +    }
   1.135 +    return 1;
   1.136 +}
   1.137 +
   1.138 +static int reg_gc(lua_State *L)
   1.139 +{
   1.140 +    HKEY key=*whelk_checkkeyptr(L,1);
   1.141 +    if (key!=INVALID_HANDLE_VALUE)
   1.142 +	(void)whelk_reg_close_key(key);
   1.143 +    return 0;
   1.144 +}
   1.145 +
   1.146 +static const luaL_Reg reg_methods[]={
   1.147 +    { "GetValue",get_value },
   1.148 +    { "SetValue",set_value },
   1.149 +    { "DeleteKey",delete_key },
   1.150 +    { "__gc",reg_gc },
   1.151 +    { NULL }
   1.152 +};
   1.153 +
   1.154 +static void create_predefined_key(lua_State *L,HKEY key,const char *name)
   1.155 +{
   1.156 +    *newkey(L)=key;
   1.157 +    lua_setfield(L,-3,name);
   1.158 +}
   1.159 +
   1.160 +void whelk_open_reg_keys(lua_State *L)
   1.161 +{
   1.162 +    luaL_newmetatable(L,WHELK_KEYHANDLE);
   1.163 +    lua_pushvalue(L,-1);
   1.164 +    lua_setfield(L,-2,"__index");
   1.165 +    luaL_register(L,NULL,reg_methods);
   1.166 +    create_predefined_key(L,HKEY_CLASSES_ROOT,"KEY_CLASSES_ROOT");
   1.167 +    create_predefined_key(L,HKEY_CURRENT_CONFIG,"KEY_CURRENT_CONFIG");
   1.168 +    create_predefined_key(L,HKEY_CURRENT_USER,"KEY_CURRENT_USER");
   1.169 +    create_predefined_key(L,HKEY_LOCAL_MACHINE,"KEY_LOCAL_MACHINE");
   1.170 +    create_predefined_key(L,HKEY_USERS,"KEY_USERS");
   1.171 +}