~ubuntu-branches/ubuntu/natty/wine1.3/natty

« back to all changes in this revision

Viewing changes to dlls/usbd.sys/usbd.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Ritchie
  • Date: 2011-03-09 05:50:55 UTC
  • Revision ID: james.westby@ubuntu.com-20110309055055-oc6dml4hruy8wa4r
Tags: upstream-1.3.15
ImportĀ upstreamĀ versionĀ 1.3.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Damjan Jovanovic
 
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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 
17
 */
 
18
 
 
19
#include <stdarg.h>
 
20
 
 
21
#define NONAMELESSUNION
 
22
#define NONAMELESSSTRUCT
 
23
 
 
24
#include "ntstatus.h"
 
25
#define WIN32_NO_STATUS
 
26
#include "windef.h"
 
27
#include "winbase.h"
 
28
#include "winternl.h"
 
29
#include "ddk/wdm.h"
 
30
#include "ddk/usb.h"
 
31
#include "ddk/usbdlib.h"
 
32
#include "wine/debug.h"
 
33
 
 
34
WINE_DEFAULT_DEBUG_CHANNEL(usbd);
 
35
 
 
36
PURB WINAPI USBD_CreateConfigurationRequest(
 
37
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSHORT Siz )
 
38
{
 
39
    URB *urb = NULL;
 
40
    USBD_INTERFACE_LIST_ENTRY *interfaceList;
 
41
    ULONG interfaceListSize;
 
42
    USB_INTERFACE_DESCRIPTOR *interfaceDesc;
 
43
    int i;
 
44
 
 
45
    TRACE( "(%p, %p)\n", ConfigurationDescriptor, Siz );
 
46
 
 
47
    /* http://www.microsoft.com/whdc/archive/usbfaq.mspx
 
48
     * claims USBD_CreateConfigurationRequest doesn't support > 1 interface,
 
49
     * but is this on Windows 98 only or all versions?
 
50
     */
 
51
 
 
52
    *Siz = 0;
 
53
    interfaceListSize = (ConfigurationDescriptor->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY);
 
54
    interfaceList = ExAllocatePool( NonPagedPool, interfaceListSize );
 
55
    if (interfaceList)
 
56
    {
 
57
        RtlZeroMemory( interfaceList,  interfaceListSize );
 
58
        interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
 
59
            ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
 
60
            ConfigurationDescriptor, USB_INTERFACE_DESCRIPTOR_TYPE );
 
61
        for (i = 0; i < ConfigurationDescriptor->bNumInterfaces && interfaceDesc != NULL; i++)
 
62
        {
 
63
            interfaceList[i].InterfaceDescriptor = interfaceDesc;
 
64
            interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
 
65
                ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
 
66
                interfaceDesc + 1, USB_INTERFACE_DESCRIPTOR_TYPE );
 
67
        }
 
68
        urb = USBD_CreateConfigurationRequestEx( ConfigurationDescriptor, interfaceList );
 
69
        if (urb)
 
70
            *Siz = urb->u.UrbHeader.Length;
 
71
        ExFreePool( interfaceList );
 
72
    }
 
73
    return urb;
 
74
}
 
75
 
 
76
PURB WINAPI USBD_CreateConfigurationRequestEx(
 
77
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
 
78
        PUSBD_INTERFACE_LIST_ENTRY InterfaceList )
 
