[2/2] usbd.sys: implement usbd.sys

Damjan Jovanovic damjan.jov at gmail.com
Sat Mar 13 06:40:04 CST 2010


Changelog:
* usbd.sys: implement usbd.sys

This allows Blackberry's RimUsb.sys to load and start successfully.

The patch is based on Alexandre Morozov's USB patches with several
more functions written by me, and copyright is thus assigned to both
of us.

Damjan Jovanovic

P.S. General status of the USB patches:

 configure.ac                        |   24 +
 dlls/mountmgr.sys/device.c          |   17 +-
 dlls/mountmgr.sys/mountmgr.c        |   74 ++-
 dlls/ntoskrnl.exe/Makefile.in       |    2 +-
 dlls/ntoskrnl.exe/ntoskrnl.c        | 1525
++++++++++++++++++++++++++++++++-- IoIsWdmVersionAvailable PENDING
 dlls/ntoskrnl.exe/ntoskrnl.exe.spec |   67 +-
 dlls/usbd.sys/Makefile.in           |   15 + PATCH PENDING
 dlls/usbd.sys/usbd.c                |  145 ++++ PATCH PENDING
 dlls/usbd.sys/usbd.sys.spec         |   35 + PATCH PENDING
 dlls/usbhub.sys/Makefile.in         |   16 +
 dlls/usbhub.sys/usbhub.c            | 1581 +++++++++++++++++++++++++++++++++++
 dlls/usbhub.sys/usbhub.sys.spec     |    1 +
 include/cfgmgr32.h                  |    1 + ACCEPTED INTO WINE
 include/ddk/ntddk.h                 |   11 +
 include/ddk/usb.h                   |    6 + ACCEPTED INTO WINE
 include/ddk/usb100.h                |   10 +
 include/ddk/usbdrivr.h              |   28 +
 include/ddk/usbioctl.h              |   90 ++
 include/ddk/usbiodef.h              |   33 +
 include/ddk/wdm.h                   |   81 ++-
 include/ddk/wdmguid.h               |   28 +
 programs/services/services.c        |   21 +
 programs/winedevice/device.c        |  302 ++++++-
 server/device.c                     |   25 +
 server/protocol.def                 |    9 +
 tools/wine.inf.in                   |    9 +
