From f7dc083938a27e90fadf7544af2a46c1b7c25447 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Mon, 15 Mar 2010 19:53:42 +0000 Subject: added x86 & x64 installers to resource lib plus various other improvements --- driver-installer_2008.vcproj | 8 +++ examples/lsusb.c | 1 - libusb/os/driver_install.c | 58 +++++++++++------- libusb/os/driver_installer.c | 12 +++- msvc/driver_resources.rc | 141 ++++++------------------------------------- 5 files changed, 74 insertions(+), 146 deletions(-) diff --git a/driver-installer_2008.vcproj b/driver-installer_2008.vcproj index af71042..254c59c 100644 --- a/driver-installer_2008.vcproj +++ b/driver-installer_2008.vcproj @@ -343,6 +343,14 @@ > + + + + diff --git a/examples/lsusb.c b/examples/lsusb.c index 28e4b51..93951eb 100644 --- a/examples/lsusb.c +++ b/examples/lsusb.c @@ -58,7 +58,6 @@ main(void) run_installer("C:\\test", drv_info->device_id); } } -// update_drivers(); return 0; r = libusb_init(NULL); diff --git a/libusb/os/driver_install.c b/libusb/os/driver_install.c index 2118689..5b7267d 100644 --- a/libusb/os/driver_install.c +++ b/libusb/os/driver_install.c @@ -89,15 +89,19 @@ struct res { const struct res resource[] = { {"AMD64_DLL1" , "amd64", "WdfCoInstaller01009.dll"}, {"AMD64_DLL2" , "amd64", "winusbcoinstaller2.dll"}, {"X86_DLL1", "x86", "WdfCoInstaller01009.dll"}, - {"X86_DLL2", "x86", "winusbcoinstaller2.dll"} }; + {"X86_DLL2", "x86", "winusbcoinstaller2.dll"}, + {"AMD64_INSTALLER", ".", "installer_x64.exe"}, + {"X86_INSTALLER", ".", "installer_x86.exe"} }; const int nb_resources = sizeof(resource)/sizeof(resource[0]); -// TODO: remove if not needed -extern char* sanitize_path(const char* path); extern char *windows_error_str(uint32_t retval); HANDLE pipe = INVALID_HANDLE_VALUE; char* req_device_id; +// for 64 bit platforms detection +static BOOL (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL; + + char* guid_to_string(const GUID guid) { static char guid_string[MAX_GUID_STRING_LENGTH]; @@ -128,7 +132,6 @@ static int init_cfgmgr32(void) DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE); DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE); DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDW, TRUE); - return LIBUSB_SUCCESS; } @@ -163,7 +166,6 @@ struct driver_info* list_driverless(void) for (i = 0; ; i++) { driverless = false; - safe_free(sanitized_short); dev_info_data.cbSize = sizeof(dev_info_data); if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data)) { @@ -209,13 +211,7 @@ struct driver_info* list_driverless(void) continue; } - sanitized_short = sanitize_path(path); - - if (sanitized_short == NULL) { - usbi_err(NULL, "could not sanitize path for device %d", i); - continue; - } - usbi_dbg("Driverless USB device (%d): %s", i, sanitized_short); + usbi_dbg("Driverless USB device (%d): %s", i, path); drv_info = calloc(1, sizeof(struct driver_info)); if (drv_info == NULL) { @@ -229,12 +225,12 @@ struct driver_info* list_driverless(void) } cur = drv_info; - // sanitized path should NOT be used as device id + // duplicate for device id drv_info->device_id = _strdup(path); safe_strcpy(drv_info->desc, sizeof(drv_info->desc), desc); - token = strtok (sanitized_short, "#&"); + token = strtok (path, "\\#&"); while(token != NULL) { for (j = 0; j < 3; j++) { if (safe_strncmp(token, prefix[j], strlen(prefix[j])) == 0) { @@ -254,15 +250,14 @@ struct driver_info* list_driverless(void) } } } - token = strtok (NULL, "#&"); + token = strtok (NULL, "\\#&"); } } return ret; } -// TODO: dynamic res addon -int extract_dlls(char* path) +int extract_binaries(char* path) { HANDLE h; HGLOBAL h_load; @@ -273,7 +268,7 @@ int extract_dlls(char* path) int i; for (i=0; i< nb_resources; i++) { - h = FindResource(NULL, resource[i].id, "DLL"); + h = FindResource(NULL, resource[i].id, "BIN"); if (h == NULL) { usbi_dbg("could not find resource %s", resource[i].id); return -1; @@ -322,6 +317,7 @@ int extract_dlls(char* path) } // Create an inf and extract coinstallers in the directory pointed by path +// TODO: optional directory deletion int create_inf(struct driver_info* drv_info, char* path) { char filename[MAX_PATH_LENGTH]; @@ -338,7 +334,7 @@ int create_inf(struct driver_info* drv_info, char* path) return -1; } - extract_dlls(path); + extract_binaries(path); safe_strcpy(filename, MAX_PATH_LENGTH, path); safe_strcat(filename, MAX_PATH_LENGTH, "\\"); @@ -369,7 +365,6 @@ int create_inf(struct driver_info* drv_info, char* path) return 0; } - int process_message(char* buffer, DWORD size) { DWORD junk; @@ -397,7 +392,6 @@ int process_message(char* buffer, DWORD size) return 0; } -// TODO: extract driver-installer.exe into the dest dir int run_installer(char* path, char* device_id) { SHELLEXECUTEINFO shExecInfo; @@ -406,11 +400,26 @@ int run_installer(char* path, char* device_id) OVERLAPPED overlapped; int r; DWORD rd_count; + BOOL is_x64 = false; #define BUFSIZE 256 char buffer[BUFSIZE]; req_device_id = device_id; + // Detect whether if we should run the 64 bit installer, without + // relying on external libs + if (sizeof(uintptr_t) < 8) { + // This application is not 64 bit, but it might be 32 bit + // running in WOW64 + pIsWow64Process = (BOOL (__stdcall *)(HANDLE, PBOOL)) + GetProcAddress(GetModuleHandle("KERNEL32"), "IsWow64Process"); + if (pIsWow64Process != NULL) { + (*pIsWow64Process)(GetCurrentProcess(), &is_x64); + } + } else { + is_x64 = true; + } + // Use a pipe to communicate with our installer pipe = CreateNamedPipe("\\\\.\\pipe\\libusb-installer", PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE, 1, 4096, 4096, 0, NULL); @@ -428,7 +437,12 @@ int run_installer(char* path, char* device_id) overlapped.hEvent = handle[0]; safe_strcpy(exename, MAX_PATH_LENGTH, path); - safe_strcat(exename, MAX_PATH_LENGTH, "\\driver-installer.exe"); + // TODO: fallback to x86 if x64 unavailable + if (is_x64) { + safe_strcat(exename, MAX_PATH_LENGTH, "\\installer_x64.exe"); + } else { + safe_strcat(exename, MAX_PATH_LENGTH, "\\installer_x86.exe"); + } shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); diff --git a/libusb/os/driver_installer.c b/libusb/os/driver_installer.c index c2d1720..d42e17f 100644 --- a/libusb/os/driver_installer.c +++ b/libusb/os/driver_installer.c @@ -212,6 +212,8 @@ int update_driver(char* device_id) return 0; } + +// TODO: allow commandline options int main(int argc, char** argv) { DWORD r; @@ -220,6 +222,8 @@ int main(int argc, char** argv) char path[MAX_PATH_LENGTH]; char log[MAX_PATH_LENGTH]; FILE *fd; + OSVERSIONINFO os_version; + DWORD legacy_flag; // Connect to the messaging pipe pipe = CreateFile("\\\\.\\pipe\\libusb-installer", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, @@ -256,10 +260,16 @@ int main(int argc, char** argv) device_id = req_device_id(); + // using DRIVER_PACKAGE_LEGACY_MODE generates a warning on Vista and later + if ( (GetVersionEx(&os_version) != 0) + && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT) ) { + legacy_flag = (os_version.dwMajorVersion >= 6)?0:DRIVER_PACKAGE_LEGACY_MODE; + } + plog("Installing driver - please wait..."); DIFXAPISetLogCallback(log_callback, NULL); // TODO: set app dependency? - r = DriverPackageInstall(path, DRIVER_PACKAGE_LEGACY_MODE|DRIVER_PACKAGE_REPAIR|DRIVER_PACKAGE_FORCE, + r = DriverPackageInstall(path, legacy_flag|DRIVER_PACKAGE_REPAIR|DRIVER_PACKAGE_FORCE, NULL, &reboot_needed); DIFXAPISetLogCallback(NULL, NULL); // Will fail if inf not signed, unless DRIVER_PACKAGE_LEGACY_MODE is specified. diff --git a/msvc/driver_resources.rc b/msvc/driver_resources.rc index bb4ed33..6e178d6 100644 --- a/msvc/driver_resources.rc +++ b/msvc/driver_resources.rc @@ -1,125 +1,22 @@ -// Microsoft Visual C++ generated resource script. -// -//#include "resource.h" +/* + * resources for the driver installer library + */ -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// DLL -// +/* + * DLLs + */ // Make sure you set the path to your DDK as an include directory for the files below -AMD64_DLL1 DLL "redist\\wdf\\amd64\\WdfCoInstaller01009.dll" -AMD64_DLL2 DLL "redist\\winusb\\amd64\\winusbcoinstaller2.dll" -X86_DLL1 DLL "redist\\wdf\\x86\\WdfCoInstaller01009.dll" -X86_DLL2 DLL "redist\\winusb\\x86\\winusbcoinstaller2.dll" -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (Ireland) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENI) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_EIRE -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,7,0 - PRODUCTVERSION 1,0,7,0 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "libusb.org" - VALUE "FileDescription", "driver_install" - VALUE "FileVersion", "1, 0, 7, 0" - VALUE "InternalName", "driver_install" - VALUE "LegalCopyright", "See individual source files, GNU LGPL v2.1 or later." - VALUE "LegalTrademarks", "http://www.gnu.org/licenses/lgpl-2.1.html" - VALUE "OriginalFilename", "driver_install.dll" - VALUE "ProductName", "driver_install" - VALUE "ProductVersion", "1, 0, 7, 0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (Ireland) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - +AMD64_DLL1 BIN "redist\\wdf\\amd64\\WdfCoInstaller01009.dll" +AMD64_DLL2 BIN "redist\\winusb\\amd64\\winusbcoinstaller2.dll" +X86_DLL1 BIN "redist\\wdf\\x86\\WdfCoInstaller01009.dll" +X86_DLL2 BIN "redist\\winusb\\x86\\winusbcoinstaller2.dll" + +/* + * Installer executable requiring UAC elevation + */ +// Why do we need two installers? Glad you asked. If you try to run the x86 +// installer on an x64 system, you will get the annoying "This program might +// not have installed properly" prompt. So we must ensure 64 bit OS runs 64 bit exe. +AMD64_INSTALLER BIN "x64\\Release\\lib\\driver-installer.exe" +X86_INSTALLER BIN "Win32\\Release\\lib\\driver-installer.exe" -- cgit v1.2.1