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