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

« back to all changes in this revision

Viewing changes to libusbw/src/driver/libusb_driver.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 program is free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
7
 
 * (at your option) any later version.
8
 
 *
9
 
 * This program 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
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
 */
18
 
 
19
 
 
20
 
#define __LIBUSB_DRIVER_C__
21
 
 
22
 
#include "libusb_driver.h"
23
 
 
24
 
extern int debug_level;
25
 
 
26
 
static void DDKAPI unload(DRIVER_OBJECT *driver_object);
27
 
 
28
 
static NTSTATUS DDKAPI on_usbd_complete(DEVICE_OBJECT *device_object, 
29
 
                                        IRP *irp, 
30
 
                                        void *context);
31
 
 
32
 
NTSTATUS DDKAPI DriverEntry(DRIVER_OBJECT *driver_object,
33
 
                            UNICODE_STRING *registry_path)
34
 
{
35
 
  int i;
36
 
 
37
 
  DEBUG_MESSAGE("DriverEntry(): loading driver");
38
 
 
39
 
  /* initialize global variables */
40
 
  debug_level = LIBUSB_DEBUG_MSG;
41
 
 
42
 
  /* initialize the driver object's dispatch table */
43
 
  for(i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) 
44
 
    {
45
 
      driver_object->MajorFunction[i] = dispatch;
46
 
    }
47
 
  
48
 
  driver_object->DriverExtension->AddDevice = add_device;
49
 
  driver_object->DriverUnload = unload;
50
 
 
51
 
  return STATUS_SUCCESS;
52
 
}
53
 
 
54
 
NTSTATUS DDKAPI add_device(DRIVER_OBJECT *driver_object, 
55
 
                           DEVICE_OBJECT *physical_device_object)
56
 
{
57
 
  NTSTATUS status;
58
 
  DEVICE_OBJECT *device_object = NULL;
59
 
  libusb_device_t *dev;
60
 
  ULONG device_type;
61
 
 
62
 
  UNICODE_STRING nt_device_name;
63
 
  UNICODE_STRING symbolic_link_name;
64
 
  WCHAR tmp_name_0[128];
65
 
  WCHAR tmp_name_1[128];
66
 
  char id[256];
67
 
  int i;
68
 
 
69
 
  /* get the hardware ID from the registry */
70
 
  if(!reg_get_hardware_id(physical_device_object, id, sizeof(id)))
71
 
    {
72
 
      DEBUG_ERROR("add_device(): unable to read registry");
73
 
      return STATUS_SUCCESS;
74
 
    }
75
 
 
76
 
  /* only attach the (filter) driver to USB devices, skip hubs */
77
 
  /* and interfaces of composite devices */
78
 
  if(!strstr(id, "usb\\") || strstr(id, "hub") || strstr(id, "&mi_"))
79
 
    {
80
 
      return STATUS_SUCCESS;
81
 
    }
82
 
 
83
 
  /* retrieve the type of the lower device object */
84
 
  device_object = IoGetAttachedDeviceReference(physical_device_object);
85
 
 
86
 
  if(device_object)
87
 
    {
88
 
      device_type = device_object->DeviceType;
89
 
      ObDereferenceObject(device_object);
90
 
    }
91
 
  else
92
 
    {
93
 
      device_type = FILE_DEVICE_UNKNOWN;
94
 
    }
95
 
 
96
 
  /* try to create a new device object */
97
 
  for(i = 1; i < LIBUSB_MAX_NUMBER_OF_DEVICES; i++)
98
 
    {
99
 
      /* initialize some unicode strings */
100
 
      _snwprintf(tmp_name_0, sizeof(tmp_name_0)/sizeof(WCHAR), L"%s%04d", 
101
 
                 LIBUSB_NT_DEVICE_NAME, i);
102
 
      _snwprintf(tmp_name_1, sizeof(tmp_name_1)/sizeof(WCHAR), L"%s%04d", 
103
 
                 LIBUSB_SYMBOLIC_LINK_NAME, i);
104
 
 
105
 
      RtlInitUnicodeString(&nt_device_name, tmp_name_0);  
106
 
      RtlInitUnicodeString(&symbolic_link_name, tmp_name_1);
107
 
 
108
 
      /* create the object */
109
 
      status = IoCreateDevice(driver_object, 
110
 
                              sizeof(libusb_device_t), 
111
 
                              &nt_device_name, device_type, 0, FALSE, 
112
 
                              &device_object);
113
 
 
114
 
      if(NT_SUCCESS(status))
115
 
        {
116
 
          DEBUG_MESSAGE("add_device(): device #%d created", i);
117
 
          break;
118
 
        }
119
 
 
120
 
      device_object = NULL;
121
 
 
122
 
      /* continue until an unused device name is found */
123
 
    }
124
 
 
125
 
  if(!device_object)
126
 
    {
127
 
      DEBUG_ERROR("add_device(): creating device failed");
128
 
      return status;
129
 
    }
130
 
      
131
 
  status = IoCreateSymbolicLink(&symbolic_link_name, &nt_device_name);
132
 
  
133
 
  if(!NT_SUCCESS(status))
134
 
    {
135
 
      DEBUG_ERROR("add_device(): creating symbolic link failed");
136
 
      IoDeleteDevice(device_object);
137
 
      return status;
138
 
    }
139
 
 
140
 
  /* setup the "device object" */
141
 
  dev = device_object->DeviceExtension;
142
 
 
143
 
  memset(dev, 0, sizeof(libusb_device_t));
144
 
 
145
 
 
146
 
  /* attach the newly created device object to the stack */
147
 
  dev->next_stack_device = 
148
 
    IoAttachDeviceToDeviceStack(device_object, physical_device_object);
149
 
 
150
 
  if(!dev->next_stack_device)
151
 
    {
152
 
      DEBUG_ERROR("add_device(): attaching to device stack failed");
153
 
      IoDeleteSymbolicLink(&symbolic_link_name);
154
 
      IoDeleteDevice(device_object);
155
 
      return STATUS_NO_SUCH_DEVICE;
156
 
    }
157
 
 
158
 
  dev->self = device_object;
159
 
  dev->physical_device_object = physical_device_object;
160
 
  dev->id = i;
161
 
 
162
 
  /* set initial power states */
163
 
  dev->power_state.DeviceState = PowerDeviceD0;
164
 
  dev->power_state.SystemState = PowerSystemWorking;
165
 
 
166
 
  /* get device properties from the registry */
167
 
  reg_get_properties(dev);
168
 
 
169
 
  if(dev->is_filter)
170
 
    {
171
 
      /* send all USB requests to the PDO in filter driver mode */
172
 
      dev->target_device = dev->physical_device_object;
173
 
 
174
 
      /* use the same flags as the underlying object */
175
 
      device_object->Flags |= dev->next_stack_device->Flags 
176
 
        & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
177
 
    }
178
 
  else
179
 
    {
180
 
      /* send all USB requests to the lower object in device driver mode */
181
 
      dev->target_device = dev->next_stack_device;
182
 
 
183
 
      device_object->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
184
 
    }
185
 
 
186
 
  clear_pipe_info(dev);
187
 
 
188
 
  remove_lock_initialize(dev);
189
 
 
190
 
  device_object->Flags &= ~DO_DEVICE_INITIALIZING;
191
 
 
192
 
  return status;
193
 
}
194
 
 
195
 
 
196
 
