Overlapped I/O operation is in progress. #433

Closed
opened 2022-06-23 11:11:42 -05:00 by mandar1jn · 23 comments
mandar1jn commented 2022-06-23 11:11:42 -05:00 (Migrated from github.com)

I'm trying to write to a HID device, but I keep getting the same error. The error in question being hid_write/WaitForSingleObject: (0x000003E5) Overlappende I/O-bewerking wordt uitgevoerd.. Note that this is Dutch. The translation would be hid_write/WaitForSingleObject: (0x000003E5) Overlapping I/O-changes are being made. I'm not exactly sure if "changes" is the correct translation.

The device in question is a Skylanders portal. Other applications seem to work fine, but when I try to write to it doesn't work.
My code to write to the portal is:

unsigned char buffer[0x21];
	memset(buffer, 0, 0x21);

	buffer[1] = 'C';

	buffer[4] = 0xFF;

	for (int i = 0; i < 10; i++)
	{
		if (hid_write(portal->handle, buffer, 0x21) == -1)
		{
			printf("Failed to write. Attempt: %d\n", i);
			wprintf(hid_error(portal->handle));
			printf("\n");
		}
		else
		{
			break;
		}
	}
The device discovery code is:
	struct hid_device_info* list, * attributes;

    wchar_t wstr[255];

    handle = NULL;

    list = hid_enumerate(0x0, 0x0);

    if (!list) {
        printf("unable to open USB devices\n");
        exit(1);

    }
    attributes = list;
    while (attributes) {
        if (((attributes->vendor_id == 0x12ba) || (attributes->vendor_id == 0x54c)) ||
            (attributes->vendor_id == 0x1430)) {
            if ((attributes->product_id == 0x150) || (attributes->product_id == 0x967)) {
                printf("Found portal usb device\n");
                int err;

                handle = hid_open(attributes->vendor_id, attributes->product_id, NULL);
                if (handle == NULL) {
                    printf("Error communicating with Portal.\n ");
                }

                /*
                wstr[0] = 0x0000;
                err = hid_get_manufacturer_string(hPortalHandle, wstr, MAX_STR);
                if (err < 0)
                    printf("Unable to read manufacturer string\n");
                printf("Manufacturer String: %ls\n", wstr);
                // Read the Product String
                wstr[0] = 0x0000;
                err = hid_get_product_string(hPortalHandle, wstr, MAX_STR);
                if (err < 0)
                    printf("Unable to read product string\n");
                printf("Product String: %ls\n", wstr);
                // Read the Serial Number String
                wstr[0] = 0x0000;
                err = hid_get_serial_number_string(hPortalHandle, wstr, MAX_STR);
                if (err < 0)
                    printf("Unable to read serial number string\n");
                printf("Serial Number String: (%d) %ls", wstr[0], wstr);
                printf("\n");
                */

                break;
            }
        }
        attributes = attributes->next;
    }
    hid_free_enumeration(list);

    if (!handle) {
        printf("Cannot Find Portal USB.\n");
        exit(1);
    }

I copied this from another project, but it seems to find the portal just fine and I am able to read incoming data using hid_read.

I'm trying to write to a HID device, but I keep getting the same error. The error in question being ``hid_write/WaitForSingleObject: (0x000003E5) Overlappende I/O-bewerking wordt uitgevoerd.``. Note that this is Dutch. The translation would be ``hid_write/WaitForSingleObject: (0x000003E5) Overlapping I/O-changes are being made.`` I'm not exactly sure if "changes" is the correct translation. The device in question is a Skylanders portal. Other applications seem to work fine, but when I try to write to it doesn't work. My code to write to the portal is: ```cpp unsigned char buffer[0x21]; memset(buffer, 0, 0x21); buffer[1] = 'C'; buffer[4] = 0xFF; for (int i = 0; i < 10; i++) { if (hid_write(portal->handle, buffer, 0x21) == -1) { printf("Failed to write. Attempt: %d\n", i); wprintf(hid_error(portal->handle)); printf("\n"); } else { break; } } ``` The device discovery code is: ```cpp struct hid_device_info* list, * attributes; wchar_t wstr[255]; handle = NULL; list = hid_enumerate(0x0, 0x0); if (!list) { printf("unable to open USB devices\n"); exit(1); } attributes = list; while (attributes) { if (((attributes->vendor_id == 0x12ba) || (attributes->vendor_id == 0x54c)) || (attributes->vendor_id == 0x1430)) { if ((attributes->product_id == 0x150) || (attributes->product_id == 0x967)) { printf("Found portal usb device\n"); int err; handle = hid_open(attributes->vendor_id, attributes->product_id, NULL); if (handle == NULL) { printf("Error communicating with Portal.\n "); } /* wstr[0] = 0x0000; err = hid_get_manufacturer_string(hPortalHandle, wstr, MAX_STR); if (err < 0) printf("Unable to read manufacturer string\n"); printf("Manufacturer String: %ls\n", wstr); // Read the Product String wstr[0] = 0x0000; err = hid_get_product_string(hPortalHandle, wstr, MAX_STR); if (err < 0) printf("Unable to read product string\n"); printf("Product String: %ls\n", wstr); // Read the Serial Number String wstr[0] = 0x0000; err = hid_get_serial_number_string(hPortalHandle, wstr, MAX_STR); if (err < 0) printf("Unable to read serial number string\n"); printf("Serial Number String: (%d) %ls", wstr[0], wstr); printf("\n"); */ break; } } attributes = attributes->next; } hid_free_enumeration(list); if (!handle) { printf("Cannot Find Portal USB.\n"); exit(1); } ``` I copied this from another project, but it seems to find the portal just fine and I am able to read incoming data using hid_read.
mandar1jn commented 2022-06-23 11:15:51 -05:00 (Migrated from github.com)

