Skip to content

Commit 27178d0

Browse files
committed
Use TdhEnumerateProviders to obtain GUIDs to speed up the conversion and avoid conflicts with CoInitializeEx.
1 parent af17f4c commit 27178d0

File tree

1 file changed

+34
-91
lines changed

1 file changed

+34
-91
lines changed

krabs/krabs/provider.hpp

Lines changed: 34 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
#include <evntcons.h>
1818
#include <guiddef.h>
19-
#include <pla.h>
20-
#include <comutil.h>
2119

2220
#ifdef _DEBUG
2321
#pragma comment(lib, "comsuppwd.lib")
@@ -294,6 +292,8 @@ namespace krabs {
294292
T trace_flags_;
295293
bool rundown_enabled_;
296294

295+
GUID provider_name_to_guid(const std::wstring& name);
296+
297297
private:
298298
template <typename T>
299299
friend class details::trace_manager;
@@ -517,97 +517,10 @@ namespace krabs {
517517
, rundown_enabled_(false)
518518
{}
519519

520-
521-
inline void check_com_hr(HRESULT hr) {
522-
if (FAILED(hr)) {
523-
std::stringstream stream;
524-
stream << "Error in creating instance of trace providers";
525-
stream << ", hr = 0x";
526-
stream << std::hex << hr;
527-
throw std::runtime_error(stream.str());
528-
}
529-
}
530-
531-
inline void check_provider_hr(HRESULT hr, const std::wstring &providerName) {
532-
if (FAILED(hr)) {
533-
std::stringstream stream;
534-
stream << "Error in constructing guid from provider name (";
535-
stream << from_wstring(providerName);
536-
stream << "), hr = 0x";
537-
stream << std::hex << hr;
538-
throw std::runtime_error(stream.str());
539-
}
540-
}
541-
542520
template <typename T>
543521
provider<T>::provider(const std::wstring &providerName)
544-
{
545-
ITraceDataProviderCollection *allProviders;
546-
547-
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
548-
check_com_hr(hr);
549-
{
550-
hr = CoCreateInstance(
551-
CLSID_TraceDataProviderCollection,
552-
NULL,
553-
CLSCTX_SERVER,
554-
IID_ITraceDataProviderCollection,
555-
(void**)&allProviders);
556-
check_com_hr(hr);
557-
558-
auto release_ptr = [](IUnknown* ptr) { ptr->Release(); };
559-
std::unique_ptr<ITraceDataProviderCollection, decltype(release_ptr)> allProvidersPtr(allProviders, release_ptr);
560-
561-
hr = allProviders->GetTraceDataProviders(NULL);
562-
check_provider_hr(hr, providerName);
563-
564-
ULONG count;
565-
hr = allProviders->get_Count((long*)&count);
566-
check_provider_hr(hr, providerName);
567-
568-
VARIANT index;
569-
index.vt = VT_UI4;
570-
571-
GUID providerGuid = { 0 };
572-
573-
for (index.ulVal = 0; index.ulVal < count; index.ulVal++){
574-
ITraceDataProvider *provider;
575-
hr = allProviders->get_Item(index, &provider);
576-
check_provider_hr(hr, providerName);
577-
578-
std::unique_ptr<ITraceDataProvider, decltype(release_ptr)> providerPtr(provider, release_ptr);
579-
580-
_bstr_t name;
581-
hr = provider->get_DisplayName(name.GetAddress());
582-
check_provider_hr(hr, providerName);
583-
584-
if (wcscmp(name, providerName.c_str()) == 0){
585-
hr = provider->get_Guid(&providerGuid);
586-
check_provider_hr(hr, providerName);
587-
break;
588-
}
589-
}
590-
591-
if (memcmp((void*)&providerGuid, (void*)&emptyGuid, sizeof(emptyGuid)) == 0)
592-
{
593-
std::stringstream stream;
594-
stream << "Provider name does not exist. (";
595-
stream << from_wstring(providerName);
596-
stream << "), hr = 0x";
597-
stream << std::hex << hr;
598-
throw std::runtime_error(stream.str());
599-
}
600-
601-
guid_ = providerGuid;
602-
any_ = 0;
603-
all_ = 0;
604-
level_ = 5;
605-
trace_flags_ = 0;
606-
rundown_enabled_ = false;
607-
}
608-
609-
CoUninitialize();
610-
}
522+
: provider(provider_name_to_guid(providerName))
523+
{}
611524

612525
template <typename T>
613526
void provider<T>::any(T any)
@@ -658,6 +571,36 @@ namespace krabs {
658571
return tmp;
659572
}
660573

574+
template <typename T>
575+
inline GUID provider<T>::provider_name_to_guid(const std::wstring& name)
576+
{
577+
ULONG bufferSize = 0;
578+
TDHSTATUS status = TdhEnumerateProviders(NULL, &bufferSize);
579+
if (status != ERROR_INSUFFICIENT_BUFFER) {
580+
error_check_common_conditions(status);
581+
return {};
582+
}
583+
584+
auto buffer = std::unique_ptr<char[]>(new char[bufferSize]);
585+
status = TdhEnumerateProviders((PPROVIDER_ENUMERATION_INFO)buffer.get(), &bufferSize);
586+
error_check_common_conditions(status);
587+
588+
auto providers = (PPROVIDER_ENUMERATION_INFO)buffer.get();
589+
for (ULONG i = 0; i < providers->NumberOfProviders; i++)
590+
{
591+
auto provider = providers->TraceProviderInfoArray[i];
592+
std::wstring_view provider_name((wchar_t*)((char*)providers + provider.ProviderNameOffset));
593+
if (provider_name == name)
594+
return provider.ProviderGuid;
595+
}
596+
597+
std::stringstream stream;
598+
stream << "Provider name does not exist. (";
599+
stream << from_wstring(name);
600+
stream << ")";
601+
throw std::runtime_error(stream.str());
602+
}
603+
661604
inline const krabs::guid &kernel_provider::id() const
662605
{
663606
return id_;

0 commit comments

Comments
 (0)