pdh: Implement and test PdhLookupPerfIndexByName{A, W} and PdhLookupPerfNameByIndex{A, W}.
diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c
index 5517bf7..5477268 100644
--- a/dlls/pdh/pdh_main.c
+++ b/dlls/pdh/pdh_main.c
@@ -145,6 +145,7 @@
struct source
{
+ DWORD index; /* name index */
const WCHAR *path; /* identifier */
void (CALLBACK *collect)( struct counter * ); /* collect callback */
DWORD type; /* counter type */
@@ -180,10 +181,20 @@
/* counter source registry */
static const struct source counter_sources[] =
{
- { path_processor_time, collect_processor_time, TYPE_PROCESSOR_TIME, -5, 10000000 },
- { path_uptime, collect_uptime, TYPE_UPTIME, -3, 1000 }
+ { 6, path_processor_time, collect_processor_time, TYPE_PROCESSOR_TIME, -5, 10000000 },
+ { 674, path_uptime, collect_uptime, TYPE_UPTIME, -3, 1000 }
};
+static BOOL pdh_match_path( LPCWSTR fullpath, LPCWSTR path )
+{
+ const WCHAR *p;
+
+ if (strchrW( path, '\\')) p = fullpath;
+ else p = strrchrW( fullpath, '\\' ) + 1;
+ if (strcmpW( p, path )) return FALSE;
+ return TRUE;
+}
+
/***********************************************************************
* PdhAddCounterA (PDH.@)
*/
@@ -224,7 +235,7 @@
*hcounter = NULL;
for (i = 0; i < sizeof(counter_sources) / sizeof(counter_sources[0]); i++)
{
- if (strstrW( path, counter_sources[i].path ))
+ if (pdh_match_path( counter_sources[i].path, path ))
{
if ((counter = create_counter()))
{
@@ -446,6 +457,129 @@
}
/***********************************************************************
+ * PdhLookupPerfIndexByNameA (PDH.@)
+ */
+PDH_STATUS WINAPI PdhLookupPerfIndexByNameA( LPCSTR machine, LPCSTR name, LPDWORD index )
+{
+ PDH_STATUS ret;
+ WCHAR *nameW;
+
+ TRACE("%s %s %p\n", debugstr_a(machine), debugstr_a(name), index);
+
+ if (!name || !index) return PDH_INVALID_ARGUMENT;
+
+ if (machine)
+ {
+ FIXME("remote machine not supported\n");
+ return PDH_CSTATUS_NO_MACHINE;
+ }
+ if (!(nameW = pdh_strdup_aw( name )))
+ return PDH_MEMORY_ALLOCATION_FAILURE;
+
+ ret = PdhLookupPerfIndexByNameW( NULL, nameW, index );
+
+ pdh_free( nameW );
+ return ret;
+}
+
+/***********************************************************************
+ * PdhLookupPerfIndexByNameW (PDH.@)
+ */
+PDH_STATUS WINAPI PdhLookupPerfIndexByNameW( LPCWSTR machine, LPCWSTR name, LPDWORD index )
+{
+ unsigned int i;
+
+ TRACE("%s %s %p\n", debugstr_w(machine), debugstr_w(name), index);
+
+ if (!name || !index) return PDH_INVALID_ARGUMENT;
+
+ if (machine)
+ {
+ FIXME("remote machine not supported\n");
+ return PDH_CSTATUS_NO_MACHINE;
+ }
+ for (i = 0; i < sizeof(counter_sources) / sizeof(counter_sources[0]); i++)
+ {
+ if (pdh_match_path( counter_sources[i].path, name ))
+ {
+ *index = counter_sources[i].index;
+ return ERROR_SUCCESS;
+ }
+ }
+ return PDH_STRING_NOT_FOUND;
+}
+
+/***********************************************************************
+ * PdhLookupPerfNameByIndexA (PDH.@)
+ */
+PDH_STATUS WINAPI PdhLookupPerfNameByIndexA( LPCSTR machine, DWORD index, LPSTR buffer, LPDWORD size )
+{
+ PDH_STATUS ret;
+ WCHAR bufferW[PDH_MAX_COUNTER_NAME];
+ DWORD sizeW = sizeof(bufferW) / sizeof(WCHAR);
+
+ TRACE("%s %d %p %p\n", debugstr_a(machine), index, buffer, size);
+
+ if (machine)
+ {
+ FIXME("remote machine not supported\n");
+ return PDH_CSTATUS_NO_MACHINE;
+ }
+
+ if (!buffer && !size) return PDH_INVALID_ARGUMENT;
+ if (!index) return ERROR_SUCCESS;
+
+ if (!(ret = PdhLookupPerfNameByIndexW( NULL, index, bufferW, &sizeW )))
+ {
+ int required = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
+
+ if (size && *size < required) ret = PDH_MORE_DATA;
+ else WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, required, NULL, NULL );
+ if (size) *size = required;
+ }
+ return ret;
+}
+
+/***********************************************************************
+ * PdhLookupPerfNameByIndexW (PDH.@)
+ */
+PDH_STATUS WINAPI PdhLookupPerfNameByIndexW( LPCWSTR machine, DWORD index, LPWSTR buffer, LPDWORD size )
+{
+ PDH_STATUS ret;
+ unsigned int i;
+
+ TRACE("%s %d %p %p\n", debugstr_w(machine), index, buffer, size);
+
+ if (machine)
+ {
+ FIXME("remote machine not supported\n");
+ return PDH_CSTATUS_NO_MACHINE;
+ }
+
+ if (!buffer && !size) return PDH_INVALID_ARGUMENT;
+ if (!index) return ERROR_SUCCESS;
+
+ for (i = 0; i < sizeof(counter_sources) / sizeof(counter_sources[0]); i++)
+ {
+ if (counter_sources[i].index == index)
+ {
+ WCHAR *p = strrchrW( counter_sources[i].path, '\\' ) + 1;
+ unsigned int required = strlenW( p ) + 1;
+
+ if (*size < required) ret = PDH_MORE_DATA;
+ else
+ {
+ strcpyW( buffer, p );
+ ret = ERROR_SUCCESS;
+ }
+ *size = required;
+ return ret;
+ }
+ }
+ return PDH_INVALID_ARGUMENT;
+}
+
+/***********************************************************************
* PdhOpenQueryA (PDH.@)
*/
PDH_STATUS WINAPI PdhOpenQueryA( LPCSTR source, DWORD_PTR userdata, PDH_HQUERY *query )