1
/* LIBUSB-WIN32, Generic Windows USB Library
2
* Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#include <ddk/cfgmgr32.h>
30
#define strlwr(p) _strlwr(p)
36
#define CLASS_KEY_PATH_NT "SYSTEM\\CurrentControlSet\\Control\\Class\\"
37
#define CLASS_KEY_PATH_9X "SYSTEM\\CurrentControlSet\\Services\\Class\\"
39
#define USB_GET_DRIVER_NAME() \
40
usb_registry_is_nt() ? driver_name_nt : driver_name_9x;
42
typedef struct _usb_class_key usb_class_key_t;
44
struct _usb_class_key {
45
usb_class_key_t *next;
49
static const char *driver_name_nt = "libusb0";
50
static const char *driver_name_9x = "libusb0.sys";
52
static const char *default_class_keys_nt[] =
55
"{36fc9e60-c465-11cf-8056-444553540000}",
57
"{745a17a0-74d3-11d0-b6fe-00a0c90f57da}",
59
"{4d36e972-e325-11ce-bfc1-08002be10318}",
61
"{6bdd1fc6-810f-11d0-bec7-08002be2092f}",
63
"{4d36e96c-e325-11ce-bfc1-08002be10318}",
65
"{4d36e96d-e325-11ce-bfc1-08002be10318}",
66
/* SmartCardReader devices*/
67
"{50dd5230-ba8a-11d1-bf5d-0000f805f530}",
71
static const char *default_class_keys_9x[] =
88
static bool_t usb_registry_set_device_state(DWORD state, HDEVINFO dev_info,
89
SP_DEVINFO_DATA *dev_info_data);
90
static usb_class_key_t *usb_registry_get_usb_class_keys(void);
91
static usb_class_key_t *usb_registry_get_all_class_keys(void);
92
static bool_t usb_registry_add_class_key(usb_class_key_t **head,
94
static bool_t usb_registry_free_class_keys(usb_class_key_t **head);
97
bool_t usb_registry_is_nt(void)
99
return GetVersion() < 0x80000000 ? TRUE : FALSE;
102
bool_t usb_registry_get_property(DWORD which, HDEVINFO dev_info,
103
SP_DEVINFO_DATA *dev_info_data,
110
char *val_name = NULL;
113
memset(buf, 0, size);
117
case SPDRP_LOWERFILTERS:
118
val_name = "LowerFilters";
119
key_type = DIREG_DEV;
121
case SPDRP_UPPERFILTERS:
122
val_name = "UpperFilters";
123
key_type = DIREG_DEV;
126
val_name = "NTMPDriver";
127
key_type = DIREG_DRV;
129
case SPDRP_CLASSGUID:
130
val_name = "ClassGUID";
131
key_type = DIREG_DEV;
134
key_type = DIREG_DEV;
136
case SPDRP_HARDWAREID:
137
val_name = "HardwareID";
138
key_type = DIREG_DEV;
140
case SPDRP_DEVICEDESC:
141
val_name = "DeviceDesc";
142
key_type = DIREG_DEV;
146
key_type = DIREG_DEV;
153
if(usb_registry_is_nt())
155
if(!SetupDiGetDeviceRegistryProperty(dev_info, dev_info_data, which,
156
®_type, (BYTE *)buf,
169
reg_key = SetupDiOpenDevRegKey(dev_info, dev_info_data,
171
0, key_type, KEY_ALL_ACCESS);
173
if(reg_key == INVALID_HANDLE_VALUE)
175
usb_error("usb_registry_get_property(): reading "
176
"registry key failed");
180
if(RegQueryValueEx(reg_key, val_name, NULL, ®_type,
181
(BYTE *)buf, &length) != ERROR_SUCCESS
184
RegCloseKey(reg_key);
188
RegCloseKey(reg_key);
190
if(reg_type == REG_MULTI_SZ)
207
bool_t usb_registry_set_property(DWORD which, HDEVINFO dev_info,
208
SP_DEVINFO_DATA *dev_info_data,
211
char *val_name = NULL;
218
case SPDRP_LOWERFILTERS:
219
reg_type = usb_registry_is_nt() ? REG_MULTI_SZ : REG_SZ;
220
val_name = "LowerFilters";
222
case SPDRP_UPPERFILTERS:
223
reg_type = usb_registry_is_nt() ? REG_MULTI_SZ : REG_SZ;
224
val_name = "UpperFilters";
230
if(usb_registry_is_nt())
234
if(!SetupDiSetDeviceRegistryProperty(dev_info, dev_info_data,
235
which, (BYTE *)buf, size))
237
usb_error("usb_registry_set_property(): setting "
238
"property '%s' failed", val_name);
244
if(!SetupDiSetDeviceRegistryProperty(dev_info, dev_info_data,
247
usb_error("usb_registry_set_property(): deleting "
248
"property '%s' failed", val_name);
263
p += (strlen(p) + 1);
266
reg_key = SetupDiOpenDevRegKey(dev_info, dev_info_data,
268
0, DIREG_DEV, KEY_ALL_ACCESS);
270
if(reg_key == INVALID_HANDLE_VALUE)
272
usb_error("usb_registry_set_property(): reading "
273
"registry key failed");
279
if(RegSetValueEx(reg_key, val_name, 0, reg_type, (BYTE *)buf,
280
size) != ERROR_SUCCESS)
282
usb_error("usb_registry_set_property(): setting "
283
"property '%s' failed", val_name);
284
RegCloseKey(reg_key);
290
if(RegDeleteValue(reg_key, val_name) != ERROR_SUCCESS)
292
usb_error("usb_registry_set_property(): deleting "
293
"property '%s' failed", val_name);
294
RegCloseKey(reg_key);
298
RegCloseKey(reg_key);
304
bool_t usb_registry_insert_class_filter(void)
306
const char *driver_name;
307
usb_class_key_t *keys;
308
usb_class_key_t *key;
311
driver_name = USB_GET_DRIVER_NAME();
313
keys = usb_registry_get_usb_class_keys();
317
usb_error("usb_registry_insert_filter: unable to retrieve class keys\n");
325
if(usb_registry_get_mz_value(key->name, "UpperFilters",
328
usb_registry_mz_string_lower(buf);
330
if(usb_registry_mz_string_find(buf, driver_name))
337
usb_registry_mz_string_insert(buf, driver_name);
339
if(!usb_registry_set_mz_value(key->name, "UpperFilters", buf,
340
usb_registry_mz_string_size(buf)))
342
usb_error("usb_registry_insert_filter: unable to "
343
"set registry value\n");
349
usb_registry_free_class_keys(&keys);
355
bool_t usb_registry_remove_class_filter(void)
357
const char *driver_name;
358
usb_class_key_t *keys;
359
usb_class_key_t *key;
362
driver_name = USB_GET_DRIVER_NAME();
364
keys = usb_registry_get_all_class_keys();
368
usb_error("usb_registry_remove_filter: unable to retrieve class keys\n");
376
if(usb_registry_get_mz_value(key->name, "UpperFilters",
379
usb_registry_mz_string_lower(buf);
381
if(usb_registry_mz_string_find(buf, driver_name))
383
usb_registry_mz_string_remove(buf, driver_name);
385
usb_registry_set_mz_value(key->name, "UpperFilters", buf,
386
usb_registry_mz_string_size(buf));
393
usb_registry_free_class_keys(&keys);
398
bool_t usb_registry_remove_device_filter(void)
401
SP_DEVINFO_DATA dev_info_data;
403
char filters[MAX_PATH];
404
const char *driver_name;
406
driver_name = USB_GET_DRIVER_NAME();
408
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
411
dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES);
413
if(dev_info == INVALID_HANDLE_VALUE)
415
usb_error("usb_registry_remove_device_filter(): getting "
416
"device info set failed");
420
while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
422
/* remove libusb as a device upper filter */
423
if(usb_registry_get_property(SPDRP_UPPERFILTERS, dev_info,
425
filters, sizeof(filters)))
427
usb_registry_mz_string_lower(filters);
429
if(usb_registry_mz_string_find(filters, driver_name))
432
usb_registry_mz_string_remove(filters, driver_name);
433
size = usb_registry_mz_string_size(filters);
435
usb_registry_set_property(SPDRP_UPPERFILTERS, dev_info,
436
&dev_info_data, filters, size);
440
/* remove libusb as a device lower filter */
441
if(usb_registry_get_property(SPDRP_LOWERFILTERS, dev_info,
443
filters, sizeof(filters)))
445
usb_registry_mz_string_lower(filters);
447
if(usb_registry_mz_string_find(filters, driver_name))
450
usb_registry_mz_string_remove(filters, driver_name);
451
size = usb_registry_mz_string_size(filters);
453
usb_registry_set_property(SPDRP_LOWERFILTERS, dev_info,
454
&dev_info_data, filters, size);
461
SetupDiDestroyDeviceInfoList(dev_info);
466
static bool_t usb_registry_set_device_state(DWORD state, HDEVINFO dev_info,
467
SP_DEVINFO_DATA *dev_info_data)
469
SP_PROPCHANGE_PARAMS prop_params;
471
memset(&prop_params, 0, sizeof(SP_PROPCHANGE_PARAMS));
473
prop_params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
474
prop_params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
475
prop_params.StateChange = state;
476
prop_params.Scope = DICS_FLAG_CONFIGSPECIFIC;//DICS_FLAG_GLOBAL;
477
prop_params.HwProfile = 0;
480
if(!SetupDiSetClassInstallParams(dev_info, dev_info_data,
481
(SP_CLASSINSTALL_HEADER *)&prop_params,
482
sizeof(SP_PROPCHANGE_PARAMS)))
484
usb_error("usb_registry_set_device_state(): setting class "
485
"install parameters failed");
490
if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, dev_info, dev_info_data))
492
usb_error("usb_registry_set_device_state(): calling class "
500
bool_t usb_registry_restart_device(HDEVINFO dev_info,
501
SP_DEVINFO_DATA *dev_info_data)
503
return usb_registry_set_device_state(DICS_PROPCHANGE, dev_info,
507
bool_t usb_registry_stop_device(HDEVINFO dev_info,
508
SP_DEVINFO_DATA *dev_info_data)
510
return usb_registry_set_device_state(DICS_DISABLE, dev_info,
514
bool_t usb_registry_start_device(HDEVINFO dev_info,
515
SP_DEVINFO_DATA *dev_info_data)
517
return usb_registry_set_device_state(DICS_ENABLE, dev_info,
521
bool_t usb_registry_is_service_libusb(HDEVINFO dev_info,
522
SP_DEVINFO_DATA *dev_info_data)
524
char service_name[MAX_PATH];
526
if(!usb_registry_get_property(SPDRP_SERVICE, dev_info, dev_info_data,
527
service_name, sizeof(service_name)))
532
usb_registry_mz_string_lower(service_name);
534
if(usb_registry_mz_string_find_sub(service_name, "libusb"))
542
void usb_registry_stop_libusb_devices(void)
545
SP_DEVINFO_DATA dev_info_data;
548
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
551
dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
552
DIGCF_ALLCLASSES | DIGCF_PRESENT);
554
if(dev_info == INVALID_HANDLE_VALUE)
556
usb_error("usb_registry_stop_libusb_devices(): getting "
557
"device info set failed");
561
while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
563
if(usb_registry_is_service_libusb(dev_info, &dev_info_data))
565
usb_registry_stop_device(dev_info, &dev_info_data);
570
SetupDiDestroyDeviceInfoList(dev_info);
573
void usb_registry_start_libusb_devices(void)
576
SP_DEVINFO_DATA dev_info_data;
579
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
582
dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
583
DIGCF_ALLCLASSES | DIGCF_PRESENT);
585
if(dev_info == INVALID_HANDLE_VALUE)
587
usb_error("usb_registry_stop_libusb_devices(): getting "
588
"device info set failed");
592
while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
594
if(usb_registry_is_service_libusb(dev_info, &dev_info_data))
596
usb_registry_start_device(dev_info, &dev_info_data);
601
SetupDiDestroyDeviceInfoList(dev_info);
605
bool_t usb_registry_match(HDEVINFO dev_info,
606
SP_DEVINFO_DATA *dev_info_data)
610
if(!usb_registry_get_property(SPDRP_HARDWAREID, dev_info, dev_info_data,
613
usb_error("usb_registry_match_no_hubs(): getting hardware id "
618
usb_registry_mz_string_lower(tmp);
620
/* search for USB devices, skip root hubs and interfaces of composite */
622
if(usb_registry_mz_string_find_sub(tmp, "&mi_")
623
|| usb_registry_mz_string_find_sub(tmp, "root_hub"))
631
bool_t usb_registry_get_mz_value(const char *key, const char *value,
636
DWORD reg_length = size;
640
memset(buf, 0, size);
642
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_ALL_ACCESS, ®_key)
645
if(RegQueryValueEx(reg_key, value, NULL, ®_type,
646
buf, ®_length) == ERROR_SUCCESS)
648
if(reg_type == REG_SZ)
667
RegCloseKey(reg_key);
674
bool_t usb_registry_set_mz_value(const char *key, const char *value,
681
/* convert REG_MULTI_SZ to REG_SZ */
682
if(!usb_registry_is_nt())
686
while(*p && *(p + 1))
696
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_ALL_ACCESS, ®_key)
701
if(usb_registry_is_nt())
703
if(RegSetValueEx(reg_key, value, 0, REG_MULTI_SZ, buf, size)
711
if(RegSetValueEx(reg_key, value, 0, REG_SZ, buf, size)
720
if(RegDeleteValue(reg_key, value) == ERROR_SUCCESS)
729
RegCloseKey(reg_key);
735
int usb_registry_mz_string_size(const char *src)
737
char *p = (char *)src;
746
p += (strlen(p) + 1);
749
return (int)(p - src) + 1;
752
char *usb_registry_mz_string_find_sub(const char *src, const char *str)
760
src += (strlen(src) + 1);
766
char *usb_registry_mz_string_find(const char *src, const char *str)
770
if(!strcmp(src, str))
774
src += strlen(src) + 1;
780
bool_t usb_registry_mz_string_insert(char *src, const char *str)
784
src += (strlen(src) + 1);
787
memcpy(src, str, strlen(str));
797
bool_t usb_registry_mz_string_remove(char *src, const char *str)
804
src = usb_registry_mz_string_find(src, str);
821
size += strlen(p) + 1;
824
memmove(src, src + strlen(src) + 1, size);
831
void usb_registry_mz_string_lower(char *src)
836
src += (strlen(src) + 1);
840
bool_t usb_registry_restart_all_devices(void)
843
SP_DEVINFO_DATA dev_info_data;
848
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
850
dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
851
DIGCF_ALLCLASSES | DIGCF_PRESENT);
853
if(dev_info == INVALID_HANDLE_VALUE)
855
usb_error("usb_registry_restart_all_devices(): getting "
856
"device info set failed");
860
while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
862
if(!usb_registry_get_property(SPDRP_HARDWAREID, dev_info,
863
&dev_info_data, id, sizeof(id)))
865
usb_error("usb_registry_restart_all_devices(): getting hardware "
871
usb_registry_mz_string_lower(id);
873
/* restart root hubs */
874
if(usb_registry_mz_string_find_sub(id, "root_hub"))
876
usb_registry_restart_device(dev_info, &dev_info_data);
882
SetupDiDestroyDeviceInfoList(dev_info);
888
usb_class_key_t *usb_registry_get_usb_class_keys(void)
891
SP_DEVINFO_DATA dev_info_data;
894
char class[MAX_PATH];
896
usb_class_key_t *keys = NULL;
897
DWORD class_property;
898
const char *class_path;
899
const char **default_class_keys;
901
if(usb_registry_is_nt())
903
class_property = SPDRP_CLASSGUID;
904
class_path = CLASS_KEY_PATH_NT;
905
default_class_keys = default_class_keys_nt;
909
class_property = SPDRP_CLASS;
910
class_path = CLASS_KEY_PATH_9X;
911
default_class_keys = default_class_keys_9x;
916
while(default_class_keys[i])
918
if((strlen(class_path) + strlen(default_class_keys[i])) < sizeof(tmp))
920
sprintf(tmp, "%s%s", class_path, default_class_keys[i]);
921
usb_registry_add_class_key(&keys, tmp);
927
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
928
dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
931
if(dev_info == INVALID_HANDLE_VALUE)
933
usb_error("usb_registry_get_class_keys(): getting "
934
"device info set failed");
938
while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
940
if(!usb_registry_is_service_libusb(dev_info, &dev_info_data))
942
if(!usb_registry_get_property(SPDRP_CLASSGUID, dev_info,
944
class, sizeof(class)))
946
usb_error("usb_registry_get_class_keys(): getting "
947
"hardware id failed");
954
if((strlen(class_path) + strlen(class)) < sizeof(tmp))
956
sprintf(tmp, "%s%s", class_path, class);
957
usb_registry_add_class_key(&keys, tmp);
964
SetupDiDestroyDeviceInfoList(dev_info);
969
static usb_class_key_t *usb_registry_get_all_class_keys(void)
971
const char *class_path;
972
usb_class_key_t *keys = NULL;
974
char class[MAX_PATH];
977
if(usb_registry_is_nt())
979
class_path = CLASS_KEY_PATH_NT;
983
class_path = CLASS_KEY_PATH_9X;
986
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, class_path, 0, KEY_ALL_ACCESS,
987
®_key) == ERROR_SUCCESS)
990
DWORD size = sizeof(class);
993
memset(class, 0, sizeof(class));
995
while(RegEnumKeyEx(reg_key, i, class, &size, 0, NULL, NULL, &junk)
1000
if((strlen(class_path) + strlen(class)) < sizeof(tmp))
1002
sprintf(tmp, "%s%s", class_path, class);
1003
usb_registry_add_class_key(&keys, tmp);
1006
memset(class, 0, sizeof(class));
1007
size = sizeof(class);
1011
RegCloseKey(reg_key);
1017
static bool_t usb_registry_add_class_key(usb_class_key_t **head,
1020
usb_class_key_t *p = *head;
1025
if(strlen(key) >= MAX_PATH)
1030
if(!strcmp(p->name, key))
1037
p = malloc(sizeof(usb_class_key_t));
1042
memset(p, 0, sizeof(usb_class_key_t));
1043
strcpy(p->name, key);
1054
static bool_t usb_registry_free_class_keys(usb_class_key_t **head)
1056
usb_class_key_t *p = *head;