ReactOS  0.4.14-dev-293-g2b39b42
descriptor.c File Reference
#include "usbstor.h"
#include <debug.h>
Include dependency graph for descriptor.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI USBSTOR_GetDescriptor (IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescriptorType, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
 
NTSTATUS USBSTOR_GetDescriptors (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI USBSTOR_ScanConfigurationDescriptor (IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PUSB_INTERFACE_DESCRIPTOR *OutInterfaceDescriptor, OUT PUSB_ENDPOINT_DESCRIPTOR *InEndpointDescriptor, OUT PUSB_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor)
 
VOID DumpConfigurationDescriptor (PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
 
NTSTATUS USBSTOR_SelectConfigurationAndInterface (IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS USBSTOR_GetPipeHandles (IN PFDO_DEVICE_EXTENSION DeviceExtension)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file descriptor.c.

Function Documentation

◆ DumpConfigurationDescriptor()

VOID DumpConfigurationDescriptor ( PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor)

Definition at line 220 of file descriptor.c.

221 {
222  DPRINT1("Dumping ConfigurationDescriptor %p\n", ConfigurationDescriptor);
223  DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
224  DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
225  DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
226  DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
227  DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
228  DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
229  DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
230  DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
231 }
#define DPRINT1
Definition: precomp.h:8

◆ USBSTOR_GetDescriptor()

NTSTATUS NTAPI USBSTOR_GetDescriptor ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  DescriptorType,
IN ULONG  DescriptorLength,
IN UCHAR  DescriptorIndex,
IN LANGID  LanguageId,
OUT PVOID OutDescriptor 
)

Definition at line 18 of file descriptor.c.

25 {
26  PURB Urb;
29 
31  ASSERT(OutDescriptor);
32  ASSERT(DescriptorLength);
33 
34  // first allocate descriptor buffer
35  Descriptor = AllocateItem(NonPagedPool, DescriptorLength);
36  if (!Descriptor)
37  {
38  // no memory
40  }
41 
42  Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB));
43  if (!Urb)
44  {
45  // no memory
48  }
49 
50  // initialize urb
52  sizeof(Urb->UrbControlDescriptorRequest),
54  DescriptorIndex,
55  LanguageId,
56  Descriptor,
57  NULL,
58  DescriptorLength,
59  NULL);
60 
61  // submit urb
63 
64  FreeItem(Urb);
65 
66  if (NT_SUCCESS(Status))
67  {
68  *OutDescriptor = Descriptor;
69  }
70 
71  return Status;
72 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
Definition: usb.h:529
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:107
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:145
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966

Referenced by USBSTOR_GetDescriptors().

◆ USBSTOR_GetDescriptors()

NTSTATUS USBSTOR_GetDescriptors ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 75 of file descriptor.c.

77 {
79  PFDO_DEVICE_EXTENSION DeviceExtension;
80  USHORT DescriptorLength;
81 
83 
84  // first get device descriptor
85  Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
86  if (!NT_SUCCESS(Status))
87  {
88  DeviceExtension->DeviceDescriptor = NULL;
89  return Status;
90  }
91 
92  // now get basic configuration descriptor
93  Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
94  if (!NT_SUCCESS(Status))
95  {
96  FreeItem(DeviceExtension->DeviceDescriptor);
97  DeviceExtension->DeviceDescriptor = NULL;
98  return Status;
99  }
100 
101  // backup length
102  DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
103 
104  // release basic descriptor
105  FreeItem(DeviceExtension->ConfigurationDescriptor);
106  DeviceExtension->ConfigurationDescriptor = NULL;
107 
108  // allocate full descriptor
109  Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
110  if (!NT_SUCCESS(Status))
111  {
112  FreeItem(DeviceExtension->DeviceDescriptor);
113  DeviceExtension->DeviceDescriptor = NULL;
114  return Status;
115  }
116 
117  // check if there is a serial number provided
118  if (DeviceExtension->DeviceDescriptor->iSerialNumber)
119  {
120  // get serial number
121  Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber);
122  if (!NT_SUCCESS(Status))
123  {
124  FreeItem(DeviceExtension->DeviceDescriptor);
125  DeviceExtension->DeviceDescriptor = NULL;
126 
127  FreeItem(DeviceExtension->ConfigurationDescriptor);
128  DeviceExtension->ConfigurationDescriptor = NULL;
129 
130  DeviceExtension->SerialNumber = NULL;
131  return Status;
132  }
133  }
134 
135  return Status;
136 }
LONG NTSTATUS
Definition: precomp.h:26
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
NTSTATUS NTAPI USBSTOR_GetDescriptor(IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescriptorType, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: descriptor.c:18
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned short USHORT
Definition: pedump.c:61

Referenced by USBSTOR_FdoHandleStartDevice().

◆ USBSTOR_GetPipeHandles()

NTSTATUS USBSTOR_GetPipeHandles ( IN PFDO_DEVICE_EXTENSION  DeviceExtension)

Definition at line 319 of file descriptor.c.

321 {
322  ULONG Index;
323  BOOLEAN BulkInFound = FALSE, BulkOutFound = FALSE;
324 
325  // enumerate all pipes and extract bulk-in / bulk-out pipe handle
326  for (Index = 0; Index < DeviceExtension->InterfaceInformation->NumberOfPipes; Index++)
327  {
328  if (DeviceExtension->InterfaceInformation->Pipes[Index].PipeType == UsbdPipeTypeBulk)
329  {
330  if (USB_ENDPOINT_DIRECTION_IN(DeviceExtension->InterfaceInformation->Pipes[Index].EndpointAddress))
331  {
332  DeviceExtension->BulkInPipeIndex = Index;
333 
334  // there should not be another bulk in pipe
335  ASSERT(BulkInFound == FALSE);
336  BulkInFound = TRUE;
337  }
338  else
339  {
340  DeviceExtension->BulkOutPipeIndex = Index;
341 
342  // there should not be another bulk out pipe
343  ASSERT(BulkOutFound == FALSE);
344  BulkOutFound = TRUE;
345  }
346  }
347  }
348 
349  if (!BulkInFound || !BulkOutFound)
350  {
351  // WTF? usb port driver does not give us bulk pipe access
352  DPRINT1("USBSTOR_GetPipeHandles> BulkInFound %c BulkOutFound %c missing!!!\n", BulkInFound, BulkOutFound);
354  }
355 
356  return STATUS_SUCCESS;
357 }
#define TRUE
Definition: types.h:120
#define USB_ENDPOINT_DIRECTION_IN(x)
Definition: usb100.h:76
unsigned char BOOLEAN
static const UCHAR Index[8]
Definition: usbohci.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:605
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by USBSTOR_FdoHandleStartDevice().

◆ USBSTOR_ScanConfigurationDescriptor()

NTSTATUS NTAPI USBSTOR_ScanConfigurationDescriptor ( IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
OUT PUSB_INTERFACE_DESCRIPTOR OutInterfaceDescriptor,
OUT PUSB_ENDPOINT_DESCRIPTOR InEndpointDescriptor,
OUT PUSB_ENDPOINT_DESCRIPTOR OutEndpointDescriptor 
)

Definition at line 140 of file descriptor.c.

145 {
146  PUSB_CONFIGURATION_DESCRIPTOR CurrentDescriptor;
147  PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
148 
149  ASSERT(ConfigurationDescriptor);
150  ASSERT(OutInterfaceDescriptor);
151  ASSERT(InEndpointDescriptor);
152  ASSERT(OutEndpointDescriptor);
153 
154  *OutInterfaceDescriptor = NULL;
155  *InEndpointDescriptor = NULL;
156  *OutEndpointDescriptor = NULL;
157 
158  // start scanning
159  CurrentDescriptor = ConfigurationDescriptor;
160 
161  do
162  {
163  if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
164  {
165  if (*OutInterfaceDescriptor)
166  {
167  // we only process the first interface descriptor as ms does -> see documentation
168  break;
169  }
170 
171  // store interface descriptor
172  *OutInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)CurrentDescriptor;
173  }
174  else if (CurrentDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
175  {
176  EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CurrentDescriptor;
177 
178  ASSERT(*OutInterfaceDescriptor);
179 
180  // get endpoint type
181  if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK)
182  {
183  if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress))
184  {
185  *InEndpointDescriptor = EndpointDescriptor;
186  }
187  else
188  {
189  *OutEndpointDescriptor = EndpointDescriptor;
190  }
191  }
192  else if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT)
193  {
195  }
196  }
197 
198  // move to next descriptor
199  CurrentDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)CurrentDescriptor + CurrentDescriptor->bLength);
200 
201  // was it the last descriptor
202  if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
203  {
204  break;
205  }
206 
207  } while(TRUE);
208 
209  // check if everything has been found
210  if (*OutInterfaceDescriptor == NULL || *InEndpointDescriptor == NULL || *OutEndpointDescriptor == NULL)
211  {
212  DPRINT1("USBSTOR_ScanConfigurationDescriptor: Failed to find InterfaceDescriptor %p InEndpointDescriptor %p OutEndpointDescriptor %p\n", *OutInterfaceDescriptor, *InEndpointDescriptor, *OutEndpointDescriptor);
213  return STATUS_UNSUCCESSFUL;
214  }
215 
216  return STATUS_SUCCESS;
217 }
#define TRUE
Definition: types.h:120
#define USB_ENDPOINT_DIRECTION_IN(x)
Definition: usb100.h:76
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _USB_CONFIGURATION_DESCRIPTOR * PUSB_CONFIGURATION_DESCRIPTOR
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
smooth NULL
Definition: ftsmooth.c:416
struct _USB_ENDPOINT_DESCRIPTOR * PUSB_ENDPOINT_DESCRIPTOR
#define USB_ENDPOINT_TYPE_MASK
Definition: usb100.h:61
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usb100.h:53
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define USB_ENDPOINT_TYPE_INTERRUPT
Definition: usb100.h:65

