| 1467 | } |
| 1468 | |
| 1469 | error_code cellGameDeleteGameData(vm::cptr<char> dirName) |
| 1470 | { |
| 1471 | cellGame.warning("cellGameDeleteGameData(dirName=%s)", dirName); |
| 1472 | |
| 1473 | if (!dirName) |
| 1474 | { |
| 1475 | return CELL_GAME_ERROR_PARAM; |
| 1476 | } |
| 1477 | |
| 1478 | const std::string name = dirName.get_ptr(); |
| 1479 | const std::string dir = vfs::get("/dev_hdd0/game/"s + name); |
| 1480 | |
| 1481 | auto& perm = g_fxo->get<content_permission>(); |
| 1482 | |
| 1483 | auto remove_gd = [&]() -> error_code |
| 1484 | { |
| 1485 | if (Emu.GetCat() == "GD" && |
| 1486 | Emu.GetDir().substr(Emu.GetDir().find_last_of('/') + 1) == |
| 1487 | vfs::escape(name)) |
| 1488 | { |
| 1489 | // Boot patch cannot delete its own directory |
| 1490 | return CELL_GAME_ERROR_NOTSUPPORTED; |
| 1491 | } |
| 1492 | |
| 1493 | const auto [sfo, psf_error] = psf::load(dir + "/PARAM.SFO"); |
| 1494 | |
| 1495 | if (psf::get_string(sfo, "CATEGORY") != "GD" && |
| 1496 | psf_error != psf::error::stream) |
| 1497 | { |
| 1498 | return {CELL_GAME_ERROR_NOTSUPPORTED, psf_error}; |
| 1499 | } |
| 1500 | |
| 1501 | if (sfo.empty()) |
| 1502 | { |
| 1503 | // Nothing to remove |
| 1504 | return CELL_GAME_ERROR_NOTFOUND; |
| 1505 | } |
| 1506 | |
| 1507 | if (auto id = psf::get_string(sfo, "TITLE_ID"); |
| 1508 | !id.empty() && id != Emu.GetTitleID()) |
| 1509 | { |
| 1510 | cellGame.error("cellGameDeleteGameData(%s): Attempts to delete GameData " |
| 1511 | "with TITLE ID which does not match the program's (%s)", |
| 1512 | id, Emu.GetTitleID()); |
| 1513 | } |
| 1514 | |
| 1515 | // Actually remove game data |
| 1516 | if (!vfs::host::remove_all(dir, rpcs3::utils::get_hdd0_dir(), |
| 1517 | &g_mp_sys_dev_hdd0, true)) |
| 1518 | { |
| 1519 | return {CELL_GAME_ERROR_ACCESS_ERROR, dir}; |
| 1520 | } |
| 1521 | |
| 1522 | return CELL_OK; |
| 1523 | }; |
| 1524 | |
| 1525 | while (true) |
| 1526 | { |
nothing calls this directly
no test coverage detected