Paul Gofman : advapi32: Improve perflib provider registration stubs.

Alexandre Julliard julliard at winehq.org
Mon Nov 22 16:05:18 CST 2021


Module: wine
Branch: master
Commit: e843605b238a754c819f0a1f80242ee7f35deda1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e843605b238a754c819f0a1f80242ee7f35deda1

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Mon Nov 22 17:07:56 2021 +0300

advapi32: Improve perflib provider registration stubs.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/advapi32/tests/Makefile.in |   1 +
 dlls/advapi32/tests/perf.c      | 100 ++++++++++++++++++++++++++++++++++++++++
 dlls/kernelbase/main.c          |  49 ++++++++++++++++----
 include/perflib.h               |   4 ++
 4 files changed, 146 insertions(+), 8 deletions(-)

diff --git a/dlls/advapi32/tests/Makefile.in b/dlls/advapi32/tests/Makefile.in
index 12583e59f57..2e9b007a91f 100644
--- a/dlls/advapi32/tests/Makefile.in
+++ b/dlls/advapi32/tests/Makefile.in
@@ -10,6 +10,7 @@ C_SRCS = \
 	crypt_sha.c \
 	eventlog.c \
 	lsa.c \
+	perf.c \
 	registry.c \
 	security.c \
 	service.c
diff --git a/dlls/advapi32/tests/perf.c b/dlls/advapi32/tests/perf.c
new file mode 100644
index 00000000000..34fedd2b645
--- /dev/null
+++ b/dlls/advapi32/tests/perf.c
@@ -0,0 +1,100 @@
+/*
+ * Unit tests for Perflib functions
+ *
+ * Copyright (c) 2021 Paul Gofman for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "perflib.h"
+
+#include "wine/test.h"
+
+static ULONG WINAPI test_provider_callback(ULONG code, void *buffer, ULONG size)
+{
+    ok(0, "Provider callback called.\n");
+    return ERROR_SUCCESS;
+}
+
+void test_provider_init(void)
+{
+    static GUID test_guid = {0xdeadbeef, 0x0001, 0x0002, {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00 ,0x0a}};
+    PERF_PROVIDER_CONTEXT prov_context;
+    HANDLE prov, prov2;
+    ULONG ret;
+    BOOL bret;
+
+    prov = (HANDLE)0xdeadbeef;
+    ret = PerfStartProvider(NULL, test_provider_callback, &prov);
+    ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
+    ok(prov == (HANDLE)0xdeadbeef, "Got unexpected prov %p.\n", prov);
+
+    prov = (HANDLE)0xdeadbeef;
+    ret = PerfStartProvider(&test_guid, test_provider_callback, NULL);
+    ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
+    ok(prov == (HANDLE)0xdeadbeef, "Got unexpected prov %p.\n", prov);
+
+    prov = (HANDLE)0xdeadbeef;
+    ret = PerfStartProvider(&test_guid, test_provider_callback, &prov);
+    ok(!ret, "Got unexpected ret %u.\n", ret);
+    ok(prov != (HANDLE)0xdeadbeef, "Provider handle is not set.\n");
+
+    prov2 = prov;
+    ret = PerfStartProvider(&test_guid, test_provider_callback, &prov2);
+    ok(!ret, "Got unexpected ret %u.\n", ret);
+    ok(prov2 != prov, "Got the same provider handle.\n");
+
+    ret = PerfStopProvider(prov2);
+    ok(!ret, "Got unexpected ret %u.\n", ret);
+
+    if (0)
+    {
+        /* Access violation on Windows. */
+        PerfStopProvider(prov2);
+    }
+
+    /* Provider handle is a pointer and not a kernel object handle. */
+    bret = DuplicateHandle(GetCurrentProcess(), prov, GetCurrentProcess(), &prov2, 0, FALSE, DUPLICATE_SAME_ACCESS);
+    ok(!bret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected bret %d, err %u.\n", bret, GetLastError());
+    bret = IsBadWritePtr(prov, 8);
+    ok(!bret, "Handle does not point to the data.\n");
+
+    ret = PerfStopProvider(prov);
+    ok(!ret, "Got unexpected ret %u.\n", ret);
+
+    memset( &prov_context, 0, sizeof(prov_context) );
+    prov = (HANDLE)0xdeadbeef;
+    ret = PerfStartProviderEx( &test_guid, &prov_context, &prov );
+    ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
+    ok(prov == (HANDLE)0xdeadbeef, "Got unexpected prov %p.\n", prov);
+
+    prov_context.ContextSize = sizeof(prov_context) + 1;
+    ret = PerfStartProviderEx( &test_guid, &prov_context, &prov );
+    ok(!ret, "Got unexpected ret %u.\n", ret);
+    ok(prov != (HANDLE)0xdeadbeef, "Provider handle is not set.\n");
+
+    ret = PerfStopProvider(prov);
+    ok(!ret, "Got unexpected ret %u.\n", ret);
+}
+
+START_TEST(perf)
+{
+    test_provider_init();
+}
diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c
index e6cf892a4dc..d468c84f619 100644
--- a/dlls/kernelbase/main.c
+++ b/dlls/kernelbase/main.c
@@ -154,6 +154,17 @@ LONG WINAPI AppPolicyGetWindowingModel(HANDLE token, AppPolicyWindowingModel *po
     return ERROR_SUCCESS;
 }
 
