Windows: Ensure proper cleanup when backend init() functions fail

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This commit is contained in:
Chris Dickens
2016-01-27 11:46:01 -08:00
parent 4dfa6d6493
commit c8f7115146
3 changed files with 29 additions and 15 deletions
+20 -10
View File
@@ -114,16 +114,18 @@ static FARPROC get_usbdk_proc_addr(struct libusb_context *ctx, LPCSTR api_name)
{
FARPROC api_ptr = GetProcAddress(usbdk_helper.module, api_name);
if (api_ptr == NULL) {
if (api_ptr == NULL)
usbi_err(ctx, "UsbDkHelper API %s not found, error %d", api_name, GetLastError());
}
return api_ptr;
}
static void unload_usbdk_helper_dll(void)
{
FreeLibrary(usbdk_helper.module);
if (usbdk_helper.module != NULL) {
FreeLibrary(usbdk_helper.module);
usbdk_helper.module = NULL;
}
}
static int load_usbdk_helper_dll(struct libusb_context *ctx)
@@ -190,6 +192,7 @@ static int load_usbdk_helper_dll(struct libusb_context *ctx)
error_unload:
FreeLibrary(usbdk_helper.module);
usbdk_helper.module = NULL;
return LIBUSB_ERROR_NOT_FOUND;
}
@@ -197,23 +200,30 @@ static int usbdk_init(struct libusb_context *ctx)
{
int r;
if (++concurrent_usage == 0) {
if (++concurrent_usage == 0) { // First init?
r = load_usbdk_helper_dll(ctx);
if (r)
return r;
goto init_exit;
init_polling();
r = windows_common_init(ctx);
if (r)
goto error_roll_back;
goto init_exit;
}
// At this stage, either we went through full init successfully, or didn't need to
r = LIBUSB_SUCCESS;
init_exit:
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
exit_polling();
windows_common_exit();
unload_usbdk_helper_dll();
}
return LIBUSB_SUCCESS;
if (r != LIBUSB_SUCCESS)
--concurrent_usage; // Not expected to call libusb_exit if we failed.
error_roll_back:
windows_common_exit();
unload_usbdk_helper_dll();
return r;
}
+8 -4
View File
@@ -760,9 +760,9 @@ static int windows_init(struct libusb_context *ctx)
{
int i, r = LIBUSB_ERROR_OTHER;
HANDLE semaphore;
char sem_name[11 + 1 + 8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId());
sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
if (semaphore == NULL) {
usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
@@ -782,6 +782,7 @@ static int windows_init(struct libusb_context *ctx)
if (++concurrent_usage == 0) { // First init?
get_windows_version();
usbi_dbg(windows_version_str);
if (windows_version == WINDOWS_UNSUPPORTED) {
usbi_err(ctx, "This version of Windows is NOT supported");
r = LIBUSB_ERROR_NOT_SUPPORTED;
@@ -813,6 +814,9 @@ static int windows_init(struct libusb_context *ctx)
init_exit: // Holds semaphore here.
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
for (i = 0; i < USB_API_MAX; i++)
usb_api_backend[i].exit(SUBAPI_NOT_SET);
exit_polling();
windows_common_exit();
usbi_mutex_destroy(&autoclaim_lock);
}
@@ -1622,9 +1626,9 @@ static void windows_exit(void)
{
int i;
HANDLE semaphore;
char sem_name[11 + 1 + 8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId());
sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name);
if (semaphore == NULL)
return;
+1 -1
View File
@@ -1 +1 @@
#define LIBUSB_NANO 11040
#define LIBUSB_NANO 11041