Try opening with sharing mode enabled on Windows if normal open fails.

Multiple users have reported the need to pass
SHARE_MODE_READ|SHARE_MODE_WRITE to CreateFileA(). It seems that some
devices will not open at all if sharing is not requested. This commit
makes it so that CreateFileA() will be tried twice, the first time with
sharing mode OFF (passing 0x0 to the ShareMode parameter of CreateFileA()),
and if that fails, it will try to open the device with share mode ON
(passing the above SHARE_MODE_ flags to the ShareMode parameter of
CreateFileA()). This will have the following effects:

For normal devices:
   Devices will open as normal. Only one instance can be opened at a time.
For devices which require share mode to be on:
   Devices will now open (they would not open at all before). Multiple
   instances can be opened. This is less than desirable, but the
   alternative is that these devices don't open at all.
This commit is contained in:
Alan Ott 2011-08-31 12:39:02 -04:00
parent 36c309f521
commit c7f35c3a46

View File

@ -191,6 +191,37 @@ static void lookup_functions()
}
#endif
static HANDLE open_device(const char *path)
{
HANDLE handle;
/* First, try to open with sharing mode turned off. This will make it so
that a HID device can only be opened once. This is to be consistent
with the behavior on the other platforms. */
handle = CreateFileA(path,
GENERIC_WRITE |GENERIC_READ,
0, /*share mode*/
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
0);
if (handle == INVALID_HANDLE_VALUE) {
/* Couldn't open the device. Some devices must be opened
with sharing enabled (even though they are only opened once),
so try it here. */
handle = CreateFileA(path,
GENERIC_WRITE |GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, /*share mode*/
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
0);
}
return handle;
}
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
BOOL res;
@ -268,13 +299,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
// Open a handle to the device
write_handle = CreateFileA(device_interface_detail_data->DevicePath,
GENERIC_WRITE |GENERIC_READ,
0x0, /*share mode*/
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
0);
write_handle = open_device(device_interface_detail_data->DevicePath);
// Check validity of write_handle.
if (write_handle == INVALID_HANDLE_VALUE) {
@ -472,13 +497,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
dev = new_hid_device();
// Open a handle to the device
dev->device_handle = CreateFileA(path,
GENERIC_WRITE |GENERIC_READ,
0x0, /*share mode*/
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
0);
dev->device_handle = open_device(path);
// Check validity of write_handle.
if (dev->device_handle == INVALID_HANDLE_VALUE) {