Okay. So the correct error translation is: Overlapped I/O operation is in progress.

Okay. So the correct error translation is: ``Overlapped I/O operation is in progress.``
Youw commented 2022-06-23 12:25:41 -05:00 (Migrated from github.com)

Can you confirm you're opening the device with correct usage_page/usage?

Can you confirm you're opening the device with correct usage_page/usage?
mandar1jn commented 2022-06-23 12:28:56 -05:00 (Migrated from github.com)

hid_open does not have a usage page variable

hid_open does not have a usage page variable
Youw commented 2022-06-23 12:31:03 -05:00 (Migrated from github.com)

Use what you call attributes to filter for the correct usage_page/usage, and then hid_open_path(attributes->path).

Use what you call `attributes` to filter for the correct usage_page/usage, and then `hid_open_path(attributes->path)`.
Youw commented 2022-06-23 12:32:48 -05:00 (Migrated from github.com)

Can you confirm that your device doesn't use numbered reports, and the only report you have is 20 bytes long?

Can you confirm that your device doesn't use numbered reports, and the only report you have is 20 bytes long?
mandar1jn commented 2022-06-23 12:35:03 -05:00 (Migrated from github.com)

Can you confirm that your device doesn't use numbered reports, and the only report you have is 20 bytes long?

I'm pretty sure it does not use numbered reports, from what I can gather from https://github.com/tresni/PoweredPortals/wiki/USB-Protocols and https://pastebin.com/EqtTRzeF

> Can you confirm that your device doesn't use numbered reports, and the only report you have is 20 bytes long? I'm pretty sure it does not use numbered reports, from what I can gather from https://github.com/tresni/PoweredPortals/wiki/USB-Protocols and https://pastebin.com/EqtTRzeF
mandar1jn commented 2022-06-23 12:37:04 -05:00 (Migrated from github.com)

usage page gives 65280, usage is 1 and weirdly, interface is -1

usage page gives 65280, usage is 1 and weirdly, interface is -1
mandar1jn commented 2022-06-23 12:42:26 -05:00 (Migrated from github.com)

also, I updated my portal finder to just

struct hid_device_info* devices;

    handle = NULL;

    devices = hid_enumerate(0x1430, 0x0150);

    if (!devices) {
        printf("unable to open USB devices\n");
        exit(1);

    }
    
    handle = hid_open_path(devices->path);

    hid_free_enumeration(devices);

    if (!handle) {
        printf("Cannot Find Portal USB.\n");
        exit(1);
    }
also, I updated my portal finder to just ```cpp struct hid_device_info* devices; handle = NULL; devices = hid_enumerate(0x1430, 0x0150); if (!devices) { printf("unable to open USB devices\n"); exit(1); } handle = hid_open_path(devices->path); hid_free_enumeration(devices); if (!handle) { printf("Cannot Find Portal USB.\n"); exit(1); } ```
Youw commented 2022-06-23 13:28:10 -05:00 (Migrated from github.com)

also, I updated my portal finder to just

My point is that your device may have several usage_page/usages, and each unique pair is reported as a separate device.
And the report you're interesting is tight to a specific usage_page/usages.
It may happen, that you're using a "wrong" device to hid_write.

I'm pretty sure it does not use numbered reports

But what is the size of the report?
I can't predictably tell what happens if you pass more data to the hid_write than the report size.