VOID DDKAPI unload(DRIVER_OBJECT *driver_object)
197
 
{
198
 
  DEBUG_MESSAGE("unload(): unloading driver");
199
 
}
200
 
 
201
 
NTSTATUS complete_irp(IRP *irp, NTSTATUS status, ULONG info)
202
 
{
203
 
  irp->IoStatus.Status = status;
204
 
  irp->IoStatus.Information = info;
205
 
  IoCompleteRequest(irp, IO_NO_INCREMENT);
206
 
  
207
 
  return status;
208
 
}
209
 
 
210
 
NTSTATUS call_usbd(libusb_device_t *dev, void *urb, ULONG control_code,  
211
 
                   int timeout)
212
 
{
213
 
  KEVENT event;
214
 
  NTSTATUS status;
215
 
  IRP *irp;
216
 
  IO_STACK_LOCATION *next_irp_stack;
217
 
  LARGE_INTEGER _timeout;
218
 
  IO_STATUS_BLOCK io_status;
219
 
 
220
 
  if(timeout > LIBUSB_MAX_CONTROL_TRANSFER_TIMEOUT)
221
 
    {
222
 
      timeout = LIBUSB_MAX_CONTROL_TRANSFER_TIMEOUT;
223
 
    }
224
 
 
225
 
  KeInitializeEvent(&event, NotificationEvent, FALSE);
226
 
 
227
 
  irp = IoBuildDeviceIoControlRequest(control_code, dev->target_device,
228
 
                                      NULL, 0, NULL, 0, TRUE,
229
 
                                      NULL, &io_status);
230
 
 
231
 
  if(!irp)
232
 
    {
233
 
      return STATUS_NO_MEMORY;
234
 
    }
235
 
 
236
 
  next_irp_stack = IoGetNextIrpStackLocation(irp);
237
 
  next_irp_stack->Parameters.Others.Argument1 = urb;
238
 
  next_irp_stack->Parameters.Others.Argument2 = NULL;
239
 
 
240
 
  IoSetCompletionRoutine(irp, on_usbd_complete, &event, TRUE, TRUE, TRUE); 
241
 
 
242
 
  status = IoCallDriver(dev->target_device, irp);
243
 
    
244
 
  if(status == STATUS_PENDING)
245
 
    {
246
 
      _timeout.QuadPart = -(timeout * 10000);
247
 
      
248
 
      if(KeWaitForSingleObject(&event, Executive, KernelMode,
249
 
                               FALSE, &_timeout) == STATUS_TIMEOUT)
250
 
        {
251
 
          DEBUG_ERROR("call_usbd(): request timed out");
252
 
          IoCancelIrp(irp);
253
 
        }
254
 
    }
255
 
 
256
 
  /* wait until completion routine is called */
257
 
  KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
258
 
 
259
 
  status = irp->IoStatus.Status;
260
 
  
261
 
  /* complete the request */
262
 
  IoCompleteRequest(irp, IO_NO_INCREMENT);
263
 
 
264
 
  return status;
265
 
}
266
 
 
267
 
 
268
 
