Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
43888392
Commit
43888392
authored
Sep 09, 2015
by
Aric Stewart
Committed by
Alexandre Julliard
Sep 11, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hidclass.sys: Add Plug-and-play and AddDevice.
parent
a5b4ed75
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
208 additions
and
2 deletions
+208
-2
Makefile.in
dlls/hidclass.sys/Makefile.in
+2
-1
hid.h
dlls/hidclass.sys/hid.h
+11
-0
main.c
dlls/hidclass.sys/main.c
+49
-1
pnp.c
dlls/hidclass.sys/pnp.c
+146
-0
No files found.
dlls/hidclass.sys/Makefile.in
View file @
43888392
...
...
@@ -5,4 +5,5 @@ DELAYIMPORTS = setupapi hid
C_SRCS
=
\
device.c
\
main.c
main.c
\
pnp.c
dlls/hidclass.sys/hid.h
View file @
43888392
...
...
@@ -33,6 +33,8 @@
#define DEFAULT_POLL_INTERVAL 200
#define MAX_POLL_INTERVAL_MSEC 10000
typedef
NTSTATUS
(
WINAPI
*
pAddDevice
)(
DRIVER_OBJECT
*
DriverObject
,
DEVICE_OBJECT
*
PhysicalDeviceObject
);
typedef
struct
_BASE_DEVICE_EXTENSTION
{
HID_DEVICE_EXTENSION
deviceExtension
;
...
...
@@ -57,9 +59,18 @@ typedef struct _minidriver
HID_MINIDRIVER_REGISTRATION
minidriver
;
PDRIVER_UNLOAD
DriverUnload
;
pAddDevice
AddDevice
;
}
minidriver
;
NTSTATUS
call_minidriver
(
ULONG
code
,
DEVICE_OBJECT
*
device
,
void
*
in_buff
,
ULONG
in_size
,
void
*
out_buff
,
ULONG
out_size
)
DECLSPEC_HIDDEN
;
minidriver
*
find_minidriver
(
DRIVER_OBJECT
*
driver
)
DECLSPEC_HIDDEN
;
/* Internal device functions */
NTSTATUS
HID_CreateDevice
(
DEVICE_OBJECT
*
native_device
,
HID_MINIDRIVER_REGISTRATION
*
driver
,
DEVICE_OBJECT
**
device
)
DECLSPEC_HIDDEN
;
NTSTATUS
HID_LinkDevice
(
DEVICE_OBJECT
*
device
,
LPCWSTR
serial
,
LPCWSTR
index
)
DECLSPEC_HIDDEN
;
void
HID_DeleteDevice
(
HID_MINIDRIVER_REGISTRATION
*
driver
,
DEVICE_OBJECT
*
device
)
DECLSPEC_HIDDEN
;
/* Pseudo-Plug and Play support*/
NTSTATUS
WINAPI
PNP_AddDevice
(
DRIVER_OBJECT
*
driver
,
DEVICE_OBJECT
*
PDO
)
DECLSPEC_HIDDEN
;
void
PNP_CleanupPNP
(
DRIVER_OBJECT
*
driver
)
DECLSPEC_HIDDEN
;
dlls/hidclass.sys/main.c
View file @
43888392
...
...
@@ -30,7 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(hid);
static
struct
list
minidriver_list
=
LIST_INIT
(
minidriver_list
);
static
minidriver
*
find_minidriver
(
DRIVER_OBJECT
*
driver
)
minidriver
*
find_minidriver
(
DRIVER_OBJECT
*
driver
)
{
minidriver
*
md
;
LIST_FOR_EACH_ENTRY
(
md
,
&
minidriver_list
,
minidriver
,
entry
)
...
...
@@ -51,6 +51,7 @@ static VOID WINAPI UnloadDriver(DRIVER_OBJECT *driver)
{
if
(
md
->
DriverUnload
)
md
->
DriverUnload
(
md
->
minidriver
.
DriverObject
);
PNP_CleanupPNP
(
md
->
minidriver
.
DriverObject
);
list_remove
(
&
md
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
md
);
}
...
...
@@ -67,8 +68,55 @@ NTSTATUS WINAPI HidRegisterMinidriver(HID_MINIDRIVER_REGISTRATION *registration)
driver
->
DriverUnload
=
registration
->
DriverObject
->
DriverUnload
;
registration
->
DriverObject
->
DriverUnload
=
UnloadDriver
;
driver
->
AddDevice
=
registration
->
DriverObject
->
DriverExtension
->
AddDevice
;
registration
->
DriverObject
->
DriverExtension
->
AddDevice
=
PNP_AddDevice
;
driver
->
minidriver
=
*
registration
;
list_add_tail
(
&
minidriver_list
,
&
driver
->
entry
);
return
STATUS_SUCCESS
;
}
static
NTSTATUS
WINAPI
internalComplete
(
DEVICE_OBJECT
*
deviceObject
,
IRP
*
irp
,
void
*
context
)
{
SetEvent
(
irp
->
UserEvent
);
return
STATUS_MORE_PROCESSING_REQUIRED
;
}
NTSTATUS
call_minidriver
(
ULONG
code
,
DEVICE_OBJECT
*
device
,
void
*
in_buff
,
ULONG
in_size
,
void
*
out_buff
,
ULONG
out_size
)
{
IRP
*
irp
;
IO_STATUS_BLOCK
irp_status
;
IO_STACK_LOCATION
*
irpsp
;
NTSTATUS
status
;
void
*
buffer
=
NULL
;
HANDLE
event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
if
(
out_size
)
{
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
out_size
);
memcpy
(
buffer
,
out_buff
,
out_size
);
}
irp
=
IoBuildDeviceIoControlRequest
(
code
,
device
,
in_buff
,
in_size
,
buffer
,
out_size
,
TRUE
,
event
,
&
irp_status
);
irpsp
=
IoGetNextIrpStackLocation
(
irp
);
irpsp
->
CompletionRoutine
=
internalComplete
;
irpsp
->
Control
=
SL_INVOKE_ON_SUCCESS
|
SL_INVOKE_ON_ERROR
;
IoCallDriver
(
device
,
irp
);
if
(
irp
->
IoStatus
.
u
.
Status
==
STATUS_PENDING
)
WaitForSingleObject
(
event
,
INFINITE
);
memcpy
(
out_buff
,
buffer
,
out_size
);
status
=
irp
->
IoStatus
.
u
.
Status
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
CloseHandle
(
event
);
return
status
;
}
dlls/hidclass.sys/pnp.c
0 → 100644
View file @
43888392
/*
* WINE HID Pseudo-Plug and Play support
*
* Copyright 2015 Aric Stewart
*
* 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
*/
#define NONAMELESSUNION
#include <unistd.h>
#include <stdarg.h>
#include "hid.h"
#include "ddk/hidtypes.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
hid
);
typedef
struct
_NATIVE_DEVICE
{
struct
list
entry
;
DWORD
vidpid
;
DEVICE_OBJECT
*
PDO
;
DEVICE_OBJECT
*
FDO
;
HID_MINIDRIVER_REGISTRATION
*
minidriver
;
}
NATIVE_DEVICE
;
static
struct
list
tracked_devices
=
LIST_INIT
(
tracked_devices
);
NTSTATUS
WINAPI
PNP_AddDevice
(
DRIVER_OBJECT
*
driver
,
DEVICE_OBJECT
*
PDO
)
{
DEVICE_OBJECT
*
device
=
NULL
;
NTSTATUS
status
;
minidriver
*
minidriver
;
HID_DEVICE_ATTRIBUTES
attr
;
BASE_DEVICE_EXTENSION
*
ext
=
NULL
;
WCHAR
serial
[
256
];
WCHAR
interface
[
256
];
DWORD
index
=
HID_STRING_ID_ISERIALNUMBER
;
NATIVE_DEVICE
*
tracked_device
,
*
ptr
;
INT
interface_index
=
1
;
static
const
WCHAR
ig_fmtW
[]
=
{
'I'
,
'G'
,
'_'
,
'%'
,
'i'
,
0
};
static
const
WCHAR
im_fmtW
[]
=
{
'I'
,
'M'
,
'_'
,
'%'
,
'i'
,
0
};
TRACE
(
"PDO add device(%p)
\n
"
,
PDO
);
minidriver
=
find_minidriver
(
driver
);
status
=
HID_CreateDevice
(
PDO
,
&
minidriver
->
minidriver
,
&
device
);
if
(
status
!=
STATUS_SUCCESS
)
{
ERR
(
"Failed to create HID object (%x)
\n
"
,
status
);
return
status
;
}
TRACE
(
"Created device %p
\n
"
,
device
);
status
=
minidriver
->
AddDevice
(
minidriver
->
minidriver
.
DriverObject
,
device
);
if
(
status
!=
STATUS_SUCCESS
)
{
ERR
(
"Minidriver AddDevice failed (%x)
\n
"
,
status
);
HID_DeleteDevice
(
&
minidriver
->
minidriver
,
device
);
return
status
;
}
status
=
call_minidriver
(
IOCTL_HID_GET_DEVICE_ATTRIBUTES
,
device
,
NULL
,
0
,
&
attr
,
sizeof
(
attr
));
if
(
status
!=
STATUS_SUCCESS
)
{
ERR
(
"Minidriver failed to get Attributes(%x)
\n
"
,
status
);
HID_DeleteDevice
(
&
minidriver
->
minidriver
,
device
);
return
status
;
}
ext
=
device
->
DeviceExtension
;
ext
->
information
.
VendorID
=
attr
.
VendorID
;
ext
->
information
.
ProductID
=
attr
.
ProductID
;
ext
->
information
.
VersionNumber
=
attr
.
VersionNumber
;
ext
->
information
.
Polled
=
minidriver
->
minidriver
.
DevicesArePolled
;
tracked_device
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
tracked_device
));
tracked_device
->
vidpid
=
MAKELONG
(
attr
.
VendorID
,
attr
.
ProductID
);
tracked_device
->
PDO
=
PDO
;
tracked_device
->
FDO
=
device
;
tracked_device
->
minidriver
=
&
minidriver
->
minidriver
;
LIST_FOR_EACH_ENTRY
(
ptr
,
&
tracked_devices
,
NATIVE_DEVICE
,
entry
)
if
(
ptr
->
vidpid
==
tracked_device
->
vidpid
)
interface_index
++
;
list_add_tail
(
&
tracked_devices
,
&
tracked_device
->
entry
);
serial
[
0
]
=
0
;
status
=
call_minidriver
(
IOCTL_HID_GET_STRING
,
device
,
&
index
,
sizeof
(
DWORD
),
serial
,
sizeof
(
serial
));
if
(
serial
[
0
]
==
0
)
{
static
const
WCHAR
wZeroSerial
[]
=
{
'0'
,
'0'
,
'0'
,
'0'
,
0
};
lstrcpyW
(
serial
,
wZeroSerial
);
}
if
(
ext
->
preparseData
->
caps
.
UsagePage
==
HID_USAGE_PAGE_GENERIC
&&
(
ext
->
preparseData
->
caps
.
Usage
==
HID_USAGE_GENERIC_GAMEPAD
||
ext
->
preparseData
->
caps
.
Usage
==
HID_USAGE_GENERIC_JOYSTICK
))
sprintfW
(
interface
,
ig_fmtW
,
interface_index
);
else
sprintfW
(
interface
,
im_fmtW
,
interface_index
);
HID_LinkDevice
(
device
,
serial
,
interface
);
ext
->
poll_interval
=
DEFAULT_POLL_INTERVAL
;
InitializeListHead
(
&
ext
->
irp_queue
);
return
STATUS_SUCCESS
;
}
void
PNP_CleanupPNP
(
DRIVER_OBJECT
*
driver
)
{
NATIVE_DEVICE
*
tracked_device
,
*
ptr
;
LIST_FOR_EACH_ENTRY_SAFE
(
tracked_device
,
ptr
,
&
tracked_devices
,
NATIVE_DEVICE
,
entry
)
{
if
(
tracked_device
->
minidriver
->
DriverObject
==
driver
)
{
list_remove
(
&
tracked_device
->
entry
);
HID_DeleteDevice
(
tracked_device
->
minidriver
,
tracked_device
->
FDO
);
HeapFree
(
GetProcessHeap
(),
0
,
tracked_device
);
}
}
}
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