-------------- next part --------------
diff --git a/dlls/usbd.sys/Makefile.in b/dlls/usbd.sys/Makefile.in
new file mode 100644
index 0000000..f745ffb
--- /dev/null
+++ b/dlls/usbd.sys/Makefile.in
@@ -0,0 +1,15 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = usbd.sys
+IMPORTLIB = usbd.sys
+IMPORTS   = kernel32 ntoskrnl.exe
+EXTRADLLFLAGS = -Wb,--subsystem,native
+
+C_SRCS = \
+	usbd.c
+
+ at MAKE_DLL_RULES@
+
+ at DEPENDENCIES@  # everything below this line is overwritten by make depend
diff --git a/dlls/usbd.sys/usbd.c b/dlls/usbd.sys/usbd.c
new file mode 100644
index 0000000..49102d0
--- /dev/null
+++ b/dlls/usbd.sys/usbd.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2010 Damjan Jovanovic
+ * Copyright (C) 2009 Alexander Morozov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "ddk/wdm.h"
+#include "ddk/usb.h"
+#include "ddk/usbdlib.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(usbd);
+
+PURB WINAPI USBD_CreateConfigurationRequestEx(
+        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+        PUSBD_INTERFACE_LIST_ENTRY InterfaceList )
+{
+    URB *urb;
+    UCHAR k, num_interfaces = 0;
+    SIZE_T size;
+    struct _URB_SELECT_CONFIGURATION *sel_conf;
+    USBD_INTERFACE_INFORMATION *if_info;
+    USB_INTERFACE_DESCRIPTOR *if_desc;
+    USBD_INTERFACE_LIST_ENTRY *entry;
+
+    TRACE( "%p, %p\n", ConfigurationDescriptor, InterfaceList );
+
+    entry = InterfaceList;
+    size = sizeof(struct _URB_SELECT_CONFIGURATION);
+    while (entry->InterfaceDescriptor)
+    {
+        size += (entry->InterfaceDescriptor->bNumEndpoints - 1) *
+                sizeof(USBD_PIPE_INFORMATION);
+        ++num_interfaces;
+        ++entry;
+    }
+    size += (num_interfaces - 1) * sizeof(USBD_INTERFACE_INFORMATION);
+
+    urb = ExAllocatePool( NonPagedPool, size );
+    RtlZeroMemory( urb, size );
+
+    sel_conf = &urb->u.UrbSelectConfiguration;
+    sel_conf->Hdr.Length = size;
+    sel_conf->Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
+    sel_conf->ConfigurationDescriptor = ConfigurationDescriptor;
+
+    entry = InterfaceList;
+    if_info = &sel_conf->Interface;
+    while (entry->InterfaceDescriptor)
+    {
+        if_desc = entry->InterfaceDescriptor;
+        entry->Interface = if_info;
+        if_info->InterfaceNumber = if_desc->bInterfaceNumber;
+        if_info->NumberOfPipes = if_desc->bNumEndpoints;
+        for (k = 0; k < if_info->NumberOfPipes; ++k)
+            if_info->Pipes[k].MaximumTransferSize = 4096;
+        if_info->Length = sizeof(USBD_INTERFACE_INFORMATION) +
+                (k - 1) * sizeof(USBD_PIPE_INFORMATION);
+        if_info = (USBD_INTERFACE_INFORMATION *)((char *)if_info +
+                if_info->Length);
+        ++entry;
+    }
+
+    return urb;
+}
+
+PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(
+        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+        PVOID StartPosition, LONG InterfaceNumber,
+        LONG AlternateSetting, LONG InterfaceClass,
+        LONG InterfaceSubClass, LONG InterfaceProtocol )
+{
+    int i;
+    char *p = (char*)(ConfigurationDescriptor + 1);
+
+    TRACE( "%p, %p, %d, %d, %d, %d, %d\n", ConfigurationDescriptor,
+            StartPosition, InterfaceNumber, AlternateSetting,
+            InterfaceClass, InterfaceSubClass, InterfaceProtocol );
+
+    for (i = 0; i < ConfigurationDescriptor->bNumInterfaces; i++)
+    {
+        PUSB_COMMON_DESCRIPTOR common;
+        PUSB_INTERFACE_DESCRIPTOR interface;
+        do
+        {
+            common = (PUSB_COMMON_DESCRIPTOR) p;
+            p += common->bLength;
+        } while (common->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE);
+        interface = (PUSB_INTERFACE_DESCRIPTOR) common;
+        if (StartPosition <= (PVOID) interface &&
+            (InterfaceNumber == -1 || interface->bInterfaceNumber == InterfaceNumber) &&
+            (AlternateSetting == -1 || interface->bAlternateSetting == AlternateSetting) &&
+            (InterfaceClass == -1 || interface->bInterfaceClass == InterfaceClass) &&
+            (InterfaceSubClass == -1 || interface->bInterfaceSubClass == InterfaceSubClass) &&
+            (InterfaceProtocol == -1 || interface->bInterfaceProtocol == InterfaceProtocol))
+        {
+            return interface;
+        }
+    }
+    return NULL;
+}
+
+PURB WINAPI USBD_CreateConfigurationRequest(
+        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSHORT Siz )
+{
+    USBD_INTERFACE_LIST_ENTRY *uile;
+    USB_INTERFACE_DESCRIPTOR *if_desc, *max;
+    ULONG uile_size, k = 0;
+    URB *urb;
+
+    TRACE( "%p, %p\n", ConfigurationDescriptor, Siz );
+
+    uile_size = (ConfigurationDescriptor->bNumInterfaces + 1) *
+            sizeof(USBD_INTERFACE_LIST_ENTRY);
+    uile = ExAllocatePool( NonPagedPool, uile_size );
+    if (NULL == uile)
+        return NULL;
+    RtlZeroMemory( uile, uile_size );
+
+    if_desc = (USB_INTERFACE_DESCRIPTOR *)(ConfigurationDescriptor + 1);
+    max = (USB_INTERFACE_DESCRIPTOR *)((char *)ConfigurationDescriptor +
+            ConfigurationDescriptor->wTotalLength);
+    while (if_desc < max && k < ConfigurationDescriptor->bNumInterfaces)
+    {
+        if (USB_INTERFACE_DESCRIPTOR_TYPE == if_desc->bDescriptorType)
+            uile[k++].InterfaceDescriptor = if_desc;
+        if_desc = (USB_INTERFACE_DESCRIPTOR *)((char *)if_desc +
+                if_desc->bLength);
+    }
+
+    urb = USBD_CreateConfigurationRequestEx( ConfigurationDescriptor, uile );
+    *Siz = (NULL == urb) ? 0 : urb->u.UrbSelectConfiguration.Hdr.Length;
+
+    ExFreePool( uile );
+
+    return urb;
+}
+
+ULONG WINAPI USBD_GetInterfaceLength(
+        PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
+        PUCHAR BufferEnd)
+{
+    PUSB_COMMON_DESCRIPTOR common;
+    ULONG total = InterfaceDescriptor->bLength;
+
+    TRACE( "%p, %p\n", InterfaceDescriptor, BufferEnd );
+
+    for (common = (PUSB_COMMON_DESCRIPTOR)(InterfaceDescriptor + 1);
+         (((PUCHAR)common) + sizeof(USB_COMMON_DESCRIPTOR)) <= BufferEnd &&
+             common->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE;
+         common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
+    {
+        total += common->bLength;
+    }
+    return total;
+}
+
+void WINAPI USBD_GetUSBDIVersion( PUSBD_VERSION_INFORMATION VersionInformation )
+{
+    TRACE( "%p\n", VersionInformation );
+    VersionInformation->USBDI_Version = 0x300;
+    VersionInformation->Supported_USB_Version = 0x100;
+}
+
+PUSB_COMMON_DESCRIPTOR WINAPI USBD_ParseDescriptors(
+        PVOID DescriptorBuffer,
+        ULONG TotalLength,
+        PVOID StartPosition,
+        LONG DescriptorType)
+{
+    PUSB_COMMON_DESCRIPTOR common;
+
+    TRACE( "%p, %u, %p, %d\n", DescriptorBuffer, TotalLength, StartPosition, DescriptorType );
+
+    for (common = (PUSB_COMMON_DESCRIPTOR)DescriptorBuffer;
+         ((char*)common) + sizeof(USB_COMMON_DESCRIPTOR) <= ((char*)DescriptorBuffer) + TotalLength;
+         common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
+    {
+        if (StartPosition <= (PVOID)common && common->bDescriptorType == DescriptorType)
+            return common;
+    }
+    return NULL;
+}
+
+NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
+{
+    return STATUS_SUCCESS;
+}
diff --git a/dlls/usbd.sys/usbd.sys.spec b/dlls/usbd.sys/usbd.sys.spec
new file mode 100644
index 0000000..0784894
--- /dev/null
+++ b/dlls/usbd.sys/usbd.sys.spec
@@ -0,0 +1,35 @@
+@ stdcall USBD_CreateConfigurationRequestEx(ptr ptr)
+@ stdcall USBD_ParseConfigurationDescriptorEx(ptr ptr)
+@ stdcall USBD_ParseDescriptors(ptr long ptr long)
+@ stub DllInitialize
+@ stub DllUnload
+@ stub USBD_AllocateDeviceName
+@ stub USBD_CalculateUsbBandwidth
+@ stub USBD_CompleteRequest
+@ stdcall USBD_CreateConfigurationRequest(ptr ptr)
+@ stdcall _USBD_CreateConfigurationRequestEx at 8(ptr ptr) USBD_CreateConfigurationRequestEx
+@ stub USBD_CreateDevice
+@ stub USBD_Debug_GetHeap
+@ stub USBD_Debug_LogEntry
+@ stub USBD_Debug_RetHeap
+@ stub USBD_Dispatch
+@ stub USBD_FreeDeviceMutex
+@ stub USBD_FreeDeviceName
+@ stub USBD_GetDeviceInformation
+@ stdcall USBD_GetInterfaceLength(ptr ptr)
+@ stub USBD_GetPdoRegistryParameter
+@ stub USBD_GetSuspendPowerState
+@ stdcall USBD_GetUSBDIVersion(ptr)
+@ stub USBD_InitializeDevice
+@ stub USBD_MakePdoName
+@ stub USBD_ParseConfigurationDescriptor
+@ stdcall _USBD_ParseConfigurationDescriptorEx at 28(ptr ptr long long long long long) USBD_ParseConfigurationDescriptorEx
+@ stdcall _USBD_ParseDescriptors at 16(ptr long ptr long) USBD_ParseDescriptors
+@ stub USBD_QueryBusTime
+@ stub USBD_RegisterHcDeviceCapabilities
+@ stub USBD_RegisterHcFilter
+@ stub USBD_RegisterHostController
+@ stub USBD_RemoveDevice
+@ stub USBD_RestoreDevice
+@ stub USBD_SetSuspendPowerState
+@ stub USBD_WaitDeviceMutex


More information about the wine-patches mailing list