static NTSTATUS DDKAPI on_usbd_complete(DEVICE_OBJECT *device_object, 
269
 
                                        IRP *irp, void *context)
270
 
{
271
 
  KeSetEvent((KEVENT *) context, IO_NO_INCREMENT, FALSE);
272
 
 
273
 
  return STATUS_MORE_PROCESSING_REQUIRED;
274
 
}
275
 
 
276
 
 
277
 
NTSTATUS pass_irp_down(libusb_device_t *dev, IRP *irp, 
278
 
                       PIO_COMPLETION_ROUTINE completion_routine, 
279
 
                       void *context)
280
 
{
281
 
  if(completion_routine)
282
 
    {
283
 
      IoCopyCurrentIrpStackLocationToNext(irp);
284
 
      IoSetCompletionRoutine(irp, completion_routine, context,
285
 
                             TRUE, TRUE, TRUE);
286
 
    }
287
 
  else
288
 
    {
289
 
      IoSkipCurrentIrpStackLocation(irp);
290
 
    }
291
 
 
292
 
  return IoCallDriver(dev->next_stack_device, irp);
293
 
}
294
 
 
295
 
bool_t accept_irp(libusb_device_t *dev, IRP *irp)
296
 
{
297
 
  /* check if the IRP is sent to libusb's device object or to */
298
 
  /* the lower one. This check is neccassary since the device object */
299
 
  /* might be a filter */
300
 
  if(irp->Tail.Overlay.OriginalFileObject)
301
 
    {
302
 
     return irp->Tail.Overlay.OriginalFileObject->DeviceObject
303
 
         == dev->self ? TRUE : FALSE;
304
 
    }
305
 
 
306
 
  return FALSE;
307
 
}
308
 
 
309
 
bool_t get_pipe_handle(libusb_device_t *dev, int endpoint_address, 
310
 
                       USBD_PIPE_HANDLE *pipe_handle)
311
 
{
312
 
  int i, j;
313
 
 
314
 
  *pipe_handle = NULL;
315
 
 
316
 
  for(i = 0; i < LIBUSB_MAX_NUMBER_OF_INTERFACES; i++)
317
 
    {
318
 
      if(dev->config.interfaces[i].valid)
319
 
        {
320
 
          for(j = 0; j < LIBUSB_MAX_NUMBER_OF_ENDPOINTS; j++)
321
 
            {
322
 
              if(dev->config.interfaces[i].endpoints[j].address 
323
 
                 == endpoint_address)
324
 
                {
325
 
                  *pipe_handle = dev->config.interfaces[i].endpoints[j].handle;
326
 
                  
327
 
                  return !*pipe_handle ? FALSE : TRUE;
328
 
                }
329
 
            }
330
 
        }
331
 
    }
332
 
 
333
 
  return FALSE;
334
 
}
335
 
 
336
 
void clear_pipe_info(libusb_device_t *dev)
337
 
{
338
 
  memset(dev->config.interfaces, 0 , sizeof(dev->config.interfaces));
339
 
}
340
 
 
341
 
bool_t update_pipe_info(libusb_device_t *dev,
342
 
                        USBD_INTERFACE_INFORMATION *interface_info)
343
 
