bool CProfilerCallback::GetClassNameFromClassId(ClassID classId, LPWSTR wszClass ) { ModuleID moduleId; mdTypeDef typeDef; wszClass[0] = 0; HRESULT hr = m_pICorProfilerInfo->GetClassIDInfo( classId, &moduleId, &typeDef ); if ( FAILED(hr) ) return false; if ( typeDef == 0 ) // ::GetClassIDInfo can fail, yet not set HRESULT { // __asm int 3 return false; } IMetaDataImport * pIMetaDataImport = 0; hr = m_pICorProfilerInfo->GetModuleMetaData( moduleId, ofRead, IID_IMetaDataImport, (LPUNKNOWN *)&pIMetaDataImport ); if ( FAILED(hr) ) return false; if ( !pIMetaDataImport ) return false; wchar_t wszTypeDef[512]; DWORD cchTypeDef = sizeof(wszTypeDef)/sizeof(wszTypeDef[0]); hr = pIMetaDataImport->GetTypeDefProps( typeDef, wszTypeDef, cchTypeDef, &cchTypeDef, 0, 0 ); if ( FAILED(hr) ) return false; lstrcpyW( wszClass, wszTypeDef ); // // If we were ambitious, we'd save the ClassID away in a map to avoid // needing to hit the metatdata APIs every time. // pIMetaDataImport->Release(); return true; }
std::wstring GetFunctionName( UINT functionId ) { mdToken methodToken, classToken, newClassToken; IMetaDataImport * pm = NULL; if (FAILED(profiler->GetTokenAndMetaDataFromFunction( functionId, IID_IMetaDataImport, (IUnknown **) &pm, &methodToken ))) return L"<no metadata>"; wchar_t buf[512]; DWORD size = 512; if (FAILED(pm->GetMethodProps( methodToken, &classToken, buf, size, &size, NULL, NULL, NULL, NULL, NULL ))) { pm->Release(); return L"<no metadata>"; } std::wstring class_buf_string; while( true ) { wchar_t class_buf[512]; size = 512; if (FAILED(pm->GetTypeDefProps( classToken, class_buf, size, &size, NULL, NULL ))) { pm->Release(); return L"<no metadata>"; } class_buf_string = std::wstring( class_buf ) + class_buf_string; if( FAILED( pm->GetNestedClassProps( classToken, &newClassToken ) ) ) break; if( newClassToken == classToken || newClassToken == 0 ) break; class_buf_string = L"$" + class_buf_string; classToken = newClassToken; } pm->Release(); return class_buf_string + L"::" + std::wstring( buf ); }
bool CProfilerCallback::GetMethodNameFromFunctionId(FunctionID functionId, LPWSTR wszClass, LPWSTR wszMethod) { mdToken dwToken; IMetaDataImport * pIMetaDataImport = 0; HRESULT hr = m_pICorProfilerInfo->GetTokenAndMetaDataFromFunction( functionId, IID_IMetaDataImport, (LPUNKNOWN *)&pIMetaDataImport, &dwToken ); if ( FAILED(hr) ) return false; wchar_t _wszMethod[512]; DWORD cchMethod = sizeof(_wszMethod)/sizeof(_wszMethod[0]); mdTypeDef mdClass; hr = pIMetaDataImport->GetMethodProps( dwToken, &mdClass, _wszMethod, cchMethod, &cchMethod, 0, 0, 0, 0, 0 ); if ( FAILED(hr) ) return false; lstrcpyW( wszMethod, _wszMethod ); wchar_t wszTypeDef[512]; DWORD cchTypeDef = sizeof(wszTypeDef)/sizeof(wszTypeDef[0]); if ( mdClass == 0x02000000 ) mdClass = 0x02000001; hr = pIMetaDataImport->GetTypeDefProps( mdClass, wszTypeDef, cchTypeDef, &cchTypeDef, 0, 0 ); if ( FAILED(hr) ) return false; lstrcpyW( wszClass, wszTypeDef ); pIMetaDataImport->Release(); // // If we were ambitious, we'd save every FunctionID away in a map to avoid // needing to hit the metatdata APIs every time. // return true; }
HRESULT CMnProfiler::GetMethodInfo(FunctionID functionID, wstring& assemblyName, wstring& className, wstring& methodName, wstring& methodParameters) { IMetaDataImport* pIMetaDataImport = 0; HRESULT hr = S_OK; mdToken funcToken = 0; WCHAR szName[NAME_BUFFER_SIZE]; ClassID classId; ModuleID moduleId; hr = m_pICorProfilerInfo->GetFunctionInfo(functionID, &classId, &moduleId, &funcToken); if(SUCCEEDED(hr)) { AssemblyID assemblyID; ULONG cchModule; LPCBYTE baseLoadAddress; hr = m_pICorProfilerInfo->GetModuleInfo(moduleId, &baseLoadAddress, NAME_BUFFER_SIZE, &cchModule, szName, &assemblyID); if(SUCCEEDED(hr)) { AppDomainID appDomainId; hr = m_pICorProfilerInfo->GetAssemblyInfo(assemblyID, NAME_BUFFER_SIZE, &cchModule, szName, &appDomainId, &moduleId); if(SUCCEEDED(hr)) { assemblyName = wstring(szName, cchModule); hr = m_pICorProfilerInfo->GetTokenAndMetaDataFromFunction(functionID, IID_IMetaDataImport, (LPUNKNOWN *) &pIMetaDataImport, &funcToken); if(SUCCEEDED(hr)) { mdTypeDef classTypeDef; ULONG cchFunction; ULONG cchClass; PCCOR_SIGNATURE methodSignatureBlob; ULONG methodSignatureBlobSize; hr = pIMetaDataImport->GetMethodProps(funcToken, &classTypeDef, szName, NAME_BUFFER_SIZE, &cchFunction, 0, &methodSignatureBlob, &methodSignatureBlobSize, 0, 0); if (SUCCEEDED(hr)) { methodName = wstring(szName, cchFunction); if (CheckMethodName(methodName)) { hr = pIMetaDataImport->GetTypeDefProps(classTypeDef, szName, NAME_BUFFER_SIZE, &cchClass, 0, 0); if (SUCCEEDED(hr)) { className = wstring(szName, cchClass); if (CheckMethodName(className)) { hr = MnFunctionInfo::ParseFunctionParameters(pIMetaDataImport, funcToken, methodParameters); } else { hr = E_FAIL; } /*logs::Logger::OutputInfo(_T("%s: Method \"%s\" Class %s Signature %s"), _T(__FUNCTION__), methodName.c_str(), className.c_str(), methodParameters.c_str());*/ } } else { hr = E_FAIL; } } pIMetaDataImport->Release(); } } } } return hr; }