whelk/reg_keys.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Jul 09 08:52:03 2009 +0100 (2009-07-09)
changeset 0 8525965e930d
child 10 9ae1a7880142
permissions -rw-r--r--
Initial checkin
ali@0
     1
#include <stdlib.h>
ali@0
     2
#include <errno.h>
ali@0
     3
#include <windows.h>
ali@0
     4
#include <lua.h>
ali@0
     5
#include <lualib.h>
ali@0
     6
#include <lauxlib.h>
ali@0
     7
#include "_whelk.h"
ali@0
     8
ali@0
     9
#define WHELK_KEYHANDLE		"HKEY"
ali@0
    10
#define whelk_checkkeyptr(L,n)	((HKEY *)luaL_checkudata(L,n,WHELK_KEYHANDLE))
ali@0
    11
ali@0
    12
static HKEY whelk_checkkey(lua_State *L,int n)
ali@0
    13
{
ali@0
    14
    HKEY *key=whelk_checkkeyptr(L,n);
ali@0
    15
    if (*key==INVALID_HANDLE_VALUE)
ali@0
    16
	luaL_error(L,"attempt to use a closed WIN32 registry key");
ali@0
    17
    return *key;
ali@0
    18
}
ali@0
    19
ali@0
    20
static HKEY *newkey(lua_State *L)
ali@0
    21
{
ali@0
    22
    HKEY *key=(HKEY *)lua_newuserdata(L,sizeof(HKEY));
ali@0
    23
    *key=INVALID_HANDLE_VALUE;
ali@0
    24
    luaL_getmetatable(L,WHELK_KEYHANDLE);
ali@0
    25
    lua_setmetatable(L,-2);
ali@0
    26
    return key;
ali@0
    27
}
ali@0
    28
ali@0
    29
static int get_value(lua_State *L)
ali@0
    30
{
ali@0
    31
    DWORD type,nb;
ali@0
    32
    HRESULT result;
ali@0
    33
    int retval=1;
ali@0
    34
    void *data;
ali@0
    35
    HKEY key=whelk_checkkey(L,1);
ali@0
    36
    const char *subkey=luaL_checkstring(L,2);
ali@0
    37
    const char *value=luaL_checkstring(L,3);
ali@0
    38
    result=whelk_reg_get_value(key,subkey,value,&type,&data,&nb);
ali@0
    39
    if (result!=ERROR_SUCCESS)
ali@0
    40
    {
ali@0
    41
	lua_pushnil(L);
ali@0
    42
	lua_pushfstring(L,"%s: Failed to get value",value);
ali@0
    43
	lua_pushinteger(L,result);
ali@0
    44
	retval=3;
ali@0
    45
    }
ali@0
    46
    else
ali@0
    47
	switch(type)
ali@0
    48
	{
ali@0
    49
	    case REG_SZ:
ali@0
    50
	    case REG_EXPAND_SZ:
ali@0
    51
		lua_pushstring(L,(char *)data);
ali@0
    52
		break;
ali@0
    53
	    case REG_DWORD:
ali@0
    54
		lua_pushnumber(L,*(DWORD *)data);
ali@0
    55
		break;
ali@0
    56
	    default:
ali@0
    57
		lua_pushnil(L);
ali@0
    58
		lua_pushfstring(L,"%s: Data is not a string or number",value);
ali@0
    59
		lua_pushinteger(L,ERROR_INVALID_PARAMETER);
ali@0
    60
		retval=3;
ali@0
    61
	}
ali@0
    62
    free(data);
ali@0
    63
    return retval;
ali@0
    64
}
ali@0
    65
ali@0
    66
static int set_value(lua_State *L)
ali@0
    67
{
ali@0
    68
    DWORD type;
ali@0
    69
    int nb;
ali@0
    70
    HRESULT result;
ali@0
    71
    lua_Number number;
ali@0
    72
    DWORD d;
ali@0
    73
    const void *data;
ali@0
    74
    HKEY key=whelk_checkkey(L,1);
ali@0
    75
    const char *subkey=luaL_checkstring(L,2);
ali@0
    76
    const char *value=luaL_checkstring(L,3);
ali@0
    77
    switch(lua_type(L,4))
ali@0
    78
    {
ali@0
    79
	case LUA_TSTRING:
ali@0
    80
	    data=lua_tostring(L,4);
ali@0
    81
	    type=REG_SZ;
ali@0
    82
	    nb=-1;
ali@0
    83
	    break;
ali@0
    84
	case LUA_TNUMBER:
ali@0
    85
	    number=lua_tonumber(L,4);
ali@0
    86
	    d=(DWORD)number;
ali@0
    87
	    if ((lua_Number)d!=number)
ali@0
    88
	    {
ali@0
    89
		lua_pushnil(L);
ali@0
    90
		lua_pushfstring(L,"%s: Data is not storable as DWORD",value);
ali@0
    91
		lua_pushinteger(L,ERROR_INVALID_PARAMETER);
ali@0
    92
	    }
ali@0
    93
	    data=&d;
ali@0
    94
	    type=REG_DWORD;
ali@0
    95
	    nb=sizeof(d);
ali@0
    96
	    break;
ali@0
    97
	case LUA_TNIL:
ali@0
    98
	    data=NULL;
ali@0
    99
	    type=REG_NONE;
ali@0
   100
	    nb=0;
ali@0
   101
	    break;
ali@0
   102
	default:
ali@0
   103
	    lua_pushnil(L);
ali@0
   104
	    lua_pushfstring(L,"%s: Data is not a string or number",value);
ali@0
   105
	    lua_pushinteger(L,ERROR_INVALID_PARAMETER);
ali@0
   106
	    return 3;
ali@0
   107
    }
ali@0
   108
    result=whelk_reg_set_value(key,subkey,value,type,data,nb);
ali@0
   109
    if (result!=ERROR_SUCCESS)
ali@0
   110
    {
ali@0
   111
	lua_pushnil(L);
ali@0
   112
	lua_pushfstring(L,"%s: Failed to set value",value);
ali@0
   113
	lua_pushinteger(L,result);
ali@0
   114
	return 3;
ali@0
   115
    }
ali@0
   116
    return 1;
ali@0
   117
}
ali@0
   118
ali@0
   119
static int delete_key(lua_State *L)
ali@0
   120
{
ali@0
   121
    HRESULT result;
ali@0
   122
    HKEY key=whelk_checkkey(L,1);
ali@0
   123
    const char *subkey=luaL_checkstring(L,2);
ali@0
   124
    result=whelk_reg_delete_key(key,subkey);
ali@0
   125
    if (result!=ERROR_SUCCESS)
ali@0
   126
    {
ali@0
   127
	lua_pushnil(L);
ali@0
   128
	lua_pushfstring(L,"%s: Failed to delete key",subkey);
ali@0
   129
	lua_pushinteger(L,result);
ali@0
   130
	return 3;
ali@0
   131
    }
ali@0
   132
    return 1;
ali@0
   133
}
ali@0
   134
ali@0
   135
static int reg_gc(lua_State *L)
ali@0
   136
{
ali@0
   137
    HKEY key=*whelk_checkkeyptr(L,1);
ali@0
   138
    if (key!=INVALID_HANDLE_VALUE)
ali@0
   139
	(void)whelk_reg_close_key(key);
ali@0
   140
    return 0;
ali@0
   141
}
ali@0
   142
ali@0
   143
static const luaL_Reg reg_methods[]={
ali@0
   144
    { "GetValue",get_value },
ali@0
   145
    { "SetValue",set_value },
ali@0
   146
    { "DeleteKey",delete_key },
ali@0
   147
    { "__gc",reg_gc },
ali@0
   148
    { NULL }
ali@0
   149
};
ali@0
   150
ali@0
   151
static void create_predefined_key(lua_State *L,HKEY key,const char *name)
ali@0
   152
{
ali@0
   153
    *newkey(L)=key;
ali@0
   154
    lua_setfield(L,-3,name);
ali@0
   155
}
ali@0
   156
ali@0
   157
void whelk_open_reg_keys(lua_State *L)
ali@0
   158
{
ali@0
   159
    luaL_newmetatable(L,WHELK_KEYHANDLE);
ali@0
   160
    lua_pushvalue(L,-1);
ali@0
   161
    lua_setfield(L,-2,"__index");
ali@0
   162
    luaL_register(L,NULL,reg_methods);
ali@0
   163
    create_predefined_key(L,HKEY_CLASSES_ROOT,"KEY_CLASSES_ROOT");
ali@0
   164
    create_predefined_key(L,HKEY_CURRENT_CONFIG,"KEY_CURRENT_CONFIG");
ali@0
   165
    create_predefined_key(L,HKEY_CURRENT_USER,"KEY_CURRENT_USER");
ali@0
   166
    create_predefined_key(L,HKEY_LOCAL_MACHINE,"KEY_LOCAL_MACHINE");
ali@0
   167
    create_predefined_key(L,HKEY_USERS,"KEY_USERS");
ali@0
   168
}