These functions are used by Visual Studio 2019, when opening or converting some projects.
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it
-- v22: kernelbase: Check for PERF_SIZE_LARGE in PerfSetULongLongCounterValue and PerfSetULongCounterValue kernelbase: Check for PERF_ATTRIB_BY_REFERENCE attribute in PerfSetCounterRefValue advapi32/test: Add Test For PerfSetULongLongCounterValue advapi32/tests: Create Tests for PerfSetULongCounterValue. advapi32: Forward PerfSetULongCounterValue and PerfSetULongLongCounterValue to kernelbase kernelbase: Add implementation for PerfSetULongLongCounterValue kernelbase: Add implementation of PerfSetULongCounterValue kernelbase: factor out common functionality for performance counter functions
From: Lorenzo Ferrillo lorenzofersteam@live.it
--- dlls/kernelbase/main.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c index 60173ba6513..7829f02f785 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -301,6 +301,22 @@ ULONG WINAPI PerfSetCounterSetInfo( HANDLE handle, PERF_COUNTERSET_INFO *templat return STATUS_SUCCESS; }
+static PERF_COUNTER_INFO* get_performance_counter_info(PERF_COUNTERSET_INSTANCE *instance, ULONG counter_id ,struct counterset_instance ** out_instance) +{ + unsigned int i; + struct counterset_template *template; + struct counterset_instance *inst; + + inst = CONTAINING_RECORD(instance, struct counterset_instance, instance); + template = inst->template; + + *out_instance = inst; + + for (i = 0; i < template->counterset.NumCounters; ++i) + if (template->counter[i].CounterId == counter_id) return &template->counter[i]; + return NULL; +} + /*********************************************************************** * PerfSetCounterRefValue (KERNELBASE.@) */ @@ -308,23 +324,18 @@ ULONG WINAPI PerfSetCounterRefValue(HANDLE provider, PERF_COUNTERSET_INSTANCE *i ULONG counterid, void *address) { struct perf_provider *prov = perf_provider_from_handle( provider ); - struct counterset_template *template; struct counterset_instance *inst; - unsigned int i; + PERF_COUNTER_INFO* counter;
FIXME( "provider %p, instance %p, counterid %lu, address %p semi-stub.\n", provider, instance, counterid, address );
if (!prov || !instance || !address) 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; + counter = get_performance_counter_info(instance, counterid, &inst);
- if (i == template->counterset.NumCounters) return ERROR_NOT_FOUND; - *(void **)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + template->counter[i].Offset) = address; + if (counter == NULL) return ERROR_NOT_FOUND; + *(void **)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + counter->Offset) = address;
return STATUS_SUCCESS; }
From: Lorenzo Ferrillo lorenzofersteam@live.it
--- dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/main.c | 25 +++++++++++++++++++++++++ include/perflib.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index d11a4417d48..fa6858a893a 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1195,7 +1195,7 @@ # @ stub PerfQueryInstance @ stdcall PerfSetCounterRefValue(long ptr long ptr) @ stdcall PerfSetCounterSetInfo(long ptr long) -# @ stub PerfSetULongCounterValue +@ stdcall PerfSetULongCounterValue(long ptr long long) # @ stub PerfSetULongLongCounterValue @ stdcall PerfStartProvider(ptr ptr ptr) @ stdcall PerfStartProviderEx(ptr ptr ptr) diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c index 7829f02f785..d448593a632 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -340,6 +340,31 @@ 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_instance *inst; + PERF_COUNTER_INFO* counter; + + TRACE( "provider %p, instance %p, counterid %lu, address %lu semi-stub.\n", + provider, instance, counterid, value ); + + if (!prov || !instance) return ERROR_INVALID_PARAMETER; + + counter = get_performance_counter_info(instance, counterid, &inst); + + if (counter == NULL) return ERROR_NOT_FOUND; + if (counter->Attrib & PERF_ATTRIB_BY_REFERENCE) return ERROR_INVALID_PARAMETER; + + *(ULONG*)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + counter->Offset) = value; + + return STATUS_SUCCESS; +} + /*********************************************************************** * PerfStartProvider (KERNELBASE.@) */ diff --git a/include/perflib.h b/include/perflib.h index 188f26e3e74..53c17f9efe8 100644 --- a/include/perflib.h +++ b/include/perflib.h @@ -106,6 +106,7 @@ 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 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
--- dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/main.c | 25 +++++++++++++++++++++++++ include/perflib.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index fa6858a893a..daab63e85e2 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1196,7 +1196,7 @@ @ stdcall PerfSetCounterRefValue(long ptr long ptr) @ stdcall PerfSetCounterSetInfo(long ptr long) @ stdcall PerfSetULongCounterValue(long ptr long long) -# @ stub PerfSetULongLongCounterValue +@ 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 d448593a632..44d9866dddd 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -365,6 +365,31 @@ ULONG WINAPI PerfSetULongCounterValue(HANDLE provider, PERF_COUNTERSET_INSTANCE 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_instance *inst; + PERF_COUNTER_INFO* counter; + + TRACE( "provider %p, instance %p, counterid %lu, address %I64u semi-stub.\n", + provider, instance, counterid, value ); + + if (!prov || !instance) return ERROR_INVALID_PARAMETER; + + counter = get_performance_counter_info(instance, counterid, &inst); + + if (counter == NULL) return ERROR_NOT_FOUND; + if (counter->Attrib & PERF_ATTRIB_BY_REFERENCE) return ERROR_INVALID_PARAMETER; + + *(ULONGLONG*)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + counter->Offset) = value; + + return STATUS_SUCCESS; +} + /*********************************************************************** * PerfStartProvider (KERNELBASE.@) */ diff --git a/include/perflib.h b/include/perflib.h index 53c17f9efe8..6d14daffc4d 100644 --- a/include/perflib.h +++ b/include/perflib.h @@ -107,6 +107,7 @@ PERF_COUNTERSET_INSTANCE WINAPI *PerfCreateInstance(HANDLE, const GUID *, const 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 kernelbase --- 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 79b64df8abb..e4b6c5a981a 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 tests showing that PerfSetCounterRefValue cannot be used without BYREF counters --- dlls/advapi32/tests/perf.c | 77 +++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 6 deletions(-)
diff --git a/dlls/advapi32/tests/perf.c b/dlls/advapi32/tests/perf.c index 7481020dd4e..f8b29662d7c 100644 --- a/dlls/advapi32/tests/perf.c +++ b/dlls/advapi32/tests/perf.c @@ -54,17 +54,18 @@ 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,6 +75,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; @@ -187,6 +198,60 @@ 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 = PerfSetULongCounterValue(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 = 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);
From: Lorenzo Ferrillo lorenzofersteam@live.it
--- dlls/advapi32/tests/perf.c | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/dlls/advapi32/tests/perf.c b/dlls/advapi32/tests/perf.c index f8b29662d7c..82114449c66 100644 --- a/dlls/advapi32/tests/perf.c +++ b/dlls/advapi32/tests/perf.c @@ -85,6 +85,16 @@ void test_provider_init(void) PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, }, }; + struct template pc_template_val_long = + { + {{0}}, + { + {1, (PERF_COUNTER_COUNTER & ~PERF_SIZE_DWORD) | PERF_SIZE_LARGE, 0, sizeof(PERF_COUNTER_INFO), + PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, + {2, (PERF_COUNTER_COUNTER & ~PERF_SIZE_DWORD) | PERF_SIZE_LARGE, 0, sizeof(PERF_COUNTER_INFO), + PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, + }, + };
PERF_COUNTERSET_INSTANCE *instance; PERF_PROVIDER_CONTEXT prov_context; @@ -203,9 +213,15 @@ void test_provider_init(void) 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); @@ -247,6 +263,15 @@ void test_provider_init(void) ret = PerfSetULongCounterValue(prov, instance, 2, 9000L); ok(!ret, "Got unexpected ret %lu.\n", ret);
+ /* Cannot be used with PERF_SIZE_DWORD */ + ret = PerfSetULongLongCounterValue(prov, instance, 1, 900000L); + todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongLongCounterValue(prov, instance, 2, 666L); + todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + + ret = PerfSetULongLongCounterValue(prov, instance, 0, 42); + ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret); + 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); @@ -258,6 +283,48 @@ void test_provider_init(void) 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_long.counterset.CounterSetGuid = test_set_guid; + pc_template_val_long.counterset.ProviderGuid = test_guid; + pc_template_val_long.counterset.NumCounters = 2; + pc_template_val_long.counterset.InstanceType = PERF_COUNTERSET_SINGLE_INSTANCE; + ret = PerfSetCounterSetInfo(prov, &pc_template_val_long.counterset, sizeof(pc_template_val_long)); + 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 = 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)); + + /* Don't work on PERF_SIZE_LARGE */ + ret = PerfSetULongCounterValue(prov, instance, 1, 666L); + todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ret = PerfSetULongCounterValue(prov, instance, 2, 900000L); + 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); + + ret = PerfStopProvider(prov); + ok(!ret, "Got unexpected ret %lu.\n", ret); + memset( &prov_context, 0, sizeof(prov_context) ); prov = (HANDLE)0xdeadbeef; ret = PerfStartProviderEx( &test_guid, &prov_context, &prov );
From: Lorenzo Ferrillo lorenzofersteam@live.it
Tests shown that counters that have this attribute not set should be rejected in the SetCounterRefValue function --- dlls/advapi32/tests/perf.c | 4 ++-- dlls/kernelbase/main.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/advapi32/tests/perf.c b/dlls/advapi32/tests/perf.c index 82114449c66..409ebff95d5 100644 --- a/dlls/advapi32/tests/perf.c +++ b/dlls/advapi32/tests/perf.c @@ -273,9 +273,9 @@ void test_provider_init(void) ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret);
ret = PerfSetCounterRefValue(prov, instance, 1, &counter1); - todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + 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); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
ret = PerfDeleteInstance(prov, instance); ok(!ret, "Got unexpected ret %lu.\n", ret); diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c index 44d9866dddd..0313b0406e1 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -335,6 +335,8 @@ ULONG WINAPI PerfSetCounterRefValue(HANDLE provider, PERF_COUNTERSET_INSTANCE *i counter = get_performance_counter_info(instance, counterid, &inst);
if (counter == NULL) return ERROR_NOT_FOUND; + if (!(counter->Attrib & PERF_ATTRIB_BY_REFERENCE)) return ERROR_INVALID_PARAMETER; + *(void **)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + counter->Offset) = address;
return STATUS_SUCCESS;
From: Lorenzo Ferrillo lorenzofersteam@live.it
Should be setted for SetULongULong function and unsetted fo SetULong one, as test shown. --- dlls/advapi32/tests/perf.c | 8 ++++---- dlls/kernelbase/main.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/dlls/advapi32/tests/perf.c b/dlls/advapi32/tests/perf.c index 409ebff95d5..f46eca1397a 100644 --- a/dlls/advapi32/tests/perf.c +++ b/dlls/advapi32/tests/perf.c @@ -265,9 +265,9 @@ void test_provider_init(void)
/* Cannot be used with PERF_SIZE_DWORD */ ret = PerfSetULongLongCounterValue(prov, instance, 1, 900000L); - todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); ret = PerfSetULongLongCounterValue(prov, instance, 2, 666L); - todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
ret = PerfSetULongLongCounterValue(prov, instance, 0, 42); ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret); @@ -315,9 +315,9 @@ void test_provider_init(void)
/* Don't work on PERF_SIZE_LARGE */ ret = PerfSetULongCounterValue(prov, instance, 1, 666L); - todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); ret = PerfSetULongCounterValue(prov, instance, 2, 900000L); - todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
ret = PerfDeleteInstance(prov, instance); ok(!ret, "Got unexpected ret %lu.\n", ret); diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c index 0313b0406e1..ce6e0d8d5f5 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -26,6 +26,7 @@ #include "shlwapi.h" #include "perflib.h" #include "winternl.h" +#include "winperf.h"
#include "wine/debug.h" #include "kernelbase.h" @@ -361,6 +362,7 @@ ULONG WINAPI PerfSetULongCounterValue(HANDLE provider, PERF_COUNTERSET_INSTANCE
if (counter == NULL) return ERROR_NOT_FOUND; if (counter->Attrib & PERF_ATTRIB_BY_REFERENCE) return ERROR_INVALID_PARAMETER; + if (counter->Type & PERF_SIZE_LARGE) return ERROR_INVALID_PARAMETER;
*(ULONG*)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + counter->Offset) = value;
@@ -386,6 +388,7 @@ ULONG WINAPI PerfSetULongLongCounterValue(HANDLE provider, PERF_COUNTERSET_INSTA
if (counter == NULL) return ERROR_NOT_FOUND; if (counter->Attrib & PERF_ATTRIB_BY_REFERENCE) return ERROR_INVALID_PARAMETER; + if (!(counter->Type & PERF_SIZE_LARGE)) return ERROR_INVALID_PARAMETER;
*(ULONGLONG*)((BYTE *)&inst->instance + sizeof(PERF_COUNTERSET_INSTANCE) + counter->Offset) = value;