79
{
 
80
    URB *urb;
 
81
    ULONG size = 0;
 
82
    USBD_INTERFACE_LIST_ENTRY *interfaceEntry;
 
83
    ULONG interfaceCount = 0;
 
84
 
 
85
    TRACE( "(%p, %p)\n", ConfigurationDescriptor, InterfaceList );
 
86
 
 
87
    size = sizeof(struct _URB_SELECT_CONFIGURATION);
 
88
    for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
 
89
    {
 
90
        ++interfaceCount;
 
91
        size += (interfaceEntry->InterfaceDescriptor->bNumEndpoints - 1) *
 
92
            sizeof(USBD_PIPE_INFORMATION);
 
93
    }
 
94
    size += (interfaceCount - 1) * sizeof(USBD_INTERFACE_INFORMATION);
 
95
 
 
96
    urb = ExAllocatePool( NonPagedPool, size );
 
97
    if (urb)
 
98
    {
 
99
        USBD_INTERFACE_INFORMATION *interfaceInfo;
 
100
 
 
101
        RtlZeroMemory( urb, size );
 
102
        urb->u.UrbSelectConfiguration.Hdr.Length = size;
 
103
        urb->u.UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
 
104
        urb->u.UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor;
 
105
        interfaceInfo = &urb->u.UrbSelectConfiguration.Interface;
 
106
        for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
 
107
        {
 
108
            int i;
 
109
            USB_INTERFACE_DESCRIPTOR *currentInterface;
 
110
            USB_ENDPOINT_DESCRIPTOR *endpointDescriptor;
 
111
            interfaceInfo->InterfaceNumber = interfaceEntry->InterfaceDescriptor->bInterfaceNumber;
 
112
            interfaceInfo->AlternateSetting = interfaceEntry->InterfaceDescriptor->bAlternateSetting;
 
113
            interfaceInfo->Class = interfaceEntry->InterfaceDescriptor->bInterfaceClass;
 
114
            interfaceInfo->SubClass = interfaceEntry->InterfaceDescriptor->bInterfaceSubClass;
 
115
            interfaceInfo->Protocol = interfaceEntry->InterfaceDescriptor->bInterfaceProtocol;
 
116
            interfaceInfo->NumberOfPipes = interfaceEntry->InterfaceDescriptor->bNumEndpoints;
 
117
            currentInterface = USBD_ParseConfigurationDescriptorEx(
 
118
                ConfigurationDescriptor, ConfigurationDescriptor,
 
119
                interfaceEntry->InterfaceDescriptor->bInterfaceNumber, -1, -1, -1, -1 );
 
120
            endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
 
121
                ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
 
122
                currentInterface, USB_ENDPOINT_DESCRIPTOR_TYPE );
 
123
            for (i = 0; i < interfaceInfo->NumberOfPipes && endpointDescriptor; i++)
 
124
            {
 
125
                interfaceInfo->Pipes[i].MaximumPacketSize = endpointDescriptor->wMaxPacketSize;
 
126
                interfaceInfo->Pipes[i].EndpointAddress = endpointDescriptor->bEndpointAddress;
 
127
                interfaceInfo->Pipes[i].Interval = endpointDescriptor->bInterval;
 
128
                switch (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
 
129
                {
 
130
                case USB_ENDPOINT_TYPE_CONTROL:
 
131
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeControl;
 
132
                    break;
 
133
                case USB_ENDPOINT_TYPE_BULK:
 
134
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeBulk;
 
135
                    break;
 
136
                case USB_ENDPOINT_TYPE_INTERRUPT:
 
137
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeInterrupt;
 
138
                    break;
 
139
                case USB_ENDPOINT_TYPE_ISOCHRONOUS:
 
140
                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeIsochronous;
 
141
                    break;
 
142
                }
 
143
                endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
 
144
                    ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
 
145
                    endpointDescriptor + 1, USB_ENDPOINT_DESCRIPTOR_TYPE );
 
146
            }
 
147
            interfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION) +
 
148
                (i - 1) * sizeof(USBD_PIPE_INFORMATION);
 
149
            interfaceEntry->Interface = interfaceInfo;
 
150
            interfaceInfo = (USBD_INTERFACE_INFORMATION*)(((char*)interfaceInfo)+interfaceInfo->Length);
 
151
        }
 
152
    }
 
153
    return urb;
 
154
}
 
155
 
 
156
VOID WINAPI USBD_GetUSBDIVersion(
 
157
        PUSBD_VERSION_INFORMATION VersionInformation )
 
158
{
 
159
    TRACE( "(%p)\n", VersionInformation );
 
160
    /* Emulate Windows 2000 (= 0x300) for now */
 
161
    VersionInformation->USBDI_Version = 0x300;
 
162
    VersionInformation->Supported_USB_Version = 0x200;
 
163
}
 
