pdh: Implement and test PdhAddEnglishCounter{A, W} and PdhCollectQueryDataWithTime.
diff --git a/dlls/pdh/pdh.spec b/dlls/pdh/pdh.spec
index 9f9e9b3..c28d2a8 100644
--- a/dlls/pdh/pdh.spec
+++ b/dlls/pdh/pdh.spec
@@ -3,6 +3,8 @@
 @ stub PdhAdd009CounterW
 @ stdcall PdhAddCounterA(ptr str long ptr)
 @ stdcall PdhAddCounterW(ptr wstr long ptr)
+@ stdcall PdhAddEnglishCounterA(ptr str long ptr)
+@ stdcall PdhAddEnglishCounterW(ptr wstr long ptr)
 @ stub PdhBindInputDataSourceA
 @ stub PdhBindInputDataSourceW
 @ stub PdhBrowseCountersA
@@ -13,6 +15,7 @@
 @ stub PdhCloseLog
 @ stdcall PdhCloseQuery(ptr)
 @ stdcall PdhCollectQueryData(ptr)
+@ stdcall PdhCollectQueryDataWithTime(ptr ptr)
 @ stub PdhCollectQueryDataEx
 @ stub PdhComputeCounterStatistics
 @ stub PdhConnectMachineA
@@ -135,6 +138,8 @@
 @ stub PdhUpdateLogFileCatalog
 @ stub PdhUpdateLogW
 @ stub PdhValidatePathA
+@ stub PdhValidatePathExA
+@ stub PdhValidatePathExW
 @ stub PdhValidatePathW
 @ stub PdhVbAddCounter
 @ stub PdhVbCreateCounterPathList
diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c
index 5477268..5253620 100644
--- a/dlls/pdh/pdh_main.c
+++ b/dlls/pdh/pdh_main.c
@@ -259,6 +259,24 @@
 }
 
 /***********************************************************************
+ *              PdhAddEnglishCounterA   (PDH.@)
+ */
+PDH_STATUS WINAPI PdhAddEnglishCounterA( PDH_HQUERY query, LPCSTR path,
+                                         DWORD_PTR userdata, PDH_HCOUNTER *counter )
+{
+    return PdhAddCounterA( query, path, userdata, counter );
+}
+
+/***********************************************************************
+ *              PdhAddEnglishCounterW   (PDH.@)
+ */
+PDH_STATUS WINAPI PdhAddEnglishCounterW( PDH_HQUERY query, LPCWSTR path,
+                                         DWORD_PTR userdata, PDH_HCOUNTER *counter )
+{
+    return PdhAddCounterW( query, path, userdata, counter );
+}
+
+/***********************************************************************
  *              PdhCloseQuery   (PDH.@)
  */
 PDH_STATUS WINAPI PdhCloseQuery( PDH_HQUERY handle )
@@ -312,6 +330,31 @@
 }
 
 /***********************************************************************
+ *              PdhCollectQueryDataWithTime   (PDH.@)
+ */
+PDH_STATUS WINAPI PdhCollectQueryDataWithTime( PDH_HQUERY handle, LONGLONG *timestamp )
+{
+    PDH_STATUS ret;
+    struct query *query = handle;
+
+    TRACE("%p %p\n", handle, timestamp);
+
+    if (!query || (query->magic != PDH_MAGIC_QUERY)) return PDH_INVALID_HANDLE;
+
+    if (list_empty( &query->counters )) return PDH_NO_DATA;
+
+    ret = PdhCollectQueryData( query );
+    if (!ret && timestamp)
+    {
+        struct list *item = list_head( &query->counters );
+        struct counter *counter = LIST_ENTRY( item, struct counter, entry );
+
+        *timestamp = ((LONGLONG)counter->stamp.dwHighDateTime << 32) | counter->stamp.dwLowDateTime;
+    }
+    return ret;
+}
+
+/***********************************************************************
  *              PdhGetCounterInfoA   (PDH.@)
  */
 PDH_STATUS WINAPI PdhGetCounterInfoA( PDH_HCOUNTER handle, BOOLEAN text, LPDWORD size, PPDH_COUNTER_INFO_A info )
diff --git a/dlls/pdh/tests/pdh.c b/dlls/pdh/tests/pdh.c
index ce27f52..220f35a 100644
--- a/dlls/pdh/tests/pdh.c
+++ b/dlls/pdh/tests/pdh.c
@@ -27,6 +27,22 @@
 
 #include "wine/test.h"
 