Referenced by USBSTOR_SelectConfigurationAndInterface().

◆ USBSTOR_SelectConfigurationAndInterface()

NTSTATUS USBSTOR_SelectConfigurationAndInterface ( IN PDEVICE_OBJECT  DeviceObject,
IN PFDO_DEVICE_EXTENSION  DeviceExtension 
)

Definition at line 234 of file descriptor.c.

237 {
238  PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
239  PUSB_ENDPOINT_DESCRIPTOR InEndpointDescriptor, OutEndpointDescriptor;
241  PURB Urb;
243 
244  Status = USBSTOR_ScanConfigurationDescriptor(DeviceExtension->ConfigurationDescriptor, &InterfaceDescriptor, &InEndpointDescriptor, &OutEndpointDescriptor);
245  if (!NT_SUCCESS(Status))
246  {
247  return Status;
248  }
249 
250  // now allocate one interface entry and terminating null entry
252  if (!InterfaceList)
253  {
255  }
256 
257  // initialize interface list entry
258  InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor;
259 
260  // now allocate the urb
261  Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, InterfaceList);
262  if (!Urb)
263  {
266  }
267 
268 
270 
271  // submit urb
272  Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
273  if (!NT_SUCCESS(Status))
274  {
275  // failed to set configuration
276  DPRINT1("USBSTOR_SelectConfiguration failed to set interface %x\n", Status);
278  ExFreePoolWithTag(Urb, 0);
279  return Status;
280  }
281 
282  // backup interface information
283  DeviceExtension->InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)AllocateItem(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length);
284  if (!DeviceExtension->InterfaceInformation)
285  {
287  ExFreePoolWithTag(Urb, 0);
289  }
290 
291  // copy interface information
292  RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
293 
294  // store pipe handle
295  DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
296 
297  // now prepare interface urb
298  UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting);
299 
300  // copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ
301  RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInformation, DeviceExtension->InterfaceInformation->Length);
302 
303  // now select the interface
304  Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
305  if (NT_SUCCESS(Status))
306  {
307  // update configuration info
308  ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInformation->Length);
309  RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
310  }
311 
313  ExFreePoolWithTag(Urb, 0);
314 
315  return Status;
316 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _USBD_INTERFACE_LIST_ENTRY * PUSBD_INTERFACE_LIST_ENTRY
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:168
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:104
struct _USBD_INTERFACE_INFORMATION * PUSBD_INTERFACE_INFORMATION
Definition: usbdlib.h:7
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
NTSTATUS NTAPI USBSTOR_ScanConfigurationDescriptor(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PUSB_INTERFACE_DESCRIPTOR *OutInterfaceDescriptor, OUT PUSB_ENDPOINT_DESCRIPTOR *InEndpointDescriptor, OUT PUSB_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor)
Definition: descriptor.c:140
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbdlib.h:8
Definition: usb.h:529
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:107
#define DPRINT1
Definition: precomp.h:8
#define UsbBuildSelectInterfaceRequest(urb, length, configurationHandle, interfaceNumber, alternateSetting)
Definition: usbdlib.h:59
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PURB NTAPI USBD_CreateConfigurationRequestEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSBD_INTERFACE_LIST_ENTRY InterfaceList)
Definition: usbd.c:329
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532

Referenced by USBSTOR_FdoHandleStartDevice().