summaryrefslogtreecommitdiff
path: root/libusb/os/driver_install.c
diff options
context:
space:
mode:
Diffstat (limited to 'libusb/os/driver_install.c')
-rw-r--r--libusb/os/driver_install.c144
1 files changed, 77 insertions, 67 deletions
diff --git a/libusb/os/driver_install.c b/libusb/os/driver_install.c
index 83b7bde..dbbfcd5 100644
--- a/libusb/os/driver_install.c
+++ b/libusb/os/driver_install.c
@@ -11,6 +11,7 @@
#include "libusbi.h"
#include "windows_usb.h"
#include "driver_install.h"
+#include "driver-installer.h"
#define INF_NAME "libusb-device.inf"
@@ -79,7 +80,6 @@ const char inf[] = "Date = \"03/08/2010\"\n\n" \
"WdfCoInstaller01009.dll=2\n\n" \
"[SourceDisksFiles.ia64]\n";
-
struct res {
char* id;
char* subdir;
@@ -91,8 +91,11 @@ const struct res resource[] = { {"AMD64_DLL1" , "amd64", "WdfCoInstaller01009.dl
{"X86_DLL1", "x86", "WdfCoInstaller01009.dll"},
{"X86_DLL2", "x86", "winusbcoinstaller2.dll"} };
const int nb_resources = sizeof(resource)/sizeof(resource[0]);
-
extern char* sanitize_path(const char* path);
+
+HANDLE pipe = INVALID_HANDLE_VALUE;
+char* req_device_id;
+
char* guid_to_string(const GUID guid)
{
static char guid_string[MAX_GUID_STRING_LENGTH];
@@ -123,8 +126,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);
- DLL_LOAD(Cfgmgr32.dll, CM_Locate_DevNode, TRUE);
- DLL_LOAD(Cfgmgr32.dll, CM_Reenumerate_DevNode, TRUE);
return LIBUSB_SUCCESS;
}
@@ -226,6 +227,9 @@ struct driver_info* list_driverless(void)
}
cur = drv_info;
+ // sanitized path should NOT be used as device id
+ drv_info->device_id = strdup(path);
+
safe_strcpy(drv_info->desc, sizeof(drv_info->desc), desc);
token = strtok (sanitized_short, "#&");
@@ -363,21 +367,50 @@ int create_inf(struct driver_info* drv_info, char* path)
return 0;
}
+
+int process_message(char* buffer, DWORD size)
+{
+ DWORD junk;
+
+ if (size <= 0)
+ return -1;
+
+ switch(buffer[0])
+ {
+ case IC_GET_DEVICE_ID:
+ usbi_dbg("got request for device_id");
+ WriteFile(pipe, req_device_id, strlen(req_device_id), &junk, NULL);
+ break;
+ case IC_PRINT_MESSAGE:
+ if (size < 2) {
+ usbi_err(NULL, "print_message: no data");
+ return -1;
+ }
+ usbi_dbg("[installer process] %s", buffer+1);
+ break;
+ default:
+ usbi_err(NULL, "unrecognized installer message");
+ return -1;
+ }
+ return 0;
+}
+
// TODO: extract driver-installer.exe into the dest dir
-int run_installer(char* path)
+int run_installer(char* path, char* device_id)
{
SHELLEXECUTEINFO shExecInfo;
char exename[MAX_PATH_LENGTH];
HANDLE handle[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
- HANDLE pipe = INVALID_HANDLE_VALUE;
OVERLAPPED overlapped;
- int r, ret;
+ int r;
DWORD rd_count;
- char buffer[256];
+#define BUFSIZE 256
+ char buffer[BUFSIZE];
+ req_device_id = device_id;
// Use a pipe to communicate with our installer
- pipe = CreateNamedPipe("\\\\.\\pipe\\libusb-installer", PIPE_ACCESS_INBOUND|FILE_FLAG_OVERLAPPED,
+ pipe = CreateNamedPipe("\\\\.\\pipe\\libusb-installer", PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE, 1, 4096, 4096, 0, NULL);
if (pipe == INVALID_HANDLE_VALUE) {
usbi_err(NULL, "could not create read pipe: errcode %d", (int)GetLastError());
@@ -387,7 +420,7 @@ int run_installer(char* path)
// Set the overlapped for messaging
memset(&overlapped, 0, sizeof(OVERLAPPED));
handle[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
- if(!handle[0]) {
+ if(handle[0] == NULL) {
r = -1; goto out;
}
overlapped.hEvent = handle[0];
@@ -404,8 +437,9 @@ int run_installer(char* path)
// if INF_NAME ever has a space, it will be seen as multiple parameters
shExecInfo.lpParameters = INF_NAME;
shExecInfo.lpDirectory = path;
+ // TODO: hide
+// shExecInfo.nShow = SW_NORMAL;
shExecInfo.nShow = SW_HIDE;
- // SW_NORMAL;
shExecInfo.hInstApp = NULL;
ShellExecuteEx(&shExecInfo);
@@ -417,54 +451,53 @@ int run_installer(char* path)
handle[1] = shExecInfo.hProcess;
while (1) {
- if (!ReadFile(pipe, buffer, 256, &rd_count, &overlapped)) {
+ if (ReadFile(pipe, buffer, 256, &rd_count, &overlapped)) {
+ // Message was read synchronously
+ process_message(buffer, rd_count);
+ } else {
switch(GetLastError()) {
case ERROR_BROKEN_PIPE:
// The pipe has been ended - wait for installer to finish
WaitForSingleObject(handle[1], INFINITE);
- usbi_dbg("hProcess1 = %p terminated", shExecInfo.hProcess);
r = 0; goto out;
case ERROR_PIPE_LISTENING:
// Wait for installer to open the pipe
Sleep(100);
continue;
case ERROR_IO_PENDING:
- break;
- default:
- usbi_err(NULL, "pipe read message failed: %d", (int)GetLastError());
- continue;
- }
-
- // We have IO_PENDING
- switch(WaitForMultipleObjects(2, handle, FALSE, INFINITE)) {
- case WAIT_OBJECT_0: // Pipe event
- if (!GetOverlappedResult(pipe, &overlapped, &rd_count, FALSE)) {
- switch(GetLastError()) {
- case ERROR_BROKEN_PIPE:
- // The pipe has been ended - wait for installer to finish
- WaitForSingleObject(handle[1], INFINITE);
- usbi_dbg("hProcess3 = %p terminated", shExecInfo.hProcess);
- r = 0; goto out;
- case ERROR_MORE_DATA:
- usbi_warn(NULL, "message overflow");
- break;
- default:
- usbi_warn(NULL, "message async read error: %d", (int)GetLastError());
- break;
+ switch(WaitForMultipleObjects(2, handle, FALSE, INFINITE)) {
+ case WAIT_OBJECT_0: // Pipe event
+ if (GetOverlappedResult(pipe, &overlapped, &rd_count, FALSE)) {
+ // Message was read asynchronously
+ process_message(buffer, rd_count);
+ } else {
+ switch(GetLastError()) {
+ case ERROR_BROKEN_PIPE:
+ // The pipe has been ended - wait for installer to finish
+ WaitForSingleObject(handle[1], INFINITE);
+ r = 0; goto out;
+ case ERROR_MORE_DATA:
+ usbi_warn(NULL, "program assertion failed: message overflow");
+ process_message(buffer, rd_count);
+ break;
+ default:
+ usbi_err(NULL, "could not read from pipe (async): %d", (int)GetLastError());
+ break;
+ }
}
- } else {
- usbi_dbg("async: %s", buffer);
+ break;
+ case WAIT_OBJECT_0+1:
+ // installer process terminated
+ r = 0; goto out;
+ default:
+ usbi_err(NULL, "could not read from pipe (wait): %d", (int)GetLastError());
+ break;
}
break;
- case WAIT_OBJECT_0+1:
- usbi_dbg("hProcess2 = %p terminated", shExecInfo.hProcess);
- r = 0; goto out;
default:
- usbi_dbg("are?");
+ usbi_err(NULL, "could not read from pipe (sync): %d", (int)GetLastError());
break;
}
- } else {
- usbi_dbg(" sync: %s", buffer);
}
}
out:
@@ -474,27 +507,4 @@ out:
return r;
}
-// TODO: use devinst from setupdi and pass it as param to driver-installer.exe
-int update_drivers(void)
-{
- DEVINST devInst;
- CONFIGRET status;
-
- usbi_dbg("updating drivers, please wait...");
- // Get the root devnode.
- status = CM_Locate_DevNode(&devInst, NULL, 0);
- if (status != CR_SUCCESS) {
- printf("failed to locate root devnode: %x\n", status);
- return -1;
- }
-
- // Needs admin privileges, but even with admin and the
- // http://support.microsoft.com/kb/259697 doesn't work!!!
- status = CM_Reenumerate_DevNode(devInst, 0);
- if (status != CR_SUCCESS) {
- printf("failed to re-enumerate nodes: %x\n", status);
- return -1;
- }
-
- return 0;
-} \ No newline at end of file
+//TODO: add a call to free strings & list \ No newline at end of file