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
34cbc202
Commit
34cbc202
authored
Jun 17, 2021
by
Rémi Bernon
Committed by
Alexandre Julliard
Jun 17, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hidclass.sys: Add a stack to parser_state to store global items.
Signed-off-by:
Rémi Bernon
<
rbernon@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
08deef6a
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
54 deletions
+71
-54
descriptor.c
dlls/hidclass.sys/descriptor.c
+70
-54
ntoskrnl.c
dlls/ntoskrnl.exe/tests/ntoskrnl.c
+1
-0
No files found.
dlls/hidclass.sys/descriptor.c
View file @
34cbc202
...
...
@@ -128,11 +128,6 @@ struct collection {
struct
list
collections
;
};
struct
caps_stack
{
struct
list
entry
;
struct
hid_value_caps
caps
;
};
static
inline
const
char
*
debugstr_hidp_value_caps
(
HIDP_VALUE_CAPS
*
caps
)
{
if
(
!
caps
)
return
"(null)"
;
...
...
@@ -298,17 +293,69 @@ struct hid_parser_state
DWORD
usages_size
;
struct
hid_value_caps
items
;
struct
hid_value_caps
*
stack
;
DWORD
stack_size
;
DWORD
global_idx
;
};
static
BOOL
array_reserve
(
struct
hid_value_caps
**
array
,
DWORD
*
array_size
,
DWORD
index
)
{
if
(
index
<
*
array_size
)
return
TRUE
;
if
((
*
array_size
=
*
array_size
?
(
*
array_size
*
3
/
2
)
:
32
)
<=
index
)
return
FALSE
;
if
(
!
(
*
array
=
realloc
(
*
array
,
*
array_size
*
sizeof
(
**
array
)
)))
return
FALSE
;
return
TRUE
;
}
static
void
copy_global_items
(
struct
hid_value_caps
*
dst
,
const
struct
hid_value_caps
*
src
)
{
dst
->
usage_page
=
src
->
usage_page
;
dst
->
logical_min
=
src
->
logical_min
;
dst
->
logical_max
=
src
->
logical_max
;
dst
->
physical_min
=
src
->
physical_min
;
dst
->
physical_max
=
src
->
physical_max
;
dst
->
units_exp
=
src
->
units_exp
;
dst
->
units
=
src
->
units
;
dst
->
bit_size
=
src
->
bit_size
;
dst
->
report_id
=
src
->
report_id
;
dst
->
report_count
=
src
->
report_count
;
}
static
void
reset_local_items
(
struct
hid_parser_state
*
state
)
{
st
ate
->
items
.
is_range
=
FALSE
;
state
->
items
.
is_string_range
=
FALSE
;
state
->
items
.
is_designator_range
=
FALSE
;
state
->
items
.
usage_min
=
FALSE
;
st
ruct
hid_value_caps
tmp
;
copy_global_items
(
&
tmp
,
&
state
->
items
)
;
memset
(
&
state
->
items
,
0
,
sizeof
(
state
->
items
)
)
;
copy_global_items
(
&
state
->
items
,
&
tmp
)
;
state
->
usages_size
=
0
;
}
static
BOOL
parse_global_push
(
struct
hid_parser_state
*
state
)
{
if
(
!
array_reserve
(
&
state
->
stack
,
&
state
->
stack_size
,
state
->
global_idx
))
{
ERR
(
"HID parser stack overflow!
\n
"
);
return
FALSE
;
}
copy_global_items
(
state
->
stack
+
state
->
global_idx
,
&
state
->
items
);
state
->
global_idx
++
;
return
TRUE
;
}
static
BOOL
parse_global_pop
(
struct
hid_parser_state
*
state
)
{
if
(
!
state
->
global_idx
)
{
ERR
(
"HID parser global stack underflow!
\n
"
);
return
FALSE
;
}
state
->
global_idx
--
;
copy_global_items
(
&
state
->
items
,
state
->
stack
+
state
->
global_idx
);
return
TRUE
;
}
static
BOOL
parse_local_usage
(
struct
hid_parser_state
*
state
,
USAGE
usage
)
{
state
->
usages
[
state
->
usages_size
]
=
usage
;
...
...
@@ -317,6 +364,13 @@ static BOOL parse_local_usage( struct hid_parser_state *state, USAGE usage )
return
state
->
usages_size
<=
255
;
}
static
void
free_parser_state
(
struct
hid_parser_state
*
state
)
{
if
(
state
->
global_idx
)
ERR
(
"%u unpopped device caps on the stack
\n
"
,
state
->
global_idx
);
free
(
state
->
stack
);
free
(
state
);
}
static
void
parse_io_feature
(
unsigned
int
bSize
,
int
itemVal
,
int
bTag
,
unsigned
int
*
feature_index
,
struct
feature
*
feature
)
...
...
@@ -366,7 +420,7 @@ static void parse_collection(unsigned int bSize, int itemVal,
static
int
parse_descriptor
(
BYTE
*
descriptor
,
unsigned
int
index
,
unsigned
int
length
,
unsigned
int
*
feature_index
,
unsigned
int
*
collection_index
,
struct
collection
*
collection
,
struct
hid_parser_state
*
state
,
struct
list
*
stack
)
struct
collection
*
collection
,
struct
hid_parser_state
*
state
)
{
int
i
,
j
;
UINT32
value
;
...
...
@@ -445,7 +499,7 @@ static int parse_descriptor( BYTE *descriptor, unsigned int index, unsigned int
reset_local_items
(
state
);
if
((
i
=
parse_descriptor
(
descriptor
,
i
,
length
,
feature_index
,
collection_index
,
subcollection
,
state
,
stack
))
<
0
)
subcollection
,
state
))
<
0
)
return
i
;
continue
;
}
...
...
@@ -484,34 +538,11 @@ static int parse_descriptor( BYTE *descriptor, unsigned int index, unsigned int
state
->
items
.
report_count
=
value
;
break
;
case
SHORT_ITEM
(
TAG_GLOBAL_PUSH
,
TAG_TYPE_GLOBAL
):
{
struct
caps_stack
*
saved
;
if
(
!
(
saved
=
malloc
(
sizeof
(
*
saved
))))
return
-
1
;
saved
->
caps
=
state
->
items
;
TRACE
(
"Push
\n
"
);
list_add_tail
(
stack
,
&
saved
->
entry
);
if
(
!
parse_global_push
(
state
))
return
-
1
;
break
;
}
case
SHORT_ITEM
(
TAG_GLOBAL_POP
,
TAG_TYPE_GLOBAL
):
{
struct
list
*
tail
;
struct
caps_stack
*
saved
;
TRACE
(
"Pop
\n
"
);
tail
=
list_tail
(
stack
);
if
(
tail
)
{
saved
=
LIST_ENTRY
(
tail
,
struct
caps_stack
,
entry
);
state
->
items
=
saved
->
caps
;
list_remove
(
tail
);
free
(
saved
);
}
else
{
ERR
(
"Pop but no stack!
\n
"
);
return
-
1
;
}
if
(
!
parse_global_pop
(
state
))
return
-
1
;
break
;
}
case
SHORT_ITEM
(
TAG_LOCAL_USAGE
,
TAG_TYPE_LOCAL
):
if
(
!
parse_local_usage
(
state
,
value
))
return
-
1
;
...
...
@@ -775,8 +806,6 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
struct
collection
*
base
;
int
i
;
struct
list
caps_stack
;
unsigned
int
feature_count
=
0
;
unsigned
int
cidx
;
...
...
@@ -791,8 +820,6 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
}
}
list_init
(
&
caps_stack
);
if
(
!
(
state
=
calloc
(
1
,
sizeof
(
*
state
)
)))
return
NULL
;
if
(
!
(
base
=
calloc
(
1
,
sizeof
(
*
base
)
)))
{
...
...
@@ -804,30 +831,19 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
list_init
(
&
base
->
collections
);
cidx
=
0
;
if
(
parse_descriptor
(
descriptor
,
0
,
length
,
&
feature_count
,
&
cidx
,
base
,
state
,
&
caps_stack
)
<
0
)
if
(
parse_descriptor
(
descriptor
,
0
,
length
,
&
feature_count
,
&
cidx
,
base
,
state
)
<
0
)
{
free_collection
(
base
);
free
(
state
);
free
_parser_state
(
state
);
return
NULL
;
}
debug_collection
(
base
);
if
(
!
list_empty
(
&
caps_stack
))
{
struct
caps_stack
*
entry
,
*
cursor
;
ERR
(
"%i unpopped device caps on the stack
\n
"
,
list_count
(
&
caps_stack
));
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
cursor
,
&
caps_stack
,
struct
caps_stack
,
entry
)
{
list_remove
(
&
entry
->
entry
);
free
(
entry
);
}
}
if
((
data
=
build_PreparseData
(
base
,
cidx
)))
debug_print_preparsed
(
data
);
free_collection
(
base
);
free
(
state
);
free
_parser_state
(
state
);
return
data
;
}
dlls/ntoskrnl.exe/tests/ntoskrnl.c
View file @
34cbc202
...
...
@@ -2093,6 +2093,7 @@ static void test_hidp(HANDLE file, int report_id)
check_member
(
value_caps
[
4
],
value_caps
[
3
],
"%d"
,
PhysicalMax
);
todo_wine
check_member
(
value_caps
[
4
],
value_caps
[
3
],
"%04x"
,
Range
.
UsageMin
);
todo_wine
check_member
(
value_caps
[
4
],
value_caps
[
3
],
"%04x"
,
Range
.
UsageMax
);
check_member
(
value_caps
[
4
],
value_caps
[
3
],
"%d"
,
Range
.
StringMin
);
check_member
(
value_caps
[
4
],
value_caps
[
3
],
"%d"
,
Range
.
StringMax
);
...
...
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