These functions are used by Visual Studio 2019, when opening or converting some projects.
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it
-- v2: advapi32/tests: Create Tests for PerfSetULongCounterValue and PerfSetULongLongCounterValue advapi32: Forward PerfSetULongCounterValue and PerfSetULongLongCounterValue to kernelbase kernelbase: Add implementation of PerfSetULongCounterValue and PerfSetULongLongCounterValue
From: Lorenzo Ferrillo lorenzofersteam@live.it
These functions are used by Visual Studio 2019, when opening or converting some projects
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it --- dlls/kernelbase/kernelbase.spec | 4 +-- dlls/kernelbase/main.c | 58 +++++++++++++++++++++++++++++++++ include/perflib.h | 3 ++ 3 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 104dd99d619..f34276af021 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1188,8 +1188,8 @@ # @ stub PerfQueryInstance @ stdcall PerfSetCounterRefValue(long ptr long ptr) @ stdcall PerfSetCounterSetInfo(long ptr long) -# @ stub PerfSetULongCounterValue -# @ stub PerfSetULongLongCounterValue +@ stdcall PerfSetULongCounterValue(long ptr long long) +@ stdcall PerfSetULongLongCounterValue(long ptr long int64) @ stdcall PerfStartProvider(ptr ptr ptr) @ stdcall PerfStartProviderEx(ptr ptr ptr) @ stdcall PerfStopProvider(long) diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c index 0309ec91589..7d02b1eeee9 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -338,6 +338,64 @@ ULONG WINAPI PerfSetCounterRefValue(HANDLE provider, PERF_COUNTERSET_INSTANCE *i return STATUS_SUCCESS; }
+/*********************************************************************** + * PerfSetULongCounterValue (KERNELBASE.@) + */ +ULONG WINAPI PerfSetULongCounterValue(HANDLE provider, PERF_COUNTERSET_INSTANCE *instance, + ULONG counterid, ULONG value) +{ + struct perf_provider *prov = perf_provider_from_handle( provider ); + struct counterset_template *template; + struct counterset_instance *inst; + unsigned int i; + + TRACE( "provider %p, instance %p, counterid %lu, address %lu semi-stub.\n", + provider, instance, counterid, value ); + + if (!prov || !instance) return ERROR_INVALID_PARAMETER; + + inst = CONTAINING_RECORD(instance, struct counterset_instance, instance); + template = inst->template; + + for (i = 0; i < template->counterset.NumCounters; ++i) + if (template->counter[i].CounterId == counterid) break; + + if (i == template->counterset.NumCounters) return ERROR_NOT_FOUND; + if (template->counter[i].Attrib & PERF_ATTRIB_BY_REFERENCE) return ERROR_INVALID_PARAMETER; + + *(ULONG*)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + template->counter[i].Offset) = value; + + return STATUS_SUCCESS; +} +/*********************************************************************** + * PerfSetULongLongCounterValue (KERNELBASE.@) + */ +ULONG WINAPI PerfSetULongLongCounterValue(HANDLE provider, PERF_COUNTERSET_INSTANCE *instance, + ULONG counterid, ULONGLONG value) +{ + struct perf_provider *prov = perf_provider_from_handle( provider ); + struct counterset_template *template; + struct counterset_instance *inst; + unsigned int i; + + TRACE( "provider %p, instance %p, counterid %lu, address %I64u semi-stub.\n", + provider, instance, counterid, value ); + + if (!prov || !instance) return ERROR_INVALID_PARAMETER; + + inst = CONTAINING_RECORD(instance, struct counterset_instance, instance); + template = inst->template; + + for (i = 0; i < template->counterset.NumCounters; ++i) + if (template->counter[i].CounterId == counterid) break; + if (i == template->counterset.NumCounters) return ERROR_NOT_FOUND; + if (template->counter[i].Attrib & PERF_ATTRIB_BY_REFERENCE) return ERROR_INVALID_PARAMETER; + + *(ULONGLONG*)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + template->counter[i].Offset) = value; + + return STATUS_SUCCESS; +} + /*********************************************************************** * PerfStartProvider (KERNELBASE.@) */ diff --git a/include/perflib.h b/include/perflib.h index 188f26e3e74..b84bdfa2466 100644 --- a/include/perflib.h +++ b/include/perflib.h @@ -106,6 +106,9 @@ typedef struct _PERF_DATA_HEADER { 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 PerfSetULongCounterValue(HANDLE, PERF_COUNTERSET_INSTANCE *, ULONG, ULONG); +ULONG WINAPI PerfSetULongLongCounterValue(HANDLE, PERF_COUNTERSET_INSTANCE *, ULONG, ULONGLONG); + ULONG WINAPI PerfSetCounterSetInfo(HANDLE, PERF_COUNTERSET_INFO *, ULONG); ULONG WINAPI PerfStartProvider(GUID *, PERFLIBREQUEST, HANDLE *); ULONG WINAPI PerfStartProviderEx(GUID *, PERF_PROVIDER_CONTEXT *, HANDLE *);
From: Lorenzo Ferrillo lorenzofersteam@live.it
VS2019 call these functions from advapi32
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it --- dlls/advapi32/advapi32.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index b69186d07a7..26622f17137 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -577,8 +577,8 @@ # @ stub PerfRegSetValue @ stdcall -import PerfSetCounterRefValue(long ptr long ptr) @ stdcall -import PerfSetCounterSetInfo(long ptr long) -# @ stub PerfSetULongCounterValue -# @ stub PerfSetULongLongCounterValue +@ stdcall -import PerfSetULongCounterValue(long ptr long long) +@ stdcall -import PerfSetULongLongCounterValue(long ptr long int64) @ stdcall -import PerfStartProvider(ptr ptr ptr) @ stdcall -import PerfStartProviderEx(ptr ptr ptr) @ stdcall -import PerfStopProvider(long)
From: Lorenzo Ferrillo lorenzofersteam@live.it
Also add test showing that PerfSetCounterRefValue cannot be used without BYREF counters
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it --- dlls/advapi32/tests/perf.c | 99 +++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 7 deletions(-)
diff --git a/dlls/advapi32/tests/perf.c b/dlls/advapi32/tests/perf.c index 7481020dd4e..0637359b599 100644 --- a/dlls/advapi32/tests/perf.c +++ b/dlls/advapi32/tests/perf.c @@ -45,6 +45,7 @@ static void init_functions(void) GET_FUNCTION(PerfOpenQueryHandle); GET_FUNCTION(PerfAddCounters); GET_FUNCTION(PerfQueryCounterData); + #undef GET_FUNCTION }
@@ -54,17 +55,19 @@ static ULONG WINAPI test_provider_callback(ULONG code, void *buffer, ULONG size) return ERROR_SUCCESS; }
+struct template +{ + PERF_COUNTERSET_INFO counterset; + PERF_COUNTER_INFO counter[2]; +}; + void test_provider_init(void) { static GUID test_set_guid = {0xdeadbeef, 0x0002, 0x0003, {0x0f, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00 ,0x0a}}; static GUID test_set_guid2 = {0xdeadbeef, 0x0003, 0x0003, {0x0f, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00 ,0x0a}}; static GUID test_guid = {0xdeadbeef, 0x0001, 0x0002, {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00 ,0x0a}}; - static struct - { - PERF_COUNTERSET_INFO counterset; - PERF_COUNTER_INFO counter[2]; - } - pc_template = + + struct template pc_template = { {{0}}, { @@ -74,7 +77,16 @@ void test_provider_init(void) PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, }, }; - + struct template pc_template_val = + { + {{0}}, + { + {1, PERF_COUNTER_COUNTER, 0, sizeof(PERF_COUNTER_INFO), + PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, + {2, PERF_COUNTER_COUNTER, 0, sizeof(PERF_COUNTER_INFO), + PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, + }, + }; PERF_COUNTERSET_INSTANCE *instance; PERF_PROVIDER_CONTEXT prov_context; UINT64 counter1, counter2; @@ -187,6 +199,79 @@ void test_provider_init(void) ok(*(void **)((BYTE *)instance + sizeof(*instance) + sizeof(UINT64)) == &counter2, "Got unexpected counter value %p.\n", *(void **)(instance + 1));
+ /*Counter defined as BYREF error if modified with SetValue functions*/ + ret = PerfSetULongCounterValue(prov, instance, 1, 666L); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongCounterValue(prov, instance, 2, 900000L); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongLongCounterValue(prov, instance, 1, 666L); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongLongCounterValue(prov, instance, 2, 900000L); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + + ret = PerfSetULongCounterValue(prov, instance, 0, 42L); + ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongLongCounterValue(prov, instance, 0, 42L); + ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret); + + ret = PerfDeleteInstance(prov, instance); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ret = PerfStopProvider(prov); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + ret = PerfStartProvider(&test_guid, test_provider_callback, &prov); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + pc_template_val.counterset.CounterSetGuid = test_set_guid; + pc_template_val.counterset.ProviderGuid = test_guid; + pc_template_val.counterset.NumCounters = 2; + pc_template_val.counterset.InstanceType = PERF_COUNTERSET_SINGLE_INSTANCE; + ret = PerfSetCounterSetInfo(prov, &pc_template_val.counterset, sizeof(pc_template_val)); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + instance = PerfCreateInstance(prov, &test_set_guid, L"11", 1); + ok(!!instance, "Got NULL instance.\n"); + ok(instance->InstanceId == 1, "Got unexpected InstanceId %lu.\n", instance->InstanceId); + ok(instance->InstanceNameSize == 6, "Got unexpected InstanceNameSize %lu.\n", instance->InstanceNameSize); + ok(IsEqualGUID(&instance->CounterSetGuid, &test_set_guid), "Got unexpected guid %s.\n", + debugstr_guid(&instance->CounterSetGuid)); + + ret = PerfSetULongCounterValue(prov, instance, 1, 666L); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongCounterValue(prov, instance, 2, 900000L); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + ret = PerfSetULongCounterValue(prov, instance, 0, 42); + ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret); + + ok(*(ULONG *)(instance + 1) == 666L, "Got unexpected counter value %lu.\n", + *(ULONG *)(instance + 1)); + ok(*(ULONG *)((BYTE *)instance + sizeof(*instance) + sizeof(UINT64)) == 900000L, + "Got unexpected counter value %lu.\n", *(ULONG *)(instance + 1)); + + ret = PerfSetULongCounterValue(prov, instance, 1, 55L); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongCounterValue(prov, instance, 2, 9000L); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + ret = PerfSetULongLongCounterValue(prov, instance, 1, 900000L); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongLongCounterValue(prov, instance, 2, 666L); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + ret = PerfSetULongLongCounterValue(prov, instance, 0, 42); + ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret); + + ok(*(ULONGLONG *)(instance + 1) == 900000L, "Got unexpected counter value %I64u.\n", + *(ULONGLONG *)(instance + 1)); + ok(*(ULONGLONG *)((BYTE *)instance + sizeof(*instance) + sizeof(UINT64)) == 666L, + "Got unexpected counter value %I64u.\n", *(ULONGLONG *)(instance + 1)); + + ret = PerfSetCounterRefValue(prov, instance, 1, &counter1); + todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ret = PerfSetCounterRefValue(prov, instance, 2, &counter2); + todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ret = PerfDeleteInstance(prov, instance); ok(!ret, "Got unexpected ret %lu.\n", ret);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=137286
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w7u_adm (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w7u_el (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w8 (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w8adm (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w864 (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064v1507 (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064v1809 (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064_tsign (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w10pro64 (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w11pro64 (32 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w7pro64 (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w864 (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064v1507 (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064v1809 (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064_2qxl (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064_adm (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w1064_tsign (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w10pro64 (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w10pro64_en_AE_u8 (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w10pro64_ar (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w10pro64_ja (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w10pro64_zh_CN (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== w11pro64_amd (64 bit report) ===
advapi32: perf.c:258: Test failed: Got unexpected ret 87. perf.c:260: Test failed: Got unexpected ret 87. perf.c:265: Test failed: Got unexpected counter value 55. perf.c:267: Test failed: Got unexpected counter value 55.
=== debian11b (64 bit WoW report) ===
uiautomationcore: Unhandled exception: page fault on read access to 0xffffffffffffffff in 64-bit code (0x0000017002acba). uiautomation.c:15294: Test failed: unhandled exception c0000005 in child process 00e8