164
 
 
165
PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(
 
166
        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
 
167
        PVOID StartPosition, LONG InterfaceNumber,
 
168
        LONG AlternateSetting, LONG InterfaceClass,
 
169
        LONG InterfaceSubClass, LONG InterfaceProtocol )
 
170
{
 
171
    /* http://blogs.msdn.com/usbcoreblog/archive/2009/12/12/
 
172
     *        what-is-the-right-way-to-validate-and-parse-configuration-descriptors.aspx
 
173
     */
 
174
 
 
175
    PUSB_INTERFACE_DESCRIPTOR interface;
 
176
 
 
177
    TRACE( "(%p, %p, %d, %d, %d, %d, %d)\n", ConfigurationDescriptor,
 
178
            StartPosition, InterfaceNumber, AlternateSetting,
 
179
            InterfaceClass, InterfaceSubClass, InterfaceProtocol );
 
180
 
 
181
    interface = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
 
182
        ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
 
183
        StartPosition, USB_INTERFACE_DESCRIPTOR_TYPE );
 
184
    while (interface != NULL)
 
185
    {
 
186
        if ((InterfaceNumber == -1 || interface->bInterfaceNumber == InterfaceNumber) &&
 
187
            (AlternateSetting == -1 || interface->bAlternateSetting == AlternateSetting) &&
 
188
            (InterfaceClass == -1 || interface->bInterfaceClass == InterfaceClass) &&
 
189
            (InterfaceSubClass == -1 || interface->bInterfaceSubClass == InterfaceSubClass) &&
 
190
            (InterfaceProtocol == -1 || interface->bInterfaceProtocol == InterfaceProtocol))
 
191
        {
 
192
            return interface;
 
193
        }
 
194
        interface = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
 
195
            ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
 
196
            interface + 1, USB_INTERFACE_DESCRIPTOR_TYPE );
 
197
    }
 
198
    return NULL;
 
199
}
 
200
 
 
201
PUSB_COMMON_DESCRIPTOR WINAPI USBD_ParseDescriptors(
 
202
        PVOID DescriptorBuffer,
 
203
        ULONG TotalLength,
 
204
        PVOID StartPosition,
 
205
        LONG DescriptorType )
 
206
{
 
207
    PUSB_COMMON_DESCRIPTOR common;
 
208
 
 
209
    TRACE( "(%p, %u, %p, %d)\n", DescriptorBuffer, TotalLength, StartPosition, DescriptorType );
 
210
 
 
211
    for (common = (PUSB_COMMON_DESCRIPTOR)DescriptorBuffer;
 
212
         ((char*)common) + sizeof(USB_COMMON_DESCRIPTOR) <= ((char*)DescriptorBuffer) + TotalLength;
 
213
         common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
 
214
    {
 
215
        if (StartPosition <= (PVOID)common && common->bDescriptorType == DescriptorType)
 
216
            return common;
 
217
    }
 
218
    return NULL;
 
219
}
 
220
 
 
221
ULONG WINAPI USBD_GetInterfaceLength(
 
222
        PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
 
223
        PUCHAR BufferEnd )
 
224
{
 
225
    PUSB_COMMON_DESCRIPTOR common;
 
226
    ULONG total = InterfaceDescriptor->bLength;
 
227
 
 
228
    TRACE( "(%p, %p)\n", InterfaceDescriptor, BufferEnd );
 
229
 
 
230
    for (common = (PUSB_COMMON_DESCRIPTOR)(InterfaceDescriptor + 1);
 
231
         (((PUCHAR)common) + sizeof(USB_COMMON_DESCRIPTOR)) <= BufferEnd &&
 
232
             common->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE;
 
233
         common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
 
234
    {
 
235
        total += common->bLength;
 
236
    }
 
237
    return total;
 
238
}
 
239
 
 
240
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
 
241
{
 
242
    TRACE( "(%p, %s)\n", driver, debugstr_w(path->Buffer) );
 
243
    return STATUS_SUCCESS;
 
244
}