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
eec443af
Commit
eec443af
authored
Nov 22, 2021
by
Paul Gofman
Committed by
Alexandre Julliard
Nov 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
advapi32: Improve PerfCreateInstance() stub.
Signed-off-by:
Paul Gofman
<
pgofman@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ee8af8ff
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
156 additions
and
10 deletions
+156
-10
perf.c
dlls/advapi32/tests/perf.c
+59
-4
main.c
dlls/kernelbase/main.c
+94
-6
perflib.h
include/perflib.h
+3
-0
No files found.
dlls/advapi32/tests/perf.c
View file @
eec443af
...
...
@@ -42,17 +42,24 @@ void test_provider_init(void)
static
struct
{
PERF_COUNTERSET_INFO
counterset
;
PERF_COUNTER_INFO
counter
;
PERF_COUNTER_INFO
counter
[
2
]
;
}
pc_template
=
{
{{
0
}},
{
1
,
PERF_COUNTER_COUNTER
,
PERF_ATTRIB_BY_REFERENCE
,
sizeof
(
PERF_COUNTER_INFO
),
PERF_DETAIL_NOVICE
,
0
,
0
},
{
{
1
,
PERF_COUNTER_COUNTER
,
PERF_ATTRIB_BY_REFERENCE
,
sizeof
(
PERF_COUNTER_INFO
),
PERF_DETAIL_NOVICE
,
0
,
0xdeadbeef
},
{
2
,
PERF_COUNTER_COUNTER
,
PERF_ATTRIB_BY_REFERENCE
,
sizeof
(
PERF_COUNTER_INFO
),
PERF_DETAIL_NOVICE
,
0
,
0xdeadbeef
},
},
};
PERF_COUNTERSET_INSTANCE
*
instance
;
PERF_PROVIDER_CONTEXT
prov_context
;
UINT64
counter1
,
counter2
;
HANDLE
prov
,
prov2
;
ULONG
ret
;
ULONG
ret
,
size
;
BOOL
bret
;
prov
=
(
HANDLE
)
0xdeadbeef
;
...
...
@@ -99,7 +106,7 @@ void test_provider_init(void)
pc_template
.
counterset
.
CounterSetGuid
=
test_set_guid
;
pc_template
.
counterset
.
ProviderGuid
=
test_guid
;
pc_template
.
counterset
.
NumCounters
=
1
;
pc_template
.
counterset
.
NumCounters
=
2
;
pc_template
.
counterset
.
InstanceType
=
PERF_COUNTERSET_SINGLE_INSTANCE
;
ret
=
PerfSetCounterSetInfo
(
prov
,
&
pc_template
.
counterset
,
sizeof
(
pc_template
));
ok
(
!
ret
,
"Got unexpected ret %u.
\n
"
,
ret
);
...
...
@@ -115,6 +122,54 @@ void test_provider_init(void)
ret
=
PerfSetCounterSetInfo
(
prov
,
&
pc_template
.
counterset
,
sizeof
(
pc_template
));
ok
(
ret
==
ERROR_ALREADY_EXISTS
,
"Got unexpected ret %u.
\n
"
,
ret
);
SetLastError
(
0xdeadbeef
);
instance
=
PerfCreateInstance
(
prov
,
NULL
,
L"1"
,
1
);
ok
(
!
instance
,
"Got unexpected instance %p.
\n
"
,
instance
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Got unexpected error %u.
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
instance
=
PerfCreateInstance
(
prov
,
&
test_guid
,
L"1"
,
1
);
ok
(
!
instance
,
"Got unexpected instance %p.
\n
"
,
instance
);
ok
(
GetLastError
()
==
ERROR_NOT_FOUND
,
"Got unexpected error %u.
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
instance
=
PerfCreateInstance
(
prov
,
&
test_guid
,
NULL
,
1
);
ok
(
!
instance
,
"Got unexpected instance %p.
\n
"
,
instance
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Got unexpected error %u.
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
instance
=
PerfCreateInstance
(
prov
,
&
test_set_guid
,
L"11"
,
1
);
ok
(
!!
instance
,
"Got NULL instance.
\n
"
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"Got unexpected error %u.
\n
"
,
GetLastError
());
ok
(
instance
->
InstanceId
==
1
,
"Got unexpected InstanceId %u.
\n
"
,
instance
->
InstanceId
);
ok
(
instance
->
InstanceNameSize
==
6
,
"Got unexpected InstanceNameSize %u.
\n
"
,
instance
->
InstanceNameSize
);
ok
(
IsEqualGUID
(
&
instance
->
CounterSetGuid
,
&
test_set_guid
),
"Got unexpected guid %s.
\n
"
,
debugstr_guid
(
&
instance
->
CounterSetGuid
));
ok
(
instance
->
InstanceNameOffset
==
sizeof
(
*
instance
)
+
sizeof
(
UINT64
)
*
2
,
"Got unexpected InstanceNameOffset %u.
\n
"
,
instance
->
InstanceNameOffset
);
ok
(
!
lstrcmpW
((
WCHAR
*
)((
BYTE
*
)
instance
+
instance
->
InstanceNameOffset
),
L"11"
),
"Got unexpected instance name %s.
\n
"
,
debugstr_w
((
WCHAR
*
)((
BYTE
*
)
instance
+
instance
->
InstanceNameOffset
)));
size
=
((
sizeof
(
*
instance
)
+
sizeof
(
UINT64
)
*
2
+
instance
->
InstanceNameSize
)
+
7
)
&
~
7
;
ok
(
size
==
instance
->
dwSize
,
"Got unexpected size %u, instance->dwSize %u.
\n
"
,
size
,
instance
->
dwSize
);
ret
=
PerfSetCounterRefValue
(
prov
,
instance
,
1
,
&
counter1
);
todo_wine
ok
(
!
ret
,
"Got unexpected ret %u.
\n
"
,
ret
);
ret
=
PerfSetCounterRefValue
(
prov
,
instance
,
2
,
&
counter2
);
todo_wine
ok
(
!
ret
,
"Got unexpected ret %u.
\n
"
,
ret
);
ret
=
PerfSetCounterRefValue
(
prov
,
instance
,
0
,
&
counter2
);
todo_wine
ok
(
ret
==
ERROR_NOT_FOUND
,
"Got unexpected ret %u.
\n
"
,
ret
);
todo_wine
ok
(
*
(
void
**
)(
instance
+
1
)
==
&
counter1
,
"Got unexpected counter value %p.
\n
"
,
*
(
void
**
)(
instance
+
1
));
todo_wine
ok
(
*
(
void
**
)((
BYTE
*
)
instance
+
sizeof
(
*
instance
)
+
sizeof
(
UINT64
))
==
&
counter2
,
"Got unexpected counter value %p.
\n
"
,
*
(
void
**
)(
instance
+
1
));
ret
=
PerfDeleteInstance
(
prov
,
instance
);
ok
(
!
ret
,
"Got unexpected ret %u.
\n
"
,
ret
);
ret
=
PerfStopProvider
(
prov
);
ok
(
!
ret
,
"Got unexpected ret %u.
\n
"
,
ret
);
...
...
dlls/kernelbase/main.c
View file @
eec443af
...
...
@@ -30,6 +30,7 @@
#include "wine/debug.h"
#include "kernelbase.h"
#include "wine/heap.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
kernelbase
);
...
...
@@ -160,12 +161,21 @@ struct counterset_template
PERF_COUNTER_INFO
counter
[
1
];
};
struct
counterset_instance
{
struct
list
entry
;
struct
counterset_template
*
template
;
PERF_COUNTERSET_INSTANCE
instance
;
};
struct
perf_provider
{
GUID
guid
;
PERFLIBREQUEST
callback
;
struct
counterset_template
**
countersets
;
unsigned
int
counterset_count
;
struct
list
instance_list
;
};
static
struct
perf_provider
*
perf_provider_from_handle
(
HANDLE
prov
)
...
...
@@ -176,20 +186,82 @@ static struct perf_provider *perf_provider_from_handle(HANDLE prov)
/***********************************************************************
* PerfCreateInstance (KERNELBASE.@)
*/
P
PERF_COUNTERSET_INSTANCE
WINAPI
PerfCreateInstance
(
HANDLE
handle
,
LPCGUID
guid
,
const
WCHAR
*
name
,
ULONG
id
)
P
ERF_COUNTERSET_INSTANCE
WINAPI
*
PerfCreateInstance
(
HANDLE
handle
,
const
GUID
*
guid
,
const
WCHAR
*
name
,
ULONG
id
)
{
FIXME
(
"%p %s %s %u: stub
\n
"
,
handle
,
debugstr_guid
(
guid
),
debugstr_w
(
name
),
id
);
struct
perf_provider
*
prov
=
perf_provider_from_handle
(
handle
);
struct
counterset_template
*
template
;
struct
counterset_instance
*
inst
;
unsigned
int
i
;
ULONG
size
;
FIXME
(
"handle %p, guid %s, name %s, id %u semi-stub.
\n
"
,
handle
,
debugstr_guid
(
guid
),
debugstr_w
(
name
),
id
);
if
(
!
prov
||
!
guid
||
!
name
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
NULL
;
}
for
(
i
=
0
;
i
<
prov
->
counterset_count
;
++
i
)
if
(
IsEqualGUID
(
guid
,
&
prov
->
countersets
[
i
]
->
counterset
.
CounterSetGuid
))
break
;
if
(
i
==
prov
->
counterset_count
)
{
SetLastError
(
ERROR_NOT_FOUND
);
return
NULL
;
}
template
=
prov
->
countersets
[
i
];
LIST_FOR_EACH_ENTRY
(
inst
,
&
prov
->
instance_list
,
struct
counterset_instance
,
entry
)
{
if
(
inst
->
template
==
template
&&
inst
->
instance
.
InstanceId
==
id
)
{
SetLastError
(
ERROR_ALREADY_EXISTS
);
return
NULL
;
}
}
size
=
(
sizeof
(
PERF_COUNTERSET_INSTANCE
)
+
template
->
counterset
.
NumCounters
*
sizeof
(
UINT64
)
+
(
lstrlenW
(
name
)
+
1
)
*
sizeof
(
WCHAR
)
+
7
)
&
~
7
;
inst
=
heap_alloc_zero
(
offsetof
(
struct
counterset_instance
,
instance
)
+
size
);
if
(
!
inst
)
{
SetLastError
(
ERROR_OUTOFMEMORY
);
return
NULL
;
}
inst
->
template
=
template
;
inst
->
instance
.
CounterSetGuid
=
*
guid
;
inst
->
instance
.
dwSize
=
size
;
inst
->
instance
.
InstanceId
=
id
;
inst
->
instance
.
InstanceNameOffset
=
sizeof
(
PERF_COUNTERSET_INSTANCE
)
+
template
->
counterset
.
NumCounters
*
sizeof
(
UINT64
);
inst
->
instance
.
InstanceNameSize
=
(
lstrlenW
(
name
)
+
1
)
*
sizeof
(
WCHAR
);
memcpy
(
(
BYTE
*
)
&
inst
->
instance
+
inst
->
instance
.
InstanceNameOffset
,
name
,
inst
->
instance
.
InstanceNameSize
);
list_add_tail
(
&
prov
->
instance_list
,
&
inst
->
entry
);
return
&
inst
->
instance
;
}
/***********************************************************************
* PerfDeleteInstance (KERNELBASE.@)
*/
ULONG
WINAPI
PerfDeleteInstance
(
HANDLE
provider
,
P
PERF_COUNTERSET_INSTANCE
block
)
ULONG
WINAPI
PerfDeleteInstance
(
HANDLE
provider
,
P
ERF_COUNTERSET_INSTANCE
*
block
)
{
FIXME
(
"%p %p: stub
\n
"
,
provider
,
block
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
struct
perf_provider
*
prov
=
perf_provider_from_handle
(
provider
);
struct
counterset_instance
*
inst
;
TRACE
(
"provider %p, block %p.
\n
"
,
provider
,
block
);
if
(
!
prov
||
!
block
)
return
ERROR_INVALID_PARAMETER
;
inst
=
CONTAINING_RECORD
(
block
,
struct
counterset_instance
,
instance
);
list_remove
(
&
inst
->
entry
);
heap_free
(
inst
);
return
ERROR_SUCCESS
;
}
/***********************************************************************
...
...
@@ -229,6 +301,8 @@ ULONG WINAPI PerfSetCounterSetInfo( HANDLE handle, PERF_COUNTERSET_INFO *templat
return
ERROR_OUTOFMEMORY
;
}
memcpy
(
new
,
template
,
size
);
for
(
i
=
0
;
i
<
template
->
NumCounters
;
++
i
)
new
->
counter
[
i
].
Offset
=
i
*
sizeof
(
UINT64
);
new_array
[
prov
->
counterset_count
++
]
=
new
;
prov
->
countersets
=
new_array
;
...
...
@@ -273,7 +347,11 @@ ULONG WINAPI PerfStartProviderEx( GUID *guid, PERF_PROVIDER_CONTEXT *context, HA
if
(
!
guid
||
!
context
||
!
provider
)
return
ERROR_INVALID_PARAMETER
;
if
(
context
->
ContextSize
<
sizeof
(
*
context
))
return
ERROR_INVALID_PARAMETER
;
if
(
context
->
MemAllocRoutine
||
context
->
MemFreeRoutine
)
FIXME
(
"Memory allocation routine is not supported.
\n
"
);
if
(
!
(
prov
=
heap_alloc_zero
(
sizeof
(
*
prov
)
)))
return
ERROR_OUTOFMEMORY
;
list_init
(
&
prov
->
instance_list
);
memcpy
(
&
prov
->
guid
,
guid
,
sizeof
(
prov
->
guid
)
);
prov
->
callback
=
context
->
ControlCallback
;
*
provider
=
prov
;
...
...
@@ -287,10 +365,20 @@ ULONG WINAPI PerfStartProviderEx( GUID *guid, PERF_PROVIDER_CONTEXT *context, HA
ULONG
WINAPI
PerfStopProvider
(
HANDLE
handle
)
{
struct
perf_provider
*
prov
=
perf_provider_from_handle
(
handle
);
struct
counterset_instance
*
inst
,
*
next
;
unsigned
int
i
;
TRACE
(
"handle %p.
\n
"
,
handle
);
if
(
!
list_empty
(
&
prov
->
instance_list
))
WARN
(
"Stopping provider with active counter instances.
\n
"
);
LIST_FOR_EACH_ENTRY_SAFE
(
inst
,
next
,
&
prov
->
instance_list
,
struct
counterset_instance
,
entry
)
{
list_remove
(
&
inst
->
entry
);
heap_free
(
inst
);
}
for
(
i
=
0
;
i
<
prov
->
counterset_count
;
++
i
)
heap_free
(
prov
->
countersets
[
i
]
);
heap_free
(
prov
->
countersets
);
...
...
include/perflib.h
View file @
eec443af
...
...
@@ -81,6 +81,9 @@ typedef struct _PROVIDER_CONTEXT {
LPVOID
pMemContext
;
}
PERF_PROVIDER_CONTEXT
,
*
PPERF_PROVIDER_CONTEXT
;
PERF_COUNTERSET_INSTANCE
WINAPI
*
PerfCreateInstance
(
HANDLE
,
const
GUID
*
,
const
WCHAR
*
,
ULONG
);
ULONG
WINAPI
PerfDeleteInstance
(
HANDLE
,
PERF_COUNTERSET_INSTANCE
*
);
ULONG
WINAPI
PerfSetCounterRefValue
(
HANDLE
,
PERF_COUNTERSET_INSTANCE
*
,
ULONG
,
void
*
);
ULONG
WINAPI
PerfSetCounterSetInfo
(
HANDLE
,
PERF_COUNTERSET_INFO
*
,
ULONG
);
ULONG
WINAPI
PerfStartProvider
(
GUID
*
,
PERFLIBREQUEST
,
HANDLE
*
);
ULONG
WINAPI
PerfStartProviderEx
(
GUID
*
,
PERF_PROVIDER_CONTEXT
*
,
HANDLE
*
);
...
...
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