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
0aca2d7d
Commit
0aca2d7d
authored
Sep 01, 2015
by
Aric Stewart
Committed by
Alexandre Julliard
Sep 04, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hidclass.sys: Implement creating/destroying HID devices.
parent
515b4a97
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
342 additions
and
0 deletions
+342
-0
Makefile.in
dlls/hidclass.sys/Makefile.in
+1
-0
device.c
dlls/hidclass.sys/device.c
+196
-0
hid.h
dlls/hidclass.sys/hid.h
+30
-0
parse.h
dlls/hidclass.sys/parse.h
+72
-0
hidport.h
include/ddk/hidport.h
+43
-0
No files found.
dlls/hidclass.sys/Makefile.in
View file @
0aca2d7d
...
...
@@ -4,4 +4,5 @@ IMPORTS = ntoskrnl.exe
DELAYIMPORTS
=
setupapi hid
C_SRCS
=
\
device.c
\
main.c
dlls/hidclass.sys/device.c
0 → 100644
View file @
0aca2d7d
/*
* HIDClass device functions
*
* Copyright (C) 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
*/
#include "config.h"
#include <stdarg.h>
#define NONAMELESSUNION
#include "hid.h"
#include "wine/unicode.h"
#include "winreg.h"
#include "winuser.h"
#include "setupapi.h"
#include "wine/debug.h"
#include "ddk/hidsdi.h"
#include "ddk/hidtypes.h"
#include "initguid.h"
#include "devguid.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
hid
);
static
const
WCHAR
device_name_fmtW
[]
=
{
'\\'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
'\\'
,
'H'
,
'I'
,
'D'
,
'#'
,
'%'
,
'p'
,
'&'
,
'%'
,
'p'
,
0
};
static
const
WCHAR
device_regname_fmtW
[]
=
{
'H'
,
'I'
,
'D'
,
'\\'
,
'v'
,
'i'
,
'd'
,
'_'
,
'%'
,
'0'
,
'4'
,
'x'
,
'&'
,
'p'
,
'i'
,
'd'
,
'_'
,
'%'
,
'0'
,
'4'
,
'x'
,
'&'
,
'%'
,
's'
,
'\\'
,
'%'
,
'i'
,
'&'
,
'%'
,
's'
,
0
};
static
const
WCHAR
device_link_fmtW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'h'
,
'i'
,
'd'
,
'#'
,
'v'
,
'i'
,
'd'
,
'_'
,
'%'
,
'0'
,
'4'
,
'x'
,
'&'
,
'p'
,
'i'
,
'd'
,
'_'
,
'%'
,
'0'
,
'4'
,
'x'
,
'&'
,
'%'
,
's'
,
'#'
,
'%'
,
'i'
,
'&'
,
'%'
,
's'
,
'#'
,
'%'
,
's'
,
0
};
/* GUID_DEVINTERFACE_HID */
static
const
WCHAR
class_guid
[]
=
{
'{'
,
'4'
,
'D'
,
'1'
,
'E'
,
'5'
,
'5'
,
'B'
,
'2'
,
'-'
,
'F'
,
'1'
,
'6'
,
'F'
,
'-'
,
'1'
,
'1'
,
'C'
,
'F'
,
'-'
,
'8'
,
'8'
,
'C'
,
'B'
,
'-'
,
'0'
,
'0'
,
'1'
,
'1'
,
'1'
,
'1'
,
'0'
,
'0'
,
'0'
,
'0'
,
'3'
,
'0'
,
'}'
,
0
};
NTSTATUS
HID_CreateDevice
(
DEVICE_OBJECT
*
native_device
,
HID_MINIDRIVER_REGISTRATION
*
driver
,
DEVICE_OBJECT
**
device
)
{
WCHAR
dev_name
[
255
];
UNICODE_STRING
nameW
;
NTSTATUS
status
;
BASE_DEVICE_EXTENSION
*
ext
;
sprintfW
(
dev_name
,
device_name_fmtW
,
driver
->
DriverObject
,
native_device
);
RtlInitUnicodeString
(
&
nameW
,
dev_name
);
TRACE
(
"Create base hid device %s
\n
"
,
debugstr_w
(
dev_name
));
status
=
IoCreateDevice
(
driver
->
DriverObject
,
driver
->
DeviceExtensionSize
+
sizeof
(
BASE_DEVICE_EXTENSION
),
&
nameW
,
0
,
0
,
FALSE
,
device
);
if
(
status
)
{
FIXME
(
"failed to create device error %x
\n
"
,
status
);
return
status
;
}
ext
=
(
*
device
)
->
DeviceExtension
;
ext
->
deviceExtension
.
MiniDeviceExtension
=
ext
+
1
;
ext
->
deviceExtension
.
PhysicalDeviceObject
=
*
device
;
ext
->
deviceExtension
.
NextDeviceObject
=
native_device
;
ext
->
device_name
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
lstrlenW
(
dev_name
)
+
1
)
*
sizeof
(
WCHAR
));
lstrcpyW
(
ext
->
device_name
,
dev_name
);
ext
->
link_name
=
NULL
;
return
S_OK
;
}
NTSTATUS
HID_LinkDevice
(
DEVICE_OBJECT
*
device
,
LPCWSTR
serial
,
LPCWSTR
index
)
{
WCHAR
regname
[
255
];
WCHAR
dev_link
[
255
];
SP_DEVINFO_DATA
Data
;
UNICODE_STRING
nameW
,
linkW
;
NTSTATUS
status
;
HDEVINFO
devinfo
;
GUID
hidGuid
;
BASE_DEVICE_EXTENSION
*
ext
;
HidD_GetHidGuid
(
&
hidGuid
);
ext
=
device
->
DeviceExtension
;
sprintfW
(
dev_link
,
device_link_fmtW
,
ext
->
information
.
VendorID
,
ext
->
information
.
ProductID
,
index
,
ext
->
information
.
VersionNumber
,
serial
,
class_guid
);
struprW
(
dev_link
);
RtlInitUnicodeString
(
&
nameW
,
ext
->
device_name
);
RtlInitUnicodeString
(
&
linkW
,
dev_link
);
TRACE
(
"Create link %s
\n
"
,
debugstr_w
(
dev_link
));
ext
->
link_name
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WCHAR
)
*
(
lstrlenW
(
dev_link
)
+
1
));
lstrcpyW
(
ext
->
link_name
,
dev_link
);
status
=
IoCreateSymbolicLink
(
&
linkW
,
&
nameW
);
if
(
status
)
{
FIXME
(
"failed to create link error %x
\n
"
,
status
);
return
status
;
}
sprintfW
(
regname
,
device_regname_fmtW
,
ext
->
information
.
VendorID
,
ext
->
information
.
ProductID
,
index
,
ext
->
information
.
VersionNumber
,
serial
);
devinfo
=
SetupDiGetClassDevsW
(
&
GUID_DEVCLASS_HIDCLASS
,
NULL
,
NULL
,
DIGCF_DEVICEINTERFACE
);
if
(
!
devinfo
)
{
FIXME
(
"failed to get ClassDevs %x
\n
"
,
GetLastError
());
return
GetLastError
();
}
Data
.
cbSize
=
sizeof
(
Data
);
if
(
!
SetupDiCreateDeviceInfoW
(
devinfo
,
regname
,
&
GUID_DEVCLASS_HIDCLASS
,
NULL
,
NULL
,
DICD_INHERIT_CLASSDRVS
,
&
Data
))
{
if
(
GetLastError
()
==
ERROR_DEVINST_ALREADY_EXISTS
)
{
SetupDiDestroyDeviceInfoList
(
devinfo
);
return
ERROR_SUCCESS
;
}
FIXME
(
"failed to Create Device Info %x
\n
"
,
GetLastError
());
return
GetLastError
();
}
if
(
!
SetupDiRegisterDeviceInfo
(
devinfo
,
&
Data
,
0
,
NULL
,
NULL
,
NULL
))
{
FIXME
(
"failed to Register Device Info %x
\n
"
,
GetLastError
());
return
GetLastError
();
}
if
(
!
SetupDiCreateDeviceInterfaceW
(
devinfo
,
&
Data
,
&
hidGuid
,
NULL
,
0
,
NULL
))
{
FIXME
(
"failed to Create Device Interface %x
\n
"
,
GetLastError
());
return
GetLastError
();
}
SetupDiDestroyDeviceInfoList
(
devinfo
);
return
S_OK
;
}
void
HID_DeleteDevice
(
HID_MINIDRIVER_REGISTRATION
*
driver
,
DEVICE_OBJECT
*
device
)
{
NTSTATUS
status
;
BASE_DEVICE_EXTENSION
*
ext
;
UNICODE_STRING
linkW
;
LIST_ENTRY
*
entry
;
IRP
*
irp
;
ext
=
device
->
DeviceExtension
;
if
(
ext
->
link_name
)
{
TRACE
(
"Delete link %s
\n
"
,
debugstr_w
(
ext
->
link_name
));
RtlInitUnicodeString
(
&
linkW
,
ext
->
link_name
);
status
=
IoDeleteSymbolicLink
(
&
linkW
);
if
(
status
!=
STATUS_SUCCESS
)
ERR
(
"Delete Symbolic Link failed (%x)
\n
"
,
status
);
}
if
(
ext
->
thread
)
{
SetEvent
(
ext
->
halt_event
);
WaitForSingleObject
(
ext
->
thread
,
INFINITE
);
}
CloseHandle
(
ext
->
halt_event
);
HeapFree
(
GetProcessHeap
(),
0
,
ext
->
preparseData
);
entry
=
RemoveHeadList
(
&
ext
->
irp_queue
);
while
(
entry
!=
&
ext
->
irp_queue
)
{
irp
=
CONTAINING_RECORD
(
entry
,
IRP
,
Tail
.
Overlay
.
ListEntry
);
irp
->
IoStatus
.
u
.
Status
=
STATUS_DEVICE_REMOVED
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
entry
=
RemoveHeadList
(
&
ext
->
irp_queue
);
}
TRACE
(
"Delete device(%p) %s
\n
"
,
device
,
debugstr_w
(
ext
->
device_name
));
HeapFree
(
GetProcessHeap
(),
0
,
ext
->
device_name
);
HeapFree
(
GetProcessHeap
(),
0
,
ext
->
link_name
);
IoDeleteDevice
(
device
);
}
dlls/hidclass.sys/hid.h
View file @
0aca2d7d
...
...
@@ -21,9 +21,34 @@
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winioctl.h"
#include "ddk/wdm.h"
#include "hidusage.h"
#include "ddk/hidport.h"
#include "ddk/hidclass.h"
#include "ddk/hidpi.h"
#include "wine/list.h"
#include "parse.h"
#define DEFAULT_POLL_INTERVAL 200
#define MAX_POLL_INTERVAL_MSEC 10000
typedef
struct
_BASE_DEVICE_EXTENSTION
{
HID_DEVICE_EXTENSION
deviceExtension
;
HID_COLLECTION_INFORMATION
information
;
WINE_HIDP_PREPARSED_DATA
*
preparseData
;
ULONG
poll_interval
;
WCHAR
*
device_name
;
WCHAR
*
link_name
;
HANDLE
halt_event
;
HANDLE
thread
;
LIST_ENTRY
irp_queue
;
/* Minidriver Specific stuff will end up here */
}
BASE_DEVICE_EXTENSION
;
typedef
struct
_minidriver
{
...
...
@@ -33,3 +58,8 @@ typedef struct _minidriver
PDRIVER_UNLOAD
DriverUnload
;
}
minidriver
;
/* 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
;
dlls/hidclass.sys/parse.h
0 → 100644
View file @
0aca2d7d
/*
* Wine internal HID structures
*
* 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
*/
#ifndef __WINE_PARSE_H
#define __WINE_PARSE_H
#define HID_MAGIC 0x8491759
typedef
enum
__WINE_ELEMENT_TYPE
{
UnknownElement
=
0
,
ButtonElement
,
ValueElement
,
}
WINE_ELEMENT_TYPE
;
typedef
struct
__WINE_ELEMENT
{
WINE_ELEMENT_TYPE
ElementType
;
UINT
valueStartBit
;
UINT
bitCount
;
union
{
HIDP_VALUE_CAPS
value
;
HIDP_BUTTON_CAPS
button
;
}
caps
;
}
WINE_HID_ELEMENT
;
typedef
struct
__WINE_HID_REPORT
{
UCHAR
reportID
;
DWORD
dwSize
;
DWORD
elementCount
;
WINE_HID_ELEMENT
Elements
[
1
];
}
WINE_HID_REPORT
;
typedef
struct
__WINE_HIDP_PREPARSED_DATA
{
DWORD
magic
;
DWORD
dwSize
;
HIDP_CAPS
caps
;
DWORD
dwInputReportCount
;
DWORD
dwOutputReportCount
;
DWORD
dwFeatureReportCount
;
DWORD
dwOutputReportOffset
;
DWORD
dwFeatureReportOffset
;
WINE_HID_REPORT
InputReports
[
1
];
}
WINE_HIDP_PREPARSED_DATA
;
#define HID_NEXT_REPORT(d,r) ((r)?(WINE_HID_REPORT*)(((BYTE*)(r))+(r)->dwSize):(d)->InputReports)
#define HID_INPUT_REPORTS(d) ((d)->InputReports)
#define HID_OUTPUT_REPORTS(d) (WINE_HID_REPORT*)(((BYTE*)(d)->InputReports)+(d)->dwOutputReportOffset)
#define HID_FEATURE_REPORTS(d) (WINE_HID_REPORT*)(((BYTE*)(d)->InputReports)+(d)->dwFeatureReportOffset)
#endif
/* __WINE_PARSE_H */
include/ddk/hidport.h
View file @
0aca2d7d
...
...
@@ -33,4 +33,47 @@ typedef struct _HID_MINIDRIVER_REGISTRATION
NTSTATUS
WINAPI
HidRegisterMinidriver
(
PHID_MINIDRIVER_REGISTRATION
MinidriverRegistration
);
typedef
struct
_HID_DEVICE_EXTENSION
{
PDEVICE_OBJECT
PhysicalDeviceObject
;
PDEVICE_OBJECT
NextDeviceObject
;
PVOID
MiniDeviceExtension
;
}
HID_DEVICE_EXTENSION
,
*
PHID_DEVICE_EXTENSION
;
typedef
struct
_HID_DEVICE_ATTRIBUTES
{
ULONG
Size
;
USHORT
VendorID
;
USHORT
ProductID
;
USHORT
VersionNumber
;
USHORT
Reserved
[
11
];
}
HID_DEVICE_ATTRIBUTES
,
*
PHID_DEVICE_ATTRIBUTES
;
typedef
struct
_HID_DESCRIPTOR
{
UCHAR
bLength
;
UCHAR
bDescriptorType
;
USHORT
bcdHID
;
UCHAR
bCountry
;
UCHAR
bNumDescriptors
;
struct
_HID_DESCRIPTOR_DESC_LIST
{
UCHAR
bReportType
;
USHORT
wReportLength
;
}
DescriptorList
[
1
];
}
HID_DESCRIPTOR
,
*
PHID_DESCRIPTOR
;
#define HID_HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESCRIPTOR_TYPE 0x22
#define IOCTL_HID_GET_DEVICE_DESCRIPTOR HID_CTL_CODE(0)
#define IOCTL_HID_GET_REPORT_DESCRIPTOR HID_CTL_CODE(1)
#define IOCTL_HID_READ_REPORT HID_CTL_CODE(2)
#define IOCTL_HID_WRITE_REPORT HID_CTL_CODE(3)
#define IOCTL_HID_GET_STRING HID_CTL_CODE(4)
#define IOCTL_HID_ACTIVATE_DEVICE HID_CTL_CODE(7)
#define IOCTL_HID_DEACTIVATE_DEVICE HID_CTL_CODE(8)
#define IOCTL_HID_GET_DEVICE_ATTRIBUTES HID_CTL_CODE(9)
#define IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST HID_CTL_CODE(10)
#endif
/* __HIDPORT_H__ */
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