Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
b0c2e5c6
Commit
b0c2e5c6
authored
Apr 15, 2020
by
Zebediah Figura
Committed by
Alexandre Julliard
Apr 16, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineusb.sys: Create USB devices.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
eb8cb9e0
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
161 additions
and
1 deletion
+161
-1
wineusb.c
dlls/wineusb.sys/wineusb.c
+159
-1
usbioctl.h
include/ddk/usbioctl.h
+2
-0
No files found.
dlls/wineusb.sys/wineusb.c
View file @
b0c2e5c6
...
...
@@ -38,11 +38,115 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
wineusb
);
#define DECLARE_CRITICAL_SECTION(cs) \
static CRITICAL_SECTION cs; \
static CRITICAL_SECTION_DEBUG cs##_debug = \
{ 0, 0, &cs, { &cs##_debug.ProcessLocksList, &cs##_debug.ProcessLocksList }, \
0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \
static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 };
DECLARE_CRITICAL_SECTION
(
wineusb_cs
);
static
struct
list
device_list
=
LIST_INIT
(
device_list
);
struct
usb_device
{
struct
list
entry
;
DEVICE_OBJECT
*
device_obj
;
libusb_device
*
libusb_device
;
libusb_device_handle
*
handle
;
};
static
DRIVER_OBJECT
*
driver_obj
;
static
DEVICE_OBJECT
*
bus_fdo
,
*
bus_pdo
;
static
libusb_hotplug_callback_handle
hotplug_cb_handle
;
static
void
add_usb_device
(
libusb_device
*
libusb_device
)
{
static
const
WCHAR
formatW
[]
=
{
'\\'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
'\\'
,
'U'
,
'S'
,
'B'
,
'P'
,
'D'
,
'O'
,
'-'
,
'%'
,
'u'
,
0
};
struct
libusb_device_descriptor
device_desc
;
static
unsigned
int
name_index
;
libusb_device_handle
*
handle
;
struct
usb_device
*
device
;
DEVICE_OBJECT
*
device_obj
;
UNICODE_STRING
string
;
NTSTATUS
status
;
WCHAR
name
[
20
];
int
ret
;
libusb_get_device_descriptor
(
libusb_device
,
&
device_desc
);
TRACE
(
"Adding new device %p, vendor %04x, product %04x.
\n
"
,
libusb_device
,
device_desc
.
idVendor
,
device_desc
.
idProduct
);
if
((
ret
=
libusb_open
(
libusb_device
,
&
handle
)))
{
WARN
(
"Failed to open device: %s
\n
"
,
libusb_strerror
(
ret
));
return
;
}
sprintfW
(
name
,
formatW
,
name_index
++
);
RtlInitUnicodeString
(
&
string
,
name
);
if
((
status
=
IoCreateDevice
(
driver_obj
,
sizeof
(
*
device
),
&
string
,
FILE_DEVICE_USB
,
0
,
FALSE
,
&
device_obj
)))
{
ERR
(
"Failed to create device, status %#x.
\n
"
,
status
);
LeaveCriticalSection
(
&
wineusb_cs
);
libusb_close
(
handle
);
return
;
}
device
=
device_obj
->
DeviceExtension
;
device
->
device_obj
=
device_obj
;
device
->
libusb_device
=
libusb_ref_device
(
libusb_device
);
device
->
handle
=
handle
;
EnterCriticalSection
(
&
wineusb_cs
);
list_add_tail
(
&
device_list
,
&
device
->
entry
);
LeaveCriticalSection
(
&
wineusb_cs
);
IoInvalidateDeviceRelations
(
bus_pdo
,
BusRelations
);
}
static
void
remove_usb_device
(
libusb_device
*
libusb_device
)
{
struct
usb_device
*
device
;
TRACE
(
"Removing device %p.
\n
"
,
libusb_device
);
EnterCriticalSection
(
&
wineusb_cs
);
LIST_FOR_EACH_ENTRY
(
device
,
&
device_list
,
struct
usb_device
,
entry
)
{
if
(
device
->
libusb_device
==
libusb_device
)
{
libusb_unref_device
(
device
->
libusb_device
);
libusb_close
(
device
->
handle
);
list_remove
(
&
device
->
entry
);
IoInvalidateDeviceRelations
(
bus_pdo
,
BusRelations
);
IoDeleteDevice
(
device
->
device_obj
);
break
;
}
}
LeaveCriticalSection
(
&
wineusb_cs
);
}
static
BOOL
thread_shutdown
;
static
HANDLE
event_thread
;
static
int
LIBUSB_CALL
hotplug_cb
(
libusb_context
*
context
,
libusb_device
*
device
,
libusb_hotplug_event
event
,
void
*
user_data
)
{
if
(
event
==
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED
)
add_usb_device
(
device
);
else
remove_usb_device
(
device
);
return
0
;
}
static
DWORD
CALLBACK
event_thread_proc
(
void
*
arg
)
{
int
ret
;
...
...
@@ -69,22 +173,49 @@ static NTSTATUS fdo_pnp(IRP *irp)
switch
(
stack
->
MinorFunction
)
{
case
IRP_MN_START_DEVICE
:
if
((
ret
=
libusb_hotplug_register_callback
(
NULL
,
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED
|
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT
,
LIBUSB_HOTPLUG_ENUMERATE
,
LIBUSB_HOTPLUG_MATCH_ANY
,
LIBUSB_HOTPLUG_MATCH_ANY
,
LIBUSB_HOTPLUG_MATCH_ANY
,
hotplug_cb
,
NULL
,
&
hotplug_cb_handle
)))
{
ERR
(
"Failed to register callback: %s
\n
"
,
libusb_strerror
(
ret
));
irp
->
IoStatus
.
Status
=
STATUS_UNSUCCESSFUL
;
break
;
}
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
break
;
case
IRP_MN_SURPRISE_REMOVAL
:
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
break
;
case
IRP_MN_REMOVE_DEVICE
:
{
struct
usb_device
*
device
,
*
cursor
;
libusb_hotplug_deregister_callback
(
NULL
,
hotplug_cb_handle
);
thread_shutdown
=
TRUE
;
libusb_interrupt_event_handler
(
NULL
);
WaitForSingleObject
(
event_thread
,
INFINITE
);
CloseHandle
(
event_thread
);
EnterCriticalSection
(
&
wineusb_cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
device
,
cursor
,
&
device_list
,
struct
usb_device
,
entry
)
{
libusb_unref_device
(
device
->
libusb_device
);
libusb_close
(
device
->
handle
);
list_remove
(
&
device
->
entry
);
IoDeleteDevice
(
device
->
device_obj
);
}
LeaveCriticalSection
(
&
wineusb_cs
);
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
IoSkipCurrentIrpStackLocation
(
irp
);
ret
=
IoCallDriver
(
bus_pdo
,
irp
);
IoDetachDevice
(
bus_pdo
);
IoDeleteDevice
(
bus_fdo
);
return
ret
;
}
default:
FIXME
(
"Unhandled minor function %#x.
\n
"
,
stack
->
MinorFunction
);
...
...
@@ -94,9 +225,34 @@ static NTSTATUS fdo_pnp(IRP *irp)
return
IoCallDriver
(
bus_pdo
,
irp
);
}
static
NTSTATUS
pdo_pnp
(
DEVICE_OBJECT
*
device_obj
,
IRP
*
irp
)
{
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
NTSTATUS
ret
=
irp
->
IoStatus
.
Status
;
TRACE
(
"device_obj %p, irp %p, minor function %#x.
\n
"
,
device_obj
,
irp
,
stack
->
MinorFunction
);
switch
(
stack
->
MinorFunction
)
{
case
IRP_MN_START_DEVICE
:
case
IRP_MN_QUERY_CAPABILITIES
:
ret
=
STATUS_SUCCESS
;
break
;
default:
FIXME
(
"Unhandled minor function %#x.
\n
"
,
stack
->
MinorFunction
);
}
irp
->
IoStatus
.
Status
=
ret
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
return
ret
;
}
static
NTSTATUS
WINAPI
driver_pnp
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
return
fdo_pnp
(
irp
);
if
(
device
==
bus_fdo
)
return
fdo_pnp
(
irp
);
return
pdo_pnp
(
device
,
irp
);
}
static
NTSTATUS
WINAPI
driver_add_device
(
DRIVER_OBJECT
*
driver
,
DEVICE_OBJECT
*
pdo
)
...
...
@@ -129,6 +285,8 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path)
TRACE
(
"driver %p, path %s.
\n
"
,
driver
,
debugstr_w
(
path
->
Buffer
));
driver_obj
=
driver
;
if
((
err
=
libusb_init
(
NULL
)))
{
ERR
(
"Failed to initialize libusb: %s
\n
"
,
libusb_strerror
(
err
));
...
...
include/ddk/usbioctl.h
View file @
b0c2e5c6
...
...
@@ -19,6 +19,8 @@
#ifndef __DDK_USBIOCTL_H__
#define __DDK_USBIOCTL_H__
#include "ddk/usbiodef.h"
#define IOCTL_INTERNAL_USB_SUBMIT_URB \
CTL_CODE(FILE_DEVICE_USB, USB_SUBMIT_URB, METHOD_NEITHER, FILE_ANY_ACCESS)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment