The checks are different for the various functions, so the actually shared parts are the for loop to extract the index and actually set the value. Maybe the
` for (i = 0; i < template->counterset.NumCounters; ++i) if (template->counter[i].CounterId == counterid) break;`
loop could be replaced with a get_performance_counter_index function and the line to set the value with a set_perfromance_counter_value function.
Yes, something like that, though you should be able to abstract pretty much everything except the checks.