MCPcopy Create free account
hub / github.com/PCSX2/pcsx2 / OpenCHD

Function OpenCHD

pcsx2/CDVD/ChdFileReader.cpp:234–365  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

232}
233
234static chd_file* OpenCHD(const std::string& filename, FileSystem::ManagedCFilePtr fp, Error* error, u32 recursion_level)
235{
236 chd_file* chd;
237 ChdCoreFileWrapper* core_wrapper = new ChdCoreFileWrapper(fp.get(), nullptr);
238 // libchdr will take ownership of core_wrapper, and will close/free it on failure.
239 chd_error err = chd_open_core_file(core_wrapper->GetCoreFile(), CHD_OPEN_READ, nullptr, &chd);
240 if (err == CHDERR_NONE)
241 {
242 // core_wrapper should manage fp.
243 core_wrapper->SetFileOwner(true);
244 fp.release();
245 return chd;
246 }
247 else if (err != CHDERR_REQUIRES_PARENT)
248 {
249 Console.Error(fmt::format("Failed to open CHD '{}': {}", filename, chd_error_string(err)));
250 Error::SetString(error, chd_error_string(err));
251 return nullptr;
252 }
253
254 if (recursion_level >= MAX_PARENTS)
255 {
256 Console.Error(fmt::format("Failed to open CHD '{}': Too many parent files", filename));
257 Error::SetString(error, "Too many parent files");
258 return nullptr;
259 }
260
261 // Need to get the sha1 to look for.
262 chd_header header;
263 err = chd_read_header_file(fp.get(), &header);
264 if (err != CHDERR_NONE)
265 {
266 Console.Error(fmt::format("Failed to read CHD header '{}': {}", filename, chd_error_string(err)));
267 Error::SetString(error, chd_error_string(err));
268 return nullptr;
269 }
270
271 // Find a chd with a matching sha1 in the same directory.
272 // Have to do *.* and filter on the extension manually because Linux is case sensitive.
273 chd_file* parent_chd = nullptr;
274 const std::string parent_dir(Path::GetDirectory(filename));
275 const std::unique_lock hash_cache_lock(s_chd_hash_cache_mutex);
276
277 // Memoize which hashes came from what files, to avoid reading them repeatedly.
278 for (auto it = s_chd_hash_cache.begin(); it != s_chd_hash_cache.end(); ++it)
279 {
280 if (!StringUtil::compareNoCase(parent_dir, Path::GetDirectory(it->first)))
281 continue;
282
283 if (!IsHeaderParentCHD(header, it->second))
284 continue;
285
286 // Re-check the header, it might have changed since we last opened.
287 chd_header parent_header;
288 auto parent_fp = FileSystem::OpenManagedSharedCFile(it->first.c_str(), "rb", FileSystem::FileShareMode::DenyWrite);
289 if (parent_fp && chd_read_header_file(parent_fp.get(), &parent_header) == CHDERR_NONE &&
290 IsHeaderParentCHD(header, parent_header))
291 {

Callers 1

Open2Method · 0.85

Calls 15

chd_open_core_fileFunction · 0.85
chd_error_stringFunction · 0.85
chd_read_header_fileFunction · 0.85
compareNoCaseFunction · 0.85
IsHeaderParentCHDFunction · 0.85
EndsWithNoCaseFunction · 0.85
GetCoreFileMethod · 0.80
SetFileOwnerMethod · 0.80
formatFunction · 0.50
chd_core_fileFunction · 0.50
getMethod · 0.45
releaseMethod · 0.45

Tested by

no test coverage detected