+struct perf_provider
+{
+    GUID guid;
+    PERFLIBREQUEST callback;
+};
+
+static struct perf_provider *perf_provider_from_handle(HANDLE prov)
+{
+    return (struct perf_provider *)prov;
+}
+
 /***********************************************************************
  *           PerfCreateInstance   (KERNELBASE.@)
  */
@@ -195,19 +206,37 @@ ULONG WINAPI PerfSetCounterRefValue(HANDLE provider, PPERF_COUNTERSET_INSTANCE i
 /***********************************************************************
  *           PerfStartProvider   (KERNELBASE.@)
  */
-ULONG WINAPI PerfStartProvider(GUID *guid, PERFLIBREQUEST callback, HANDLE *provider)
+ULONG WINAPI PerfStartProvider( GUID *guid, PERFLIBREQUEST callback, HANDLE *provider )
 {
-    FIXME("%s %p %p: stub\n", debugstr_guid(guid), callback, provider);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    PERF_PROVIDER_CONTEXT ctx;
+
+    FIXME( "guid %s, callback %p, provider %p semi-stub.\n", debugstr_guid(guid), callback, provider );
+
+    memset( &ctx, 0, sizeof(ctx) );
+    ctx.ContextSize = sizeof(ctx);
+    ctx.ControlCallback = callback;
+
+    return PerfStartProviderEx( guid, &ctx, provider );
 }
 
 /***********************************************************************
  *           PerfStartProviderEx   (KERNELBASE.@)
  */
-ULONG WINAPI PerfStartProviderEx(GUID *guid, PPERF_PROVIDER_CONTEXT context, HANDLE *provider)
+ULONG WINAPI PerfStartProviderEx( GUID *guid, PERF_PROVIDER_CONTEXT *context, HANDLE *provider )
 {
-    FIXME("%s %p %p: stub\n", debugstr_guid(guid), context, provider);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    struct perf_provider *prov;
+
+    FIXME( "guid %s, context %p, provider %p semi-stub.\n", debugstr_guid(guid), context, provider );
+
+    if (!guid || !context || !provider) return ERROR_INVALID_PARAMETER;
+    if (context->ContextSize < sizeof(*context)) return ERROR_INVALID_PARAMETER;
+
+    if (!(prov = heap_alloc_zero( sizeof(*prov) ))) return ERROR_OUTOFMEMORY;
+    memcpy( &prov->guid, guid, sizeof(prov->guid) );
+    prov->callback = context->ControlCallback;
+    *provider = prov;
+
+    return STATUS_SUCCESS;
 }
 
 /***********************************************************************
@@ -215,8 +244,12 @@ ULONG WINAPI PerfStartProviderEx(GUID *guid, PPERF_PROVIDER_CONTEXT context, HAN
  */
 ULONG WINAPI PerfStopProvider(HANDLE handle)
 {
-    FIXME("%p: stub\n", handle);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    struct perf_provider *prov = perf_provider_from_handle( handle );
+
+    TRACE( "handle %p.\n", handle );
+
+    heap_free( prov );
+    return STATUS_SUCCESS;
 }
 
 /***********************************************************************
diff --git a/include/perflib.h b/include/perflib.h
index 2d3f6efb419..47bc0716541 100644
--- a/include/perflib.h
+++ b/include/perflib.h
@@ -51,6 +51,10 @@ typedef struct _PROVIDER_CONTEXT {
     LPVOID pMemContext;
 } PERF_PROVIDER_CONTEXT, * PPERF_PROVIDER_CONTEXT;
 
+ULONG WINAPI PerfStartProvider(GUID *, PERFLIBREQUEST, HANDLE *);
+ULONG WINAPI PerfStartProviderEx(GUID *, PERF_PROVIDER_CONTEXT *, HANDLE *);
+ULONG WINAPI PerfStopProvider(HANDLE);
+
 #ifdef __cplusplus
 }       /* extern "C" */
 #endif




More information about the wine-cvs mailing list