> also, I updated my portal finder to just My point is that your device may have several usage_page/usages, and each unique pair is reported as a separate device. And the report you're interesting is tight to a specific usage_page/usages. It may happen, that you're using a "wrong" device to `hid_write`. > I'm pretty sure it does not use numbered reports But what is the size of the report? I can't predictably tell what happens if you pass more data to the `hid_write` than the report size.
mandar1jn commented 2022-06-23 14:14:27 -05:00 (Migrated from github.com)

Enumerate only results in a single device. And similar programs also use a 32 byte buffer

Enumerate only results in a single device. And similar programs also use a 32 byte buffer
Youw commented 2022-06-23 14:21:46 -05:00 (Migrated from github.com)

similar programs also use a 32 byte buffer

With the same device?

> similar programs also use a 32 byte buffer With the same device?
mandar1jn commented 2022-06-23 14:47:54 -05:00 (Migrated from github.com)

Yes. With the same device.

Yes. With the same device.
Youw commented 2022-06-23 14:55:13 -05:00 (Migrated from github.com)

So you have access to the working source code for this example?

So you have access to the working source code for this example?
mandar1jn commented 2022-06-23 14:59:04 -05:00 (Migrated from github.com)

“Working”. There are several projects, but they’re all years old. And either: 1. Don’t compile 2. Don’t support visual studio. For the ones I could get binaries off, they work just fine. I don’t know why my code doesn’t.

“Working”. There are several projects, but they’re all years old. And either: 1. Don’t compile 2. Don’t support visual studio. For the ones I could get binaries off, they work just fine. I don’t know why my code doesn’t.
mandar1jn commented 2022-06-23 15:00:38 -05:00 (Migrated from github.com)

One thing I did notice is that when using a usb monitor my code’s data uses bulk and interrupt where at least one other reports using interface. Weirdly enough, this code also uses hidapi and hid_write

One thing I did notice is that when using a usb monitor my code’s data uses bulk and interrupt where at least one other reports using interface. Weirdly enough, this code also uses hidapi and hid_write
mandar1jn commented 2022-06-23 15:01:03 -05:00 (Migrated from github.com)

I’ll try and get some screenshots of this tomorrow to show what I mean.

I’ll try and get some screenshots of this tomorrow to show what I mean.
mandar1jn commented 2022-06-23 15:04:43 -05:00 (Migrated from github.com)

Oh. Something I forgot to note: the device constantly sends status packets. This might be the origin of the original error. Should have told that earlier.

Oh. Something I forgot to note: the device constantly sends status packets. This might be the origin of the original error. Should have told that earlier.
Youw commented 2022-06-23 15:18:24 -05:00 (Migrated from github.com)

the device constantly sends status packets

That shouldn't matter.

> the device constantly sends status packets That shouldn't matter.
Youw commented 2022-06-23 15:21:36 -05:00 (Migrated from github.com)

Logically I don't see why this code shouldn't work (from HIDAPI perspective).
Do you happened to know what version of HIDAPI uses that "working" binary that you mentioned?
Is there a chance it does more than that hid_write (e.g. set some feature report first).

Logically I don't see why this code shouldn't work (from HIDAPI perspective). Do you happened to know what version of HIDAPI uses that "working" binary that you mentioned? Is there a chance it does more than that `hid_write` (e.g. set some feature report first).
mandar1jn commented 2022-06-24 02:10:18 -05:00 (Migrated from github.com)

No. A version from at the latest 2017. https://github.com/capull0/SkyDumper This is the project some of my code is based off of. The hidapi files don’t seem to contain a version definition

No. A version from at the latest 2017. https://github.com/capull0/SkyDumper This is the project some of my code is based off of. The hidapi files don’t seem to contain a version definition
mandar1jn commented 2022-06-24 02:15:24 -05:00 (Migrated from github.com)

Okay. Looking at the source of the reference program I used, the hid files are either really old, or manually modified.

Okay. Looking at the source of the reference program I used, the hid files are either really old, or manually modified.
mandar1jn commented 2022-06-24 02:16:08 -05:00 (Migrated from github.com)

Yes. I think they modified the hid write function.

Yes. I think they modified the hid write function.
mandar1jn commented 2022-06-24 03:16:12 -05:00 (Migrated from github.com)

Okay. The other programs indeed use a modified version of hidapi. Thank you for attempting to help me. It's all resolved now.

Okay. The other programs indeed use a modified version of hidapi. Thank you for attempting to help me. It's all resolved now.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-libusb/hidapi#433
No description provided.