[Spice-devel] [PATCH 6/6] usbclerk: add device filter support
Uri Lublin
uril at redhat.com
Tue Jul 24 02:08:22 PDT 2012
Hi Arnon,
Two comments below.
On 07/23/2012 12:23 PM, Arnon Gilboa wrote:
> read from HKLM\Software\USBClerk\filter_rules
> same format as in client
> ---
> usbclerk.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> usbclerk.vcproj | 40 +++++++++++++++++++++++++++++++
> 2 files changed, 109 insertions(+), 0 deletions(-)
>
>
> class USBClerk {
> public:
> @@ -40,6 +43,7 @@ private:
> bool remove_dev(HDEVINFO devs, PSP_DEVINFO_DATA dev_info);
> bool rescan();
> bool get_dev_info(HDEVINFO devs, int vid, int pid, SP_DEVINFO_DATA *dev_info);
> + bool dev_filter_check(int vid, int pid);
> static DWORD WINAPI control_handler(DWORD control, DWORD event_type,
> LPVOID event_data, LPVOID context);
> static VOID WINAPI main(DWORD argc, TCHAR * argv[]);
> @@ -48,6 +52,8 @@ private:
> static USBClerk* _singleton;
> SERVICE_STATUS _status;
> SERVICE_STATUS_HANDLE _status_handle;
> + struct usbredirfilter_rule *filter_rules;
> + int filter_count;
> char _wdi_path[MAX_PATH];
> HANDLE _pipe;
> bool _running;
> @@ -265,8 +271,11 @@ bool USBClerk::execute()
> SECURITY_DESCRIPTOR* sec_desr;
> USBClerkReply reply = {{USB_CLERK_MAGIC, USB_CLERK_VERSION,
> USB_CLERK_REPLY, sizeof(USBClerkReply)}};
> + CHAR filter_str[MAX_DEVICE_FILTER_LEN];
> CHAR buffer[USB_CLERK_PIPE_BUF_SIZE];
> DWORD bytes;
> + HKEY hkey;
> + LONG ret;
>
> #if 0
> /* Hack for wdi logging */
> @@ -288,6 +297,20 @@ bool USBClerk::execute()
> vd_printf("CreatePipe() failed: %u", GetLastError());
> return false;
> }
filter_rules should be initialized to NULL and filter_count to 0.
In case they are not initialized by usbredirfilter_string_to_rules (e.g. if
that registry entry does not exist).
> + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\USBClerk", 0, KEY_READ,&hkey);
> + if (ret == ERROR_SUCCESS) {
> + DWORD size = sizeof(filter_str);
> + ret = RegQueryValueExA(hkey, "filter_rules", NULL, NULL, (LPBYTE)filter_str,&size);
> + if (ret == ERROR_SUCCESS) {
> + ret = usbredirfilter_string_to_rules(filter_str, ",", "|",
> +&filter_rules,&filter_count);
> + if (ret != 0) {
> + vd_printf("Failed parsing filter rules: %s %d", filter_str, ret);
> + }
> + }
> + RegCloseKey(hkey);
> + }
> + vd_printf("filter_count: %d", filter_count);
> while (_running) {
> if (!ConnectNamedPipe(_pipe, NULL)&& GetLastError() != ERROR_PIPE_CONNECTED) {
> vd_printf("ConnectNamedPipe() failed: %u", GetLastError());
> @@ -308,6 +331,7 @@ bool USBClerk::execute()
> disconnect:
> DisconnectNamedPipe(_pipe);
> }
> + free(filter_rules);
> CloseHandle(_pipe);
> return true;
> }
> @@ -326,6 +350,10 @@ bool USBClerk::dispatch_message(CHAR *buffer, DWORD bytes, USBClerkReply *reply)
> return false;
> }
> dev = (USBClerkDriverOp *)buffer;
> + if (!dev_filter_check(dev->vid, dev->pid)) {
> + reply->status = FALSE;
> + return true;
> + }
> switch (hdr->type) {
> case USB_CLERK_DRIVER_INSTALL:
> vd_printf("Installing winusb driver for %04x:%04x", dev->vid, dev->pid);
> @@ -504,6 +532,47 @@ bool USBClerk::get_dev_info(HDEVINFO devs, int vid, int pid, SP_DEVINFO_DATA *de
> return false;
> }
>
> +bool USBClerk::dev_filter_check(int vid, int pid)
> +{
> + HDEVINFO devs;
> + SP_DEVINFO_DATA dev_info;
> + TCHAR compat_ids[MAX_DEVICE_HCID_LEN];
> + uint8_t dev_cls, dev_subcls, dev_proto;
> + bool ret = false;
> +
> + if (!filter_rules) {
> + return true;
> + }
> + devs = SetupDiGetClassDevs(NULL, L"USB", NULL, DIGCF_ALLCLASSES);
> + if (devs == INVALID_HANDLE_VALUE) {
> + vd_printf("SetupDiGetClassDevsEx failed: %u", GetLastError());
> + return false;
> + }
> + if (!get_dev_info(devs, vid, pid,&dev_info)) {
> + vd_printf("Cannot find device info %04x:%04x", vid, pid);
> + goto cleanup;
> + }
> + if (!SetupDiGetDeviceRegistryProperty(devs,&dev_info, SPDRP_COMPATIBLEIDS, NULL,
> + (PBYTE)compat_ids, sizeof(compat_ids), NULL)) {
> + vd_printf("Cannot get compatible id %04x:%04x", vid, pid);
> + goto cleanup;
> + }
> + if (swscanf_s(compat_ids, L"USB\\Class_%02hx&SubClass_%02hx&Prot_%02hx",
> +&dev_cls,&dev_subcls,&dev_proto) != 3) {
> + vd_printf("Cannot parse compatible id %S", compat_ids);
> + goto cleanup;
> + }
> + if (usbredirfilter_check(filter_rules, filter_count, dev_cls, dev_subcls, dev_proto,
> + NULL, NULL, NULL, 0, vid, pid, 0, 0) == 0) {
> + ret = true;
> + } else {
> + vd_printf("Device filter failed %04x:%04x", vid, pid);
> + }
> +cleanup:
> + SetupDiDestroyDeviceInfoList(devs);
> + return ret;
> +}
> +
> int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> {
> bool success = false;
> diff --git a/usbclerk.vcproj b/usbclerk.vcproj
This can be moved to the previous commit, if you like.
> index b692737..dc59ad5 100644
> --- a/usbclerk.vcproj
> +++ b/usbclerk.vcproj
> @@ -347,6 +347,10 @@
> >
> </File>
> <File
> + RelativePath=".\usbredirfilter.h"
> + >
> + </File>
> + <File
> RelativePath=".\vdlog.h"
> >
> </File>
> @@ -371,6 +375,42 @@
> >
> </File>
> <File
> + RelativePath=".\usbredirfilter.c"
> + >
> + <FileConfiguration
> + Name="Debug|Win32"
> + >
> + <Tool
> + Name="VCCLCompilerTool"
> + CompileAs="2"
> + />
> + </FileConfiguration>
> + <FileConfiguration
> + Name="Debug|x64"
> + >
> + <Tool
> + Name="VCCLCompilerTool"
> + CompileAs="2"
> + />
> + </FileConfiguration>
> + <FileConfiguration
> + Name="Release|Win32"
> + >
> + <Tool
> + Name="VCCLCompilerTool"
> + CompileAs="2"
> + />
> + </FileConfiguration>
> + <FileConfiguration
> + Name="Release|x64"
> + >
> + <Tool
> + Name="VCCLCompilerTool"
> + CompileAs="2"
> + />
> + </FileConfiguration>
> + </File>
> + <File
> RelativePath=".\vdlog.cpp"
> >
> </File>
More information about the Spice-devel
mailing list