diff --git a/dlls/pdh/pdh.spec b/dlls/pdh/pdh.spec index 7ed42076daa..2f575f89c9c 100644 --- a/dlls/pdh/pdh.spec +++ b/dlls/pdh/pdh.spec @@ -40,9 +40,9 @@ @ stub PdhExpandWildCardPathHW @ stub PdhExpandWildCardPathW @ stub PdhFormatFromRawValue -@ stub PdhGetCounterInfoA -@ stub PdhGetCounterInfoW -@ stub PdhGetCounterTimeBase +@ stdcall PdhGetCounterInfoA(ptr long ptr ptr) +@ stdcall PdhGetCounterInfoW(ptr long ptr ptr) +@ stdcall PdhGetCounterTimeBase(ptr ptr) @ stub PdhGetDataSourceTimeRangeA @ stub PdhGetDataSourceTimeRangeH @ stub PdhGetDataSourceTimeRangeW diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c index a04d1ebed5f..62c99f0dd33 100644 --- a/dlls/pdh/pdh_main.c +++ b/dlls/pdh/pdh_main.c @@ -2,6 +2,7 @@ * Performance Data Helper (pdh.dll) * * Copyright 2007 Andrey Turkin + * Copyright 2007 Hans Leidekker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -283,6 +284,84 @@ PDH_STATUS WINAPI PdhCollectQueryData( PDH_HQUERY handle ) return ERROR_SUCCESS; } +/*********************************************************************** + * PdhGetCounterInfoA (PDH.@) + */ +PDH_STATUS WINAPI PdhGetCounterInfoA( PDH_HCOUNTER handle, BOOLEAN text, LPDWORD size, PPDH_COUNTER_INFO_A info ) +{ + struct counter *counter = handle; + + TRACE("%p %d %p %p\n", handle, text, size, info); + + if (!counter) return PDH_INVALID_HANDLE; + if (!size) return PDH_INVALID_ARGUMENT; + + if (*size < sizeof(PDH_COUNTER_INFO_A)) + { + *size = sizeof(PDH_COUNTER_INFO_A); + return PDH_MORE_DATA; + } + + memset( info, 0, sizeof(PDH_COUNTER_INFO_A) ); + + info->dwType = counter->type; + info->CStatus = counter->status; + info->lScale = counter->scale; + info->lDefaultScale = counter->defaultscale; + info->dwUserData = counter->user; + info->dwQueryUserData = counter->queryuser; + + *size = sizeof(PDH_COUNTER_INFO_A); + return ERROR_SUCCESS; +} + +/*********************************************************************** + * PdhGetCounterInfoW (PDH.@) + */ +PDH_STATUS WINAPI PdhGetCounterInfoW( PDH_HCOUNTER handle, BOOLEAN text, LPDWORD size, PPDH_COUNTER_INFO_W info ) +{ + struct counter *counter = handle; + + TRACE("%p %d %p %p\n", handle, text, size, info); + + if (!size) return PDH_INVALID_ARGUMENT; + if (!counter) return PDH_INVALID_HANDLE; + + if (*size < sizeof(PDH_COUNTER_INFO_W)) + { + *size = sizeof(PDH_COUNTER_INFO_W); + return PDH_MORE_DATA; + } + + memset( info, 0, sizeof(PDH_COUNTER_INFO_W) ); + + info->dwType = counter->type; + info->CStatus = counter->status; + info->lScale = counter->scale; + info->lDefaultScale = counter->defaultscale; + info->dwUserData = counter->user; + info->dwQueryUserData = counter->queryuser; + + *size = sizeof(PDH_COUNTER_INFO_A); + return ERROR_SUCCESS; +} + +/*********************************************************************** + * PdhGetCounterTimeBase (PDH.@) + */ +PDH_STATUS WINAPI PdhGetCounterTimeBase( PDH_HCOUNTER handle, LONGLONG *base ) +{ + struct counter *counter = handle; + + TRACE("%p %p\n", handle, base); + + if (!base) return PDH_INVALID_ARGUMENT; + if (!counter) return PDH_INVALID_HANDLE; + + *base = counter->base; + return ERROR_SUCCESS; +} + /*********************************************************************** * PdhGetFormattedCounterValue (PDH.@) */ diff --git a/dlls/pdh/tests/pdh.c b/dlls/pdh/tests/pdh.c index 6ddb0971d06..12770ed1aa3 100644 --- a/dlls/pdh/tests/pdh.c +++ b/dlls/pdh/tests/pdh.c @@ -213,6 +213,89 @@ static void test_PdhSetCounterScaleFactor( void ) ok(ret == ERROR_SUCCESS, "PdhCloseQuery failed 0x%08x\n", ret); } +static void test_PdhGetCounterTimeBase( void ) +{ + PDH_STATUS ret; + PDH_HQUERY query; + PDH_HCOUNTER counter; + LONGLONG base; + + ret = PdhOpenQueryA( NULL, 0, &query ); + ok(ret == ERROR_SUCCESS, "PdhOpenQueryA failed 0x%08x\n", ret); + + ret = PdhAddCounterA( query, "\\System\\System Up Time", 0, &counter ); + ok(ret == ERROR_SUCCESS, "PdhAddCounterA failed 0x%08x\n", ret); + + ret = PdhGetCounterTimeBase( NULL, NULL ); + ok(ret == PDH_INVALID_ARGUMENT, "PdhGetCounterTimeBase failed 0x%08x\n", ret); + + ret = PdhGetCounterTimeBase( NULL, &base ); + ok(ret == PDH_INVALID_HANDLE, "PdhGetCounterTimeBase failed 0x%08x\n", ret); + + ret = PdhGetCounterTimeBase( counter, NULL ); + ok(ret == PDH_INVALID_ARGUMENT, "PdhGetCounterTimeBase failed 0x%08x\n", ret); + + ret = PdhGetCounterTimeBase( counter, &base ); + ok(ret == ERROR_SUCCESS, "PdhGetCounterTimeBase failed 0x%08x\n", ret); + + ret = PdhCloseQuery( query ); + ok(ret == ERROR_SUCCESS, "PdhCloseQuery failed 0x%08x\n", ret); +} + +static void test_PdhGetCounterInfo( void ) +{ + PDH_STATUS ret; + PDH_HQUERY query; + PDH_HCOUNTER counter; + PDH_COUNTER_INFO_A info; + DWORD size; + + ret = PdhOpenQueryA( NULL, 0, &query ); + ok(ret == ERROR_SUCCESS, "PdhOpenQueryA failed 0x%08x\n", ret); + + ret = PdhAddCounterA( query, "\\System\\System Up Time", 0, &counter ); + ok(ret == ERROR_SUCCESS, "PdhAddCounterA failed 0x%08x\n", ret); + + ret = PdhGetCounterInfoA( NULL, 0, NULL, NULL ); + ok(ret == PDH_INVALID_HANDLE, "PdhGetCounterInfoA failed 0x%08x\n", ret); + + ret = PdhGetCounterInfoA( counter, 0, NULL, NULL ); + ok(ret == PDH_INVALID_ARGUMENT, "PdhGetCounterInfoA failed 0x%08x\n", ret); + + ret = PdhGetCounterInfoA( counter, 0, NULL, &info ); + ok(ret == PDH_INVALID_ARGUMENT, "PdhGetCounterInfoA failed 0x%08x\n", ret); + + size = sizeof(info) - 1; + ret = PdhGetCounterInfoA( counter, 0, &size, NULL ); + ok(ret == PDH_MORE_DATA, "PdhGetCounterInfoA failed 0x%08x\n", ret); + + size = sizeof(info); + ret = PdhGetCounterInfoA( counter, 0, &size, &info ); + ok(ret == ERROR_SUCCESS, "PdhGetCounterInfoA failed 0x%08x\n", ret); + ok(size == sizeof(info), "PdhGetCounterInfoA failed %d\n", size); + + ret = PdhGetCounterInfoA( counter, 0, &size, &info ); + ok(ret == ERROR_SUCCESS, "PdhGetCounterInfoA failed 0x%08x\n", ret); + ok(info.lScale == 0, "lScale %d\n", info.lScale); + + ret = PdhSetCounterScaleFactor( counter, 0 ); + ok(ret == ERROR_SUCCESS, "PdhSetCounterScaleFactor failed 0x%08x\n", ret); + + ret = PdhGetCounterInfoA( counter, 0, &size, &info ); + ok(ret == ERROR_SUCCESS, "PdhGetCounterInfoA failed 0x%08x\n", ret); + ok(info.lScale == 0, "lScale %d\n", info.lScale); + + ret = PdhSetCounterScaleFactor( counter, -5 ); + ok(ret == ERROR_SUCCESS, "PdhSetCounterScaleFactor failed 0x%08x\n", ret); + + ret = PdhGetCounterInfoA( counter, 0, &size, &info ); + ok(ret == ERROR_SUCCESS, "PdhGetCounterInfoA failed 0x%08x\n", ret); + ok(info.lScale == -5, "lScale %d\n", info.lScale); + + ret = PdhCloseQuery( query ); + ok(ret == ERROR_SUCCESS, "PdhCloseQuery failed 0x%08x\n", ret); +} + START_TEST(pdh) { test_open_close_query(); @@ -220,4 +303,6 @@ START_TEST(pdh) test_PdhGetFormattedCounterValue(); test_PdhGetRawCounterValue(); test_PdhSetCounterScaleFactor(); + test_PdhGetCounterTimeBase(); + test_PdhGetCounterInfo(); }