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
f266b2b5
Commit
f266b2b5
authored
Jun 18, 2021
by
Rémi Bernon
Committed by
Alexandre Julliard
Jun 18, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hidclass.sys: Create link collection caps during parsing.
Signed-off-by:
Rémi Bernon
<
rbernon@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4940d2ad
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
56 additions
and
36 deletions
+56
-36
descriptor.c
dlls/hidclass.sys/descriptor.c
+41
-26
ntoskrnl.c
dlls/ntoskrnl.exe/tests/ntoskrnl.c
+15
-10
No files found.
dlls/hidclass.sys/descriptor.c
View file @
f266b2b5
...
...
@@ -306,6 +306,9 @@ struct hid_parser_state
DWORD
stack_size
;
DWORD
global_idx
;
DWORD
collection_idx
;
struct
hid_value_caps
*
collections
;
DWORD
collections_size
;
};
static
BOOL
array_reserve
(
struct
hid_value_caps
**
array
,
DWORD
*
array_size
,
DWORD
index
)
...
...
@@ -390,12 +393,24 @@ static BOOL parse_new_collection( struct hid_parser_state *state )
return
FALSE
;
}
if
(
!
array_reserve
(
&
state
->
collections
,
&
state
->
collections_size
,
state
->
caps
.
NumberLinkCollectionNodes
))
{
ERR
(
"HID parser collections overflow!
\n
"
);
return
FALSE
;
}
copy_collection_items
(
state
->
stack
+
state
->
collection_idx
,
&
state
->
items
);
state
->
collection_idx
++
;
state
->
collections
[
state
->
caps
.
NumberLinkCollectionNodes
]
=
state
->
items
;
state
->
items
.
link_collection
=
state
->
caps
.
NumberLinkCollectionNodes
;
state
->
items
.
link_usage_page
=
state
->
items
.
usage_page
;
state
->
items
.
link_usage
=
state
->
items
.
usage_min
;
if
(
!
state
->
caps
.
NumberLinkCollectionNodes
)
{
state
->
caps
.
UsagePage
=
state
->
items
.
usage_page
;
state
->
caps
.
Usage
=
state
->
items
.
usage_min
;
}
state
->
caps
.
NumberLinkCollectionNodes
++
;
reset_local_items
(
state
);
...
...
@@ -421,6 +436,7 @@ 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
);
if
(
state
->
collection_idx
)
ERR
(
"%u unpopped device collection on the stack
\n
"
,
state
->
collection_idx
);
free
(
state
->
stack
);
free
(
state
->
collections
);
free
(
state
);
}
...
...
@@ -727,10 +743,8 @@ static void preparse_collection(const struct collection *root, const struct coll
WINE_HIDP_PREPARSED_DATA
*
data
,
struct
preparse_ctx
*
ctx
)
{
WINE_HID_ELEMENT
*
elem
=
HID_ELEMS
(
data
);
WINE_HID_LINK_COLLECTION_NODE
*
nodes
=
HID_NODES
(
data
);
struct
feature
*
f
;
struct
collection
*
c
;
struct
list
*
entry
;
LIST_FOR_EACH_ENTRY
(
f
,
&
base
->
features
,
struct
feature
,
entry
)
{
...
...
@@ -775,33 +789,18 @@ static void preparse_collection(const struct collection *root, const struct coll
}
}
if
(
root
!=
base
)
{
nodes
[
base
->
index
].
LinkUsagePage
=
base
->
caps
.
UsagePage
;
nodes
[
base
->
index
].
LinkUsage
=
base
->
caps
.
NotRange
.
Usage
;
nodes
[
base
->
index
].
Parent
=
base
->
parent
==
root
?
0
:
base
->
parent
->
index
;
nodes
[
base
->
index
].
CollectionType
=
base
->
type
;
nodes
[
base
->
index
].
IsAlias
=
0
;
if
((
entry
=
list_head
(
&
base
->
collections
)))
nodes
[
base
->
index
].
FirstChild
=
LIST_ENTRY
(
entry
,
struct
collection
,
entry
)
->
index
;
}
LIST_FOR_EACH_ENTRY
(
c
,
&
base
->
collections
,
struct
collection
,
entry
)
{
preparse_collection
(
root
,
c
,
data
,
ctx
);
if
((
entry
=
list_next
(
&
base
->
collections
,
&
c
->
entry
)))
nodes
[
c
->
index
].
NextSibling
=
LIST_ENTRY
(
entry
,
struct
collection
,
entry
)
->
index
;
if
(
root
!=
base
)
nodes
[
base
->
index
].
NumberOfChildren
++
;
}
}
static
WINE_HIDP_PREPARSED_DATA
*
build_PreparseData
(
struct
collection
*
base_collection
,
unsigned
int
node_count
)
static
WINE_HIDP_PREPARSED_DATA
*
build_preparsed_data
(
struct
collection
*
base_collection
,
struct
hid_parser_state
*
state
)
{
WINE_HID_LINK_COLLECTION_NODE
*
nodes
;
WINE_HIDP_PREPARSED_DATA
*
data
;
unsigned
int
report_count
;
unsigned
int
size
;
DWORD
i
;
struct
preparse_ctx
ctx
;
unsigned
int
element_off
;
...
...
@@ -816,18 +815,34 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(struct collection *base_coll
size
=
element_off
+
(
ctx
.
elem_count
*
sizeof
(
WINE_HID_ELEMENT
));
nodes_offset
=
size
;
size
+=
node_count
*
sizeof
(
WINE_HID_LINK_COLLECTION_NODE
);
size
+=
state
->
caps
.
NumberLinkCollectionNodes
*
sizeof
(
WINE_HID_LINK_COLLECTION_NODE
);
if
(
!
(
data
=
calloc
(
1
,
size
)))
return
NULL
;
data
->
magic
=
HID_MAGIC
;
data
->
dwSize
=
size
;
data
->
caps
.
Usage
=
base_collection
->
caps
.
NotRange
.
Usage
;
data
->
caps
.
UsagePage
=
base_collection
->
caps
.
UsagePage
;
data
->
caps
.
NumberLinkCollectionNodes
=
node_count
;
data
->
caps
=
state
->
caps
;
data
->
elementOffset
=
element_off
;
data
->
nodesOffset
=
nodes_offset
;
preparse_collection
(
base_collection
,
base_collection
,
data
,
&
ctx
);
nodes
=
HID_NODES
(
data
);
for
(
i
=
0
;
i
<
data
->
caps
.
NumberLinkCollectionNodes
;
++
i
)
{
nodes
[
i
].
LinkUsagePage
=
state
->
collections
[
i
].
usage_page
;
nodes
[
i
].
LinkUsage
=
state
->
collections
[
i
].
usage_min
;
nodes
[
i
].
Parent
=
state
->
collections
[
i
].
link_collection
;
nodes
[
i
].
CollectionType
=
state
->
collections
[
i
].
bit_field
;
nodes
[
i
].
IsAlias
=
0
;
if
(
i
>
0
)
{
nodes
[
i
].
NextSibling
=
nodes
[
nodes
[
i
].
Parent
].
FirstChild
;
nodes
[
nodes
[
i
].
Parent
].
FirstChild
=
i
;
nodes
[
nodes
[
i
].
Parent
].
NumberOfChildren
++
;
}
}
return
data
;
}
...
...
@@ -889,7 +904,7 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
debug_collection
(
base
);
if
((
data
=
build_
PreparseData
(
base
,
cidx
)))
if
((
data
=
build_
preparsed_data
(
base
,
state
)))
debug_print_preparsed
(
data
);
free_collection
(
base
);
...
...
dlls/ntoskrnl.exe/tests/ntoskrnl.c
View file @
f266b2b5
...
...
@@ -1500,6 +1500,20 @@ static void test_pnp_driver(struct testsign_context *ctx)
(val).member, (exp).member)
#define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member)
#define check_hidp_link_collection_node(a, b) check_hidp_link_collection_node_(__LINE__, a, b)
static
inline
void
check_hidp_link_collection_node_
(
int
line
,
HIDP_LINK_COLLECTION_NODE
*
node
,
const
HIDP_LINK_COLLECTION_NODE
*
exp
)
{
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%04x"
,
LinkUsage
);
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%04x"
,
LinkUsagePage
);
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%d"
,
Parent
);
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%d"
,
NumberOfChildren
);
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%d"
,
NextSibling
);
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%d"
,
FirstChild
);
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%d"
,
CollectionType
);
check_member_
(
__FILE__
,
line
,
*
node
,
*
exp
,
"%d"
,
IsAlias
);
}
#define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b)
static
inline
void
check_hidp_button_caps_
(
int
line
,
HIDP_BUTTON_CAPS
*
caps
,
const
HIDP_BUTTON_CAPS
*
exp
)
{
...
...
@@ -1850,16 +1864,7 @@ static void test_hidp(HANDLE file, int report_id)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
expect_collections
);
++
i
)
{
winetest_push_context
(
"collections[%d]"
,
i
);
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%04x"
,
LinkUsage
);
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%04x"
,
LinkUsagePage
);
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%d"
,
Parent
);
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%d"
,
NumberOfChildren
);
todo_wine_if
(
i
==
1
)
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%d"
,
NextSibling
);
todo_wine_if
(
i
==
0
)
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%d"
,
FirstChild
);
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%d"
,
CollectionType
);
check_member
(
collections
[
i
],
expect_collections
[
i
],
"%d"
,
IsAlias
);
check_hidp_link_collection_node
(
&
collections
[
i
],
&
expect_collections
[
i
]);
winetest_pop_context
();
}
...
...
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