{
344
 
  int i;
345
 
  int number;
346
 
 
347
 
  if(!interface_info)
348
 
    {
349
 
      return FALSE;
350
 
    }
351
 
 
352
 
  number = interface_info->InterfaceNumber;
353
 
 
354
 
  if(interface_info->InterfaceNumber >= LIBUSB_MAX_NUMBER_OF_INTERFACES)
355
 
    {
356
 
      return FALSE;
357
 
    }
358
 
 
359
 
  DEBUG_MESSAGE("update_pipe_info(): interface %d", number);
360
 
 
361
 
  dev->config.interfaces[number].valid = TRUE;
362
 
 
363
 
  for(i = 0; i < LIBUSB_MAX_NUMBER_OF_ENDPOINTS; i++)
364
 
    {
365
 
      dev->config.interfaces[number].endpoints[i].address = 0;
366
 
      dev->config.interfaces[number].endpoints[i].handle = NULL;
367
 
    } 
368
 
 
369
 
  if(interface_info)
370
 
    {
371
 
      for(i = 0; i < (int)interface_info->NumberOfPipes
372
 
            && i < LIBUSB_MAX_NUMBER_OF_ENDPOINTS; i++) 
373
 
        {
374
 
          DEBUG_MESSAGE("update_pipe_info(): endpoint address 0x%02x",
375
 
                        interface_info->Pipes[i].EndpointAddress);        
376
 
 
377
 
          dev->config.interfaces[number].endpoints[i].handle
378
 
            = interface_info->Pipes[i].PipeHandle;      
379
 
          dev->config.interfaces[number].endpoints[i].address = 
380
 
            interface_info->Pipes[i].EndpointAddress;
381
 
        }
382
 
    }
383
 
 
384
 
  return TRUE;
385
 
}
386
 
 
387
 
 
388
 
void remove_lock_initialize(libusb_device_t *dev)
389
 
{
390
 
  KeInitializeEvent(&dev->remove_lock.event, NotificationEvent, FALSE);
391
 
  dev->remove_lock.usage_count = 1;
392
 
  dev->remove_lock.remove_pending = FALSE;
393
 
}
394
 
 
395
 
 
396
 
NTSTATUS remove_lock_acquire(libusb_device_t *dev)
397
 
{
398
 
  InterlockedIncrement(&dev->remove_lock.usage_count);
399
 
 
400
 
  if(dev->remove_lock.remove_pending)
401
 
    {
402
 
      if(InterlockedDecrement(&dev->remove_lock.usage_count) == 0)
403
 
        {
404
 
          KeSetEvent(&dev->remove_lock.event, 0, FALSE);
405
 
        }      
406
 
      return STATUS_DELETE_PENDING;
407
 
    }
408
 
  return STATUS_SUCCESS;
409
 
}
410
 
 
411
 
 
412
 
void remove_lock_release(libusb_device_t *dev)
413
 
{
414
 
  if(InterlockedDecrement(&dev->remove_lock.usage_count) == 0)
415
 
    {
416
 
      KeSetEvent(&dev->remove_lock.event, 0, FALSE);
417
 
    }
418
 
}
419
 
 
420
 
 
421
 
void remove_lock_release_and_wait(libusb_device_t *dev)
422
 
{
423
 
  dev->remove_lock.remove_pending = TRUE;
424
 
  remove_lock_release(dev);
425
 
  remove_lock_release(dev);
426
 
  KeWaitForSingleObject(&dev->remove_lock.event, Executive, KernelMode,
427
 
                        FALSE, NULL);
428
 
}
429
 
 
430
 
 
431
 
USB_INTERFACE_DESCRIPTOR *
432
 
find_interface_desc(USB_CONFIGURATION_DESCRIPTOR *config_desc,
433
 
                    unsigned int size, int interface_number, int altsetting)
434
 
{
435
 
  usb_descriptor_header_t *desc = (usb_descriptor_header_t *)config_desc;
436
 
  char *p = (char *)desc;
437
 
  USB_INTERFACE_DESCRIPTOR *if_desc = NULL;
438
 
 
439
 
  if(!config_desc || (size < config_desc->wTotalLength))
440
 
    return NULL;
441
 
 
442
 
  while(size && desc->length <= size)
443
 
    {
444
 
      if(desc->type == USB_INTERFACE_DESCRIPTOR_TYPE)
445
 
        {
446
 
          if_desc = (USB_INTERFACE_DESCRIPTOR *)desc;
447
 
 
448
 
          if((if_desc->bInterfaceNumber == (UCHAR)interface_number)
449
 
             && (if_desc->bAlternateSetting == (UCHAR)altsetting))
450
 
          {
451
 
            return if_desc;
452
 
          }
453
 
        }
454
 
 
455
 
      size -= desc->length;
456
 
      p += desc->length;
457
 
      desc = (usb_descriptor_header_t *)p;
458
 
    }
459
 
 
460
 
  return NULL;
461
 
}
462