+static HMODULE pdh;
+
+static PDH_STATUS   (WINAPI *pPdhAddEnglishCounterA)(PDH_HQUERY, LPCSTR, DWORD_PTR, PDH_HCOUNTER *);
+static PDH_STATUS   (WINAPI *pPdhAddEnglishCounterW)(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER *);
+static PDH_STATUS   (WINAPI *pPdhCollectQueryDataWithTime)(PDH_HQUERY, LONGLONG *);
+
+#define GETFUNCPTR(func) p##func = (void *)GetProcAddress( pdh, #func );
+
+static void init_function_ptrs( void )
+{
+    pdh = GetModuleHandle( "pdh" );
+    GETFUNCPTR( PdhAddEnglishCounterA )
+    GETFUNCPTR( PdhAddEnglishCounterW )
+    GETFUNCPTR( PdhCollectQueryDataWithTime )
+}
+
 static const WCHAR processor_time[] =
     {'%',' ','P','r','o','c','e','s','s','o','r',' ','T','i','m','e',0};
 static const WCHAR uptime[] =
@@ -182,6 +198,111 @@
     ok(ret == ERROR_SUCCESS, "PdhCloseQuery failed 0x%08x\n", ret);
 }
 
+static void test_PdhAddEnglishCounterA( void )
+{
+    PDH_STATUS ret;
+    PDH_HQUERY query;
+    PDH_HCOUNTER counter;
+
+    ret = PdhOpenQueryA( NULL, 0, &query );
+    ok(ret == ERROR_SUCCESS, "PdhOpenQueryA failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterA( NULL, "\\System\\System Up Time", 0, NULL );
+    ok(ret == PDH_INVALID_ARGUMENT, "PdhAddEnglishCounterA failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterA( NULL, "\\System\\System Up Time", 0, &counter );
+    ok(ret == PDH_INVALID_HANDLE, "PdhAddEnglishCounterA failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterA( query, NULL, 0, &counter );
+    ok(ret == PDH_INVALID_ARGUMENT, "PdhAddEnglishCounterA failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterA( query, "\\System\\System Up Time", 0, NULL );
+    ok(ret == PDH_INVALID_ARGUMENT, "PdhAddEnglishCounterA failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterA( query, "\\System\\System Down Time", 0, &counter );
+    ok(ret == PDH_CSTATUS_NO_COUNTER, "PdhAddEnglishCounterA failed 0x%08x\n", ret);
+    ok(!counter, "PdhAddEnglishCounterA failed %p\n", counter);
+
+    ret = pPdhAddEnglishCounterA( query, "\\System\\System Up Time", 0, &counter );
+    ok(ret == ERROR_SUCCESS, "PdhAddEnglishCounterA failed 0x%08x\n", ret);
+
+    ret = PdhCollectQueryData( query );
+    ok(ret == ERROR_SUCCESS, "PdhCollectQueryData failed 0x%08x\n", ret);
+
+    ret = PdhRemoveCounter( counter );
+    ok(ret == ERROR_SUCCESS, "PdhRemoveCounter failed 0x%08x\n", ret);
+
+    ret = PdhCloseQuery( query );
+    ok(ret == ERROR_SUCCESS, "PdhCloseQuery failed 0x%08x\n", ret);
+}
+
+static void test_PdhAddEnglishCounterW( void )
+{
+    PDH_STATUS ret;
+    PDH_HQUERY query;
+    PDH_HCOUNTER counter;
+
+    ret = PdhOpenQueryW( NULL, 0, &query );
+    ok(ret == ERROR_SUCCESS, "PdhOpenQueryW failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterW( NULL, system_uptime, 0, NULL );
+    ok(ret == PDH_INVALID_ARGUMENT, "PdhAddEnglishCounterW failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterW( NULL, system_uptime, 0, &counter );
+    ok(ret == PDH_INVALID_HANDLE, "PdhAddEnglishCounterW failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterW( query, NULL, 0, &counter );
+    ok(ret == PDH_INVALID_ARGUMENT, "PdhAddEnglishCounterW failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterW( query, system_uptime, 0, NULL );
+    ok(ret == PDH_INVALID_ARGUMENT, "PdhAddEnglishCounterW failed 0x%08x\n", ret);
+
+    ret = pPdhAddEnglishCounterW( query, system_downtime, 0, &counter );
+    ok(ret == PDH_CSTATUS_NO_COUNTER, "PdhAddEnglishCounterW failed 0x%08x\n", ret);
+    ok(!counter, "PdhAddEnglishCounterA failed %p\n", counter);
+
+    ret = pPdhAddEnglishCounterW( query, system_uptime, 0, &counter );
+    ok(ret == ERROR_SUCCESS, "PdhAddEnglishCounterW failed 0x%08x\n", ret);
+
+    ret = PdhCollectQueryData( query );
+    ok(ret == ERROR_SUCCESS, "PdhCollectQueryData failed 0x%08x\n", ret);
+
+    ret = PdhRemoveCounter( counter );
+    ok(ret == ERROR_SUCCESS, "PdhRemoveCounter failed 0x%08x\n", ret);
+
+    ret = PdhCloseQuery( query );
+    ok(ret == ERROR_SUCCESS, "PdhCloseQuery failed 0x%08x\n", ret);
+}
+
+static void test_PdhCollectQueryDataWithTime( void )
+{
+    PDH_STATUS ret;
+    PDH_HQUERY query;
+    PDH_HCOUNTER counter;
+    LONGLONG time;
+
+    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 = pPdhCollectQueryDataWithTime( NULL, NULL );
+    ok(ret == PDH_INVALID_HANDLE, "PdhCollectQueryDataWithTime failed 0x%08x\n", ret);
+
+    ret = pPdhCollectQueryDataWithTime( query, NULL );
+    ok(ret == ERROR_SUCCESS, "PdhCollectQueryDataWithTime failed 0x%08x\n", ret);
+
+    ret = pPdhCollectQueryDataWithTime( NULL, &time );
+    ok(ret == PDH_INVALID_HANDLE, "PdhCollectQueryDataWithTime failed 0x%08x\n", ret);
+
+    ret = pPdhCollectQueryDataWithTime( query, &time );
+    ok(ret == ERROR_SUCCESS, "PdhCollectQueryDataWithTime failed 0x%08x\n", ret);
+
+    ret = PdhCloseQuery( query );
+    ok(ret == ERROR_SUCCESS, "PdhCloseQuery failed 0x%08x\n", ret);
+}
+
 static void test_PdhGetFormattedCounterValue( void )
 {
     PDH_STATUS ret;
@@ -576,12 +697,18 @@
 
 START_TEST(pdh)
 {
+    init_function_ptrs();
+
     test_PdhOpenQueryA();
     test_PdhOpenQueryW();
 
     test_PdhAddCounterA();
     test_PdhAddCounterW();
 
+    if (pPdhAddEnglishCounterA) test_PdhAddEnglishCounterA();
+    if (pPdhAddEnglishCounterW) test_PdhAddEnglishCounterW();
+    if (pPdhCollectQueryDataWithTime) test_PdhCollectQueryDataWithTime();
+
     test_PdhGetFormattedCounterValue();
     test_PdhGetRawCounterValue();
     test_PdhSetCounterScaleFactor();
diff --git a/include/pdh.h b/include/pdh.h
index 11edbfc..a392096 100644
--- a/include/pdh.h
+++ b/include/pdh.h
@@ -167,8 +167,12 @@
 PDH_STATUS WINAPI PdhAddCounterA(PDH_HQUERY, LPCSTR, DWORD_PTR, PDH_HCOUNTER *);
 PDH_STATUS WINAPI PdhAddCounterW(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER *);
 #define    PdhAddCounter WINELIB_NAME_AW(PdhAddCounter)
+PDH_STATUS WINAPI PdhAddEnglishCounterA(PDH_HQUERY, LPCSTR, DWORD_PTR, PDH_HCOUNTER *);
+PDH_STATUS WINAPI PdhAddEnglishCounterW(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER *);
+#define    PdhAddEnglishCounter WINELIB_NAME_AW(PdhAddEnglishCounter)
 PDH_STATUS WINAPI PdhCloseQuery(PDH_HQUERY);
 PDH_STATUS WINAPI PdhCollectQueryData(PDH_HQUERY);
+PDH_STATUS WINAPI PdhCollectQueryDataWithTime(PDH_HQUERY,LONGLONG *);
 PDH_STATUS WINAPI PdhGetCounterInfoA(PDH_HCOUNTER, BOOLEAN, LPDWORD, PPDH_COUNTER_INFO_A);
 PDH_STATUS WINAPI PdhGetCounterInfoW(PDH_HCOUNTER, BOOLEAN, LPDWORD, PPDH_COUNTER_INFO_W);
 #define    PdhGetCounterInfo WINELIB_NAME_AW(PdhGetCounterInfo)