Guest User

Untitled

a guest
Mar 16th, 2019
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 89.80 KB | None | 0 0
  1. #include <lv2/lv2.h>
  2. #include <lv2/libc.h>
  3. #include <lv2/memory.h>
  4. #include <lv2/storage.h>
  5. #include <lv2/io.h>
  6. #include <lv2/thread.h>
  7. #include <lv2/synchronization.h>
  8. #include <lv2/object.h>
  9. #include <lv2/time.h>
  10. #include <lv2/security.h>
  11. #include <lv2/patch.h>
  12. #include <lv2/syscall.h>
  13. #include <lv2/error.h>
  14. #include <lv2/symbols.h>
  15. #include <lv1/lv1.h>
  16. #include <lv1/lv1call.h>
  17. #include <lv1/stor.h>
  18. #include <lv1/patch.h>
  19.  
  20. #include "common.h"
  21. #include "storage_ext.h"
  22. #include "scsi.h"
  23. #include "config.h"
  24. #include "crypto.h"
  25. #include "mappath.h"
  26. #include "modulespatch.h"
  27.  
  28. #define READ_BUF_SIZE (256*1024)
  29. #define READ_BUF_SIZE_SECTORS_PSX (128)
  30. #define CD_CACHE_SIZE (64)
  31.  
  32. #ifdef DEBUG
  33. #define THREAD_NAME "DiscemuDispatchThread"
  34. #else
  35. #define THREAD_NAME ""
  36. #endif
  37.  
  38. #ifdef DO_PATCH_PS2
  39. #define PS2EMU_STAGE2_FILE "/dev_hdd0/vm/pm0"
  40. #define PS2EMU_CONFIG_FILE "/dev_hdd0/tmp/cfg.bin"
  41.  
  42. enum
  43. {
  44. PS2EMU_HW,
  45. PS2EMU_GX,
  46. PS2EMU_SW
  47. };
  48.  
  49. static int ps2emu_type;
  50. #endif
  51.  
  52. #define MIN(a, b) ((a) <= (b) ? (a) : (b))
  53. #define ABS(a) (((a) < 0) ? -(a) : (a))
  54.  
  55. typedef struct _ReadIsoCmd
  56. {
  57. uint64_t offset;
  58. uint64_t size;
  59. uint8_t *buf;
  60. process_t process;
  61. } ReadIsoCmd;
  62.  
  63. typedef struct _ReadDiscCmd
  64. {
  65. uint64_t start_sector;
  66. uint32_t sector_count;
  67. uint8_t *buf;
  68. } ReadDiscCmd;
  69.  
  70. typedef struct _ReadCdIso2352Cmd
  71. {
  72. uint32_t start_sector;
  73. uint32_t sector_count;
  74. uint8_t *buf;
  75. process_t process;
  76. } ReadCdIso2352Cmd;
  77.  
  78. typedef struct _FakeStorageEventCmd
  79. {
  80. uint64_t event;
  81. uint64_t param;
  82. uint64_t device;
  83. } FakeStorageEventCmd;
  84.  
  85. typedef struct _DiscFile
  86. {
  87. char **files;
  88. int count;
  89. int activefile;
  90. uint64_t *sizes;
  91. uint64_t totalsize;
  92. uint64_t cached_offset;
  93. void *cached_sector;
  94. } DiscFile;
  95.  
  96. typedef struct _DiscFileCD
  97. {
  98. char *file;
  99. uint32_t num_sectors;
  100. ScsiTrackDescriptor *tracks;
  101. int numtracks;
  102. uint8_t *cache;
  103. uint32_t cached_sector;
  104. } DiscFileCD;
  105.  
  106. typedef struct _DiscFileProxy
  107. {
  108. uint64_t size;
  109. ScsiTrackDescriptor *tracks;
  110. int numtracks;
  111. uint32_t read_size;
  112. uint64_t cached_offset;
  113. void *cached_sector;
  114. } DiscFileProxy;
  115.  
  116. uint8_t encrypted_image_keys[16] =
  117. {
  118. 0x11, 0x0C, 0xE4, 0x15, 0xDD, 0x39, 0x76, 0x8C,
  119. 0x90, 0xB6, 0x40, 0xF5, 0xCB, 0x33, 0xC6, 0xB6
  120. };
  121.  
  122. static mutex_t mutex;
  123. static event_port_t command_port, result_port;
  124. static event_queue_t command_queue, result_queue;
  125.  
  126. static event_port_t proxy_command_port;
  127. static event_queue_t proxy_result_queue;
  128.  
  129. static int discfd = -1;
  130. static int disc_emulation;
  131. static int total_emulation;
  132. static int skip_emu_check = 0;
  133. static volatile int loop = 0;
  134. static DiscFile *discfile;
  135. static DiscFileCD *discfile_cd;
  136. static DiscFileProxy *discfile_proxy;
  137.  
  138. static int disc_being_mounted = 0;
  139. static int could_not_read_disc;
  140. static int hdd0_mounted = 0;
  141.  
  142. static int video_mode = -2;
  143.  
  144. static char *encrypted_image;
  145. static int encrypted_image_fd = -1;
  146. static uint64_t encrypted_image_nonce;
  147.  
  148. unsigned int real_disctype; /* Real disc in the drive */
  149. unsigned int effective_disctype; /* The type of disc we want it to be, and the one faked in storage event. */
  150. unsigned int fake_disctype; /* If no zero, get device type command will fake disc type to this. */
  151.  
  152. // -- AV: cd sector size
  153. static uint32_t cd_sector_size = 2352;
  154. //
  155.  
  156. LV2_EXPORT int storage_internal_get_device_object(void *object, device_handle_t handle, void **dev_object);
  157.  
  158. static INLINE void get_next_read(int64_t discoffset, uint64_t bufsize, uint64_t *fileoffset, uint64_t *readsize, int *file)
  159. {
  160. uint64_t base = 0;
  161. *file = -1;
  162. *readsize = bufsize;
  163. *fileoffset = 0;
  164.  
  165. for (int i = 0; i < discfile->count; i++)
  166. {
  167. uint64_t last = base+discfile->sizes[i];
  168.  
  169. if (discoffset >= base && discoffset < last)
  170. {
  171. uint64_t maxfileread = last-discoffset;
  172.  
  173. if (bufsize > maxfileread)
  174. *readsize = maxfileread;
  175. else
  176. *readsize = bufsize;
  177.  
  178. *file = i;
  179. *fileoffset = discoffset-base;
  180. return;
  181. }
  182.  
  183. base += discfile->sizes[i];
  184. }
  185.  
  186. #ifdef DEBUG
  187. DPRINTF("Offset or size out of range %lx %lx!!!!!!!!\n", discoffset, bufsize);
  188. #endif
  189. }
  190.  
  191. static INLINE int process_read_iso_cmd(ReadIsoCmd *cmd)
  192. {
  193. void *readbuf;
  194. uint8_t *ptr;
  195. uint64_t remaining, bufsize, offset;
  196. int ret, iskernel, activefile, doseek;
  197. int cache = 0;
  198.  
  199. ret = 0;
  200. iskernel = (((uint64_t)cmd->buf) >> 63);
  201. offset = cmd->offset;
  202. remaining = cmd->size;
  203.  
  204. #ifdef DEBUG
  205. DPRINTF("Read %lx %lx\n", cmd->offset, cmd->size);
  206. #endif
  207.  
  208. if (disc_emulation == EMU_PS3 && remaining == 2048)
  209. {
  210. cache = 1;
  211. }
  212.  
  213. if (cache)
  214. {
  215. if (discfile->cached_sector && discfile->cached_offset == offset)
  216. {
  217. if (iskernel)
  218. {
  219. memcpy(cmd->buf, discfile->cached_sector, 2048);
  220. }
  221. else
  222. {
  223. copy_to_process(cmd->process, discfile->cached_sector, cmd->buf, 2048);
  224. }
  225.  
  226. return 0;
  227. }
  228. }
  229.  
  230. if (discfile->cached_sector)
  231. {
  232. dealloc(discfile->cached_sector, 0x2F);
  233. discfile->cached_sector = NULL;
  234. }
  235.  
  236. if (iskernel)
  237. {
  238. readbuf = cmd->buf;
  239. bufsize = remaining;
  240. }
  241. else
  242. {
  243. bufsize = (remaining > READ_BUF_SIZE) ? READ_BUF_SIZE : remaining;
  244. ret = page_allocate_auto(NULL, bufsize, 0x2F, &readbuf);
  245. if (ret != 0)
  246. return ret;
  247. }
  248.  
  249. ptr = cmd->buf;
  250. activefile = discfile->activefile;
  251. doseek = 1;
  252.  
  253. while (remaining > 0)
  254. {
  255. uint64_t maxreadsize, filepos, readsize, v;
  256. int file;
  257.  
  258. maxreadsize = (remaining > bufsize) ? bufsize : remaining;
  259. get_next_read(offset, maxreadsize, &filepos, &readsize, &file);
  260.  
  261. if (file != -1)
  262. {
  263. if (discfd == -1 || file != activefile)
  264. {
  265. if (discfd != -1)
  266. cellFsClose(discfd);
  267.  
  268. #ifdef DEBUG
  269. DPRINTF("Changed to part file %d\n", file);
  270. #endif
  271.  
  272. ret = cellFsOpen(discfile->files[file], CELL_FS_O_RDONLY, &discfd, 0, NULL, 0);
  273. if (ret != 0)
  274. {
  275. discfd = -1;
  276. break;
  277. }
  278.  
  279. activefile = file;
  280. doseek = 1;
  281. }
  282.  
  283. if (doseek)
  284. {
  285. ret = cellFsLseek(discfd, filepos, SEEK_SET, &v);
  286. if (ret != 0)
  287. break;
  288.  
  289. doseek = 0;
  290. }
  291.  
  292. ret = cellFsRead(discfd, readbuf, readsize, &v);
  293. if (ret != 0)
  294. break;
  295.  
  296. if (v != readsize)
  297. {
  298. ret = -1;
  299. break;
  300. }
  301. }
  302. else
  303. {
  304. // don't know why, but in some video blu ray iso i've seen a read request over the size reported. Let's just dummy data.
  305. memset(readbuf, 0, readsize);
  306. ret = 0;
  307. }
  308.  
  309. if (!iskernel)
  310. {
  311. ret = copy_to_process(cmd->process, readbuf, ptr, readsize);
  312. if (ret != 0)
  313. break;
  314. }
  315.  
  316. ptr += readsize;
  317. offset += readsize;
  318. remaining -= readsize;
  319.  
  320. if (iskernel)
  321. readbuf = ptr;
  322. }
  323. #ifdef DEBUG
  324. if (ret != 0)
  325. {
  326. DPRINTF("WARNING: Error %x\n", ret);
  327. }
  328. else
  329. #endif
  330. if (ret == 0)
  331. {
  332. if (cache)
  333. {
  334. discfile->cached_sector = alloc(2048, 0x2F);
  335.  
  336. if (iskernel)
  337. {
  338. memcpy(discfile->cached_sector, cmd->buf, 2048);
  339. }
  340. else
  341. {
  342. copy_from_process(cmd->process, cmd->buf, discfile->cached_sector, 2048);
  343. }
  344.  
  345. discfile->cached_offset = cmd->offset;
  346. }
  347. }
  348.  
  349. discfile->activefile = activefile;
  350.  
  351. if (!iskernel)
  352. {
  353. page_free(NULL, readbuf, 0x2F);
  354. }
  355.  
  356. return ret;
  357. }
  358.  
  359. static INLINE int process_read_cd_iso2048_cmd(ReadIsoCmd *cmd)
  360. {
  361. uint8_t *readbuf, *ptr;
  362. uint64_t sector;
  363. uint32_t remaining, bufsize;
  364. int iskernel, ret, doseek;
  365.  
  366. sector = cmd->offset/2048;
  367. remaining = cmd->size/2048;
  368. iskernel = (((uint64_t)cmd->buf) >> 63);
  369.  
  370. if (discfd == -1)
  371. {
  372. ret = cellFsOpen(discfile_cd->file, CELL_FS_O_RDONLY, &discfd, 0, NULL, 0);
  373. if (ret != 0)
  374. return ret;
  375. }
  376.  
  377. bufsize = (remaining > READ_BUF_SIZE_SECTORS_PSX) ? READ_BUF_SIZE_SECTORS_PSX : remaining;
  378. ret = page_allocate_auto(NULL, bufsize * cd_sector_size, 0x2F, (void **)&readbuf);
  379. if (ret != 0)
  380. return ret;
  381.  
  382. ptr = cmd->buf;
  383. doseek = 1;
  384.  
  385. while (remaining > 0)
  386. {
  387. uint64_t v;
  388. uint32_t readsize = (remaining > bufsize) ? bufsize : remaining;
  389. int read = 1;
  390.  
  391. if (sector >= discfile_cd->num_sectors)
  392. {
  393. read = 0;
  394. }
  395. else
  396. {
  397. if (doseek)
  398. {
  399. ret = cellFsLseek(discfd, sector * cd_sector_size, SEEK_SET, &v);
  400. if (ret != 0)
  401. break;
  402.  
  403. doseek = 0;
  404. }
  405. }
  406.  
  407. if (read)
  408. {
  409. ret = cellFsRead(discfd, readbuf, readsize * cd_sector_size, &v);
  410. if (ret != 0)
  411. break;
  412.  
  413. if (v < (readsize * cd_sector_size))
  414. {
  415. memset(readbuf+v, 0, (readsize * cd_sector_size)-v);
  416. }
  417. }
  418. else
  419. {
  420. memset(readbuf, 0, readsize * cd_sector_size);
  421. }
  422.  
  423. for (int i = 0; i < readsize; i++)
  424. {
  425. uint8_t *s = readbuf+(i * cd_sector_size)+24;
  426.  
  427. if (iskernel)
  428. {
  429. memcpy(ptr, s, 2048);
  430. }
  431. else
  432. {
  433. copy_to_process(cmd->process, s, ptr, 2048);
  434. }
  435.  
  436. ptr += 2048;
  437. }
  438.  
  439. remaining -= readsize;
  440. sector += readsize;
  441. }
  442.  
  443. page_free(NULL, readbuf, 0x2F);
  444. return ret;
  445. }
  446.  
  447. static INLINE int process_read_cd_iso2352_cmd(ReadCdIso2352Cmd *cmd)
  448. {
  449. void *readbuf;
  450. uint8_t *buf;
  451. uint8_t *ptr;
  452. uint64_t sector;
  453. uint32_t remaining, bufsize;
  454. int iskernel, ret, doseek, cache;
  455.  
  456. ret = 0;
  457. sector = cmd->start_sector;
  458. remaining = cmd->sector_count;
  459. buf = cmd->buf;
  460. iskernel = (((uint64_t)buf) >> 63);
  461.  
  462. if (discfd == -1)
  463. {
  464. ret = cellFsOpen(discfile_cd->file, CELL_FS_O_RDONLY, &discfd, 0, NULL, 0);
  465. if (ret != 0)
  466. return ret;
  467. }
  468.  
  469. if (remaining <= CD_CACHE_SIZE)
  470. {
  471. int dif = (int)discfile_cd->cached_sector-sector;
  472.  
  473. if (ABS(dif) < CD_CACHE_SIZE)
  474. {
  475. uint8_t *copy_ptr = NULL;
  476. uint32_t copy_offset = 0;
  477. uint32_t copy_size = 0;
  478.  
  479. if (dif > 0)
  480. {
  481. if (dif < remaining)
  482. {
  483. copy_ptr = discfile_cd->cache;
  484. copy_offset = dif;
  485. copy_size = remaining-dif;
  486. }
  487. }
  488. else
  489. {
  490.  
  491. copy_ptr = discfile_cd->cache+((-dif) * cd_sector_size);
  492. copy_size = MIN(remaining, CD_CACHE_SIZE+dif);
  493. }
  494.  
  495. if (copy_ptr)
  496. {
  497. if (iskernel)
  498. {
  499. memcpy(buf+(copy_offset * cd_sector_size), copy_ptr, copy_size * cd_sector_size);
  500. }
  501. else
  502. {
  503. copy_to_process(cmd->process, copy_ptr, buf+(copy_offset * cd_sector_size), copy_size * cd_sector_size);
  504. }
  505.  
  506. if (remaining == copy_size)
  507. {
  508. return 0;
  509. }
  510.  
  511. remaining -= copy_size;
  512.  
  513. if (dif <= 0)
  514. {
  515. uint32_t newsector = discfile_cd->cached_sector + CD_CACHE_SIZE;
  516. buf += ((newsector-sector) * cd_sector_size);
  517. sector = newsector;
  518. }
  519. }
  520. }
  521.  
  522. cache = 1;
  523. }
  524.  
  525. if (cache)
  526. {
  527. readbuf = discfile_cd->cache;
  528. }
  529. else
  530. {
  531. if (iskernel)
  532. {
  533. bufsize = remaining;
  534. readbuf = buf;
  535. }
  536. else
  537. {
  538. bufsize = (remaining > READ_BUF_SIZE_SECTORS_PSX) ? READ_BUF_SIZE_SECTORS_PSX : remaining;
  539. ret = page_allocate_auto(NULL, bufsize * cd_sector_size, 0x2F, (void **)&readbuf);
  540. if (ret != 0)
  541. return ret;
  542. }
  543. }
  544.  
  545. ptr = buf;
  546. doseek = 1;
  547.  
  548. while (remaining > 0)
  549. {
  550. uint64_t v;
  551. uint32_t readsize;
  552. int read = 1;
  553.  
  554. if (cache)
  555. {
  556. readsize = CD_CACHE_SIZE;
  557. }
  558. else
  559. {
  560. readsize = (remaining > bufsize) ? bufsize : remaining;
  561. }
  562.  
  563. if (sector >= discfile_cd->num_sectors)
  564. {
  565. read = 0;
  566. }
  567. else
  568. {
  569. if (doseek)
  570. {
  571. ret = cellFsLseek(discfd, sector * cd_sector_size, SEEK_SET, &v);
  572. if (ret != 0)
  573. break;
  574.  
  575. doseek = 0;
  576. }
  577. }
  578.  
  579. if (read)
  580. {
  581. ret = cellFsRead(discfd, readbuf, readsize * cd_sector_size, &v);
  582. if (ret != 0)
  583. break;
  584.  
  585. if (v < (readsize * cd_sector_size))
  586. {
  587. memset(readbuf+v, 0, (readsize * cd_sector_size)-v);
  588. }
  589. }
  590. else
  591. {
  592. memset(readbuf, 0, readsize * cd_sector_size);
  593. }
  594.  
  595. if (!cache)
  596. {
  597. if (iskernel)
  598. {
  599. ptr += readsize * cd_sector_size;
  600. readbuf = ptr;
  601. }
  602. else
  603. {
  604. copy_to_process(cmd->process, readbuf, ptr, readsize * cd_sector_size);
  605. ptr += readsize * cd_sector_size;
  606. }
  607. }
  608. else
  609. {
  610. if (iskernel)
  611. memcpy(ptr, readbuf, remaining * cd_sector_size);
  612. else
  613. copy_to_process(cmd->process, readbuf, ptr, remaining * cd_sector_size);
  614.  
  615. discfile_cd->cached_sector = sector;
  616. return 0;
  617. }
  618.  
  619. remaining -= readsize;
  620. sector += readsize;
  621.  
  622. }
  623.  
  624. if (!iskernel)
  625. page_free(NULL, readbuf, 0x2F);
  626.  
  627. return ret;
  628. }
  629.  
  630. int process_read_disc_cmd(ReadDiscCmd *cmd)
  631. {
  632. lv1_stor_wrapper_var var;
  633. u64 dma_lpar;
  634. void *dma;
  635. int ret;
  636.  
  637. // reasons to use lv1 calls here over lv2 storage functions
  638. // 1: this function may be called when lv2 storage functions haven't yet received the bdvd ready event, and thus, they don't work.
  639. // 2: this will read the real disc even with iso mounted, it may be useful in the future.
  640.  
  641. ret = page_allocate_auto(NULL, 4096, 0x2F, &dma);
  642. memset(dma, 0x5B, 4096);
  643.  
  644. if (ret == 0)
  645. {
  646. ret = kernel_ea_to_lpar_addr(dma, &dma_lpar);
  647. if (ret == 0)
  648. {
  649. suspend_intr();
  650. uint64_t state = spin_lock_irqsave();
  651.  
  652. ret = lv1_stor_wrapper_open(LV1_BDVD_DEV_ID, dma, dma_lpar, 12, &var);
  653. if (ret == 0)
  654. {
  655. ret = lv1_stor_wrapper_read(&var, 0, cmd->start_sector, cmd->sector_count, 0x2, cmd->buf);
  656. lv1_stor_wrapper_close(&var);
  657. }
  658.  
  659. spin_unlock_irqrestore(state);
  660. resume_intr();
  661. }
  662.  
  663. page_free(NULL, dma, 0x2F);
  664. }
  665.  
  666. return ret;
  667. }
  668.  
  669. int process_proxy_cmd(uint64_t command, process_t process, uint8_t *buf, uint64_t offset, uint32_t size)
  670. {
  671. uint32_t remaining;
  672. int iskernel, do_copy;
  673. int ret;
  674. event_t event;
  675.  
  676. iskernel = (((uint64_t)buf) >> 63);
  677. remaining = size;
  678.  
  679. if (!vsh_process) vsh_process = get_vsh_process(); //NzV
  680. if(!vsh_process) return -666;
  681.  
  682. do_copy = (iskernel || process != vsh_process);
  683.  
  684. if (!do_copy)
  685. {
  686.  
  687. #ifdef DEBUG
  688. DPRINTF("Native VSH read\n");
  689. #endif
  690. ret = event_port_send(proxy_command_port, command, offset, (((uint64_t)buf)<<32ULL) | remaining);
  691. if (ret != 0)
  692. {
  693.  
  694. #ifdef DEBUG
  695. DPRINTF("event_port send failed: %x\n", ret);
  696. #endif
  697. return ret;
  698. }
  699.  
  700. ret = event_queue_receive(proxy_result_queue, &event, 0);
  701. if (ret != 0)
  702. {
  703. #ifdef DEBUG
  704. DPRINTF("event_queue_receive failed: %x\n", ret);
  705. #endif
  706. return ret;
  707. }
  708.  
  709. ret = (int)event.data1;
  710. }
  711. else
  712. {
  713. uint64_t read_size;
  714. void *kbuf, *vbuf;
  715. uint8_t *obuf;
  716. int cache = 0;
  717.  
  718. obuf = buf;
  719.  
  720. if (disc_emulation == EMU_PS3 && remaining == 2048)
  721. {
  722. cache = 1;
  723. }
  724.  
  725. if (cache)
  726. {
  727. if (discfile_proxy->cached_sector && discfile_proxy->cached_offset == offset)
  728. {
  729. if (iskernel)
  730. {
  731. memcpy(buf, discfile_proxy->cached_sector, 2048);
  732. }
  733. else
  734. {
  735. copy_to_process(process, discfile_proxy->cached_sector, buf, 2048);
  736. }
  737.  
  738. return 0;
  739. }
  740. }
  741.  
  742. if (discfile_proxy->cached_sector)
  743. {
  744. dealloc(discfile_proxy->cached_sector, 0x2F);
  745. discfile_proxy->cached_sector = NULL;
  746. }
  747.  
  748. read_size = (remaining <= discfile_proxy->read_size) ? remaining : discfile_proxy->read_size;
  749.  
  750. ret = page_allocate_auto(vsh_process, read_size, 0x2F, &kbuf);
  751. if (ret != 0)
  752. {
  753. #ifdef DEBUG
  754. DPRINTF("page_allocate failed: %x\n", ret);
  755. #endif
  756. return ret;
  757. }
  758.  
  759. ret = page_export_to_proc(vsh_process, kbuf, 0x40000, &vbuf);
  760. if (ret != 0)
  761. {
  762. #ifdef DEBUG
  763. DPRINTF("page_export_to_proc failed: %x\n", ret);
  764. #endif
  765. page_free(vsh_process, kbuf, 0x2F);
  766. return ret;
  767. }
  768.  
  769. while (remaining > 0)
  770. {
  771. uint64_t this_read_size;
  772.  
  773. this_read_size = (remaining <= read_size) ? remaining : read_size;
  774. ret = event_port_send(proxy_command_port, command, offset, (((uint64_t)vbuf)<<32ULL) | this_read_size);
  775. if (ret != 0)
  776. break;
  777.  
  778. ret = event_queue_receive(proxy_result_queue, &event, 0);
  779. if (ret != 0)
  780. break;
  781.  
  782. ret = (int)event.data1;
  783. if (ret != 0)
  784. break;
  785.  
  786. if (iskernel)
  787. {
  788. memcpy(buf, kbuf, this_read_size);
  789. }
  790. else
  791. {
  792. copy_to_process(process, kbuf, buf, this_read_size);
  793. }
  794.  
  795. buf += this_read_size;
  796. offset += this_read_size;
  797. remaining -= this_read_size;
  798. }
  799.  
  800. page_unexport_from_proc(vsh_process, vbuf);
  801. page_free(vsh_process, kbuf, 0x2F);
  802.  
  803. if (cache)
  804. {
  805. discfile_proxy->cached_sector = alloc(2048, 0x2F);
  806.  
  807. if (iskernel)
  808. {
  809. memcpy(discfile_proxy->cached_sector, obuf, 2048);
  810. }
  811. else
  812. {
  813. copy_from_process(process, obuf, discfile_proxy->cached_sector, 2048);
  814. }
  815.  
  816. discfile_proxy->cached_offset = offset-2048;
  817. }
  818. }
  819. #ifdef DEBUG
  820.  
  821. if (ret != 0)
  822. {
  823. DPRINTF("proxy read failed: %x\n", ret);
  824. }
  825. #endif
  826.  
  827.  
  828. return ret;
  829. }
  830.  
  831. static INLINE int process_read_iso_cmd_proxy(ReadIsoCmd *cmd)
  832. {
  833. return process_proxy_cmd(CMD_READ_ISO, cmd->process, cmd->buf, cmd->offset, cmd->size);
  834. }
  835.  
  836. static INLINE int process_read_cd_iso2352_cmd_proxy(ReadCdIso2352Cmd *cmd)
  837. {
  838. return process_proxy_cmd(CMD_READ_CD_ISO_2352, cmd->process, cmd->buf, cmd->start_sector * cd_sector_size, cmd->sector_count * cd_sector_size);
  839. }
  840.  
  841. #ifdef ENCRYPT_FUNCTIONS
  842. // Base function without wrappers is "__"
  843. #define device_event_func __device_event
  844. #else
  845. // Base function without wrappers is "_"
  846. #define device_event_func _device_event
  847. #endif
  848.  
  849. int device_event_func(event_port_t port, uint64_t event, uint64_t param, uint64_t device);
  850.  
  851. int process_fake_storage_event_cmd(FakeStorageEventCmd *cmd)
  852. {
  853. uint64_t *ptr = (uint64_t *)(*(uint64_t *)MKA(TOC+device_event_rtoc_entry_1));
  854. ptr = (uint64_t *)ptr[0];
  855.  
  856. event_port_t port = (event_port_t)ptr[0x40/8];
  857.  
  858. loop = 1;
  859. int ret = device_event_func(port, cmd->event, cmd->param, cmd->device);
  860. loop = 0;
  861.  
  862. return ret;
  863. }
  864.  
  865. int emu_read_bdvd1(void *object, void *buf, uint64_t size, uint64_t offset);
  866. int emu_storage_read(device_handle_t device_handle, uint64_t unk, uint64_t start_sector, uint32_t sector_count, void *buf, uint32_t *nread, uint64_t unk2);
  867.  
  868. int read_psx_sector(void *dma, void *buf, uint64_t sector)
  869. {
  870. if (disc_emulation == EMU_OFF)
  871. {
  872. device_handle_t handle;
  873. int ret;
  874.  
  875. ret = storage_open(BDVD_DRIVE, 0, &handle, 0);
  876. if (ret == 0)
  877. {
  878. ret = storage_map_io_memory(BDVD_DRIVE, dma, 4096);
  879. if (ret == 0)
  880. {
  881. for (int i = 0; i < 3; i++)
  882. {
  883. uint32_t nread;
  884.  
  885. skip_emu_check = 1;
  886. ret = call_hooked_function_7(emu_storage_read, (uint64_t)handle, 0, sector, 1, (uint64_t)dma, (uint64_t)&nread, 0);
  887. skip_emu_check = 0;
  888.  
  889. if (ret == 0)
  890. {
  891. memcpy(buf, dma, 2048);
  892. break;
  893. }
  894. }
  895.  
  896. storage_unmap_io_memory(BDVD_DRIVE, dma);
  897. }
  898. #ifdef DEBUG
  899. else
  900. {
  901. DPRINTF("retm %x\n", ret);
  902. }
  903. #endif
  904.  
  905. storage_close(handle);
  906.  
  907. }
  908.  
  909. return ret;
  910. }
  911. else if (discfd >= 0)
  912. {
  913. uint64_t x;
  914.  
  915. cellFsLseek(discfd, (sector * cd_sector_size)+0x18, SEEK_SET, &x);
  916. return cellFsRead(discfd, buf, 2048, &x);
  917. }
  918. else if (discfile_proxy)
  919. {
  920. return process_proxy_cmd(CMD_READ_ISO, NULL, buf, sector*2048, 2048);
  921. }
  922.  
  923. return -1;
  924. }
  925.  
  926. uint32_t find_file_sector(uint8_t *buf, char *file)
  927. {
  928. uint8_t *p = (uint8_t *)buf;
  929. int len = strlen(file);
  930.  
  931. while (((p+p[0]) < (buf+2048)) && (p[0] != 0))
  932. {
  933. if (p[0x20] == len && strncasecmp((char *)p+0x21, file, len) == 0)
  934. {
  935. return *(uint32_t *)&p[6];
  936. }
  937.  
  938. p += p[0];
  939. }
  940.  
  941.  
  942. #ifdef DEBUG
  943. DPRINTF("%s not found\n", file);
  944. #endif
  945.  
  946. return 0;
  947. }
  948.  
  949. int process_get_psx_video_mode(void)
  950. {
  951. int ret = -1;
  952.  
  953. if (effective_disctype == DEVICE_TYPE_PSX_CD)
  954. {
  955. char *buf, *bbuf, *p, *dma;
  956. char *exe_path;
  957.  
  958. bbuf = alloc(4096, 0x27);
  959.  
  960. page_allocate_auto(NULL, 4096, 0x2F, (void **)&dma);
  961. exe_path = alloc(140, 0x27);
  962.  
  963. if (read_psx_sector(dma, bbuf, 0x10) == 0 && read_psx_sector(dma, bbuf+2048, *(uint32_t *)&bbuf[0x9C+6]) == 0)
  964. {
  965. uint32_t sector = find_file_sector((uint8_t *)bbuf+2048, "SYSTEM.CNF;1");
  966.  
  967. buf = alloc(4096, 0x27);
  968.  
  969. if (sector != 0 && read_psx_sector(dma, buf, sector) == 0)
  970. {
  971. p = strstr(buf, "cdrom");
  972. if (!p) p = strstr(buf, "CDROM");
  973.  
  974. if (p)
  975. {
  976. p += 5;
  977.  
  978. while (*p != 0 && !isalpha(*p)) p++;
  979.  
  980. if (*p != 0)
  981. {
  982. int i = 0;
  983.  
  984. memset(exe_path, 0, 140);
  985.  
  986. while (*p >= ' ' && *p != ';' && i < 117)
  987. {
  988. if(*p=='\\' || *p=='/') {i = 0; memset(exe_path, 0, 140);} else {exe_path[i] = *p; i++;}
  989. p++;
  990. }
  991.  
  992. strcat(exe_path, ";1");
  993.  
  994. #ifdef DEBUG
  995. DPRINTF("PSX EXE: %s\n", exe_path);
  996. #endif
  997.  
  998. while(1)
  999. {
  1000. p = strstr(exe_path, "SLES_"); if(p) {ret = 1; break;}
  1001. p = strstr(exe_path, "SCES_"); if(p) {ret = 1; break;}
  1002.  
  1003. p = strstr(exe_path, "SLUS_"); if(p) {ret = 0; break;}
  1004. p = strstr(exe_path, "SCUS_"); if(p) {ret = 0; break;}
  1005.  
  1006. p = strstr(exe_path, "SLPM_"); if(p) {ret = 0; break;}
  1007. p = strstr(exe_path, "SLPS_"); if(p) {ret = 0; break;}
  1008. p = strstr(exe_path, "SCPM_"); if(p) {ret = 0; break;}
  1009. p = strstr(exe_path, "SCPS_"); if(p) {ret = 0; break;}
  1010. p = strstr(exe_path, "SIPS_"); if(p) {ret = 0; break;}
  1011.  
  1012. p = strstr(exe_path, "SCED_"); if(p) {ret = 1; break;}
  1013. p = strstr(exe_path, "SLED_"); if(p) {ret = 1; break;}
  1014.  
  1015. p = strstr(exe_path, "SCUD_"); if(p) {ret = 0; break;}
  1016. p = strstr(exe_path, "SLUD_"); if(p) {ret = 0; break;}
  1017.  
  1018. p = strstr(exe_path, "PAPX_"); if(p) {ret = 0; break;}
  1019. p = strstr(exe_path, "PBPX_"); if(p) {ret = 0; break;}
  1020. p = strstr(exe_path, "PCPX_"); if(p) {ret = 0; break;}
  1021.  
  1022. if(ret == -1)
  1023. {
  1024. sector = find_file_sector((uint8_t *)bbuf+2048, exe_path);
  1025.  
  1026. if (sector != 0 && read_psx_sector(dma, buf, sector) == 0)
  1027. {
  1028. if (strncmp(buf+0x71, "North America", 13) == 0 || strncmp(buf+0x71, "Japan", 5) == 0)
  1029. {
  1030. ret = 0;
  1031. }
  1032. else if (strncmp(buf+0x71, "Europe", 6) == 0)
  1033. {
  1034. ret = 1;
  1035. }
  1036. }
  1037. }
  1038.  
  1039. break;
  1040. }
  1041. }
  1042. }
  1043. }
  1044. dealloc(buf, 0x27);
  1045. }
  1046.  
  1047. #ifdef DEBUG
  1048. if(ret == 0) DPRINTF("NTSC\n");
  1049. if(ret == 1) DPRINTF("PAL\n");
  1050. #endif
  1051.  
  1052. dealloc(exe_path, 0x27);
  1053. dealloc(bbuf, 0x27);
  1054. page_free(NULL, dma, 0x2F);
  1055. }
  1056.  
  1057. return ret;
  1058. }
  1059.  
  1060. void dispatch_thread_entry(uint64_t arg)
  1061. {
  1062. int ret;
  1063.  
  1064. while (1)
  1065. {
  1066. event_t event;
  1067. int64_t cmd_result = 0;
  1068.  
  1069. ret = event_queue_receive(command_queue, &event, 0);
  1070. if (ret != 0)
  1071. break;
  1072.  
  1073. switch (event.data1)
  1074. {
  1075. case CMD_READ_ISO:
  1076.  
  1077. if (discfile_proxy)
  1078. {
  1079. cmd_result = process_read_iso_cmd_proxy((ReadIsoCmd *)event.data2);
  1080. }
  1081. else if (discfile_cd)
  1082. {
  1083. cmd_result = process_read_cd_iso2048_cmd((ReadIsoCmd *)event.data2);
  1084. }
  1085. else
  1086. {
  1087. cmd_result = process_read_iso_cmd((ReadIsoCmd *)event.data2);
  1088. }
  1089. break;
  1090.  
  1091. case CMD_READ_DISC:
  1092. cmd_result = process_read_disc_cmd((ReadDiscCmd *)event.data2);
  1093. break;
  1094.  
  1095. case CMD_READ_CD_ISO_2352:
  1096. if (discfile_proxy)
  1097. {
  1098. cmd_result = process_read_cd_iso2352_cmd_proxy((ReadCdIso2352Cmd *)event.data2);
  1099. }
  1100. else
  1101. {
  1102. cmd_result = process_read_cd_iso2352_cmd((ReadCdIso2352Cmd *)event.data2);
  1103. }
  1104. break;
  1105.  
  1106. case CMD_FAKE_STORAGE_EVENT:
  1107. cmd_result = process_fake_storage_event_cmd((FakeStorageEventCmd *)event.data2);
  1108. break;
  1109.  
  1110. case CMD_GET_PSX_VIDEO_MODE:
  1111. cmd_result = process_get_psx_video_mode();
  1112. break;
  1113. }
  1114.  
  1115. event_port_send(result_port, cmd_result, 0, 0);
  1116. }
  1117.  
  1118. #ifdef DEBUG
  1119. DPRINTF("Exiting dispatch thread %d\n", ret);
  1120. #endif
  1121.  
  1122. ppu_thread_exit(0);
  1123. }
  1124.  
  1125. static int read_real_disc_sector (void *buf, uint64_t lba, uint32_t size, int retries)
  1126. {
  1127. ReadDiscCmd cmd;
  1128. int ret = -1;
  1129.  
  1130. cmd.buf = buf;
  1131. cmd.start_sector = lba;
  1132. cmd.sector_count = size;
  1133.  
  1134. #ifdef DEBUG
  1135. DPRINTF("Read sector %lx\n", lba);
  1136. #endif
  1137.  
  1138. for (int i = 0; i < retries && ret != 0; i++)
  1139. {
  1140. if (0)//!loop)
  1141. {
  1142. event_t event;
  1143.  
  1144. event_port_send(command_port, CMD_READ_DISC, (uint64_t)&cmd, 0);
  1145. if (event_queue_receive(result_queue, &event, 0) == 0)
  1146. {
  1147. ret = (int)(int64_t)event.data1;
  1148. }
  1149.  
  1150. }
  1151. else
  1152. {
  1153. ret = process_read_disc_cmd(&cmd);
  1154. }
  1155.  
  1156. if (ret == 0)
  1157. {
  1158. // Even when we cannot really read the disc, we are reported success, do a lame check here:
  1159. if (*(uint32_t *)buf == 0x5B5B5B5B)
  1160. ret = -1;
  1161. }
  1162. }
  1163.  
  1164. return ret;
  1165. }
  1166.  
  1167. int is_psx(int check_ps2)
  1168. {
  1169. uint8_t *buf;
  1170. int result;
  1171. int ret = 0;
  1172.  
  1173. if (page_allocate_auto(NULL, 2048, 0x2F, (void **)&buf) == 0)
  1174. {
  1175. result = read_real_disc_sector(buf, 0x10, 1, 3);
  1176.  
  1177. if (result == 0)
  1178. {
  1179. // Probably not the best way to say if a disc is psx...
  1180. ret = (memcmp(buf+1, "CD001", 5) == 0 && memcmp(buf+8, "PLAYSTATION ", 12) == 0);
  1181. if (ret && check_ps2)
  1182. {
  1183. // Check for ps2, we need to read SYSTEM.CNF
  1184. if (read_real_disc_sector(buf, *(uint32_t *)&buf[0x9C+6], 1, 2) == 0)
  1185. {
  1186. uint8_t *p = buf;
  1187.  
  1188. while (((p+p[0]) < (buf+2048)) && (p[0] != 0))
  1189. {
  1190. if (p[0x20] == 12 && memcmp(p+0x21, "SYSTEM.CNF;1", 12) == 0)
  1191. {
  1192. if (read_real_disc_sector(buf, *(uint32_t *)&p[6], 1, 2) == 0)
  1193. {
  1194. if (memcmp(buf, "BOOT2", 5) == 0)
  1195. {
  1196. // It is ps2
  1197. ret = 2;
  1198. }
  1199. }
  1200.  
  1201. break;
  1202. }
  1203.  
  1204. p += p[0];
  1205. }
  1206. }
  1207. }
  1208. }
  1209. else
  1210. {
  1211. could_not_read_disc = 1;
  1212. }
  1213.  
  1214. page_free(NULL, buf, 0x2F);
  1215. }
  1216.  
  1217. return ret;
  1218. }
  1219.  
  1220. void process_disc_insert(uint32_t disctype)
  1221. {
  1222. could_not_read_disc = 0;
  1223. real_disctype = disctype;
  1224. effective_disctype = real_disctype;
  1225. fake_disctype = 0;
  1226. #ifdef DEBUG
  1227. DPRINTF("real disc type = %x\n", real_disctype);
  1228. #endif
  1229.  
  1230. switch (disc_emulation)
  1231. {
  1232. case EMU_PS3:
  1233. if (real_disctype != DEVICE_TYPE_PS3_BD)
  1234. {
  1235. fake_disctype = effective_disctype = DEVICE_TYPE_PS3_BD;
  1236. }
  1237. break;
  1238.  
  1239. case EMU_DVD:
  1240. if (real_disctype != DEVICE_TYPE_DVD)
  1241. {
  1242. fake_disctype = effective_disctype = DEVICE_TYPE_DVD;
  1243. }
  1244. break;
  1245.  
  1246. case EMU_BD:
  1247. // We must fake to BD-R/BD-RE and not to BD-ROM, otherwise the player will/may fail.
  1248. // (maybe beause it attemps to do some AACS shit?)
  1249. if (real_disctype < DEVICE_TYPE_BDMR_SR || real_disctype > DEVICE_TYPE_BDMRE)
  1250. {
  1251. fake_disctype = effective_disctype = DEVICE_TYPE_BDMR_SR;
  1252. }
  1253. break;
  1254.  
  1255. case EMU_PSX:
  1256. if (real_disctype != DEVICE_TYPE_PSX_CD)
  1257. {
  1258. fake_disctype = effective_disctype = DEVICE_TYPE_PSX_CD;
  1259. }
  1260. break;
  1261. #ifdef DO_PATCH_PS2
  1262. case EMU_PS2_CD:
  1263. if (real_disctype != DEVICE_TYPE_PS2_CD)
  1264. {
  1265. fake_disctype = effective_disctype = DEVICE_TYPE_PS2_CD;
  1266. }
  1267. break;
  1268.  
  1269. case EMU_PS2_DVD:
  1270. if (real_disctype != DEVICE_TYPE_PS2_DVD)
  1271. {
  1272. fake_disctype = effective_disctype = DEVICE_TYPE_PS2_DVD;
  1273. }
  1274. break;
  1275. #endif
  1276.  
  1277. case EMU_OFF:
  1278. if (real_disctype == DEVICE_TYPE_CD)
  1279. {
  1280. int psx_type = is_psx(1);
  1281.  
  1282. if (psx_type == 1)
  1283. {
  1284. // PSX CD-R support
  1285. fake_disctype = effective_disctype = DEVICE_TYPE_PSX_CD;
  1286. }
  1287. else if (psx_type == 2)
  1288. {
  1289. // PS2 CD-R support
  1290. fake_disctype = effective_disctype = DEVICE_TYPE_PS2_CD;
  1291. }
  1292. }
  1293.  
  1294. else if (real_disctype == DEVICE_TYPE_DVD)
  1295. {
  1296. if (is_psx(0))
  1297. {
  1298. fake_disctype = effective_disctype = DEVICE_TYPE_PS2_DVD;
  1299. }
  1300. }
  1301. break;
  1302. }
  1303.  
  1304. #ifdef DEBUG
  1305. DPRINTF("effective disc type = %x, fake disc type = %x\n", effective_disctype, fake_disctype);
  1306. #endif
  1307. }
  1308.  
  1309. LV2_PATCHED_FUNCTION(int, device_event, (event_port_t event_port, uint64_t event, uint64_t param, uint64_t device))
  1310. {
  1311. int lock = !loop;
  1312. #ifdef DEBUG
  1313. DPRINTF("Storage event: %lx %lx %lx\n", event, param, device);
  1314. #endif
  1315.  
  1316. if (device == BDVD_DRIVE)
  1317. {
  1318. disc_being_mounted = (event == 7);
  1319.  
  1320. if (event == 3)
  1321. {
  1322. #ifdef DEBUG
  1323. DPRINTF("Disc Insert\n");
  1324. #endif
  1325. if (lock)
  1326. mutex_lock(mutex, 0);
  1327.  
  1328. process_disc_insert(param>>32);
  1329. param = (uint64_t)(effective_disctype)<<32;
  1330.  
  1331. if (lock)
  1332. mutex_unlock(mutex);
  1333. }
  1334. else if (event == 4)
  1335. {
  1336. if (lock)
  1337. mutex_lock(mutex, 0);
  1338.  
  1339. #ifdef DEBUG
  1340. DPRINTF("Disc removed.\n");
  1341. #endif
  1342.  
  1343. if (effective_disctype == DEVICE_TYPE_PSX_CD)
  1344. {
  1345. video_mode = -1;
  1346. }
  1347.  
  1348. real_disctype = 0;
  1349. effective_disctype = 0;
  1350. fake_disctype = 0;
  1351.  
  1352. if (lock)
  1353. mutex_unlock(mutex);
  1354. }
  1355. }
  1356.  
  1357. return event_port_send(event_port, event, param, device);
  1358. }
  1359.  
  1360. int do_read_iso(void *buf, uint64_t offset, uint64_t size)
  1361. {
  1362. ReadIsoCmd cmd;
  1363. event_t event;
  1364. int ret;
  1365.  
  1366. cmd.offset = offset;
  1367. cmd.size = size;
  1368. cmd.buf = buf;
  1369. cmd.process = get_current_process_critical();
  1370.  
  1371. event_port_send(command_port, CMD_READ_ISO, (uint64_t)&cmd, 0);
  1372. ret = event_queue_receive(result_queue, &event, 0);
  1373.  
  1374. if (ret == 0)
  1375. {
  1376. ret = (int)(int64_t)event.data1;
  1377. }
  1378. #ifdef DEBUG
  1379. else
  1380. {
  1381. DPRINTF("Read failed: %x\n", ret);
  1382. }
  1383. #endif
  1384.  
  1385. return ret;
  1386. }
  1387.  
  1388. LV2_HOOKED_FUNCTION_COND_POSTCALL_8(int, emu_read_bdvd0, (void *object, uint64_t offset, void *buf, uint64_t size, int r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t st0, uint64_t st1))
  1389. {
  1390. int ret = DO_POSTCALL;
  1391.  
  1392. mutex_lock(mutex, 0);
  1393.  
  1394. if (disc_emulation != EMU_OFF)
  1395. {
  1396. #ifdef DEBUG
  1397. DPRINTF("Warning: emu_read_bdvd0 called.\n");
  1398. dump_stack_trace2(16);
  1399.  
  1400. if (r7 != 1 || r8 != 0 || r9 != 0 || r10 != 0 || st0 != 0 || st1 != 1)
  1401. {
  1402. DPRINTF("emu_read_bdvd called with unknown params\n");
  1403. //dump_stack_trace2(16);
  1404. fatal("aborting.\n");
  1405. }
  1406. #endif
  1407. ret = do_read_iso(buf, offset, size);
  1408.  
  1409. }
  1410.  
  1411. mutex_unlock(mutex);
  1412. return ret;
  1413. }
  1414.  
  1415. LV2_HOOKED_FUNCTION_COND_POSTCALL_4(int, emu_read_bdvd1, (void *object, void *buf, uint64_t size, uint64_t offset))
  1416. {
  1417. int ret = DO_POSTCALL;
  1418.  
  1419. mutex_lock(mutex, 0);
  1420.  
  1421. if (disc_emulation != EMU_OFF)
  1422. {
  1423. ret = do_read_iso(buf, offset, size);
  1424. }
  1425.  
  1426. mutex_unlock(mutex);
  1427.  
  1428. return ret;
  1429. }
  1430.  
  1431. LV2_HOOKED_FUNCTION_COND_POSTCALL_3(int, emu_read_bdvd2, (uint64_t *object, void *buf, int64_t size))
  1432. {
  1433. int ret = DO_POSTCALL;
  1434.  
  1435. mutex_lock(mutex, 0);
  1436.  
  1437. if (disc_emulation != EMU_OFF)
  1438. {
  1439. if (do_read_iso(buf, object[0x98/8], size) == 0)
  1440. ret = size;
  1441. else
  1442. ret = -1;
  1443. }
  1444.  
  1445. mutex_unlock(mutex);
  1446. return ret;
  1447. }
  1448.  
  1449. LV2_HOOKED_FUNCTION_PRECALL_SUCCESS_2(int, post_storage_get_device_info, (uint64_t device_id, device_info_t *device_info))
  1450. {
  1451. if (device_id == BDVD_DRIVE)
  1452. {
  1453. mutex_lock(mutex, 0);
  1454.  
  1455. if (effective_disctype && disc_emulation)
  1456. {
  1457. if (discfile_cd)
  1458. {
  1459. device_info->sector_count = discfile_cd->num_sectors;
  1460. }
  1461. else if (discfile_proxy)
  1462. {
  1463. device_info->sector_count = (discfile_proxy->tracks) ? discfile_proxy->size/cd_sector_size : discfile_proxy->size/2048;
  1464. }
  1465. else
  1466. {
  1467. device_info->sector_count = discfile->totalsize / device_info->sector_size;
  1468. }
  1469.  
  1470. #ifdef DEBUG
  1471. DPRINTF("Faked size to %lx\n", device_info->sector_count);
  1472. #endif
  1473.  
  1474. }
  1475.  
  1476. mutex_unlock(mutex);
  1477. }
  1478.  
  1479. return 0;
  1480. }
  1481.  
  1482. static int get_handle_device(int handle, uint64_t *device)
  1483. {
  1484. uint64_t *object;
  1485. uint64_t *ptr = (uint64_t *)(*(uint64_t *)MKA(TOC+storage_rtoc_entry_1));
  1486. ptr = (uint64_t *)(ptr[0] + 0x40);
  1487.  
  1488. int ret = storage_internal_get_device_object(ptr, handle, (void **)&object);
  1489. if (ret == 0)
  1490. {
  1491. *device = object[0xA0/8];
  1492. }
  1493.  
  1494. return ret;
  1495. }
  1496.  
  1497. LV2_HOOKED_FUNCTION_COND_POSTCALL_7(int, emu_storage_read, (device_handle_t device_handle, uint64_t unk, uint64_t start_sector, uint32_t sector_count, void *buf, uint32_t *nread, uint64_t unk2))
  1498. {
  1499. uint64_t device;
  1500. int ret = DO_POSTCALL;
  1501.  
  1502. if (skip_emu_check)
  1503. return ret;
  1504.  
  1505. if (get_handle_device(device_handle, &device) == 0)
  1506. {
  1507. if (device == BDVD_DRIVE)
  1508. {
  1509. mutex_lock(mutex, 0);
  1510.  
  1511. if (disc_emulation != EMU_OFF)
  1512. {
  1513. if (do_read_iso(buf, start_sector*2048, sector_count*2048) == 0)
  1514. {
  1515. ret = 0;
  1516. *nread = sector_count;
  1517. }
  1518. else
  1519. {
  1520. ret = -1;
  1521. }
  1522. }
  1523.  
  1524. mutex_unlock(mutex);
  1525. }
  1526. }
  1527.  
  1528. return ret;
  1529. }
  1530.  
  1531. LV2_HOOKED_FUNCTION_COND_POSTCALL_7(int, emu_sys_storage_async_read, (sys_device_handle_t device_handle, uint32_t unk, uint64_t start_sector, uint32_t sector_count, void *buf, uint64_t param, uint64_t unk2))
  1532. {
  1533. object_handle_t obj_handle;
  1534. uint64_t *sys_storage_object;
  1535. void *table;
  1536. int ret = DO_POSTCALL;
  1537.  
  1538. table = get_current_process_critical()->object_table;
  1539.  
  1540. if (open_shared_kernel_object(table, device_handle, (void **)&sys_storage_object, &obj_handle, SYS_STORAGE_HANDLE_OBJECT, 1) == 0)
  1541. {
  1542. uint64_t device = sys_storage_object[8/8];
  1543.  
  1544. if (device == BDVD_DRIVE)
  1545. {
  1546. mutex_lock(mutex, 0);
  1547.  
  1548. if (disc_emulation != EMU_OFF)
  1549. {
  1550. mutex_t storage_mutex;
  1551. event_port_t async_port;
  1552.  
  1553. storage_mutex = (mutex_t)sys_storage_object[0x98/8];
  1554.  
  1555. #ifdef DEBUG
  1556. if (unk2 != 0)
  1557. {
  1558. DPRINTF("WARNING: unk2 not 0: %lx\n", unk2);
  1559. }
  1560. #endif
  1561.  
  1562.  
  1563. mutex_lock(storage_mutex, 0);
  1564.  
  1565. async_port = (event_port_t) ((uint64_t *)sys_storage_object[(0x28+8)/8])[0x30/8];
  1566.  
  1567. if (do_read_iso(get_secure_user_ptr(buf), start_sector*2048, sector_count*2048) == 0)
  1568. {
  1569. event_port_send(async_port, param, 0, 0);
  1570. }
  1571. else
  1572. {
  1573. // Umm oh oh, what to send to port on error?
  1574. // Let's try...
  1575. event_port_send(async_port, param, -1, 0);
  1576. }
  1577.  
  1578. mutex_unlock(storage_mutex);
  1579. ret = 0;
  1580. }
  1581.  
  1582. mutex_unlock(mutex);
  1583. }
  1584.  
  1585. close_kernel_object_handle(table, obj_handle);
  1586. }
  1587.  
  1588. return ret;
  1589. }
  1590.  
  1591. int process_generic_iso_scsi_cmd(uint8_t *indata, uint64_t inlen, uint8_t *outdata, uint64_t outlen)
  1592. {
  1593. memset(outdata, 0, outlen);
  1594.  
  1595. switch (indata[0])
  1596. {
  1597. case SCSI_CMD_GET_EVENT_STATUS_NOTIFICATION:
  1598. {
  1599.  
  1600. ScsiCmdGetEventStatusNotification *cmd = (ScsiCmdGetEventStatusNotification *)indata;
  1601.  
  1602. if (cmd->notification_class_request == 0x10)
  1603. {
  1604. ScsiMediaEventResponse *resp;
  1605. int alloc_size = sizeof(ScsiMediaEventResponse);
  1606.  
  1607. resp = alloc(alloc_size, 0x27);
  1608. memset(resp, 0, alloc_size);
  1609.  
  1610. resp->event_header.event_length = sizeof(ScsiMediaEventResponse) - sizeof(ScsiEventHeader);
  1611. resp->event_header.nea_rv_nc = 4;
  1612. resp->event_header.supported_event_class = 0xF;
  1613. resp->media_status = 2;
  1614.  
  1615. memcpy(outdata, resp, (outlen <= alloc_size) ? outlen : alloc_size);
  1616. dealloc(resp, 0x27);
  1617. }
  1618. #ifdef DEBUG
  1619. else
  1620. {
  1621. DPRINTF("Event status: %02X\n", cmd->notification_class_request);
  1622. }
  1623. #endif
  1624. }
  1625. break;
  1626.  
  1627. case SCSI_CMD_READ_DISC_INFORMATION:
  1628. {
  1629. ScsiCmdReadDiscInformation *cmd = (ScsiCmdReadDiscInformation *)indata;
  1630.  
  1631. int alloc_size = sizeof(ScsiReadDiscInformationResponse);
  1632. ScsiReadDiscInformationResponse *resp = alloc(alloc_size, 0x27);
  1633.  
  1634. memset(resp, 0, sizeof(ScsiReadDiscInformationResponse));
  1635. resp->length = sizeof(ScsiReadDiscInformationResponse) - sizeof(resp->length);
  1636.  
  1637. resp->misc = 0x0E;
  1638. resp->first_track = 1;
  1639. resp->num_sessions_lb = 1;
  1640. resp->first_track_lastsession_lb = 1;
  1641. resp->last_track_lastsession_lb = 1;
  1642. resp->misc2 = 0x20;
  1643. resp->last_session_leadin = 0xFFFFFFFF;
  1644. resp->last_session_leadout = 0xFFFFFFFF;
  1645. memcpy(outdata, resp, (outlen <= cmd->alloc_length) ? outlen : cmd->alloc_length);
  1646. dealloc(resp, 0x27);
  1647. }
  1648. break;
  1649. /* #ifdef DEBUG //FREEZE PS3 WHEN MOUNT GAME ON MAMBA [NZV]
  1650. default:
  1651. DPRINTF("Command %s outlen=%ld\n", get_scsi_cmd_name(indata[0]), outlen);
  1652. #endif */
  1653. }
  1654.  
  1655. return 1;
  1656. }
  1657.  
  1658. #define GET_MSF(x) ((x)->rv_msf&2)
  1659. #define GET_FORMAT(x) ((x)->rv_format&0xF)
  1660. #define GET_EXPECTED_SECTOR_TYPE(x) (((x)->rv_est_raddr >> 2)&3)
  1661. #define GET_READ_SIZE(x) (((x)->length[0] << 16) | ((x)->length[1] << 8) | ((x)->length[2]))
  1662.  
  1663. static INLINE ScsiTrackDescriptor *find_track_by_lba(uint32_t lba)
  1664. {
  1665. ScsiTrackDescriptor *tracks;
  1666. uint32_t num_sectors;
  1667. int n;
  1668.  
  1669. if (discfile_proxy)
  1670. {
  1671. tracks = discfile_proxy->tracks;
  1672. num_sectors = discfile_proxy->size/cd_sector_size;
  1673. n = discfile_proxy->numtracks;
  1674. }
  1675. else
  1676. {
  1677. tracks = discfile_cd->tracks;
  1678. num_sectors = discfile_cd->num_sectors;
  1679. n = discfile_cd->numtracks;
  1680. }
  1681.  
  1682. for (int i = 0; i < n; i++)
  1683. {
  1684. uint32_t track_start = tracks[i].track_start_addr;
  1685. uint32_t track_end;
  1686.  
  1687. if (i == (n-1))
  1688. {
  1689. track_end = num_sectors;
  1690. }
  1691. else
  1692. {
  1693. track_end = tracks[i+1].track_start_addr;
  1694. }
  1695.  
  1696. if (lba >= track_start && lba < track_end)
  1697. {
  1698. return &tracks[i];
  1699. }
  1700. }
  1701.  
  1702. return NULL;
  1703. }
  1704.  
  1705. static uint16_t q_crc_lut[256] = {
  1706. 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
  1707. 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
  1708. 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B,
  1709. 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,
  1710. 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE,
  1711. 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6,
  1712. 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D,
  1713. 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
  1714. 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5,
  1715. 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC,
  1716. 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4,
  1717. 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,
  1718. 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,
  1719. 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
  1720. 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E,
  1721. 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
  1722. 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1,
  1723. 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,
  1724. 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0,
  1725. 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,
  1726. 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657,
  1727. 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,
  1728. 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882,
  1729. 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
  1730. 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E,
  1731. 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
  1732. 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D,
  1733. 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
  1734. 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
  1735. };
  1736.  
  1737. static INLINE uint16_t calculate_subq_crc(uint8_t *data) {
  1738. uint16_t crc = 0;
  1739. int i;
  1740.  
  1741. for (i = 0; i < 10; i++) {
  1742. crc = q_crc_lut[(crc >> 8) ^ data[i]] ^ (crc << 8);
  1743. }
  1744.  
  1745. return ~crc;
  1746. }
  1747.  
  1748. int process_cd_iso_scsi_cmd(uint8_t *indata, uint64_t inlen, uint8_t *outdata, uint64_t outlen, int is2048)
  1749. {
  1750. if (inlen < 1)
  1751. return 0;
  1752.  
  1753. switch (indata[0])
  1754. {
  1755. case SCSI_CMD_READ_TOC_PMA_ATIP:
  1756. {
  1757. ScsiCmdReadTocPmaAtip *cmd = (ScsiCmdReadTocPmaAtip *)indata;
  1758. int numtracks;
  1759.  
  1760. // TODO: this part needs change when adding proxy to ps2
  1761. if (is2048)
  1762. {
  1763. numtracks = 1;
  1764. }
  1765. else
  1766. {
  1767. numtracks = (discfile_proxy) ? discfile_proxy->numtracks : discfile_cd->numtracks;
  1768. }
  1769.  
  1770. if (inlen < sizeof(ScsiCmdReadTocPmaAtip))
  1771. return -1;
  1772.  
  1773. if (GET_FORMAT(cmd) != FORMAT_TOC)
  1774. {
  1775. #ifdef DEBUG
  1776. DPRINTF("Requesting something other than TOC: %d!!\nPassing command to real function.", GET_FORMAT(cmd));
  1777. #endif
  1778. return 0;
  1779. }
  1780.  
  1781. if (GET_MSF(cmd))
  1782. {
  1783. #ifdef DEBUG
  1784. DPRINTF("Warning: requesting tracks in MSF format. Not implemented.\n");
  1785. #endif
  1786. return -1;
  1787. }
  1788.  
  1789. // Specific case of CDDA player
  1790. if (outlen == 12)
  1791. {
  1792. ScsiTocResponse *resp = (ScsiTocResponse *)outdata;
  1793. ScsiTrackDescriptor *track = (ScsiTrackDescriptor *)(resp+1);
  1794. int i;
  1795.  
  1796. memset(resp, 0, outlen);
  1797.  
  1798. resp->toc_length = sizeof(ScsiTocResponse) - sizeof(resp->toc_length) + (sizeof(ScsiTrackDescriptor)*(numtracks+1));
  1799. resp->first_track = 1;
  1800. resp->last_track = numtracks;
  1801.  
  1802. if (cmd->track_session_num > numtracks)
  1803. {
  1804. #ifdef DEBUG
  1805. DPRINTF("Track out of range %d\n", cmd->track_session_num);
  1806. #endif
  1807. }
  1808.  
  1809. if (cmd->track_session_num > 1)
  1810. {
  1811. resp->toc_length = resp->toc_length - ((cmd->track_session_num-1) * sizeof(ScsiTrackDescriptor));
  1812. }
  1813.  
  1814. if (cmd->track_session_num == 0)
  1815. {
  1816. i = 0;
  1817. }
  1818. else
  1819. {
  1820. i = cmd->track_session_num-1;
  1821. }
  1822.  
  1823. if (is2048)
  1824. {
  1825. memset(track, 0, sizeof(ScsiTrackDescriptor));
  1826. track->adr_control = 0x14;
  1827. track->track_number = 1;
  1828. track->track_start_addr = 0;
  1829. }
  1830. else
  1831. {
  1832. memcpy(track, (discfile_proxy) ? &discfile_proxy->tracks[i] : &discfile_cd->tracks[i], sizeof(ScsiTrackDescriptor));
  1833. }
  1834.  
  1835. return 1;
  1836.  
  1837. }
  1838.  
  1839. int alloc_size = sizeof(ScsiTocResponse);
  1840. if (cmd->alloc_length > sizeof(ScsiTocResponse))
  1841. {
  1842. alloc_size += (sizeof(ScsiTrackDescriptor)*(numtracks+1));
  1843. }
  1844.  
  1845. ScsiTocResponse *resp = alloc(alloc_size, 0x27);
  1846. resp->toc_length = sizeof(ScsiTocResponse) - sizeof(resp->toc_length) + (sizeof(ScsiTrackDescriptor)*(numtracks+1));
  1847. resp->first_track = 1;
  1848. resp->last_track = numtracks;
  1849.  
  1850. if (alloc_size > sizeof(ScsiTocResponse))
  1851. {
  1852. // TODO: this part needs change when adding proxy to PS2
  1853. if (is2048)
  1854. {
  1855. ScsiTrackDescriptor *track = (ScsiTrackDescriptor *)(resp+1);
  1856.  
  1857. memset(track, 0, sizeof(ScsiTrackDescriptor));
  1858. track->adr_control = 0x14;
  1859. track->track_number = 1;
  1860. track->track_start_addr = 0;
  1861. }
  1862. else
  1863. {
  1864. memcpy(resp+1, (discfile_proxy) ? discfile_proxy->tracks : discfile_cd->tracks, numtracks * sizeof(ScsiTrackDescriptor));
  1865. }
  1866.  
  1867. ScsiTrackDescriptor *leadout = &((ScsiTrackDescriptor *)(resp+1))[numtracks];
  1868.  
  1869. memset(leadout, 0, sizeof(ScsiTrackDescriptor));
  1870. leadout->adr_control = 0x10;
  1871. leadout->track_number = 0xAA;
  1872.  
  1873. // TODO: this part needs change when adding proxy to ps2
  1874. if (is2048)
  1875. {
  1876. leadout->track_start_addr = discfile->totalsize / 2048;
  1877. }
  1878. else
  1879. {
  1880. leadout->track_start_addr = (discfile_proxy) ? discfile_proxy->size/cd_sector_size : discfile_cd->num_sectors;
  1881. }
  1882. }
  1883.  
  1884. memcpy(outdata, resp, (outlen <= cmd->alloc_length) ? outlen : cmd->alloc_length);
  1885. dealloc(resp, 0x27);
  1886. return 1;
  1887. }
  1888. break;
  1889.  
  1890. case SCSI_CMD_READ_TRACK_INFORMATION:
  1891. {
  1892. ScsiCmdReadTrackInformation *cmd = (ScsiCmdReadTrackInformation *)indata;
  1893. ScsiTrackDescriptor *track;
  1894. int numtracks;
  1895. uint32_t track_size;
  1896.  
  1897. if (inlen < sizeof(ScsiCmdReadTrackInformation))
  1898. return -1;
  1899.  
  1900. if (is2048)
  1901. {
  1902. #ifdef DEBUG
  1903. DPRINTF("READ TRACK INFORMATION not implemented for 2048 cd iso!\n");
  1904. #endif
  1905. return -1;
  1906. }
  1907.  
  1908. if (cmd->rv_o_type != 1)
  1909. {
  1910. #ifdef DEBUG
  1911. DPRINTF("rv_o_type = %x, not implemented\n", cmd->rv_o_type);
  1912. #endif
  1913. return -1;
  1914. }
  1915.  
  1916. numtracks = (discfile_proxy) ? discfile_proxy->numtracks : discfile_cd->numtracks;
  1917.  
  1918. if (cmd->lba_tsn == 0 || cmd->lba_tsn > numtracks)
  1919. {
  1920. #ifdef DEBUG
  1921. DPRINTF("Invalid track %d\n", cmd->lba_tsn);
  1922. #endif
  1923.  
  1924. return -1;
  1925. }
  1926.  
  1927. if (discfile_proxy)
  1928. {
  1929. track = &discfile_proxy->tracks[cmd->lba_tsn-1];
  1930. if (cmd->lba_tsn == numtracks)
  1931. {
  1932. track_size = discfile_proxy->size/cd_sector_size - track->track_start_addr;
  1933. }
  1934. else
  1935. {
  1936. track_size = discfile_proxy->tracks[cmd->lba_tsn].track_start_addr - track->track_start_addr;
  1937. }
  1938. }
  1939. else
  1940. {
  1941. track = &discfile_cd->tracks[cmd->lba_tsn-1];
  1942. if (cmd->lba_tsn == numtracks)
  1943. {
  1944. track_size = discfile_cd->num_sectors - track->track_start_addr;
  1945. }
  1946. else
  1947. {
  1948. track_size = discfile_cd->tracks[cmd->lba_tsn].track_start_addr - track->track_start_addr;
  1949. }
  1950. }
  1951.  
  1952. int alloc_size = sizeof(ScsiReadTrackInformationResponse);
  1953. ScsiReadTrackInformationResponse *resp = alloc(alloc_size, 0x27);
  1954.  
  1955. memset(resp, 0, sizeof(ScsiReadTrackInformationResponse));
  1956. resp->length = sizeof(ScsiReadTrackInformationResponse) - sizeof(resp->length);
  1957. resp->ltn = cmd->lba_tsn&0xFF;
  1958. resp->sn = 1;
  1959. resp->misc2 = (cmd->lba_tsn == 1) ? 2 : 0xF;
  1960. resp->lt_start_addr = track->track_start_addr;
  1961. resp->lt_size = track_size;
  1962.  
  1963. memset(outdata, 0, outlen);
  1964. memcpy(outdata, resp, (outlen <= resp->length) ? outlen : resp->length);
  1965. dealloc(resp, 0x27);
  1966. return 1;
  1967.  
  1968. }
  1969. break;
  1970.  
  1971. case SCSI_CMD_READ_DISC_INFORMATION:
  1972. {
  1973. ScsiCmdReadDiscInformation *cmd = (ScsiCmdReadDiscInformation *)indata;
  1974.  
  1975. if (inlen < sizeof(ScsiCmdReadDiscInformation))
  1976. return -1;
  1977.  
  1978. int alloc_size = sizeof(ScsiReadDiscInformationResponse);
  1979. ScsiReadDiscInformationResponse *resp = alloc(alloc_size, 0x27);
  1980.  
  1981. memset(resp, 0, sizeof(ScsiReadDiscInformationResponse));
  1982. resp->length = sizeof(ScsiReadDiscInformationResponse) - sizeof(resp->length);
  1983. resp->misc = 0x0E;
  1984. resp->first_track = 1;
  1985. resp->num_sessions_lb = 1;
  1986. resp->first_track_lastsession_lb = 1;
  1987.  
  1988. // TODO: this part needs change when adding proxy support to PS2
  1989. if (is2048)
  1990. {
  1991. resp->last_track_lastsession_lb = 1;
  1992. }
  1993. else
  1994. {
  1995. resp->last_track_lastsession_lb = (discfile_proxy) ? discfile_proxy->numtracks : discfile_cd->numtracks;
  1996. }
  1997.  
  1998. resp->misc2 = 0x20;
  1999. resp->disctype = 0x20;
  2000. resp->last_session_leadin = 0xFFFFFFFF;
  2001. resp->last_session_leadout = 0xFFFFFFFF;
  2002.  
  2003. memcpy(outdata, resp, (outlen <= cmd->alloc_length) ? outlen : cmd->alloc_length);
  2004. dealloc(resp, 0x27);
  2005. return 1;
  2006. }
  2007. break;
  2008.  
  2009. case SCSI_CMD_READ_CD:
  2010. {
  2011. ScsiCmdReadCd *cmd = (ScsiCmdReadCd *)indata;
  2012. ReadCdIso2352Cmd read_cmd;
  2013. event_t event;
  2014. uint64_t outsize;
  2015. uint8_t *buf;
  2016. int ret;
  2017. int user_data = 1;
  2018.  
  2019. if (cmd->misc == 0)
  2020. {
  2021. user_data = 0;
  2022. }
  2023.  
  2024. else if (cmd->misc != 0xF8 && cmd->misc != 0x10)
  2025. {
  2026. #ifdef DEBUG
  2027. DPRINTF("Unexpected value for misc: %02X\n", cmd->misc);
  2028.  
  2029. #endif
  2030. return -1;
  2031. }
  2032.  
  2033. if (cmd->rv_scsb != 0 && cmd->rv_scsb != 2)
  2034. {
  2035. #ifdef DEBUG
  2036. DPRINTF("Unexpected value for subchannel: %02X\n", cmd->rv_scsb);
  2037.  
  2038. #endif
  2039. return -1;
  2040. }
  2041.  
  2042. if (GET_EXPECTED_SECTOR_TYPE(cmd) != 0)
  2043. {
  2044. #ifdef DEBUG
  2045. DPRINTF("Unexpected value for expected sector type: %d\n", GET_EXPECTED_SECTOR_TYPE(cmd));
  2046.  
  2047. #endif
  2048. return -1;
  2049. }
  2050.  
  2051. uint32_t length = GET_READ_SIZE(cmd);
  2052. uint32_t lba = cmd->lba;
  2053. process_t process = get_current_process_critical();
  2054.  
  2055. if (is2048)
  2056. {
  2057. #ifdef DEBUG
  2058. DPRINTF("Read CD on 2048 iso (lba=0x%x, length=0x%x)!!! Not implemented.\n", lba, length);
  2059.  
  2060. #endif
  2061. return 0; // Fallback to real disc, let's see what happens :)
  2062. }
  2063.  
  2064. if (user_data)
  2065. {
  2066. outsize = length * cd_sector_size;
  2067. }
  2068. else
  2069. {
  2070. outsize = 0;
  2071. }
  2072.  
  2073. if (cmd->rv_scsb == 2)
  2074. {
  2075. outsize += (length*sizeof(SubChannelQ));
  2076. }
  2077.  
  2078. #ifdef DEBUG
  2079. if (outsize == 0)
  2080. {
  2081. DPRINTF("Warning: outsize is zero\n");
  2082. }
  2083. #endif
  2084.  
  2085.  
  2086. if (outsize > outlen)
  2087. {
  2088. ret = page_allocate_auto(process, outsize, 0x2F, (void **)&buf);
  2089. if (ret != 0)
  2090. return -1;
  2091. }
  2092. else
  2093. {
  2094. buf = outdata;
  2095. }
  2096.  
  2097. if (cmd->rv_scsb == 0)
  2098. {
  2099. read_cmd.start_sector = lba;
  2100. read_cmd.sector_count = length;
  2101. read_cmd.buf = buf;
  2102. read_cmd.process = process;
  2103.  
  2104. event_port_send(command_port, CMD_READ_CD_ISO_2352, (uint64_t)&read_cmd, 0);
  2105. ret = event_queue_receive(result_queue, &event, 0);
  2106. if (ret == 0)
  2107. ret = (int)(int64_t)event.data1;
  2108.  
  2109. if (ret != 0)
  2110. return -1;
  2111. }
  2112. else
  2113. {
  2114. uint8_t *p = buf;
  2115.  
  2116. for (int i = 0; i < length; i++)
  2117. {
  2118. if (user_data)
  2119. {
  2120. read_cmd.start_sector = lba;
  2121. read_cmd.sector_count = 1;
  2122. read_cmd.buf = p;
  2123. read_cmd.process = process;
  2124.  
  2125. event_port_send(command_port, CMD_READ_CD_ISO_2352, (uint64_t)&read_cmd, 0);
  2126. ret = event_queue_receive(result_queue, &event, 0);
  2127. if (ret == 0)
  2128. ret = (int)(int64_t)event.data1;
  2129.  
  2130. if (ret != 0)
  2131. return -1;
  2132.  
  2133. p += cd_sector_size;
  2134. }
  2135.  
  2136. SubChannelQ *subq = (SubChannelQ *)p;
  2137. memset(subq, 0, sizeof(SubChannelQ));
  2138.  
  2139. ScsiTrackDescriptor *track = find_track_by_lba(lba);
  2140. subq->control_adr = ((track->adr_control << 4)&0xF0) | (track->adr_control >> 4);
  2141. subq->track_number = track->track_number;
  2142. subq->index_number = 1;
  2143.  
  2144. if (user_data)
  2145. lba_to_msf_bcd(lba, &subq->min, &subq->sec, &subq->frame);
  2146.  
  2147. lba_to_msf_bcd(lba+150, &subq->amin, &subq->asec, &subq->aframe);
  2148. subq->crc = calculate_subq_crc((uint8_t *)subq);
  2149.  
  2150. p += sizeof(SubChannelQ);
  2151. lba++;
  2152. }
  2153. }
  2154.  
  2155. if (outsize > outlen)
  2156. {
  2157. memcpy(outdata, buf, outlen);
  2158. page_free(process, buf, 0x2F);
  2159. }
  2160.  
  2161. return 1;
  2162. #ifdef DEBUG
  2163. DPRINTF("READ CD, sector %x size %x, expected sector type: %d\n", cmd->lba, cd_sector_size, GET_EXPECTED_SECTOR_TYPE(cmd));
  2164. DPRINTF("Misc: %02X, rv_scsb: %02X, outlen = %lu\n", cmd->misc, cmd->rv_scsb, outlen);
  2165.  
  2166. #endif
  2167.  
  2168. }
  2169. break;
  2170.  
  2171. default:
  2172. if (total_emulation)
  2173. {
  2174. return process_generic_iso_scsi_cmd(indata, inlen, outdata, outlen);
  2175. }
  2176. }
  2177.  
  2178. return 0;
  2179. }
  2180.  
  2181. static INLINE int get_psx_video_mode(void)
  2182. {
  2183. int ret = -1;
  2184. event_t event;
  2185.  
  2186. event_port_send(command_port, CMD_GET_PSX_VIDEO_MODE, 0, 0);
  2187. if (event_queue_receive(result_queue, &event, 0) == 0)
  2188. {
  2189. ret = (int)(int64_t)event.data1;
  2190. }
  2191.  
  2192. return ret;
  2193. }
  2194. uint64_t vm_patch_off = -1;
  2195. uint64_t bf_vsh_offset = 0;
  2196.  
  2197. static INLINE int get_vsh_offset()
  2198. {
  2199. int i;
  2200.  
  2201. //First try with static offset..
  2202. if ((lv1_peekd(vsh_pos_in_ram + 0x200) == 0xF821FF917C0802A6ULL) &&
  2203. (lv1_peekd(vsh_pos_in_ram + 0x208) == 0xF80100804800039DULL) &&
  2204. (lv1_peekd(vsh_pos_in_ram + 0x210) == 0x6000000048000405ULL))
  2205. {
  2206. bf_vsh_offset = vsh_pos_in_ram;
  2207. #ifdef DEBUG
  2208. DPRINTF("Vsh.self found with static offset at address 0x%lx\n", bf_vsh_offset);
  2209. #endif
  2210. }
  2211. //..if that not work brute-force the address
  2212. else
  2213. {
  2214. for (i = 0x10000; i < 0x3000000; i += 0x10000)
  2215. {
  2216. if (lv1_peekd(i + 0x200) == 0xF821FF917C0802A6ULL)
  2217. {
  2218. if (lv1_peekd(i + 0x208) == 0xF80100804800039DULL)
  2219. {
  2220. if (lv1_peekd(i + 0x210) == 0x6000000048000405ULL)
  2221. {
  2222. bf_vsh_offset = i;
  2223. #ifdef DEBUG
  2224. DPRINTF("Vsh.self found with brute-force at address 0x%lx\n", bf_vsh_offset);
  2225. #endif
  2226. break;
  2227. }
  2228. }
  2229. }
  2230. }
  2231. }
  2232. //Vsh not found
  2233. if (bf_vsh_offset == 0)
  2234. {
  2235. #ifdef DEBUG
  2236. DPRINTF("Vsh.self not found!!\n");
  2237. #endif
  2238. return -1;
  2239. }
  2240.  
  2241. return 0;
  2242. }
  2243.  
  2244. static INLINE void get_vmode_patch()
  2245. {
  2246. if (vm_patch_off != -1) { return; }
  2247.  
  2248. #ifdef DEBUG
  2249. DPRINTF("[VIDEO MODE] Trying to find patch offset...\n");
  2250. #endif
  2251.  
  2252. vm_patch_off = vmode_patch_offset;
  2253. uint64_t i;
  2254. uint64_t mv_offset;
  2255. uint64_t addr;
  2256.  
  2257. if(vsh_type == 0xCE)
  2258. {
  2259. //REBUG REX lv2 DEX and vsh CEX
  2260. #ifdef cex_vmode_patch_offset
  2261. vm_patch_off = cex_vmode_patch_offset;
  2262. #endif
  2263. }
  2264. else if(vsh_type == 0xDE)
  2265. {
  2266. //REBUG REX lv2 CEX and vsh DEX
  2267. #ifdef dex_vmode_patch_offset
  2268. vm_patch_off = dex_vmode_patch_offset;
  2269. #endif
  2270. }
  2271.  
  2272. //First try with static offset..
  2273. addr = (bf_vsh_offset + vm_patch_off);
  2274. for(mv_offset = 0; mv_offset < 0x2000000; mv_offset += 0x100000)
  2275. {
  2276.  
  2277. if(lv1_peekd(addr + mv_offset) == 0x800100742F800000ULL || // LWZ(R0, 0x74, SP)
  2278. lv1_peekd(addr + mv_offset) == 0x380000002F800000ULL || // LI(R0, 0)
  2279. lv1_peekd(addr + mv_offset) == 0x380000002F800000ULL ) // LI(R0, 1)
  2280. {
  2281. if(lv1_peekd(addr + mv_offset + 0x20) == 0x386100704800651DULL)
  2282. {
  2283. #ifdef DEBUG
  2284. DPRINTF("[VIDEO MODE] vmode_patch_offset found with static offset at address: 0x%lx\n", addr + mv_offset);
  2285. #endif
  2286. return;
  2287. }
  2288. }
  2289. }
  2290.  
  2291. //brute-force
  2292. mv_offset = bf_vsh_offset ;
  2293. for(i = 0; i < 0x2000000; i += 4)
  2294. {
  2295. if(lv1_peekd(mv_offset + i) == 0x800100742F800000ULL || // LWZ(R0, 0x74, SP)
  2296. lv1_peekd(mv_offset + i) == 0x380000002F800000ULL || // LI(R0, 0)
  2297. lv1_peekd(mv_offset + i) == 0x380000002F800000ULL ) // LI(R0, 1)
  2298. {
  2299. if(lv1_peekd(mv_offset + i + 0x20) == 0x386100704800651DULL)
  2300. {
  2301. #ifdef DEBUG
  2302. DPRINTF("[VIDEO MODE] vmode_patch_offset found with brute-force at address 0x%lx\n", i);
  2303. #endif
  2304. vm_patch_off = i;
  2305. return;
  2306. }
  2307. }
  2308. }
  2309.  
  2310. #ifdef DEBUG
  2311. DPRINTF("[VIDEO MODE] Failed to find patch offset.\n");
  2312. #endif
  2313. vm_patch_off = 0;
  2314. }
  2315.  
  2316. static INLINE void do_video_mode_patch(void)
  2317. {
  2318. get_vsh_offset();
  2319. get_vmode_patch();
  2320.  
  2321. if(vm_patch_off == 0) return;
  2322.  
  2323. process_t p = get_current_process_critical();
  2324.  
  2325. if (!vsh_process) vsh_process = get_vsh_process(); //NzV
  2326. if(!vsh_process) return;
  2327.  
  2328. if (p == vsh_process)
  2329. {
  2330. uint32_t patch = 0;
  2331.  
  2332. if (effective_disctype == DEVICE_TYPE_PSX_CD)
  2333. {
  2334. if (video_mode != 2)
  2335. {
  2336. int ret = get_psx_video_mode();
  2337. if (ret >= 0)
  2338. video_mode = ret;
  2339. }
  2340. }
  2341. else
  2342. {
  2343. if (video_mode >= 0)
  2344. video_mode = -1;
  2345. }
  2346.  
  2347. if (video_mode >= 0)
  2348. {
  2349. if (video_mode < 2)
  2350. {
  2351. patch = LI(R0, video_mode);
  2352. video_mode = 2;
  2353. }
  2354. }
  2355. else if (video_mode == -1)
  2356. {
  2357. patch = LWZ(R0, 0x74, SP);
  2358. video_mode = -2;
  2359. }
  2360.  
  2361. if (patch != 0)
  2362. {
  2363. if(vm_patch_off) // prevent undefined vmode_patch_offset
  2364. {
  2365. DPRINTF("Patching Video mode in VSH..\n");
  2366. uint64_t patch_offset = bf_vsh_offset + vm_patch_off;
  2367. copy_to_user(&patch, (void *)(&patch_offset +0x10000), 4);
  2368. DPRINTF("Offset: 0x%08X | Data: 0x%08X\n", (uint32_t)patch_offset, (uint32_t)patch);
  2369.  
  2370. }
  2371. }
  2372. }
  2373. }
  2374.  
  2375. int process_cmd(unsigned int command, void *indata, uint64_t inlen, void *outdata, uint64_t outlen)
  2376. {
  2377. int ret = 0;
  2378.  
  2379. switch (command)
  2380. {
  2381. case STORAGE_COMMAND_GET_DEVICE_SIZE:
  2382.  
  2383. do_video_mode_patch();
  2384.  
  2385. if (disc_emulation != EMU_OFF)
  2386. {
  2387. uint64_t ret;
  2388.  
  2389. if (discfile_cd)
  2390. {
  2391. ret = discfile_cd->num_sectors;
  2392. }
  2393. else if (discfile_proxy)
  2394. {
  2395. ret = (discfile_proxy->tracks) ? discfile_proxy->size/cd_sector_size : discfile_proxy->size/2048;
  2396. }
  2397. else
  2398. {
  2399. ret = discfile->totalsize / 2048;
  2400. }
  2401.  
  2402. ret = (ret << 32) | 2048;
  2403. memset(outdata, 0, outlen);
  2404. memcpy(outdata, &ret, (sizeof(ret) > outlen) ? sizeof(ret) : outlen);
  2405.  
  2406. #ifdef DEBUG
  2407. DPRINTF("FAKING to %16lx\n", ret);
  2408. #endif
  2409.  
  2410. return 1;
  2411. }
  2412. break;
  2413.  
  2414. case STORAGE_COMMAND_GET_DEVICE_TYPE:
  2415. if (fake_disctype != 0)
  2416. {
  2417. memset(outdata, 0, outlen);
  2418. memcpy(outdata, &fake_disctype, (sizeof(fake_disctype) > outlen) ? sizeof(fake_disctype) : outlen);
  2419. return 1;
  2420. }
  2421. break;
  2422.  
  2423. case STORAGE_COMMAND_NATIVE:
  2424. {
  2425. uint8_t cmd = *(uint8_t *)indata;
  2426.  
  2427. if ((effective_disctype == DEVICE_TYPE_PSX_CD || effective_disctype == DEVICE_TYPE_PS2_CD
  2428. || effective_disctype == DEVICE_TYPE_PS2_DVD) && cmd == SCSI_CMD_GET_CONFIGURATION)
  2429. {
  2430. // Region bypass on original psx/ps2 disc
  2431. memset(outdata, 0, outlen);
  2432. return 1;
  2433. }
  2434.  
  2435. if (disc_emulation != EMU_OFF)
  2436. {
  2437. if (discfile_cd || (discfile_proxy && discfile_proxy->tracks))
  2438. {
  2439. return process_cd_iso_scsi_cmd(indata, inlen, outdata, outlen, 0);
  2440. }
  2441. #ifdef DO_PATCH_PS2
  2442. else if (disc_emulation == EMU_PS2_CD)
  2443. {
  2444. return process_cd_iso_scsi_cmd(indata, inlen, outdata, outlen, 1);
  2445. }
  2446. #endif
  2447. else
  2448. {
  2449. if (total_emulation)
  2450. return process_generic_iso_scsi_cmd(indata, inlen, outdata, outlen);
  2451. }
  2452. }
  2453. }
  2454. break;
  2455. }
  2456.  
  2457. return ret;
  2458. }
  2459.  
  2460. LV2_HOOKED_FUNCTION_COND_POSTCALL_7(int, emu_storage_send_device_command, (device_handle_t device_handle, unsigned int command, void *indata, uint64_t inlen, void *outdata, uint64_t outlen, uint64_t *unkret))
  2461. {
  2462. uint64_t device;
  2463. int ret = DO_POSTCALL;
  2464.  
  2465. if (get_handle_device(device_handle, &device) == 0)
  2466. {
  2467. if (device == BDVD_DRIVE)
  2468. {
  2469. mutex_lock(mutex, 0);
  2470.  
  2471. int tri = process_cmd(command, indata, inlen, outdata, outlen);
  2472.  
  2473. if (tri > 0)
  2474. {
  2475. ret = 0;
  2476. }
  2477. else if (tri < 0)
  2478. {
  2479. ret = tri;
  2480. }
  2481.  
  2482. mutex_unlock(mutex);
  2483. }
  2484. }
  2485.  
  2486. return ret;
  2487. }
  2488.  
  2489. LV2_HOOKED_FUNCTION_COND_POSTCALL_7(int, emu_sys_storage_async_send_device_command, (sys_device_handle_t device_handle, unsigned int command, void *indata, uint64_t inlen, void *outdata, uint64_t outlen, uint64_t param))
  2490. {
  2491. object_handle_t obj_handle;
  2492. uint64_t *sys_storage_object;
  2493. void *table;
  2494. int ret = DO_POSTCALL;
  2495.  
  2496. table = get_current_process_critical()->object_table;
  2497.  
  2498. if (open_shared_kernel_object(table, device_handle, (void **)&sys_storage_object, &obj_handle, SYS_STORAGE_HANDLE_OBJECT, 1) == 0)
  2499. {
  2500. uint64_t device = sys_storage_object[8/8];
  2501.  
  2502. if (device == BDVD_DRIVE)
  2503. {
  2504. mutex_t storage_mutex;
  2505. event_port_t async_port;
  2506.  
  2507. storage_mutex = (mutex_t)sys_storage_object[0x98/8];
  2508. mutex_lock(storage_mutex, 0);
  2509.  
  2510. async_port = (event_port_t) ((uint64_t *)sys_storage_object[(0x28+8)/8])[0x30/8];
  2511. mutex_lock(mutex, 0);
  2512.  
  2513. int tri = process_cmd(command, get_secure_user_ptr(indata), inlen, get_secure_user_ptr(outdata), outlen);
  2514.  
  2515. if (tri > 0)
  2516. {
  2517. ret = 0;
  2518. event_port_send(async_port, param, 0, 0);
  2519. }
  2520. else if (tri < 0)
  2521. {
  2522. ret = 0;
  2523. event_port_send(async_port, param, -1, 0);
  2524. }
  2525.  
  2526. mutex_unlock(mutex);
  2527. mutex_unlock(storage_mutex);
  2528. }
  2529.  
  2530. close_kernel_object_handle(table, obj_handle);
  2531. }
  2532.  
  2533. return ret;
  2534. }
  2535.  
  2536. static INLINE unsigned int get_disc_type(/*int hooked*/)
  2537. {
  2538. device_handle_t handle;
  2539. unsigned int ret = 0;
  2540.  
  2541. if (storage_open(BDVD_DRIVE, 0, &handle, 0) == 0)
  2542. {
  2543. uint32_t indata = 0x01010000;
  2544. unsigned int disctype;
  2545. int res;
  2546.  
  2547. /*if (!hooked)
  2548. {
  2549. res = storage_send_device_command(handle, STORAGE_COMMAND_GET_DEVICE_TYPE, &indata,
  2550. sizeof(indata), &disctype, sizeof(disctype), NULL);
  2551. }
  2552. else*/
  2553. {
  2554. res = (int)call_hooked_function_7(emu_storage_send_device_command, (uint64_t)handle, STORAGE_COMMAND_GET_DEVICE_TYPE, (uint64_t)&indata,
  2555. sizeof(indata), (uint64_t)&disctype, sizeof(disctype), (uint64_t)NULL);
  2556. }
  2557.  
  2558. if (res == 0 && disctype != 0)
  2559. {
  2560. ret = disctype;
  2561. }
  2562.  
  2563. storage_close(handle);
  2564. }
  2565.  
  2566. return ret;
  2567. }
  2568.  
  2569. static void fake_reinsert(unsigned int disctype)
  2570. {
  2571. FakeStorageEventCmd cmd;
  2572.  
  2573. cmd.param = (uint64_t)(disctype)<<32;
  2574. cmd.device = BDVD_DRIVE;
  2575.  
  2576. cmd.event = 4;
  2577. process_fake_storage_event_cmd(&cmd);
  2578. cmd.event = 8;
  2579. process_fake_storage_event_cmd(&cmd);
  2580. cmd.event = 7;
  2581. process_fake_storage_event_cmd(&cmd);
  2582. cmd.event = 3;
  2583. process_fake_storage_event_cmd(&cmd);
  2584. }
  2585.  
  2586. LV2_HOOKED_FUNCTION_COND_POSTCALL_2(int, emu_disc_auth, (uint64_t func, uint64_t param))
  2587. {
  2588. #ifdef DEBUG
  2589. DPRINTF("Disc auth: %lx %lx (process: %s)\n", func, param, get_process_name(get_current_process_critical()));
  2590. #endif
  2591.  
  2592. if (func == 0x5004)
  2593. {
  2594. uint32_t param5004 = param;
  2595.  
  2596. if (param5004 == 1) // Auth psx disc
  2597. {
  2598. if (!vsh_process) vsh_process = get_vsh_process(); //NzV
  2599. if (vsh_process && get_current_process_critical() == vsh_process && effective_disctype == DEVICE_TYPE_PSX_CD)
  2600. {
  2601. // Just bypass auth and leave current 0x29 profile
  2602. return 0;
  2603. }
  2604. }
  2605. else if (param5004 == 0x29)
  2606. {
  2607. if (!vsh_process) vsh_process = get_vsh_process(); //NzV
  2608. if (vsh_process && get_current_process_critical() == vsh_process)
  2609. {
  2610. if (could_not_read_disc)
  2611. {
  2612. could_not_read_disc = 0;
  2613. mutex_lock(mutex, 0);
  2614.  
  2615. int ret = call_hooked_function_2(emu_disc_auth, func, param); // Recursive!
  2616. if (ret == 0)
  2617. {
  2618. fake_reinsert(get_disc_type());
  2619. }
  2620.  
  2621. mutex_unlock(mutex);
  2622. return ret;
  2623. }
  2624. }
  2625. }
  2626. }
  2627. else if (func == 0x5007)
  2628. {
  2629. if (param == 0x43)
  2630. {
  2631. return 0;
  2632. }
  2633.  
  2634. if (disc_emulation == EMU_PS3 && real_disctype != DEVICE_TYPE_PS3_BD)
  2635. {
  2636. static int inloop = 0;
  2637.  
  2638. if (!inloop)
  2639. {
  2640. inloop = 1;
  2641. call_hooked_function_2(emu_disc_auth, func, param); // Recursive!
  2642. return 0; /* return 0 regardless of result */
  2643.  
  2644. }
  2645. else
  2646. {
  2647. inloop = 0;
  2648. }
  2649. }
  2650. }
  2651.  
  2652. return DO_POSTCALL;
  2653. }
  2654.  
  2655. LV2_HOOKED_FUNCTION_PRECALL_SUCCESS_8(int, post_cellFsUtilMount, (const char *block_dev, const char *filesystem, const char *mount_point, int unk, int read_only, int unk2, char *argv[], int argc))
  2656. {
  2657. #ifdef DEBUG
  2658. DPRINTF("cellFsUtilMount: %s\n", mount_point);
  2659. #endif
  2660. if (!hdd0_mounted && strcmp(mount_point, "/dev_hdd0") == 0 && strcmp(filesystem, "CELL_FS_UFS") == 0)
  2661. {
  2662. hdd0_mounted = 1;
  2663. #ifdef DO_PATCH_PS2
  2664. copy_emus(ps2emu_type);
  2665. #endif
  2666. read_mamba_config();
  2667. mutex_lock(mutex, 0);
  2668. if (real_disctype == 0)
  2669. {
  2670. unsigned int disctype = get_disc_type();
  2671.  
  2672. if (disctype == DEVICE_TYPE_CD || disctype == DEVICE_TYPE_DVD)
  2673. {
  2674. fake_reinsert(disctype);
  2675. }
  2676. else if (disctype != 0)
  2677. {
  2678. process_disc_insert(disctype);
  2679. }
  2680. }
  2681. mutex_unlock(mutex);
  2682. #ifndef DEBUG
  2683. unhook_function_on_precall_success(cellFsUtilMount_symbol, post_cellFsUtilMount, 8);
  2684. #endif
  2685. }
  2686. return 0;
  2687. }
  2688.  
  2689. #ifdef DO_PATCH_PS2
  2690. static INLINE int get_ps2emu_type(void)
  2691. {
  2692. uint8_t config[8];
  2693. u64 v2;
  2694. lv1_get_repository_node_value(PS3_LPAR_ID_PME, FIELD_FIRST("sys", 0), FIELD("hw", 0), FIELD("config", 0), 0, (u64 *)config, &v2);
  2695. if (config[6]&1) // has emotion engine
  2696. {
  2697. return PS2EMU_HW;
  2698. }
  2699. else if (config[0]&0x20) // has graphics synthesizer
  2700. {
  2701. return PS2EMU_GX;
  2702. }
  2703. return PS2EMU_SW;
  2704. }
  2705.  
  2706. char *ps2emu_stage2[] =
  2707. {
  2708. "ps2hwemu_stage2.bin",
  2709. "ps2gxemu_stage2.bin",
  2710. };
  2711.  
  2712. static INLINE void load_ps2emu_stage2(int emu_type)
  2713. {
  2714. char name[64];
  2715. int src, dst;
  2716. uint8_t *buf;
  2717.  
  2718. if (emu_type < 0 || emu_type > PS2EMU_GX)
  2719. return;
  2720.  
  2721. page_allocate_auto(NULL, 0x10000, 0x2F, (void **)&buf);
  2722.  
  2723. sprintf(name, "/dev_flash/ps2emu/%s", ps2emu_stage2[emu_type]);
  2724.  
  2725. if (cellFsOpen(name, CELL_FS_O_RDONLY, &src, 0, NULL, 0) == 0)
  2726. {
  2727. uint64_t size;
  2728.  
  2729. cellFsRead(src, buf, 0x10000, &size);
  2730. cellFsClose(src);
  2731.  
  2732. if (cellFsOpen(PS2EMU_STAGE2_FILE, CELL_FS_O_WRONLY|CELL_FS_O_CREAT|CELL_FS_O_TRUNC, &dst, 0666, NULL, 0) == 0)
  2733. {
  2734. cellFsWrite(dst, buf, size, &size);
  2735. cellFsClose(dst);
  2736. }
  2737. }
  2738. #ifdef DEBUG
  2739. else
  2740. {
  2741. DPRINTF("Failed to open ps2 stage2: %s\n", name);
  2742. }
  2743. #endif
  2744.  
  2745. page_free(NULL, buf, 0x2F);
  2746. }
  2747.  
  2748. void copy_emus(int emu_type)
  2749. {
  2750. char name[64];
  2751. int src, dst;
  2752. uint8_t *buf;
  2753.  
  2754. if (emu_type < 0 || emu_type > PS2EMU_GX)
  2755. return;
  2756.  
  2757. page_allocate_auto(NULL, 0x10000, 0x2F, (void **)&buf);
  2758.  
  2759. sprintf(name, "/dev_flash/ps2emu/%s", ps2emu_stage2[emu_type]);
  2760.  
  2761. if (cellFsOpen(name, CELL_FS_O_RDONLY, &src, 0, NULL, 0) == 0)
  2762. {
  2763. uint64_t size;
  2764.  
  2765. cellFsRead(src, buf, 0x10000, &size);
  2766. cellFsClose(src);
  2767.  
  2768. if (cellFsOpen(PS2EMU_STAGE2_FILE, CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_TRUNC, &dst, 0666, NULL, 0) == 0)
  2769. {
  2770. cellFsWrite(dst, buf, size, &size);
  2771. cellFsClose(dst);
  2772. }
  2773. }
  2774. #ifdef DEBUG
  2775. else
  2776. {
  2777. DPRINTF("Failed to open ps2 stage2: %s\n", name);
  2778. }
  2779. #endif
  2780.  
  2781. page_free(NULL, buf, 0x2F);
  2782. }
  2783.  
  2784. static void build_netemu_params(uint8_t *ps2_soft, uint8_t *ps2_net)
  2785. {
  2786. int fd;
  2787. uint64_t written;
  2788.  
  2789. //First take care of sm arguments
  2790. memset(ps2_net, 0, 0x40);
  2791. memcpy(ps2_net, ps2_soft, 8);
  2792. ps2_net[8] = 3;
  2793. strcpy((char *)ps2_net + 9, "--COBRA--");
  2794. memcpy(ps2_net+0x2A, ps2_soft+0x118, 6);
  2795.  
  2796. //Now ps2bootparam
  2797. if (cellFsOpen("/dev_hdd0/tmp/game/ps2bootparam.dat", CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_TRUNC, &fd, 0666, NULL, 0) != 0)
  2798. {
  2799. #ifdef DEBUG
  2800. DPRINTF("Cannot open ps2bootparam.dat\n");
  2801. #endif
  2802. return;
  2803. }
  2804.  
  2805. uint64_t static_one={0x054c026840000000};
  2806. uint64_t static_two={0x3600043504082225};
  2807.  
  2808. //netemu ps2bootparam.dat has a format very similar to softemu sm arguments
  2809. ps2_soft[11] = 3;
  2810. ps2_soft[0x4d0] = 8;
  2811. ps2_soft[0x4d7] = 6;
  2812. strcpy((char *)ps2_soft+12, "--COBRA--");
  2813. memset(ps2_soft+0x4f0, 0, 0x2204);
  2814. int controller_count=0;
  2815.  
  2816. //patch controllers
  2817. uint64_t controller, offset;
  2818. for(uint32_t i = 0; i < 11; i++)
  2819. {
  2820. memcpy(&controller, ps2_soft + 0x98 + (8*i), 8);
  2821. if(controller)
  2822. {
  2823. offset = (0x218*i);
  2824. memcpy(ps2_soft+offset+0x4f4, &controller, 8);
  2825. memcpy(ps2_soft+offset+0x4f4+0x8, &static_one, 8);
  2826. ps2_soft[offset+0x515]=9;
  2827. memcpy(ps2_soft+offset+0x516, &static_two, 8);
  2828. controller_count++;
  2829. }
  2830. }
  2831.  
  2832. ps2_soft[0x4f3] = controller_count;
  2833. cellFsWrite(fd, ps2_soft, 0x26f4, &written);
  2834.  
  2835. // netemu has a 0x4F0-0x773 section where custom memory card is, but we dont need it,
  2836. // Not writing it + a patch in netemu forces the emu to use the internal ones like BC consoles
  2837. // NPDRM games will still use their memcards as the section is written
  2838. cellFsClose(fd);
  2839. }
  2840.  
  2841. LV2_HOOKED_FUNCTION(int, shutdown_copy_params_patched, (uint8_t *argp_user, uint8_t *argp, uint64_t args, uint64_t param))
  2842. {
  2843. int prepare_ps2emu = 0;
  2844.  
  2845. copy_from_user(argp_user, argp, args);
  2846. extend_kstack(0);
  2847.  
  2848. if (param == 0x8202) /* Reboot into PS2 LPAR (ps2_emu, ps2_gxemu or ps2_softemu) */
  2849. prepare_ps2emu = 1;
  2850.  
  2851. else if (param == 0x8204) /* Reboot into ps2_netemu LPAR */
  2852. {
  2853. #ifdef DEBUG
  2854. DPRINTF("Reboot into ps2_netemu LPAR (0x8204), ps2emu_type = %i\n", ps2emu_type);
  2855. #endif
  2856. // Delete ps2emu config file when ps2_netemu is loaded on BC/Semi-BC Consoles to fix the issue with ISO redirection
  2857. // Credits @Habib and @aldostools
  2858. if(ps2emu_type==PS2EMU_HW || ps2emu_type==PS2EMU_GX)
  2859. {
  2860. #ifdef DEBUG
  2861. DPRINTF("Deleting %s\n", PS2EMU_CONFIG_FILE);
  2862. #endif
  2863. cellFsUnlink(PS2EMU_CONFIG_FILE);
  2864. }
  2865.  
  2866. // We need to check first if this a NPDRM or a plain iso launched from disc icon
  2867. // Discard first the case of BC consoles, since the ps2tonet patch is not done there
  2868. if (argp[12] == 0) /* if vsh prepared the arguments for ps2_softemu */
  2869. {
  2870. if (disc_emulation == EMU_OFF)
  2871. {
  2872. // If optical disc, let's just panic
  2873. if (effective_disctype == DEVICE_TYPE_PS2_CD || effective_disctype == DEVICE_TYPE_PS2_DVD)
  2874. {
  2875. fatal("Sorry, no optical disc support in ps2_netemu\n");
  2876. }
  2877. else
  2878. {
  2879. // We should be never here "naturally" (a hb could still force this situation)
  2880. // Well, maybe if the user quckly removed a ps2 disc...
  2881. }
  2882. }
  2883. else if (disc_emulation == EMU_PS2_CD || disc_emulation == EMU_PS2_DVD)
  2884. {
  2885. prepare_ps2emu = 1;
  2886. build_netemu_params(get_secure_user_ptr(argp_user), argp);
  2887. }
  2888. else
  2889. {
  2890. // We should be never here "naturally" (a hb could still force this situation)
  2891. }
  2892. }
  2893. else
  2894. {
  2895. cellFsUnlink(PS2EMU_CONFIG_FILE);
  2896. if (disc_emulation == EMU_PS2_CD || disc_emulation == EMU_PS2_DVD)
  2897. {
  2898.  
  2899. prepare_ps2emu = 1;
  2900. }
  2901. else
  2902. {
  2903. #ifdef DEBUG
  2904. DPRINTF("NPDRM game, skipping ps2emu preparation\n");
  2905. #endif
  2906. }
  2907. }
  2908. }
  2909.  
  2910. if (prepare_ps2emu)
  2911. {
  2912. int fd;
  2913.  
  2914. if (cellFsOpen(PS2EMU_CONFIG_FILE, CELL_FS_O_WRONLY|CELL_FS_O_CREAT|CELL_FS_O_TRUNC, &fd, 0666, NULL, 0) == 0)
  2915. {
  2916. if (disc_emulation == EMU_PS2_DVD || disc_emulation == EMU_PS2_CD)
  2917. {
  2918. uint64_t nwritten;
  2919. uint8_t *buf;
  2920.  
  2921. page_allocate_auto(NULL, 0x1000, 0x2F, (void **)&buf);
  2922.  
  2923. memset(buf, 0, 0x1000);
  2924. // bit 0-> is cd
  2925. // bit 1 -> total emulation
  2926. buf[0] = (disc_emulation == EMU_PS2_CD) | ((real_disctype == 0)<<1);
  2927. strncpy((char *)buf+1, (discfile_cd) ? discfile_cd->file : discfile->files[0], 0x7FE);
  2928.  
  2929. // TODO: this will need change when adding proxy to PS2
  2930. if (discfile_cd)
  2931. {
  2932. buf[0x800] = discfile_cd->numtracks;
  2933. memcpy(buf+0x801, discfile_cd->tracks, discfile_cd->numtracks*sizeof(ScsiTrackDescriptor));
  2934. }
  2935.  
  2936. buf[0x702]=0x6d;
  2937. buf[0x703]=0x6f;
  2938. buf[0x704]=0x75;
  2939. buf[0x705]=0x6e;
  2940. buf[0x706]=0x74;
  2941.  
  2942. cellFsWrite(fd, buf, 0x1000, &nwritten);
  2943. cellFsClose(fd);
  2944.  
  2945. page_free(NULL, buf, 0x2F);
  2946. }
  2947. else
  2948. {
  2949. cellFsClose(fd);
  2950.  
  2951. // Delete file only on original disc, otherwise the file will be empty
  2952. if (real_disctype == DEVICE_TYPE_PS2_DVD || real_disctype == DEVICE_TYPE_PS2_CD)
  2953. {
  2954. cellFsUnlink(PS2EMU_CONFIG_FILE);
  2955. }
  2956. }
  2957. }
  2958. load_ps2emu_stage2(ps2emu_type);
  2959. }
  2960. return 0;
  2961. }
  2962. #endif
  2963.  
  2964. static INLINE void do_umount_discfile(void)
  2965. {
  2966. if (discfd != -1)
  2967. {
  2968. cellFsClose(discfd);
  2969. discfd = -1;
  2970. }
  2971.  
  2972. if (discfile)
  2973. {
  2974. if (discfile->cached_sector)
  2975. {
  2976. dealloc(discfile->cached_sector, 0x2F);
  2977. }
  2978.  
  2979. dealloc(discfile, 0x27);
  2980. discfile = NULL;
  2981. }
  2982.  
  2983. if (discfile_cd)
  2984. {
  2985. if (discfile_cd->cache)
  2986. {
  2987. page_free(NULL, discfile_cd->cache, 0x2F);
  2988. }
  2989.  
  2990. dealloc(discfile_cd, 0x27);
  2991. discfile_cd = NULL;
  2992. }
  2993.  
  2994. if (discfile_proxy)
  2995. {
  2996. if (discfile_proxy->cached_sector)
  2997. {
  2998. dealloc(discfile_proxy->cached_sector, 0x2F);
  2999. }
  3000.  
  3001. dealloc(discfile_proxy, 0x27);
  3002. discfile_proxy = NULL;
  3003.  
  3004. if (proxy_command_port)
  3005. {
  3006. event_port_disconnect(proxy_command_port);
  3007. event_port_destroy(proxy_command_port);
  3008. event_queue_destroy(proxy_result_queue);
  3009. proxy_command_port = NULL;
  3010. }
  3011. }
  3012.  
  3013. disc_emulation = EMU_OFF;
  3014. total_emulation = 0;
  3015. }
  3016.  
  3017. static INLINE int check_files_and_allocate(unsigned int filescount, char *files[])
  3018. {
  3019. if (filescount == 0 || filescount > 32)
  3020. return EINVAL;
  3021.  
  3022. int allocsize = sizeof(DiscFile) + (sizeof(char *) * filescount) + (sizeof(uint64_t) * filescount);
  3023.  
  3024. for (int i = 0; i < filescount; i++)
  3025. {
  3026. int len = strlen(files[i]);
  3027. if (len >= MAX_PATH)
  3028. return EINVAL;
  3029.  
  3030. allocsize += len+1;
  3031. }
  3032.  
  3033. discfile = alloc(allocsize, 0x27);
  3034. if (!discfile)
  3035. return ENOMEM;
  3036.  
  3037. discfile->count = filescount;
  3038. discfile->activefile = 0;
  3039. discfile->totalsize = 0;
  3040. discfile->files = (char **)(discfile+1);
  3041. discfile->sizes = (uint64_t *)(discfile->files+filescount);
  3042. char *p = (char *)(discfile->sizes+filescount);
  3043.  
  3044. for (int i = 0; i < filescount; i++)
  3045. {
  3046. CellFsStat stat;
  3047.  
  3048. int ret = cellFsStat(files[i], &stat);
  3049. if (ret != 0)
  3050. {
  3051. dealloc(discfile, 0x27);
  3052. discfile = NULL;
  3053. return ret;
  3054. }
  3055.  
  3056. #ifdef DEBUG
  3057. DPRINTF("%s, filesize: %lx\n", files[i], stat.st_size);
  3058. #endif
  3059.  
  3060. if (stat.st_size < 4096)
  3061. {
  3062. dealloc(discfile, 0x27);
  3063. discfile = NULL;
  3064. return EINVAL;
  3065. }
  3066.  
  3067. discfile->totalsize += stat.st_size;
  3068. discfile->sizes[i] = stat.st_size;
  3069. discfile->files[i] = p;
  3070. strcpy(p, files[i]);
  3071. p += strlen(p)+1;
  3072. }
  3073.  
  3074. return 0;
  3075. }
  3076.  
  3077. int mount_common(unsigned int filescount, char *files[])
  3078. {
  3079. if (disc_emulation != EMU_OFF)
  3080. return EBUSY;
  3081.  
  3082. int ret = check_files_and_allocate(filescount, files);
  3083. if (ret != 0)
  3084. return ret;
  3085.  
  3086. discfile->cached_sector = NULL;
  3087. discfile->cached_offset = 0;
  3088.  
  3089. return 0;
  3090. }
  3091.  
  3092. int mount_ps3_discfile(unsigned int filescount, char *files[])
  3093. {
  3094. int ret;
  3095. mutex_lock(mutex, 0);
  3096.  
  3097. ret = mount_common(filescount, files);
  3098. if (ret == 0)
  3099. {
  3100. disc_emulation = EMU_PS3;
  3101. total_emulation = (!disc_being_mounted && real_disctype == 0);
  3102. }
  3103.  
  3104. mutex_unlock(mutex);
  3105. return ret;
  3106. }
  3107.  
  3108. int mount_dvd_discfile(unsigned int filescount, char *files[])
  3109. {
  3110. int ret;
  3111. mutex_lock(mutex, 0);
  3112.  
  3113. ret = mount_common(filescount, files);
  3114. if (ret == 0)
  3115. {
  3116. disc_emulation = EMU_DVD;
  3117. total_emulation = (!disc_being_mounted && real_disctype == 0);
  3118. }
  3119.  
  3120. mutex_unlock(mutex);
  3121. return ret;
  3122. }
  3123.  
  3124. int mount_bd_discfile(unsigned int filescount, char *files[])
  3125. {
  3126. int ret;
  3127. mutex_lock(mutex, 0);
  3128.  
  3129. ret = mount_common(filescount, files);
  3130. if (ret == 0)
  3131. {
  3132. disc_emulation = EMU_BD;
  3133. total_emulation = (!disc_being_mounted && real_disctype == 0);
  3134. }
  3135.  
  3136. mutex_unlock(mutex);
  3137. return ret;
  3138. }
  3139.  
  3140. int mount_ps_cd(char *file, unsigned int trackscount, ScsiTrackDescriptor *tracks)
  3141. {
  3142. int ret;
  3143. int len;
  3144.  
  3145. if (disc_emulation != EMU_OFF)
  3146. return EBUSY;
  3147.  
  3148. len = strlen(file);
  3149.  
  3150.  
  3151. // -- AV: cd sector size
  3152. cd_sector_size = (trackscount & 0xffff00)>>4; // <- Use: trackscount = num_of_tracks | (cd_sector_size<<4);
  3153. if(cd_sector_size != 2352 && cd_sector_size != 2048 && cd_sector_size != 2336 && cd_sector_size != 2448) cd_sector_size = 2352;
  3154. trackscount &= 0xff;
  3155. // --
  3156.  
  3157. if (len >= MAX_PATH || trackscount >= 100)
  3158. {
  3159. ret = EINVAL;
  3160. }
  3161. else
  3162. {
  3163. CellFsStat stat;
  3164.  
  3165. ret = cellFsStat(file, &stat);
  3166. if (ret == 0)
  3167. {
  3168. // -- AV: cd sector size
  3169. if(cd_sector_size == 2352)
  3170. {
  3171. // detect sector size
  3172. ret = cellFsOpen(file, CELL_FS_O_RDONLY, &discfd, 0, NULL, 0);
  3173. if(ret == 0)
  3174. {
  3175. char buffer[0x10]; buffer[0xD] = 0; uint64_t v;
  3176. cellFsLseek(discfd, 0x9320, SEEK_SET, &v); cellFsRead(discfd, buffer, 0xC, &v); if(memcmp(buffer, "PLAYSTATION ", 0xC)==0) cd_sector_size = 2352; else {
  3177. cellFsLseek(discfd, 0x8020, SEEK_SET, &v); cellFsRead(discfd, buffer, 0xC, &v); if(memcmp(buffer, "PLAYSTATION ", 0xC)==0) cd_sector_size = 2048; else {
  3178. cellFsLseek(discfd, 0x9920, SEEK_SET, &v); cellFsRead(discfd, buffer, 0xC, &v); if(memcmp(buffer, "PLAYSTATION ", 0xC)==0) cd_sector_size = 2448; else {
  3179. cellFsLseek(discfd, 0x9220, SEEK_SET, &v); cellFsRead(discfd, buffer, 0xC, &v); if(memcmp(buffer, "PLAYSTATION ", 0xC)==0) cd_sector_size = 2336; }}}
  3180.  
  3181. cellFsClose(discfd);
  3182. }
  3183. discfd = -1;
  3184. }
  3185. // --
  3186.  
  3187. discfile_cd = alloc(sizeof(DiscFileCD) + (len+1) + (trackscount * sizeof(ScsiTrackDescriptor)) , 0x27);
  3188. page_allocate_auto(NULL, CD_CACHE_SIZE * cd_sector_size, 0x2F, (void **)&discfile_cd->cache);
  3189.  
  3190. discfile_cd->num_sectors = stat.st_size / cd_sector_size;
  3191. discfile_cd->numtracks = trackscount;
  3192. discfile_cd->cached_sector = 0x80000000;
  3193. discfile_cd->tracks = (ScsiTrackDescriptor *)(discfile_cd+1);
  3194. discfile_cd->file = (char *)(discfile_cd->tracks + trackscount);
  3195.  
  3196. strcpy(discfile_cd->file, file);
  3197.  
  3198. for (int i = 0; i < trackscount; i++)
  3199. {
  3200. memcpy(&discfile_cd->tracks[i], &tracks[i], sizeof(ScsiTrackDescriptor));
  3201. }
  3202. }
  3203. }
  3204.  
  3205. return ret;
  3206. }
  3207.  
  3208. int mount_psx_discfile(char *file, unsigned int trackscount, ScsiTrackDescriptor *tracks)
  3209. {
  3210. int ret;
  3211.  
  3212. mutex_lock(mutex, 0);
  3213.  
  3214. ret = mount_ps_cd(file, trackscount, tracks);
  3215. if (ret == 0)
  3216. {
  3217. disc_emulation = EMU_PSX;
  3218. total_emulation = (!disc_being_mounted && real_disctype == 0);
  3219. }
  3220.  
  3221. mutex_unlock(mutex);
  3222. return ret;
  3223. }
  3224.  
  3225. #ifdef DO_PATCH_PS2
  3226. int mount_ps2_discfile(unsigned int filescount, char *files[], unsigned int trackscount, ScsiTrackDescriptor *tracks)
  3227. {
  3228. int is_cd = 0;
  3229. int is_2352 = 0;
  3230. int ret = 0;
  3231.  
  3232. if (filescount != 1)
  3233. return EINVAL; // We don't support more than 1 file atm
  3234.  
  3235. if (trackscount > 1)
  3236. {
  3237. // We assume cd 2352 (cd_sector_size) here
  3238. is_cd = 1;
  3239. is_2352 = 1;
  3240. }
  3241. else
  3242. {
  3243. int fd;
  3244. uint64_t pos, nread;
  3245. uint8_t buf[0xB0];
  3246.  
  3247. ret = cellFsOpen(files[0], CELL_FS_O_RDONLY, &fd, 0, NULL, 0);
  3248. if (ret != 0)
  3249. return ret;
  3250.  
  3251. cellFsLseek(fd, 0x8000, SEEK_SET, &pos);
  3252. ret = cellFsRead(fd, buf, sizeof(buf), &nread);
  3253. cellFsClose(fd);
  3254.  
  3255. if (ret != 0)
  3256. {
  3257. return ret;
  3258. }
  3259. else if (nread != sizeof(buf))
  3260. {
  3261. return EINVAL;
  3262. }
  3263.  
  3264. if (buf[0] == 1 && memcmp(buf+1, "CD001", 5) == 0)
  3265. {
  3266. // rootToc.tocSize == 0x800 -> CD; else DVD
  3267. if (*(uint32_t *)&buf[0xAA] == 0x800)
  3268. {
  3269. is_cd = 1;
  3270. }
  3271. }
  3272. else
  3273. {
  3274. // We assume it is a cd 2352 (cd_sector_size) iso, and thus, a cd
  3275. is_cd = 1;
  3276. is_2352 = 1;
  3277. }
  3278. }
  3279.  
  3280. mutex_lock(mutex, 0);
  3281.  
  3282. if (is_2352)
  3283. ret = mount_ps_cd(files[0], trackscount, tracks);
  3284. else
  3285. ret = mount_common(filescount, files);
  3286.  
  3287. if (ret == 0)
  3288. {
  3289. disc_emulation = (is_cd) ? EMU_PS2_CD : EMU_PS2_DVD;
  3290. total_emulation = (!disc_being_mounted && real_disctype == 0);
  3291. }
  3292.  
  3293. mutex_unlock(mutex);
  3294. return ret;
  3295. }
  3296. #endif
  3297.  
  3298. int umount_discfile(void)
  3299. {
  3300. int ret = 0;
  3301.  
  3302. mutex_lock(mutex, 0);
  3303.  
  3304. if (disc_emulation)
  3305. {
  3306. do_umount_discfile();
  3307. }
  3308. else
  3309. {
  3310. ret = -1;
  3311. }
  3312.  
  3313. mutex_unlock(mutex);
  3314. return ret;
  3315.  
  3316. }
  3317.  
  3318. LV2_PATCHED_FUNCTION(int, fsloop_open, (const char *path, int flags, int *fd, int mode, void *arg, uint64_t size))
  3319. {
  3320. int ret = cellFsOpen(path, flags, fd, mode, arg, size);
  3321.  
  3322. if (ret == 0)
  3323. {
  3324. if (encrypted_image && strcmp(encrypted_image, path) == 0)
  3325. {
  3326. #ifdef DEBUG
  3327. DPRINTF("Encrypted image open: %s\n", path);
  3328. #endif
  3329. encrypted_image_fd = *fd;
  3330. }
  3331. }
  3332.  
  3333. return ret;
  3334. }
  3335.  
  3336. LV2_PATCHED_FUNCTION(int, fsloop_close, (int fd))
  3337. {
  3338. int ret = cellFsClose(fd);
  3339.  
  3340. if (ret == 0 && encrypted_image_fd == fd)
  3341. {
  3342. #ifdef DEBUG
  3343. DPRINTF("encrypted image close\n");
  3344. #endif
  3345. encrypted_image_fd = -1;
  3346. }
  3347.  
  3348. return cellFsClose(fd);
  3349. }
  3350.  
  3351. LV2_PATCHED_FUNCTION(int, fsloop_read, (int fd, void *buf, uint64_t nbytes, uint64_t *nread))
  3352. {
  3353. uint64_t pos;
  3354.  
  3355. cellFsLseek(fd, 0, SEEK_CUR, &pos);
  3356.  
  3357. int ret = cellFsRead(fd, buf, nbytes, nread);
  3358.  
  3359. if (ret == 0 && fd == encrypted_image_fd)
  3360. {
  3361. if (pos&7 || nbytes&7)
  3362. {
  3363. #ifdef DEBUG
  3364. DPRINTF("CRITICAL: we didn't expect this kind of read %lx %lx\n", pos, nbytes);
  3365. #endif
  3366. while (1);
  3367. }
  3368.  
  3369. xtea_ctr(encrypted_image_keys, encrypted_image_nonce+(pos/8), buf, nbytes);
  3370. }
  3371.  
  3372. return ret;
  3373. }
  3374.  
  3375. int sys_storage_ext_get_disc_type(unsigned int *rdt, unsigned int *edt, unsigned int *fdt)
  3376. {
  3377. mutex_lock(mutex, 0);
  3378. copy_to_user(&real_disctype, get_secure_user_ptr(rdt), sizeof(real_disctype));
  3379. copy_to_user(&effective_disctype, get_secure_user_ptr(edt), sizeof(effective_disctype));
  3380. copy_to_user(&fake_disctype, get_secure_user_ptr(fdt), sizeof(fake_disctype));
  3381. mutex_unlock(mutex);
  3382.  
  3383. return 0;
  3384. }
  3385.  
  3386. int sys_storage_ext_read_ps3_disc(void *buf, uint64_t start_sector, uint32_t count)
  3387. {
  3388. void *object, *unk1;
  3389. fs_object_handle_t handle;
  3390. int ret;
  3391.  
  3392. object = NULL;
  3393. unk1 = NULL;
  3394. handle = NULL;
  3395.  
  3396. ret = open_fs_object(NULL, "/dev_bdvd", &object, &unk1, &handle, NULL);
  3397. if (ret != 0)
  3398. return ret;
  3399.  
  3400. if (!object)
  3401. {
  3402. close_fs_object(NULL, handle);
  3403. return ESRCH;
  3404. }
  3405.  
  3406. ret = (int)call_hooked_function_4(emu_read_bdvd1, (uint64_t)object, (uint64_t)get_secure_user_ptr(buf), count*2048, start_sector*2048);
  3407. close_fs_object(NULL, handle);
  3408. return ret;
  3409. }
  3410.  
  3411. int sys_storage_ext_fake_storage_event(uint64_t event, uint64_t param, uint64_t device)
  3412. {
  3413. FakeStorageEventCmd cmd;
  3414.  
  3415. mutex_lock(mutex, 0);
  3416.  
  3417. cmd.event = event;
  3418. cmd.param = param;
  3419. cmd.device = device;
  3420.  
  3421. int ret = event_port_send(command_port, CMD_FAKE_STORAGE_EVENT, (uint64_t)&cmd, 0);
  3422. if (ret == 0)
  3423. {
  3424. event_t event;
  3425. ret = event_queue_receive(result_queue, &event, 0);
  3426. if (ret == 0)
  3427. {
  3428. ret = (int)event.data1;
  3429. }
  3430. }
  3431.  
  3432. mutex_unlock(mutex);
  3433.  
  3434. return ret;
  3435. }
  3436.  
  3437. int sys_storage_ext_get_emu_state(sys_emu_state_t *state)
  3438. {
  3439. int ret;
  3440.  
  3441. state = get_secure_user_ptr(state);
  3442.  
  3443. if (!state)
  3444. return EINVAL;
  3445.  
  3446. if (state->size != sizeof(sys_emu_state_t))
  3447. {
  3448. #ifdef DEBUG
  3449. DPRINTF("Unknown structure size: %d, expected %ld\n", state->size, sizeof(sys_emu_state_t));
  3450. #endif
  3451. return EINVAL;
  3452. }
  3453.  
  3454. mutex_lock(mutex, 0);
  3455.  
  3456. ret = copy_to_user(&disc_emulation, &state->disc_emulation, sizeof(disc_emulation));
  3457. if (ret == 0)
  3458. {
  3459. // No size check needed as that was done in mount
  3460. if (disc_emulation != EMU_OFF)
  3461. {
  3462. if (discfile_cd)
  3463. {
  3464. ret = copy_to_user(discfile_cd->file, state->firstfile_path, strlen(discfile_cd->file)+1);
  3465. }
  3466. else if (discfile)
  3467. {
  3468. ret = copy_to_user(discfile->files[0], state->firstfile_path, strlen(discfile->files[0])+1);
  3469. }
  3470. else
  3471. {
  3472. char c = 0;
  3473. ret = copy_to_user(&c, state->firstfile_path, 1);
  3474. }
  3475. }
  3476. }
  3477.  
  3478. mutex_unlock(mutex);
  3479. return ret;
  3480. }
  3481.  
  3482. static char **copy_user_pointer_array(char *input[], unsigned int count)
  3483. {
  3484. if (!count || !input)
  3485. return NULL;
  3486.  
  3487. char **out = alloc(count * sizeof(char *), 0x27);
  3488. uint32_t *input32 = get_secure_user_ptr(input);
  3489.  
  3490. for (int i = 0; i < count; i++)
  3491. {
  3492. out[i] = (char *)(uint64_t)input32[i];
  3493. }
  3494.  
  3495. return out;
  3496. }
  3497.  
  3498. int sys_storage_ext_mount_ps3_discfile(unsigned int filescount, char *files[])
  3499. {
  3500. char **array = copy_user_pointer_array(files, filescount);
  3501. if (!array)
  3502. return EINVAL;
  3503.  
  3504. umount_discfile();
  3505.  
  3506. int ret = mount_ps3_discfile(filescount, array);
  3507. dealloc(array, 0x27);
  3508. return ret;
  3509. }
  3510.  
  3511. int sys_storage_ext_mount_dvd_discfile(unsigned int filescount, char *files[])
  3512. {
  3513. char **array = copy_user_pointer_array(files, filescount);
  3514. if (!array)
  3515. return EINVAL;
  3516.  
  3517. umount_discfile();
  3518.  
  3519. int ret = mount_dvd_discfile(filescount, array);
  3520. dealloc(array, 0x27);
  3521. return ret;
  3522. }
  3523.  
  3524. int sys_storage_ext_mount_bd_discfile(unsigned int filescount, char *files[])
  3525. {
  3526.  
  3527. char **array = copy_user_pointer_array(files, filescount);
  3528. if (!array)
  3529. return EINVAL;
  3530.  
  3531. umount_discfile();
  3532.  
  3533. int ret = mount_bd_discfile(filescount, array);
  3534. dealloc(array, 0x27);
  3535. return ret;
  3536. }
  3537.  
  3538. int sys_storage_ext_mount_psx_discfile(char *file, unsigned int trackscount, ScsiTrackDescriptor *tracks)
  3539. {
  3540. file = get_secure_user_ptr(file);
  3541. tracks = get_secure_user_ptr(tracks);
  3542.  
  3543. if (!file || !tracks)
  3544. return EINVAL;
  3545.  
  3546. umount_discfile();
  3547.  
  3548. return mount_psx_discfile(file, trackscount, tracks);
  3549. }
  3550.  
  3551. #ifdef DO_PATCH_PS2
  3552. int sys_storage_ext_mount_ps2_discfile(unsigned int filescount, char *files[], unsigned int trackscount, ScsiTrackDescriptor *tracks)
  3553. {
  3554. char **array = copy_user_pointer_array(files, filescount);
  3555. if (!array)
  3556. return EINVAL;
  3557.  
  3558. tracks = get_secure_user_ptr(tracks);
  3559. if (!tracks)
  3560. {
  3561. dealloc(array, 0x27);
  3562. return EINVAL;
  3563. }
  3564.  
  3565. umount_discfile();
  3566.  
  3567. int ret = mount_ps2_discfile(filescount, array, trackscount, tracks);
  3568. dealloc(array, 0x27);
  3569. return ret;
  3570. }
  3571. #endif
  3572.  
  3573. int sys_storage_ext_umount_discfile(void)
  3574. {
  3575. return umount_discfile();
  3576. }
  3577.  
  3578. int sys_storage_ext_mount_discfile_proxy(sys_event_port_t result_port, sys_event_queue_t command_queue, int emu_type, uint64_t disc_size_bytes, uint32_t read_size, unsigned int trackscount, ScsiTrackDescriptor *tracks)
  3579. {
  3580. process_t process;
  3581. event_port_t proxy_result_port;
  3582. event_queue_t proxy_command_queue;
  3583. object_handle_t p, q;
  3584. void *table;
  3585. int ret;
  3586.  
  3587. if (!vsh_process) vsh_process = get_vsh_process(); //NzV
  3588. if(!vsh_process) return EINVAL;
  3589.  
  3590. process = get_current_process();
  3591. if (process != vsh_process)
  3592. return ENOSYS;
  3593.  
  3594. if (emu_type <= EMU_OFF || emu_type >= EMU_MAX
  3595. #ifdef DO_PATCH_PS2
  3596. || emu_type == EMU_PS2_CD || emu_type == EMU_PS2_DVD
  3597. #endif
  3598. ) return EINVAL;
  3599.  
  3600. // -- AV: cd sector size
  3601. cd_sector_size = (trackscount & 0xffff00)>>4; // <- Use: trackscount = num_of_tracks | (cd_sector_size<<4);
  3602. if(cd_sector_size != 2352 && cd_sector_size != 2048 && cd_sector_size != 2336 && cd_sector_size != 2448) cd_sector_size = 2352;
  3603. trackscount &= 0xff;
  3604. // --
  3605.  
  3606. if (emu_type == EMU_PSX)
  3607. {
  3608. if (trackscount >= 100 || !tracks)
  3609. return EINVAL;
  3610. }
  3611.  
  3612. table = process->object_table;
  3613.  
  3614. mutex_lock(mutex, 0);
  3615.  
  3616. if (disc_emulation != EMU_OFF)
  3617. {
  3618. mutex_unlock(mutex);
  3619. return EBUSY;
  3620. }
  3621.  
  3622. ret = open_shared_kernel_object(table, result_port, (void **)&proxy_result_port, &p, SYS_EVENT_PORT_OBJECT, 1);
  3623. if (ret == 0)
  3624. {
  3625. ret = open_shared_kernel_object(table, command_queue, (void **)&proxy_command_queue, &q, SYS_EVENT_QUEUE_OBJECT, 1);
  3626. if (ret == 0)
  3627. {
  3628. event_port_create(&proxy_command_port, EVENT_PORT_REMOTE);
  3629. event_queue_create(&proxy_result_queue, SYNC_PRIORITY, 1, 1);
  3630.  
  3631. ret = event_port_connect(proxy_command_port, proxy_command_queue);
  3632. if (ret == 0)
  3633. {
  3634. ret = event_port_connect(proxy_result_port, proxy_result_queue);
  3635. if (ret != 0)
  3636. {
  3637. #ifdef DEBUG
  3638. DPRINTF("Failed in connecting proxy result port/queue: %x\n", ret);
  3639. #endif
  3640. event_port_disconnect(proxy_command_port);
  3641. }
  3642. }
  3643. #ifdef DEBUG
  3644. else
  3645. {
  3646. DPRINTF("Failed in connecting proxy command port/queue: %x\n", ret);
  3647. }
  3648. #endif
  3649.  
  3650. if (ret != 0)
  3651. {
  3652. event_port_destroy(proxy_command_port);
  3653. event_queue_destroy(proxy_result_queue);
  3654. }
  3655.  
  3656. close_kernel_object_handle(table, q);
  3657. }
  3658.  
  3659. close_kernel_object_handle(table, p);
  3660. }
  3661. #ifdef DEBUG
  3662. else
  3663. {
  3664. DPRINTF("Cannot open even port %x (ret=%x)\n", result_port, ret);
  3665. }
  3666. #endif
  3667. if (ret == 0)
  3668. {
  3669. if (emu_type == EMU_PSX)
  3670. {
  3671. discfile_proxy = alloc(sizeof(DiscFileProxy) + (trackscount * sizeof(ScsiTrackDescriptor)), 0x27);
  3672. }
  3673. else
  3674. {
  3675. discfile_proxy = alloc(sizeof(DiscFileProxy), 0x27);
  3676. }
  3677.  
  3678. discfile_proxy->size = disc_size_bytes;
  3679. discfile_proxy->read_size = read_size;
  3680. discfile_proxy->cached_sector = NULL;
  3681.  
  3682. if (emu_type == EMU_PSX)
  3683. {
  3684. tracks = get_secure_user_ptr(tracks);
  3685. discfile_proxy->numtracks = trackscount;
  3686. discfile_proxy->tracks = (ScsiTrackDescriptor *)(discfile_proxy+1);
  3687. copy_from_user(tracks, discfile_proxy->tracks, sizeof(ScsiTrackDescriptor)*trackscount);
  3688. }
  3689. else
  3690. {
  3691. discfile_proxy->numtracks = 0;
  3692. discfile_proxy->tracks = NULL;
  3693. }
  3694.  
  3695. disc_emulation = emu_type;
  3696. total_emulation = (!disc_being_mounted && real_disctype == 0);
  3697. }
  3698.  
  3699. mutex_unlock(mutex);
  3700. return ret;
  3701. }
  3702.  
  3703.  
  3704. int sys_storage_ext_mount_encrypted_image(char *image, char *mount_point, char *filesystem, uint64_t nonce)
  3705. {
  3706. int ret;
  3707. char loop_device[96];
  3708.  
  3709. image = get_secure_user_ptr(image);
  3710. mount_point = get_secure_user_ptr(mount_point);
  3711. filesystem = get_secure_user_ptr(filesystem);
  3712.  
  3713. if (!image)
  3714. {
  3715. if (encrypted_image)
  3716. {
  3717. map_path(mount_point, NULL, 0);
  3718. cellFsUtilUmount(mount_point, 0, 0);
  3719. dealloc(encrypted_image, 0x27);
  3720. encrypted_image = NULL;
  3721. encrypted_image_nonce = 0;
  3722. }
  3723.  
  3724. return 0;
  3725. }
  3726.  
  3727. if (encrypted_image)
  3728. return EBUSY;
  3729.  
  3730. ret = pathdup_from_user(image, &encrypted_image);
  3731. if (ret != 0)
  3732. return ret;
  3733.  
  3734. if (strlen(encrypted_image) >= 0x40)
  3735. return EINVAL;
  3736.  
  3737. encrypted_image_nonce = nonce;
  3738.  
  3739. snprintf(loop_device, sizeof(loop_device), "CELL_FS_LOOP:%s", encrypted_image);
  3740. *(uint32_t *)&loop_device[0x40] = 0;
  3741. *(uint32_t *)&loop_device[0x44] = 0;
  3742.  
  3743. ret = cellFsUtilMount_h(loop_device, filesystem, mount_point, 0, 1, 0, NULL, 0);
  3744. if (ret != 0)
  3745. {
  3746. #ifdef DEBUG
  3747. DPRINTF("cellFsUtilMount failed: %x\n", ret);
  3748. #endif
  3749. return ret;
  3750. }
  3751.  
  3752. map_path(mount_point, "/dev_usb000", FLAG_COPY|FLAG_PROTECT);
  3753. return 0;
  3754. }
  3755.  
  3756. #ifdef DO_PATCH_PS2
  3757. static INLINE void patch_ps2emu_entry(int ps2emu_type)
  3758. {
  3759. int patch_count = 0;
  3760.  
  3761. if (ps2emu_type == PS2EMU_SW)
  3762. {
  3763. condition_ps2softemu = 1;
  3764. // No need to do the optical disc auth patch for ps2_netemu since there is no optical disc support
  3765. return;
  3766. }
  3767.  
  3768. // Patch needed to support PS2 CD-R(W) and DVD+-R(W). Not necessary for isos.
  3769. // Needed but not enough: patches at ps2 emus are necessary too!
  3770. // Patch address may be different in different models
  3771. for (u64 search_addr = 0x160000; search_addr < 0x300000; search_addr += 4)
  3772. {
  3773. if (lv1_peekd(search_addr) == 0x409E00702FBE0001)
  3774. {
  3775. #ifdef DEBUG
  3776. DPRINTF("PS2 auth patch at HV:%lx\n", search_addr+0x10);
  3777. #endif
  3778. lv1_pokew(search_addr+0x10, LI(R3, 0x29));
  3779.  
  3780. patch_count++;
  3781. }
  3782.  
  3783. else if (lv1_peekd(search_addr) == 0x38800002409C0014)
  3784. {
  3785. #ifdef DEBUG
  3786. DPRINTF("PS2 unauth patch at HV:%lx\n", search_addr+0x10);
  3787. #endif
  3788. lv1_pokew(search_addr+0x10, LI(R3, 0x29));
  3789.  
  3790. patch_count++;
  3791. }
  3792.  
  3793. if (patch_count == 2)
  3794. break;
  3795. }
  3796. }
  3797. #endif
  3798.  
  3799. void storage_ext_init(void)
  3800. {
  3801. thread_t dispatch_thread;
  3802.  
  3803. #ifdef DO_PATCH_PS2
  3804. ps2emu_type = get_ps2emu_type();
  3805. #endif
  3806.  
  3807. mutex_create(&mutex, SYNC_PRIORITY, SYNC_NOT_RECURSIVE);
  3808. event_port_create(&command_port, EVENT_PORT_LOCAL);
  3809. event_port_create(&result_port, EVENT_PORT_LOCAL);
  3810. event_queue_create(&command_queue, SYNC_PRIORITY, 1, 1);
  3811. event_queue_create(&result_queue, SYNC_PRIORITY, 1, 1);
  3812. event_port_connect(command_port, command_queue);
  3813. event_port_connect(result_port, result_queue);
  3814. ppu_thread_create(&dispatch_thread, dispatch_thread_entry, 0, -0x1D8, 0x4000, 0, THREAD_NAME);
  3815. }
  3816.  
  3817. uint8_t storage_ext_patches_done;
  3818.  
  3819. void storage_ext_patches(void)
  3820. {
  3821. if(storage_ext_patches_done == 1) return;
  3822. storage_ext_patches_done = 1;
  3823. #ifdef DO_PATCH_PS2
  3824. patch_ps2emu_entry(ps2emu_type);
  3825. #endif
  3826. patch_jump(device_event_port_send_call, device_event);
  3827. hook_function_on_precall_success(storage_get_device_info_symbol, post_storage_get_device_info, 2);
  3828. // read_bdvd0 is the base function called by read_bdvd1 and read_bdvd2.
  3829. // Hooking it would be enough for the other two to work, but anyways for reading efficiency let's hook those as well.
  3830. hook_function_with_cond_postcall(read_bdvd0_symbol, emu_read_bdvd0, 8);
  3831. hook_function_with_cond_postcall(read_bdvd1_symbol, emu_read_bdvd1, 4); // iso9660 driver func
  3832. hook_function_with_cond_postcall(read_bdvd2_symbol, emu_read_bdvd2, 3); // udf driver func
  3833. // High level functions
  3834. hook_function_with_cond_postcall(storage_read_symbol, emu_storage_read, 7);
  3835. hook_function_with_cond_postcall(get_syscall_address(SYS_STORAGE_ASYNC_READ), emu_sys_storage_async_read, 7);
  3836. // Command functions
  3837. hook_function_with_cond_postcall(storage_send_device_command_symbol, emu_storage_send_device_command, 7);
  3838. hook_function_with_cond_postcall(get_syscall_address(SYS_STORAGE_ASYNC_SEND_DEVICE_COMMAND), emu_sys_storage_async_send_device_command, 7);
  3839. // SS function
  3840. hook_function_with_cond_postcall(get_syscall_address(864), emu_disc_auth, 2);
  3841. #ifdef DO_PATCH_PS2
  3842. // For PS2
  3843. patch_call(shutdown_copy_params_call, shutdown_copy_params_patched);
  3844. #endif
  3845. // Initial setup
  3846. hook_function_on_precall_success(cellFsUtilMount_symbol, post_cellFsUtilMount, 8);
  3847. // For encrypted fsloop images
  3848. patch_call(fsloop_open_call, fsloop_open);
  3849. patch_call(fsloop_close_call, fsloop_close);
  3850. patch_call(fsloop_read_call, fsloop_read);
  3851. }
  3852.  
  3853. #ifdef PS3M_API
  3854. void unhook_all_storage_ext(void)
  3855. {
  3856. suspend_intr();
  3857. unhook_function_on_precall_success(storage_get_device_info_symbol, post_storage_get_device_info, 2);
  3858. unhook_function_with_cond_postcall(read_bdvd0_symbol, emu_read_bdvd0, 8);
  3859. unhook_function_with_cond_postcall(read_bdvd1_symbol, emu_read_bdvd1, 4);
  3860. unhook_function_with_cond_postcall(read_bdvd2_symbol, emu_read_bdvd2, 3);
  3861. unhook_function_with_cond_postcall(storage_read_symbol, emu_storage_read, 7);
  3862. unhook_function_with_cond_postcall(get_syscall_address(SYS_STORAGE_ASYNC_READ), emu_sys_storage_async_read, 7);
  3863. unhook_function_with_cond_postcall(storage_send_device_command_symbol, emu_storage_send_device_command, 7);
  3864. unhook_function_with_cond_postcall(get_syscall_address(SYS_STORAGE_ASYNC_SEND_DEVICE_COMMAND), emu_sys_storage_async_send_device_command, 7);
  3865. unhook_function_with_cond_postcall(get_syscall_address(864), emu_disc_auth, 2);
  3866. #ifdef DEBUG
  3867. unhook_function_on_precall_success(cellFsUtilMount_symbol, post_cellFsUtilMount, 8);
  3868. #else
  3869. if (!hdd0_mounted)
  3870. unhook_function_on_precall_success(cellFsUtilMount_symbol, post_cellFsUtilMount, 8);
  3871. #endif
  3872. resume_intr();
  3873. }
  3874. #endif
Add Comment
Please, Sign In to add comment