Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: Retry open_device if it fails with ERROR_ACCESS_DENIED #44

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

pqu
Copy link
Contributor

@pqu pqu commented Mar 8, 2012

Windows opens system mice/keyboards for exclusive access. They can still be sent feature reports, but neither read nor write access can be requested when the handle is opened.

@pqu
Copy link
Contributor Author

pqu commented Mar 14, 2012

Done. I swapped the semantics of the parameter so there wasn't a strange double-negative like no_readwrite == FALSE.

@signal11
Copy link
Owner

Can you combine these patches so they are one patch?

Use git rebase -i and git push (you'll need to do --force, but it's ok since I haven't pulled from you yet, unless someone else is tracking this branch, in which case put it on a separate branch for me).

Thanks!

Alan.

  (Ref. "Why do I receive 'Access denied' when attempting to access my HID?"
           http://www.lvr.com/hidfaq.htm)

Swap semantics on open_device()'s second parameter to make sense with new usage.
@cactrot
Copy link

cactrot commented Oct 30, 2013

On my windows 8 64bit machine instead of ERROR_ACCESS_DENIED I get ERROR_SHARING_VIOLATION. I'm trying to open a Audio Class device that, like keyboards and mice, windows claims read and write access too.
It seems to open if I use this condition:
(dev->device_handle == INVALID_HANDLE_VALUE &&
( GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == ERROR_SHARING_VIOLATION ) )

I believe the firmware on the device already has a feature report for remote wakeup and stall endpoint but so far all my attempts to get or send a feature report result in "Incorrect function".

What I want to do is add a couple of feature reports to communicate with the device while still using it as a windows sound device.

@signal11
Copy link
Owner

Your audio software probably has the device open already.

I'm not sure what you mean by "if I use this condition." Can you explain further or post a patch snippet?

@cactrot
Copy link

cactrot commented Oct 31, 2013

I'm a little new to github, hopefully this is the preferred way to link in a patch.

https://gist.github.com/cactrot/7242364

I know windows has the device open for read and write as a system audio device. I have read several places that it is still possible to send feature reports if you don't request read/write access. I have DSP chip from TI ( C5535 ) and I want to use it as a USB sound card but I also want to be able to control the DSP from an application. I'm not sure of the "Incorrect function" means the report has been sent and the device is not responding or if windows is giving the error. I suppose that is mostly what I need to figure out at the moment.

xobs added a commit to xobs/hidapi that referenced this pull request Jun 5, 2017
Modern Windows implementations don't allow opening HID devices in
READ/WRITE mode if they are claimed by the system.  Examples of such
devices include keyboards and mice.

However, these devices can be opened without READ/WRITE permissions, in
order to allow sending and receiving feature reports.

If open_device() fails, retry without requesting READ/WRITE permissions.

This inverts the logic of the parameter to open_device().

It is a refactor of signal11#44 by @pqu.

Signed-off-by: Sean Cross <sean@xobs.io>
Qbicz pushed a commit to Qbicz/hidapi-old that referenced this pull request Jan 8, 2019
Modern Windows implementations don't allow opening HID devices in
READ/WRITE mode if they are claimed by the system.  Examples of such
devices include keyboards and mice.

However, these devices can be opened without READ/WRITE permissions, in
order to allow sending and receiving feature reports.

If open_device() fails, retry without requesting READ/WRITE permissions.

This inverts the logic of the parameter to open_device().

It is a refactor of signal11#44 by @pqu.

Signed-off-by: Sean Cross <sean@xobs.io>
Signed-off-by: Kubicz, Filip <filip.kubicz@nordicsemi.no>
@z3ntu
Copy link

z3ntu commented Mar 9, 2019

EDIT: You should rather use #335

Rebased patch (makes my application able to send/receive feature reports on Windows):

(also adjusted the link in the commit message to archive.org as the link is dead)

From 61e8072d6f81504b1834c085328f10c7b6a5aadd Mon Sep 17 00:00:00 2001
From: philip <p@partylemon.com>
Date: Thu, 8 Mar 2012 16:12:52 +1300
Subject: [PATCH] Windows: Retry open_device if it fails with
 ERROR_ACCESS_DENIED.

    (Ref. "Why do I receive 'Access denied' when attempting to access my HID?"
           http://web.archive.org/web/20130317064425/http://www.lvr.com/hidfaq.htm)

Swap semantics on open_device()'s second parameter to make sense with new usage.
---
 windows/hid.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/windows/hid.c b/windows/hid.c
index 86810d7..d7aa0d2 100755
--- a/windows/hid.c
+++ b/windows/hid.c
@@ -225,11 +225,13 @@ static int lookup_functions()
 }
 #endif
 
-static HANDLE open_device(const char *path, BOOL enumerate)
+static HANDLE open_device(const char *path, BOOL request_rw)
 {
 	HANDLE handle;
-	DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ);
-	DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
+	DWORD desired_access = (request_rw)?(GENERIC_WRITE|GENERIC_READ):0;
+	DWORD share_mode = (request_rw)?
+							FILE_SHARE_READ:
+							FILE_SHARE_READ|FILE_SHARE_WRITE;
 
 	handle = CreateFileA(path,
 		desired_access,
@@ -370,7 +372,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 = open_device(device_interface_detail_data->DevicePath, TRUE);
+		write_handle = open_device(device_interface_detail_data->DevicePath, FALSE);
 
 		/* Check validity of write_handle. */
 		if (write_handle == INVALID_HANDLE_VALUE) {
@@ -566,7 +568,15 @@ 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 = open_device(path, FALSE);
+	dev->device_handle = open_device(path, TRUE);
+
+	/* If the device is a system keyboard/mouse, Windows (2k+) takes exclusive
+	   read/write access. Feature reports can still be sent, but only if
+	   neither read nor write access is requested. */
+	if (dev->device_handle == INVALID_HANDLE_VALUE &&
+		GetLastError() == ERROR_ACCESS_DENIED) {
+		dev->device_handle = open_device(path, FALSE);
+	}
 
 	/* Check validity of write_handle. */
 	if (dev->device_handle == INVALID_HANDLE_VALUE) {
-- 
2.21.0

z3ntu pushed a commit to z3ntu/hidapi-old that referenced this pull request Apr 6, 2019
Modern Windows implementations don't allow opening HID devices in
READ/WRITE mode if they are claimed by the system.  Examples of such
devices include keyboards and mice.

However, these devices can be opened without READ/WRITE permissions, in
order to allow sending and receiving feature reports.

If open_device() fails, retry without requesting READ/WRITE permissions.

This inverts the logic of the parameter to open_device().

It is a refactor of signal11#44 by @pqu.

Signed-off-by: Sean Cross <sean@xobs.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants