~ubuntu-branches/ubuntu/trusty/argyll/trusty-proposed

« back to all changes in this revision

Viewing changes to libusbw/src/registry.c

  • Committer: Package Import Robot
  • Author(s): Artur Rona
  • Date: 2014-02-12 00:35:39 UTC
  • mfrom: (13.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20140212003539-24tautzlitsiz61w
Tags: 1.5.1-5ubuntu1
* Merge from Debian unstable. (LP: #1275572) Remaining changes:
  - debian/control:
    + Build-depend on libtiff-dev rather than libtiff4-dev.
  - debian/control, debian/patches/06_fix_udev_rule.patch:
    + Fix udev rules to actually work; ENV{ACL_MANAGE} has
      stopped working ages ago, and with logind it's now the
      "uaccess" tag. Dropping also consolekit from Recommends.
  - debian/patches/drop-usb-db.patch:
    + Use hwdb builtin, instead of the obsolete usb-db
      in the udev rules.
* debian/patches/05_ftbfs-underlinkage.diff:
  - Dropped change, no needed anymore.
* Refresh the patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* LIBUSB-WIN32, Generic Windows USB Library
2
 
 * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
3
 
 *
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.
8
 
 *
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.
13
 
 *
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
17
 
 */
18
 
 
19
 
 
20
 
#include <windows.h>
21
 
#include <ctype.h>
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#include <string.h>
25
 
 
26
 
#ifdef __GNUC__
27
 
#include <ddk/cfgmgr32.h>
28
 
#else
29
 
#include <cfgmgr32.h>
30
 
#define strlwr(p) _strlwr(p)
31
 
#endif
32
 
 
33
 
#include "registry.h"
34
 
#include "error.h"
35
 
 
36
 
#define CLASS_KEY_PATH_NT "SYSTEM\\CurrentControlSet\\Control\\Class\\"
37
 
#define CLASS_KEY_PATH_9X "SYSTEM\\CurrentControlSet\\Services\\Class\\"
38
 
 
39
 
#define USB_GET_DRIVER_NAME() \
40
 
  usb_registry_is_nt() ? driver_name_nt : driver_name_9x;
41
 
 
42
 
typedef struct _usb_class_key usb_class_key_t;
43
 
 
44
 
struct _usb_class_key {
45
 
  usb_class_key_t *next;
46
 
  char name[MAX_PATH];
47
 
};
48
 
 
49
 
static const char *driver_name_nt = "libusb0";
50
 
static const char *driver_name_9x = "libusb0.sys";
51
 
 
52
 
static const char *default_class_keys_nt[] =
53
 
  {
54
 
    /* USB devices */
55
 
    "{36fc9e60-c465-11cf-8056-444553540000}",
56
 
    /* HID devices */
57
 
    "{745a17a0-74d3-11d0-b6fe-00a0c90f57da}",
58
 
    /* Network devices */
59
 
    "{4d36e972-e325-11ce-bfc1-08002be10318}",
60
 
    /* Image devices */
61
 
    "{6bdd1fc6-810f-11d0-bec7-08002be2092f}",
62
 
    /* Media devices */
63
 
    "{4d36e96c-e325-11ce-bfc1-08002be10318}",
64
 
    /* Modem devices */
65
 
    "{4d36e96d-e325-11ce-bfc1-08002be10318}",
66
 
    /* SmartCardReader devices*/
67
 
    "{50dd5230-ba8a-11d1-bf5d-0000f805f530}",
68
 
    NULL
69
 
  };
70
 
 
71
 
static const char *default_class_keys_9x[] =
72
 
  {
73
 
    /* USB devices */
74
 
    "usb",
75
 
    /* HID devices */
76
 
    "hid",
77
 
    /* Network devices */
78
 
    "net",
79
 
    /* Image devices */
80
 
    "image",
81
 
    /* Media devices */
82
 
    "media",
83
 
    /* Modem devices */
84
 
    "modem",
85
 
    NULL
86
 
  };
87
 
 
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,
93
 
                                         const char *key);
94
 
static bool_t usb_registry_free_class_keys(usb_class_key_t **head);
95
 
 
96
 
 
97
 
bool_t usb_registry_is_nt(void)
98
 
{
99
 
  return GetVersion() < 0x80000000 ? TRUE : FALSE;
100
 
}
101
 
 
102
 
bool_t usb_registry_get_property(DWORD which, HDEVINFO dev_info, 
103
 
                                 SP_DEVINFO_DATA *dev_info_data,
104
 
                                 char *buf, int size)
105
 
{
106
 
  DWORD reg_type;
107
 
  DWORD key_type;
108
 
  DWORD length = size;
109
 
  char *p = NULL;
110
 
  char *val_name = NULL;
111
 
  HKEY reg_key = NULL;
112
 
  
113
 
  memset(buf, 0, size);
114
 
 
115
 
  switch(which)
116
 
    {
117
 
    case SPDRP_LOWERFILTERS:
118
 
      val_name = "LowerFilters";
119
 
      key_type = DIREG_DEV; 
120
 
      break;
121
 
    case SPDRP_UPPERFILTERS:
122
 
      val_name = "UpperFilters";
123
 
      key_type = DIREG_DEV; 
124
 
      break;
125
 
    case SPDRP_SERVICE:
126
 
      val_name = "NTMPDriver";
127
 
      key_type = DIREG_DRV;
128
 
      break;
129
 
    case SPDRP_CLASSGUID:
130
 
      val_name = "ClassGUID";
131
 
      key_type = DIREG_DEV;    
132
 
    case SPDRP_CLASS:
133
 
      val_name = "Class";
134
 
      key_type = DIREG_DEV;    
135
 
      break;
136
 
    case SPDRP_HARDWAREID:
137
 
      val_name = "HardwareID";
138
 
      key_type = DIREG_DEV;
139
 
      break;
140
 
    case SPDRP_DEVICEDESC:
141
 
      val_name = "DeviceDesc";
142
 
      key_type = DIREG_DEV;
143
 
      break;
144
 
    case SPDRP_MFG:
145
 
      val_name = "Mfg";
146
 
      key_type = DIREG_DEV;
147
 
      break;
148
 
 
149
 
    default:
150
 
      return FALSE;
151
 
    }
152
 
 
153
 
  if(usb_registry_is_nt())
154
 
    {
155
 
      if(!SetupDiGetDeviceRegistryProperty(dev_info, dev_info_data, which,  
156
 
                                           &reg_type, (BYTE *)buf, 
157
 
                                           size, &length))
158
 
        {
159
 
          return FALSE;
160
 
        }
161
 
 
162
 
      if(length <= 2)
163
 
        {
164
 
          return FALSE;
165
 
        }
166
 
    }
167
 
  else /* Win9x */
168
 
    {
169
 
      reg_key = SetupDiOpenDevRegKey(dev_info, dev_info_data, 
170
 
                                     DICS_FLAG_GLOBAL, 
171
 
                                     0, key_type, KEY_ALL_ACCESS);
172
 
      
173
 
      if(reg_key == INVALID_HANDLE_VALUE)
174
 
        {
175
 
          usb_error("usb_registry_get_property(): reading "
176
 
                    "registry key failed");
177
 
          return FALSE;
178
 
        }
179
 
      
180
 
      if(RegQueryValueEx(reg_key, val_name, NULL, &reg_type, 
181
 
                         (BYTE *)buf, &length) != ERROR_SUCCESS
182
 
         || length <= 2)
183
 
        {
184
 
          RegCloseKey(reg_key);
185
 
          return FALSE;
186
 
        }
187
 
 
188
 
      RegCloseKey(reg_key);
189
 
      
190
 
      if(reg_type == REG_MULTI_SZ)
191
 
        {
192
 
          p = buf;
193
 
          while(*p)
194
 
            {
195
 
              if(*p == ',')
196
 
                {
197
 
                  *p = 0;
198
 
                }
199
 
              p++;
200
 
            }
201
 
        }
202
 
    }
203
 
 
204
 
  return TRUE;
205
 
}
206
 
 
207
 
bool_t usb_registry_set_property(DWORD which, HDEVINFO dev_info, 
208
 
                                 SP_DEVINFO_DATA *dev_info_data, 
209
 
                                 char *buf, int size)
210
 
{
211
 
  char *val_name = NULL;
212
 
  char *p = NULL;
213
 
  HKEY reg_key;
214
 
  DWORD reg_type;
215
 
 
216
 
  switch(which)
217
 
    {
218
 
    case SPDRP_LOWERFILTERS:
219
 
      reg_type = usb_registry_is_nt() ? REG_MULTI_SZ : REG_SZ;
220
 
      val_name = "LowerFilters";
221
 
      break;
222
 
    case SPDRP_UPPERFILTERS:
223
 
      reg_type = usb_registry_is_nt() ? REG_MULTI_SZ : REG_SZ;
224
 
      val_name = "UpperFilters";
225
 
      break;
226
 
    default:
227
 
      return 0;
228
 
    }
229
 
 
230
 
  if(usb_registry_is_nt())
231
 
    {
232
 
      if(size > 2)
233
 
        {
234
 
          if(!SetupDiSetDeviceRegistryProperty(dev_info, dev_info_data,
235
 
                                               which, (BYTE *)buf, size))
236
 
            {
237
 
              usb_error("usb_registry_set_property(): setting "
238
 
                        "property '%s' failed", val_name);
239
 
              return FALSE;
240
 
            }
241
 
        }
242
 
      else
243
 
        {
244
 
          if(!SetupDiSetDeviceRegistryProperty(dev_info, dev_info_data,
245
 
                                               which, NULL, 0))
246
 
            {
247
 
              usb_error("usb_registry_set_property(): deleting "
248
 
                        "property '%s' failed", val_name);
249
 
              return FALSE;
250
 
            }
251
 
        }
252
 
    }
253
 
  else
254
 
    {
255
 
      p = buf;
256
 
      
257
 
      while(*p)
258
 
        {
259
 
          if(*p == ',')
260
 
            {
261
 
              *p = 0;
262
 
            }
263
 
          p += (strlen(p) + 1);
264
 
        }
265
 
 
266
 
      reg_key = SetupDiOpenDevRegKey(dev_info, dev_info_data, 
267
 
                                     DICS_FLAG_GLOBAL, 
268
 
                                     0, DIREG_DEV, KEY_ALL_ACCESS);
269
 
      
270
 
      if(reg_key == INVALID_HANDLE_VALUE)
271
 
        {
272
 
          usb_error("usb_registry_set_property(): reading "
273
 
                    "registry key failed");
274
 
          return FALSE;
275
 
        }
276
 
      
277
 
      if(size > 3)
278
 
        {
279
 
          if(RegSetValueEx(reg_key, val_name, 0, reg_type, (BYTE *)buf, 
280
 
                           size) != ERROR_SUCCESS)
281
 
            {
282
 
              usb_error("usb_registry_set_property(): setting "
283
 
                        "property '%s' failed", val_name);
284
 
              RegCloseKey(reg_key);
285
 
              return FALSE;
286
 
            }
287
 
        }
288
 
      else
289
 
        {
290
 
          if(RegDeleteValue(reg_key, val_name) != ERROR_SUCCESS)
291
 
            {
292
 
              usb_error("usb_registry_set_property(): deleting "
293
 
                        "property '%s' failed", val_name);
294
 
              RegCloseKey(reg_key);
295
 
              return FALSE;
296
 
            }
297
 
        }
298
 
      RegCloseKey(reg_key);
299
 
    }
300
 
 
301
 
  return TRUE;
302
 
}
303
 
 
304
 
bool_t usb_registry_insert_class_filter(void)
305
 
{
306
 
  const char *driver_name;
307
 
  usb_class_key_t *keys;
308
 
  usb_class_key_t *key;
309
 
  char buf[MAX_PATH];
310
 
  
311
 
  driver_name = USB_GET_DRIVER_NAME();
312
 
 
313
 
  keys = usb_registry_get_usb_class_keys();
314
 
 
315
 
  if(!keys)
316
 
    {
317
 
      usb_error("usb_registry_insert_filter: unable to retrieve class keys\n");
318
 
      return FALSE;
319
 
    }
320
 
 
321
 
  key = keys;
322
 
 
323
 
  while(key)
324
 
    {
325
 
      if(usb_registry_get_mz_value(key->name, "UpperFilters", 
326
 
                                   buf, sizeof(buf)))
327
 
        {
328
 
          usb_registry_mz_string_lower(buf);
329
 
      
330
 
          if(usb_registry_mz_string_find(buf, driver_name))
331
 
            {
332
 
              key = key->next;
333
 
              continue;
334
 
            }
335
 
        }
336
 
      
337
 
      usb_registry_mz_string_insert(buf, driver_name);
338
 
 
339
 
      if(!usb_registry_set_mz_value(key->name, "UpperFilters", buf, 
340
 
                                    usb_registry_mz_string_size(buf)))
341
 
        {
342
 
          usb_error("usb_registry_insert_filter: unable to "
343
 
                    "set registry value\n");
344
 
        }
345
 
 
346
 
      key = key->next;
347
 
    }
348
 
 
349
 
  usb_registry_free_class_keys(&keys);
350
 
 
351
 
  return TRUE;
352
 
}
353
 
 
354
 
 
355
 
bool_t usb_registry_remove_class_filter(void)
356
 
{
357
 
  const char *driver_name;
358
 
  usb_class_key_t *keys;
359
 
  usb_class_key_t *key;
360
 
  char buf[MAX_PATH];
361
 
  
362
 
  driver_name = USB_GET_DRIVER_NAME();
363
 
 
364
 
  keys = usb_registry_get_all_class_keys();
365
 
      
366
 
  if(!keys)
367
 
    {
368
 
      usb_error("usb_registry_remove_filter: unable to retrieve class keys\n");
369
 
      return FALSE;
370
 
    }
371
 
 
372
 
  key = keys;
373
 
 
374
 
  while(key)
375
 
    {
376
 
      if(usb_registry_get_mz_value(key->name, "UpperFilters", 
377
 
                                   buf, sizeof(buf)))
378
 
        {
379
 
          usb_registry_mz_string_lower(buf);
380
 
      
381
 
          if(usb_registry_mz_string_find(buf, driver_name))
382
 
            {
383
 
              usb_registry_mz_string_remove(buf, driver_name);
384
 
              
385
 
              usb_registry_set_mz_value(key->name, "UpperFilters", buf, 
386
 
                                        usb_registry_mz_string_size(buf));
387
 
            }
388
 
        }
389
 
 
390
 
      key = key->next;
391
 
    }
392
 
 
393
 
  usb_registry_free_class_keys(&keys);
394
 
 
395
 
  return TRUE;
396
 
}
397
 
 
398
 
bool_t usb_registry_remove_device_filter(void)
399
 
{
400
 
  HDEVINFO dev_info;
401
 
  SP_DEVINFO_DATA dev_info_data;
402
 
  int dev_index = 0;
403
 
  char filters[MAX_PATH];
404
 
  const char *driver_name;
405
 
 
406
 
  driver_name = USB_GET_DRIVER_NAME();
407
 
 
408
 
  dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
409
 
  dev_index = 0;
410
 
 
411
 
  dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES);
412
 
  
413
 
  if(dev_info == INVALID_HANDLE_VALUE)
414
 
    {
415
 
      usb_error("usb_registry_remove_device_filter(): getting "
416
 
                "device info set failed");
417
 
      return FALSE;
418
 
    }
419
 
  
420
 
  while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
421
 
    {
422
 
      /* remove libusb as a device upper filter */
423
 
      if(usb_registry_get_property(SPDRP_UPPERFILTERS, dev_info, 
424
 
                                   &dev_info_data, 
425
 
                                   filters, sizeof(filters)))
426
 
        {
427
 
          usb_registry_mz_string_lower(filters);
428
 
 
429
 
          if(usb_registry_mz_string_find(filters, driver_name))
430
 
            {
431
 
              int size;
432
 
              usb_registry_mz_string_remove(filters, driver_name);
433
 
              size = usb_registry_mz_string_size(filters);
434
 
 
435
 
              usb_registry_set_property(SPDRP_UPPERFILTERS, dev_info, 
436
 
                                        &dev_info_data, filters, size);
437
 
            }
438
 
        }
439
 
 
440
 
      /* remove libusb as a device lower filter */
441
 
      if(usb_registry_get_property(SPDRP_LOWERFILTERS, dev_info, 
442
 
                                   &dev_info_data, 
443
 
                                   filters, sizeof(filters)))
444
 
        {
445
 
          usb_registry_mz_string_lower(filters);
446
 
 
447
 
          if(usb_registry_mz_string_find(filters, driver_name))
448
 
            {
449
 
              int size;
450
 
              usb_registry_mz_string_remove(filters, driver_name);
451
 
              size = usb_registry_mz_string_size(filters);
452
 
 
453
 
              usb_registry_set_property(SPDRP_LOWERFILTERS, dev_info, 
454
 
                                        &dev_info_data, filters, size);
455
 
            }
456
 
        }
457
 
 
458
 
      dev_index++;
459
 
    }
460
 
  
461
 
  SetupDiDestroyDeviceInfoList(dev_info);
462
 
  
463
 
  return TRUE;
464
 
}
465
 
 
466
 
static bool_t usb_registry_set_device_state(DWORD state, HDEVINFO dev_info, 
467
 
                                            SP_DEVINFO_DATA *dev_info_data)
468
 
{
469
 
  SP_PROPCHANGE_PARAMS prop_params;
470
 
 
471
 
  memset(&prop_params, 0, sizeof(SP_PROPCHANGE_PARAMS));
472
 
 
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;
478
 
          
479
 
 
480
 
  if(!SetupDiSetClassInstallParams(dev_info, dev_info_data,
481
 
                                   (SP_CLASSINSTALL_HEADER *)&prop_params,
482
 
                                   sizeof(SP_PROPCHANGE_PARAMS)))
483
 
    {
484
 
      usb_error("usb_registry_set_device_state(): setting class "
485
 
                "install parameters failed");
486
 
      return FALSE;
487
 
    }
488
 
          
489
 
 
490
 
  if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, dev_info, dev_info_data))
491
 
    {
492
 
      usb_error("usb_registry_set_device_state(): calling class "
493
 
                "installer failed");
494
 
      return FALSE;
495
 
    }
496
 
 
497
 
  return TRUE;
498
 
}
499
 
 
500
 
bool_t usb_registry_restart_device(HDEVINFO dev_info, 
501
 
                                   SP_DEVINFO_DATA *dev_info_data)
502
 
{
503
 
  return usb_registry_set_device_state(DICS_PROPCHANGE, dev_info, 
504
 
                                       dev_info_data);
505
 
}
506
 
 
507
 
bool_t usb_registry_stop_device(HDEVINFO dev_info, 
508
 
                                SP_DEVINFO_DATA *dev_info_data)
509
 
{
510
 
  return usb_registry_set_device_state(DICS_DISABLE, dev_info, 
511
 
                                       dev_info_data);
512
 
}
513
 
 
514
 
bool_t usb_registry_start_device(HDEVINFO dev_info, 
515
 
                                 SP_DEVINFO_DATA *dev_info_data)
516
 
{
517
 
  return usb_registry_set_device_state(DICS_ENABLE, dev_info, 
518
 
                                       dev_info_data);
519
 
}
520
 
 
521
 
bool_t usb_registry_is_service_libusb(HDEVINFO dev_info, 
522
 
                                      SP_DEVINFO_DATA *dev_info_data)
523
 
{
524
 
  char service_name[MAX_PATH];
525
 
 
526
 
  if(!usb_registry_get_property(SPDRP_SERVICE, dev_info, dev_info_data,
527
 
                                service_name, sizeof(service_name)))
528
 
    {
529
 
      return FALSE;
530
 
    }
531
 
  
532
 
  usb_registry_mz_string_lower(service_name);
533
 
   
534
 
  if(usb_registry_mz_string_find_sub(service_name, "libusb"))
535
 
    {
536
 
      return TRUE;
537
 
    }
538
 
 
539
 
  return FALSE;
540
 
}
541
 
 
542
 
void usb_registry_stop_libusb_devices(void)
543
 
{
544
 
  HDEVINFO dev_info;
545
 
  SP_DEVINFO_DATA dev_info_data;
546
 
  int dev_index = 0;
547
 
  
548
 
  dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
549
 
  dev_index = 0;
550
 
 
551
 
  dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
552
 
                                 DIGCF_ALLCLASSES | DIGCF_PRESENT);
553
 
  
554
 
  if(dev_info == INVALID_HANDLE_VALUE)
555
 
    {
556
 
      usb_error("usb_registry_stop_libusb_devices(): getting "
557
 
                "device info set failed");
558
 
      return;
559
 
    }
560
 
  
561
 
  while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
562
 
    {
563
 
      if(usb_registry_is_service_libusb(dev_info, &dev_info_data))
564
 
        {
565
 
          usb_registry_stop_device(dev_info, &dev_info_data);
566
 
        }
567
 
      dev_index++;
568
 
    }
569
 
  
570
 
  SetupDiDestroyDeviceInfoList(dev_info);
571
 
}
572
 
 
573
 
void usb_registry_start_libusb_devices(void)
574
 
{
575
 
  HDEVINFO dev_info;
576
 
  SP_DEVINFO_DATA dev_info_data;
577
 
  int dev_index = 0;
578
 
  
579
 
  dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
580
 
  dev_index = 0;
581
 
 
582
 
  dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
583
 
                                 DIGCF_ALLCLASSES | DIGCF_PRESENT);
584
 
  
585
 
  if(dev_info == INVALID_HANDLE_VALUE)
586
 
    {
587
 
      usb_error("usb_registry_stop_libusb_devices(): getting "
588
 
                "device info set failed");
589
 
      return;
590
 
    }
591
 
  
592
 
  while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
593
 
    {
594
 
      if(usb_registry_is_service_libusb(dev_info, &dev_info_data))
595
 
        {
596
 
          usb_registry_start_device(dev_info, &dev_info_data);
597
 
        }
598
 
      dev_index++;
599
 
    }
600
 
  
601
 
  SetupDiDestroyDeviceInfoList(dev_info);
602
 
}
603
 
 
604
 
 
605
 
bool_t usb_registry_match(HDEVINFO dev_info, 
606
 
                          SP_DEVINFO_DATA *dev_info_data)
607
 
{
608
 
  char tmp[MAX_PATH];
609
 
  
610
 
  if(!usb_registry_get_property(SPDRP_HARDWAREID, dev_info, dev_info_data,
611
 
                                tmp, sizeof(tmp)))
612
 
    {
613
 
      usb_error("usb_registry_match_no_hubs(): getting hardware id "
614
 
                "failed");
615
 
      return FALSE;
616
 
    }
617
 
 
618
 
  usb_registry_mz_string_lower(tmp);
619
 
 
620
 
  /* search for USB devices, skip root hubs and interfaces of composite */
621
 
  /* devices */
622
 
  if(usb_registry_mz_string_find_sub(tmp, "&mi_")
623
 
     || usb_registry_mz_string_find_sub(tmp, "root_hub"))
624
 
    {
625
 
      return FALSE;
626
 
    }
627
 
 
628
 
  return TRUE;
629
 
}
630
 
 
631
 
bool_t usb_registry_get_mz_value(const char *key, const char *value, 
632
 
                                 char *buf, int size)
633
 
{
634
 
  HKEY reg_key = NULL;
635
 
  DWORD reg_type;
636
 
  DWORD reg_length = size;
637
 
  bool_t ret = FALSE;
638
 
  char *p;
639
 
 
640
 
  memset(buf, 0, size);
641
 
      
642
 
  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_ALL_ACCESS, &reg_key)
643
 
     == ERROR_SUCCESS)
644
 
    {
645
 
      if(RegQueryValueEx(reg_key, value, NULL, &reg_type, 
646
 
                         buf, &reg_length) == ERROR_SUCCESS)
647
 
        {
648
 
          if(reg_type == REG_SZ)
649
 
            {
650
 
              p = buf;
651
 
              while(*p)
652
 
                {
653
 
                  if(*p == ',')
654
 
                    {
655
 
                      *p = 0;
656
 
                    }
657
 
                  p++;
658
 
                }
659
 
            }
660
 
 
661
 
          ret = TRUE;
662
 
        }
663
 
    }
664
 
 
665
 
  if(reg_key)
666
 
    {
667
 
      RegCloseKey(reg_key);
668
 
    }
669
 
 
670
 
  return ret;
671
 
}
672
 
 
673
 
 
674
 
bool_t usb_registry_set_mz_value(const char *key, const char *value, 
675
 
                                 char *buf, int size)
676
 
{
677
 
  HKEY reg_key = NULL;
678
 
  bool_t ret = FALSE;
679
 
  char *p;
680
 
 
681
 
  /* convert REG_MULTI_SZ to REG_SZ */
682
 
  if(!usb_registry_is_nt())
683
 
    {
684
 
      p = buf;
685
 
      
686
 
      while(*p && *(p + 1))
687
 
        {
688
 
          if(*p == 0)
689
 
            {
690
 
              *p = ',';
691
 
            }
692
 
          p++;
693
 
        }
694
 
    }
695
 
 
696
 
  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_ALL_ACCESS, &reg_key)
697
 
     == ERROR_SUCCESS)
698
 
    {
699
 
      if(size > 2)
700
 
        {
701
 
          if(usb_registry_is_nt())
702
 
            {
703
 
              if(RegSetValueEx(reg_key, value, 0, REG_MULTI_SZ, buf, size)
704
 
                 == ERROR_SUCCESS)
705
 
                {
706
 
                  ret = TRUE;
707
 
                }
708
 
            }
709
 
          else
710
 
            {
711
 
              if(RegSetValueEx(reg_key, value, 0, REG_SZ, buf, size)
712
 
                 == ERROR_SUCCESS)
713
 
                {
714
 
                  ret = TRUE;
715
 
                }
716
 
            }
717
 
        }
718
 
      else
719
 
        {
720
 
          if(RegDeleteValue(reg_key, value) == ERROR_SUCCESS)
721
 
            {
722
 
              ret = TRUE;
723
 
            }
724
 
        }
725
 
    }
726
 
  
727
 
  if(reg_key)
728
 
    {
729
 
      RegCloseKey(reg_key);
730
 
    }
731
 
 
732
 
  return ret;
733
 
}
734
 
 
735
 
int usb_registry_mz_string_size(const char *src)
736
 
{
737
 
  char *p = (char *)src;
738
 
  
739
 
  if(!src)
740
 
    {
741
 
      return 0;
742
 
    }
743
 
 
744
 
  while(*p)
745
 
    {
746
 
      p += (strlen(p) + 1);
747
 
    }
748
 
  
749
 
  return (int)(p - src) + 1;
750
 
}
751
 
 
752
 
char *usb_registry_mz_string_find_sub(const char *src, const char *str)
753
 
{
754
 
  while(*src)
755
 
    {
756
 
      if(strstr(src, str))
757
 
        {
758
 
          return (char *)src;
759
 
        }
760
 
      src += (strlen(src) + 1);
761
 
    }
762
 
 
763
 
  return NULL;
764
 
}
765
 
 
766
 
char *usb_registry_mz_string_find(const char *src, const char *str)
767
 
{
768
 
  while(*src)
769
 
    {
770
 
      if(!strcmp(src, str))
771
 
        {
772
 
          return (char *)src;
773
 
        }
774
 
      src += strlen(src) + 1;
775
 
    }
776
 
 
777
 
  return NULL;
778
 
}
779
 
 
780
 
bool_t usb_registry_mz_string_insert(char *src, const char *str)
781
 
{
782
 
  while(*src)
783
 
    {
784
 
      src += (strlen(src) + 1);
785
 
    }
786
 
 
787
 
  memcpy(src, str, strlen(str));
788
 
 
789
 
  src += strlen(str);
790
 
 
791
 
  *src = 0;
792
 
  *(src + 1) = 0;
793
 
 
794
 
  return TRUE;
795
 
}
796
 
 
797
 
bool_t usb_registry_mz_string_remove(char *src, const char *str)
798
 
{
799
 
  char *p;
800
 
  bool_t ret = FALSE;
801
 
  int size;
802
 
 
803
 
  do {
804
 
    src = usb_registry_mz_string_find(src, str);
805
 
    
806
 
    if(!src)
807
 
      {
808
 
        break;
809
 
      }
810
 
    else
811
 
      {
812
 
        ret = TRUE;
813
 
      }
814
 
    
815
 
    p = src;
816
 
    size = 0;
817
 
 
818
 
    while(*p)
819
 
      {
820
 
        p += strlen(p) + 1;
821
 
        size += strlen(p) + 1;
822
 
      }
823
 
    
824
 
    memmove(src, src + strlen(src) + 1, size);
825
 
 
826
 
  } while(1);
827
 
 
828
 
  return TRUE;
829
 
}
830
 
 
831
 
void usb_registry_mz_string_lower(char *src)
832
 
{
833
 
  while(*src)
834
 
    {
835
 
      strlwr(src);
836
 
      src += (strlen(src) + 1);
837
 
    }
838
 
}
839
 
 
840
 
bool_t usb_registry_restart_all_devices(void)
841
 
{
842
 
  HDEVINFO dev_info;
843
 
  SP_DEVINFO_DATA dev_info_data;
844
 
  int dev_index;
845
 
  char id[MAX_PATH];
846
 
 
847
 
  dev_index = 0;
848
 
  dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
849
 
  
850
 
  dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
851
 
                                 DIGCF_ALLCLASSES | DIGCF_PRESENT);
852
 
  
853
 
  if(dev_info == INVALID_HANDLE_VALUE)
854
 
    {
855
 
      usb_error("usb_registry_restart_all_devices(): getting "
856
 
                "device info set failed");
857
 
      return FALSE;
858
 
    }
859
 
    
860
 
  while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
861
 
    {
862
 
      if(!usb_registry_get_property(SPDRP_HARDWAREID, dev_info, 
863
 
                                    &dev_info_data, id, sizeof(id)))
864
 
        {
865
 
          usb_error("usb_registry_restart_all_devices(): getting hardware "
866
 
                    "id failed");
867
 
          dev_index++;
868
 
          continue;
869
 
        }
870
 
        
871
 
      usb_registry_mz_string_lower(id);
872
 
        
873
 
      /* restart root hubs */
874
 
      if(usb_registry_mz_string_find_sub(id, "root_hub"))
875
 
        {
876
 
          usb_registry_restart_device(dev_info, &dev_info_data);
877
 
        }
878
 
 
879
 
      dev_index++;
880
 
    }
881
 
    
882
 
  SetupDiDestroyDeviceInfoList(dev_info);
883
 
 
884
 
  return TRUE;
885
 
}
886
 
 
887
 
 
888
 
usb_class_key_t *usb_registry_get_usb_class_keys(void)
889
 
{
890
 
  HDEVINFO dev_info;
891
 
  SP_DEVINFO_DATA dev_info_data;
892
 
  int dev_index = 0;
893
 
  int i;
894
 
  char class[MAX_PATH];
895
 
  char tmp[MAX_PATH];
896
 
  usb_class_key_t *keys = NULL;
897
 
  DWORD class_property;
898
 
  const char *class_path;
899
 
  const char **default_class_keys;
900
 
 
901
 
  if(usb_registry_is_nt())
902
 
    {
903
 
      class_property = SPDRP_CLASSGUID;
904
 
      class_path = CLASS_KEY_PATH_NT;
905
 
      default_class_keys = default_class_keys_nt;
906
 
    }
907
 
  else
908
 
    {
909
 
      class_property = SPDRP_CLASS;
910
 
      class_path = CLASS_KEY_PATH_9X;
911
 
      default_class_keys = default_class_keys_9x;
912
 
    }
913
 
 
914
 
  i = 0;
915
 
 
916
 
  while(default_class_keys[i])
917
 
    {
918
 
      if((strlen(class_path) + strlen(default_class_keys[i])) < sizeof(tmp))
919
 
        {
920
 
          sprintf(tmp, "%s%s", class_path, default_class_keys[i]);
921
 
          usb_registry_add_class_key(&keys, tmp);
922
 
        }
923
 
      i++;
924
 
    }
925
 
 
926
 
 
927
 
  dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
928
 
  dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
929
 
                                 DIGCF_ALLCLASSES);
930
 
  
931
 
  if(dev_info == INVALID_HANDLE_VALUE)
932
 
    {
933
 
      usb_error("usb_registry_get_class_keys(): getting "
934
 
                "device info set failed");
935
 
      return NULL;
936
 
    }
937
 
  
938
 
  while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
939
 
    {
940
 
      if(!usb_registry_is_service_libusb(dev_info, &dev_info_data))
941
 
        {
942
 
          if(!usb_registry_get_property(SPDRP_CLASSGUID, dev_info, 
943
 
                                        &dev_info_data,
944
 
                                        class, sizeof(class)))
945
 
            {
946
 
              usb_error("usb_registry_get_class_keys(): getting "
947
 
                        "hardware id failed");
948
 
              dev_index++;
949
 
              continue;
950
 
            }
951
 
          
952
 
          strlwr(class);
953
 
          
954
 
          if((strlen(class_path) + strlen(class)) < sizeof(tmp))
955
 
            {
956
 
              sprintf(tmp, "%s%s", class_path, class);
957
 
              usb_registry_add_class_key(&keys, tmp);
958
 
            }
959
 
        }
960
 
 
961
 
      dev_index++;
962
 
    }
963
 
  
964
 
  SetupDiDestroyDeviceInfoList(dev_info);
965
 
 
966
 
  return keys;
967
 
}
968
 
 
969
 
static usb_class_key_t *usb_registry_get_all_class_keys(void)
970
 
{
971
 
  const char *class_path;
972
 
  usb_class_key_t *keys = NULL;
973
 
  HKEY reg_key;
974
 
  char class[MAX_PATH];
975
 
  char tmp[MAX_PATH];
976
 
 
977
 
  if(usb_registry_is_nt())
978
 
    {
979
 
      class_path = CLASS_KEY_PATH_NT;
980
 
    }
981
 
  else
982
 
    {
983
 
      class_path = CLASS_KEY_PATH_9X;
984
 
    }
985
 
 
986
 
  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, class_path, 0, KEY_ALL_ACCESS, 
987
 
                  &reg_key) == ERROR_SUCCESS)
988
 
    {
989
 
      DWORD i = 0;
990
 
      DWORD size = sizeof(class);
991
 
      FILETIME junk;
992
 
 
993
 
      memset(class, 0, sizeof(class));
994
 
 
995
 
      while(RegEnumKeyEx(reg_key, i, class, &size, 0, NULL, NULL, &junk) 
996
 
            == ERROR_SUCCESS)
997
 
        {
998
 
          strlwr(class);
999
 
 
1000
 
          if((strlen(class_path) + strlen(class)) < sizeof(tmp))
1001
 
            {
1002
 
              sprintf(tmp, "%s%s", class_path, class);
1003
 
              usb_registry_add_class_key(&keys, tmp);
1004
 
            }
1005
 
          
1006
 
          memset(class, 0, sizeof(class));
1007
 
          size = sizeof(class);
1008
 
          i++;
1009
 
        }
1010
 
 
1011
 
      RegCloseKey(reg_key);
1012
 
    }
1013
 
 
1014
 
  return keys;
1015
 
}
1016
 
 
1017
 
static bool_t usb_registry_add_class_key(usb_class_key_t **head,
1018
 
                                         const char *key)
1019
 
{
1020
 
  usb_class_key_t *p = *head;
1021
 
 
1022
 
  if(key)
1023
 
    {
1024
 
 
1025
 
      if(strlen(key) >= MAX_PATH)
1026
 
        return FALSE;
1027
 
 
1028
 
      while(p)
1029
 
        {
1030
 
          if(!strcmp(p->name, key))
1031
 
            {
1032
 
              return FALSE;
1033
 
            }
1034
 
          p = p->next;
1035
 
        }
1036
 
 
1037
 
      p = malloc(sizeof(usb_class_key_t));
1038
 
      
1039
 
      if(!p)
1040
 
        return FALSE;
1041
 
 
1042
 
      memset(p, 0, sizeof(usb_class_key_t));
1043
 
      strcpy(p->name, key);
1044
 
 
1045
 
      p->next = *head;
1046
 
      *head = p;
1047
 
 
1048
 
      return TRUE;
1049
 
    }
1050
 
 
1051
 
  return FALSE;
1052
 
}
1053
 
 
1054
 
static bool_t usb_registry_free_class_keys(usb_class_key_t **head)
1055
 
{
1056
 
  usb_class_key_t *p = *head;
1057
 
  usb_class_key_t *q;
1058
 
 
1059
 
  while(p)
1060
 
    {
1061
 
      q = p->next;
1062
 
      free(p);
1063
 
      p = q;
1064
 
    }
1065
 
 
1066
 
  *head = NULL;
1067
 
 
1068
 
  return TRUE;
1069
 
}