whelk/setup.c
author J. Ali Harlow <ali@juiblex.co.uk>
Mon Feb 08 22:07:17 2010 +0000 (2010-02-08)
changeset 10 9ae1a7880142
child 21 285b05022b5a
permissions -rw-r--r--
Add support for installing drivers
     1 #include <stdlib.h>
     2 #include <errno.h>
     3 #include <windows.h>
     4 #include <setupapi.h>
     5 #include <lua.h>
     6 #include <lualib.h>
     7 #include <lauxlib.h>
     8 #include "_whelk.h"
     9 
    10 #ifndef SUOI_FORCEDELETE
    11 #define SUOI_FORCEDELETE	1
    12 #endif
    13 
    14 int whelk_win32_error(lua_State *L,DWORD err)
    15 {
    16     DWORD n;
    17     WCHAR *buf;
    18     char *utf8;
    19     lua_pushnil(L);
    20     buf=NULL;
    21     n=FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|\
    22       FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,0,err,0,
    23       (LPWSTR)&buf,0,NULL);
    24     if (n)
    25     {
    26 	if (n>2 && buf[n-2]=='\r' && buf[n-1]=='\n')
    27 	    n-=2;
    28 	utf8=whelk_utf16_to_utf8(buf,n);
    29 	LocalFree(buf);
    30 	lua_pushstring(L,utf8);
    31 	free(utf8);
    32     }
    33     else
    34 	lua_pushstring(L,"Unknown error");
    35     lua_pushinteger(L,err);
    36     return 3;
    37 }
    38 
    39 /*
    40  * SetupCopyOEMInf(source_inf_file_name,oem_source_media_location,
    41  * 	oem_source_media_type,copy_style)
    42  *
    43  * oem_source_media_type is one of:
    44  * 	SPOST_NONE
    45  * 		No source media information is stored.
    46  *
    47  * 	SPOST_PATH
    48  * 		oem_source_media_location contains a path to the source media
    49  * 		(eg., "A:\").
    50  *
    51  *	SPOST_URL
    52  *		oem_source_media_locationcontains a universal resource locator.
    53  *
    54  * copy_style is one of:
    55  * 	SP_COPY_DELETESOURCE
    56  * 		Delete source file on successful copy.
    57  * 	SP_COPY_REPLACEONLY
    58  * 		Copy only if this file already exists in the Inf directory.
    59  *	SP_COPY_NOOVERWRITE
    60  * 		Copy only if this file does not already exist in the Inf
    61  * 		directory.
    62  *	SP_COPY_OEMINF_CATALOG_ONLY
    63  *		The specified .inf file's corresponding catalog files is
    64  *		copied to %windir%\Inf.
    65  *
    66  * Returns two strings: the destination .inf file path (including file name)
    67  * and just the file name component.
    68  */
    69 
    70 int whelk_setup_copy_oem_inf(lua_State *L)
    71 {
    72     WCHAR path[MAX_PATH];
    73     BOOL result;
    74     size_t n;
    75     const char *s;
    76     char *utf8;
    77     WCHAR *source_inf_file_name=whelk_utf8_to_utf16(luaL_checkstring(L,1),-1);
    78     WCHAR *oem_source_media_location;
    79     int oem_source_media_type=luaL_checkint(L,3);
    80     int copy_style=luaL_checkint(L,4);
    81     WCHAR *dest_in_file_name_component;
    82     s=luaL_checklstring(L,2,&n);
    83     oem_source_media_location=s?whelk_utf8_to_utf16(s,n):NULL;
    84     path[0]='\0';
    85     dest_in_file_name_component=NULL;
    86     result=SetupCopyOEMInfW(source_inf_file_name,oem_source_media_location,
    87       oem_source_media_type,copy_style,path,sizeof(path)/sizeof(*path),NULL,
    88       &dest_in_file_name_component);
    89     free(source_inf_file_name);
    90     free(oem_source_media_location);
    91     if (!result)
    92 	return whelk_win32_error(L,GetLastError());
    93     utf8=whelk_utf16_to_utf8(path,-1);
    94     lua_pushstring(L,utf8);
    95     free(utf8);
    96     if (dest_in_file_name_component)
    97     {
    98 	utf8=whelk_utf16_to_utf8(dest_in_file_name_component,-1);
    99 	lua_pushstring(L,utf8);
   100 	free(utf8);
   101     }
   102     else
   103 	lua_pushnil(L);
   104     return 2;
   105 }
   106 
   107 /*
   108  * SetupUninstallOEMInf(inf_file_name[,flags])
   109  *
   110  * The following flags are recognised:
   111  *	SUOI_FORCEDELETE
   112  *		Delete the .inf file even if an installed device uses it.
   113  *
   114  * Returns non-nil on success.
   115  */
   116 
   117 int whelk_setup_uninstall_oem_inf(lua_State *L)
   118 {
   119     BOOL result;
   120     WCHAR *inf_file_name=whelk_utf8_to_utf16(luaL_checkstring(L,1),-1);
   121     int flags=lua_isnone(L,2)?0:luaL_checkint(L,2);
   122 #ifdef HAVE_SETUPUNINSTALLOEMINFW
   123     result=SetupUninstallOEMInfW(inf_file_name,flags,NULL);
   124 #else
   125     HMODULE lib;
   126     BOOL (WINAPI *SetupUninstallOEMInfW)(WCHAR *inf_file_name,DWORD flags,
   127       VOID *reserved);
   128     lib=LoadLibrary("setupapi.dll");
   129     if (lib)
   130     {
   131 	SetupUninstallOEMInfW=GetProcAddress(lib,"SetupUninstallOEMInfW");
   132 	if (SetupUninstallOEMInfW)
   133 	    result=SetupUninstallOEMInfW(inf_file_name,flags,NULL);
   134 	else
   135 	{
   136 	    FreeLibrary(lib);
   137 	    free(inf_file_name);
   138 	    return whelk_win32_error(L,ERROR_NOT_SUPPORTED);
   139 	}
   140 	FreeLibrary(lib);
   141     }
   142     else
   143     {
   144 	free(inf_file_name);
   145 	return whelk_win32_error(L,ERROR_NOT_SUPPORTED);
   146     }
   147 #endif
   148     free(inf_file_name);
   149     if (!result)
   150 	return whelk_win32_error(L,GetLastError());
   151     lua_pushinteger(L,1);		/* Something other than nil */
   152     return 1;
   153 }
   154 
   155 void whelk_open_setup(lua_State *L)
   156 {
   157     whelk_reg_const(L,SPOST_NONE);
   158     whelk_reg_const(L,SPOST_PATH);
   159     whelk_reg_const(L,SPOST_URL);
   160     whelk_reg_const(L,SP_COPY_DELETESOURCE);
   161     whelk_reg_const(L,SP_COPY_REPLACEONLY);
   162     whelk_reg_const(L,SP_COPY_NOOVERWRITE);
   163     whelk_reg_const(L,SP_COPY_OEMINF_CATALOG_ONLY);
   164     whelk_reg_const(L,SUOI_FORCEDELETE);
   165 }