| 179 | using internal::WideFromUtf8; |
| 180 | |
| 181 | std::string NormalizeModulePath(const std::string& path) { |
| 182 | if (path.empty()) { |
| 183 | return ""; |
| 184 | } |
| 185 | |
| 186 | std::wstring widePath = WideFromUtf8(path); |
| 187 | if (widePath.empty()) { |
| 188 | return path; |
| 189 | } |
| 190 | |
| 191 | HANDLE handle = |
| 192 | CreateFileW(widePath.c_str(), 0, |
| 193 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 194 | nullptr, OPEN_EXISTING, |
| 195 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, nullptr); |
| 196 | if (handle == INVALID_HANDLE_VALUE) { |
| 197 | return path; |
| 198 | } |
| 199 | |
| 200 | std::wstring finalPath(MAX_PATH, L'\0'); |
| 201 | for (;;) { |
| 202 | DWORD copied = |
| 203 | GetFinalPathNameByHandleW(handle, finalPath.data(), |
| 204 | static_cast<DWORD>(finalPath.size()), |
| 205 | FILE_NAME_NORMALIZED); |
| 206 | if (copied == 0) { |
| 207 | CloseHandle(handle); |
| 208 | return path; |
| 209 | } |
| 210 | if (copied < finalPath.size()) { |
| 211 | finalPath.resize(copied); |
| 212 | break; |
| 213 | } |
| 214 | finalPath.resize(copied + 1); |
| 215 | } |
| 216 | CloseHandle(handle); |
| 217 | |
| 218 | const std::wstring uncPrefix = L"\\\\?\\UNC\\"; |
| 219 | const std::wstring localPrefix = L"\\\\?\\"; |
| 220 | if (finalPath.rfind(uncPrefix, 0) == 0) { |
| 221 | finalPath = L"\\" + finalPath.substr(7); |
| 222 | } else if (finalPath.rfind(localPrefix, 0) == 0) { |
| 223 | finalPath = finalPath.substr(4); |
| 224 | } |
| 225 | return Utf8FromWide(finalPath); |
| 226 | } |
| 227 | |
| 228 | std::string GetModulePath(HMODULE module) { |
| 229 | std::wstring buffer(MAX_PATH, L'\0'); |
no test coverage detected