void Disassembler::StaticInitialize() { LIMITED_METHOD_CONTRACT; #if USE_COREDISTOOLS_DISASSEMBLER _ASSERTE(!IsAvailable()); HMODULE libraryHandle = nullptr; PathString libPath; DWORD result = WszGetModuleFileName(nullptr, libPath); if (result == 0) { #ifdef _DEBUG wprintf( W("GetModuleFileName failed, function 'DisasmInstruction': error %u\n"), GetLastError()); #endif // _DEBUG return; } #if defined(FEATURE_PAL) WCHAR delim = W('/'); #else WCHAR delim = W('\\'); #endif LPCWSTR libFileName = MAKEDLLNAME(W("coredistools")); PathString::Iterator iter = libPath.End(); if (libPath.FindBack(iter, delim)) { libPath.Truncate(++iter); libPath.Append(libFileName); } else { _ASSERTE(!"unreachable"); } LPCWSTR libraryName = libPath.GetUnicode(); libraryHandle = CLRLoadLibrary(libraryName); do { if (libraryHandle == nullptr) { #ifdef _DEBUG wprintf(W("LoadLibrary failed for '%s': error %u\n"), libraryName, GetLastError()); #endif // _DEBUG break; } External_InitDisasm = reinterpret_cast<decltype(External_InitDisasm)>(GetProcAddress(libraryHandle, "InitDisasm")); if (External_InitDisasm == nullptr) { #ifdef _DEBUG wprintf( W("GetProcAddress failed for library '%s', function 'InitDisasm': error %u\n"), libraryName, GetLastError()); #endif // _DEBUG break; } External_DisasmInstruction = reinterpret_cast<decltype(External_DisasmInstruction)>(GetProcAddress(libraryHandle, "DisasmInstruction")); if (External_DisasmInstruction == nullptr) { #ifdef _DEBUG wprintf( W("GetProcAddress failed for library '%s', function 'DisasmInstruction': error %u\n"), libraryName, GetLastError()); #endif // _DEBUG break; } External_FinishDisasm = reinterpret_cast<decltype(External_FinishDisasm)>(GetProcAddress(libraryHandle, "FinishDisasm")); if (External_FinishDisasm == nullptr) { #ifdef _DEBUG wprintf( W("GetProcAddress failed for library '%s', function 'FinishDisasm': error %u\n"), libraryName, GetLastError()); #endif // _DEBUG break; } // Set this last to indicate successful load of the library and all exports s_libraryHandle = libraryHandle; _ASSERTE(IsAvailable()); return; } while (false); _ASSERTE(!IsAvailable()); #endif // USE_COREDISTOOLS_DISASSEMBLER }
//***************************************************************************** // This is used in conjunction with GetClassFromCORPath. See it for details // of the algorithm. //***************************************************************************** HRESULT CORPATHService::GetClassFromDir( __in __in_z LPWSTR wzClassname, // Fully qualified class name. __in SString& directory, // Directory to try. at most appended with a '\\' mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon *pCommon, // Scope in which the TypeRef is defined. REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd) // [OUT] typedef { WCHAR *temp; // Used as a parsing temp. int iTmp; bool bContinue; // Flag to check if the for loop should end. LPWSTR wzSaveClassname = NULL; // Saved offset into the class name string. // Process the class name appending each segment of the name to the // directory until we find a DLL. PathString dir; if (!directory.EndsWith(DIRECTORY_SEPARATOR_CHAR_W)) { directory.Append(DIRECTORY_SEPARATOR_CHAR_W); } for(;;) { bContinue = false; dir.Set(directory); if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) != NULL) { *temp = W('\0'); //terminate with null so that it can be appended dir.Append(wzClassname); *temp = NAMESPACE_SEPARATOR_WCHAR; //recover the '.' wzClassname = temp+1; // Check if a directory by this name exists. DWORD iAttrs = WszGetFileAttributes(dir); if (iAttrs != 0xffffffff && (iAttrs & FILE_ATTRIBUTE_DIRECTORY)) { // Next element in the class spec. bContinue = true; wzSaveClassname = wzClassname; } } else { dir.Append(wzClassname); // Advance past the class name. iTmp = (int)wcslen(wzClassname); wzClassname += iTmp; } // Try to load the image. dir.Append(W(".dll")); // OpenScope given the dll name and make sure that the class is defined in the module. if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) ) { return (S_OK); } // If we didn't find the dll, try some more. while (*wzClassname != W('\0')) { // Find the length of the next class name element. if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) == NULL) { temp = wzClassname + wcslen(wzClassname); } // Tack on ".element.dll" SString::Iterator iter = dir.End(); BOOL findperiod = dir.FindBack(iter, NAMESPACE_SEPARATOR_WCHAR); _ASSERTE(findperiod); iter++; dir.Truncate(iter); WCHAR save = *temp; *temp = W('\0'); dir.Append(wzClassname); //element *temp = save; // Try to load the image. dir.Append(W(".dll")); // OpenScope given the dll name and make sure that the class is defined in the module. if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) ) { return (S_OK); } // Advance to the next class name element. wzClassname = temp; if (*wzClassname != '\0') ++wzClassname; } if (bContinue) { wzClassname = wzSaveClassname; } else { break; } } return S_FALSE; } // CORPATHService::GetClassFromDir