home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / share / doc / cdrdao / examples / psxcopy-0.2 / psxdump.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  7.5 KB  |  294 lines

  1. /*
  2.  * psxdump.c - Dumps playstation disks to file
  3.  *
  4.  * Portions (c) 1999 Fabio Baracca <fabiobar@tiscalinet.it>
  5.  *
  6.  * *HEAVILY BASED* on code from readxa.c 
  7.  * that's (c) 1996,1997 Gerd Knorr <kraxel@cs.tu-berlin.de>
  8.  *
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <getopt.h>
  15.  
  16. #include <fcntl.h>
  17. #include <errno.h>
  18. #include <sys/stat.h>
  19. #include <sys/ioctl.h>
  20. #include <linux/cdrom.h>
  21. #include <linux/fs.h>
  22.  
  23. /* Ugly, I know.. */
  24. extern char *sys_errlist[];
  25.  
  26. typedef unsigned char u8bit;
  27. typedef unsigned short u16bit;
  28. typedef unsigned u32bit;
  29.  
  30. unsigned char psx_sign[] =
  31. {0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01,
  32.  0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00, 0x50, 0x4C,
  33.  0x41, 0x59, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4F, 0x4E,
  34.  0x20, 0x20, 0x20, 0x20, 0x20};
  35.  
  36. typedef struct tag_iso_dir_entry {
  37.     u8bit len_dr;
  38.     u8bit XAR_len;
  39.     u32bit loc_extentI;
  40.     u32bit loc_extentM;
  41.     u32bit data_lenI;
  42.     u32bit data_lenM;
  43.     u8bit record_time[7];
  44.     u8bit file_flags_iso;
  45.     u8bit il_size;
  46.     u8bit il_skip;
  47.     u16bit VSSNI;
  48.     u16bit VSSNM;
  49.     u8bit len_fi;
  50.     u8bit file_id[32];
  51.     u8bit padding;
  52. } iso_dir_entry;
  53.  
  54. iso_dir_entry dir_entry;
  55.  
  56. static const char *device_list[] =
  57. {
  58.     /* try most common first ... */
  59.     "/dev/cdrom",
  60.     "/dev/scd0",
  61.     "/dev/sr0",
  62.     "/dev/hdc",
  63.     "/dev/hdd",
  64.  
  65.     "/dev/scd1",
  66.     "/dev/sr1",
  67.     "/dev/scd2",
  68.     "/dev/sr2",
  69.     "/dev/scd3",
  70.     "/dev/sr3",
  71.     "/dev/hda",
  72.     "/dev/hdb",
  73.     "/dev/hde",
  74.     "/dev/hdf",
  75.     "/dev/hdg",
  76.     "/dev/hdh",
  77.     NULL
  78. };
  79.  
  80. int print_info = 0;
  81. int dump_raw = 0;
  82.  
  83. void about(void)
  84. {
  85.     fprintf(stderr, "psxdump.c - Dumps playstation disks to file\n\nA quick hack that's (c) 1999 Fabio Baracca <fabiobar@tiscalinet.it>\nLicensed under GNU GPL - *HEAVILY BASED* on code from readxa.c\nthat's (c) 1996,1997 Gerd Knorr <kraxel@cs.tu-berlin.de>\n\n");
  86. }
  87.  
  88. void usage(void)
  89. {
  90.     fprintf(stderr,
  91.         "syntax: psxdump -d <device> -f <output file>\n\n"
  92.         "  -d <device>       give device name\n"
  93.         "  -f <output file>  file to put track dump\n"
  94.         "  -F                force the program to proceed even if it's not a PSX disk\n"
  95.         "  -T                test type of disc (PSX or non) and report it as exit code\n"
  96.         "  -h                display this banner :-)\n");
  97. }
  98.  
  99. int read_raw_frame(int fd, int lba, unsigned char *buf)
  100. {
  101.     struct cdrom_msf *msf;
  102.     int rc;
  103.  
  104.     msf = (struct cdrom_msf *) buf;
  105.     msf->cdmsf_min0 = (lba + CD_MSF_OFFSET) / CD_FRAMES / CD_SECS;
  106.     msf->cdmsf_sec0 = (lba + CD_MSF_OFFSET) / CD_FRAMES % CD_SECS;
  107.     msf->cdmsf_frame0 = (lba + CD_MSF_OFFSET) % CD_FRAMES;
  108.     rc = ioctl(fd, CDROMREADMODE2, buf);
  109.     if (-1 == rc)
  110.     perror("ioctl CDROMREADMODE2");
  111.     return rc;
  112. }
  113.  
  114. int main(int argc, char *argv[])
  115. {
  116.     int forcepsx = 0, ofile, cdrom, rc, c, size, percent, maxsize, testpsx = 0;
  117.     unsigned long block;
  118.     unsigned char *buf;
  119.     struct stat st, dev_st;
  120.     int device;
  121.     long seek = -1;
  122.     struct cdrom_tocentry toc, toc2;
  123.  
  124.     char *outfile = NULL, *devname = NULL;
  125.  
  126.     /* parse options */
  127.     for (;;) {
  128.     c = getopt(argc, argv, "TFd:f:");
  129.     if (c == -1)
  130.         break;
  131.     switch (c) {
  132.     case 'f':
  133.         outfile = optarg;
  134.         break;
  135.     case 'd':
  136.         devname = optarg;
  137.         break;
  138.     case 'F':
  139.         forcepsx = 1;
  140.         break;
  141.     case 'T':
  142.         testpsx = 1;
  143.         break;
  144.     case 'h':
  145.     default:
  146.         usage();
  147.         exit(1);
  148.     }
  149.     }
  150.  
  151.     /* Malloc-ing memory */
  152.     if (NULL == (buf = malloc(CD_FRAMESIZE_RAW0))) {
  153.     fprintf(stderr, "Out of memory\n");
  154.     exit(1);
  155.     }
  156.  
  157.     if ((testpsx) && (devname)) {
  158.     if (-1 == (cdrom = open(devname ? devname : device_list[device], O_RDONLY | O_NONBLOCK))) {
  159.         fprintf(stderr, "open %s: %s\n", devname ? devname : device_list[device], sys_errlist[errno]);
  160.         exit(2);
  161.     }
  162.     if (0 != (rc = read_raw_frame(cdrom, 16, buf))) {
  163.         perror("read error");
  164.         exit(2);
  165.     }
  166.     close(rc);
  167.     if (memcmp(psx_sign, buf, sizeof(psx_sign)) == 0)
  168.         exit(0);
  169.     else
  170.         exit(1);
  171.     }
  172.     
  173.     about();
  174.  
  175.     if ((!outfile) || (!devname)) {
  176.     fprintf(stderr, "Please specify *either* the file name (or -T flag) *and* the device of the CD reader.\n\n");
  177.     usage();
  178.     exit(2);
  179.     }
  180.     /* Opening the CDROM reader  */
  181.     if (-1 == (cdrom = open(devname ? devname : device_list[device], O_RDONLY | O_NONBLOCK))) {
  182.     fprintf(stderr, "open %s: %s\n", devname ? devname : device_list[device], sys_errlist[errno]);
  183.     exit(1);
  184.     }
  185.  
  186.     if (!forcepsx) {
  187.     /* Checking if it's a PSX disk */
  188.     printf("Checking if the disk is a PSX disk..");
  189.     fflush(stdout);
  190.     if (0 != (rc = read_raw_frame(cdrom, 16, buf))) {    /* Safe PSX signature is at 0x9200 */
  191.         perror("read error");
  192.         exit(1);
  193.     }
  194.     /* Checking PSX signature */
  195.     if (memcmp(psx_sign, buf, sizeof(psx_sign)) == 0) {
  196.         printf("okay, found a PSX disk.\n");
  197.     } else {
  198.         printf("sorry.. this doesn't seem a PSX disk.\n\nIf you think it's a bug, use -F flag and send a dump of the sector 16\nto me, Fabio Baracca <fabiobar@tiscalinet.it>. Thanks!\n");
  199.         exit(3);
  200.     }
  201.     close(rc);
  202.     } else {
  203.     printf("-F specified: assuming that the disk is a PSX disk.\n");
  204.     }
  205.  
  206.     /* Checking the limits of the track */
  207.     if (-1 == (rc = open(devname, O_RDONLY | O_NONBLOCK))) {
  208.     fprintf(stderr, "open %s: %s\n", devname, sys_errlist[errno]);
  209.     exit(1);
  210.     }
  211.     toc.cdte_track = 1;
  212.     toc.cdte_format = CDROM_LBA;
  213.     if (-1 == ioctl(rc, CDROMREADTOCENTRY, &toc)) {
  214.     perror("ioctl CDROMREADTOCENTRY [start]");
  215.     exit(1);
  216.     }
  217.     toc2.cdte_track = 2;
  218.     toc2.cdte_format = CDROM_LBA;
  219.     if (-1 == ioctl(rc, CDROMREADTOCENTRY, &toc2)) {
  220.     toc2.cdte_track = CDROM_LEADOUT;
  221.     toc2.cdte_format = CDROM_LBA;
  222.     if (-1 == ioctl(rc, CDROMREADTOCENTRY, &toc2)) {
  223.         perror("ioctl CDROMREADTOCENTRY [stop]");
  224.         exit(1);
  225.     }
  226.     }
  227.     block = toc.cdte_addr.lba;    /* Should be zero */
  228.     if (block) {
  229.     fprintf(stderr, "Hei!.. S-T-R-A-N-G-E.. starting sector is NOT zero !??!\n");
  230.     }
  231.     size = (toc2.cdte_addr.lba - block) * 2048;
  232.     close(rc);
  233.  
  234.     /* Opening the output file */
  235.     if (-1 == (ofile = open(outfile, O_WRONLY | O_CREAT))) {
  236.     fprintf(stderr, "open %s: %s\n", outfile, sys_errlist[errno]);
  237.     exit(1);
  238.     }
  239.     /* Finnally dump the track */
  240.     if (-1 == (rc = open(devname ? devname : device_list[device], O_RDONLY | O_NONBLOCK))) {
  241.     fprintf(stderr, "open %s: %s\n", devname ? devname : device_list[device], sys_errlist[errno]);
  242.     exit(1);
  243.     }
  244.     if (0 != (rc = read_raw_frame(cdrom, block, buf))) {
  245.     perror("read error");
  246.     exit(1);
  247.     }
  248.     printf("\nDumping %d bytes (or maybe a bit less..) to disk..\n", (toc2.cdte_addr.lba - block) * 2336);
  249.     printf("Please IGNORE any error! Your disk WILL BE OK! 100%% Assured!\n\n");
  250.  
  251.     maxsize = size;
  252.     percent = 0;        /* Status bar */
  253.  
  254.     printf("Completed: %d%%\r", percent);
  255.     fflush(stdout);
  256.  
  257.     for (;;) {
  258.     int offset, len, tmp;
  259.  
  260.     if (buf[0] == buf[4] &&
  261.         buf[1] == buf[5] &&
  262.         buf[2] == buf[6] &&
  263.         buf[3] == buf[7] &&
  264.         buf[2] != 0 &&
  265.         buf[0] < 8 &&
  266.         buf[1] < 8) {
  267.         offset = 8;
  268.         len = (buf[2] & 0x20) ? 2324 : 2048;
  269.     } else {
  270.         offset = 0;
  271.         len = 2048;
  272.     }
  273.     write(ofile, buf, CD_FRAMESIZE_RAW0);    /* dump to disk */
  274.     size -= 2048 /* len */ ;
  275.     block++;
  276.     if (size <= 0)
  277.         break;
  278.  
  279.     tmp = (int) 100 - (((double) size / (double) maxsize) * 100);
  280.     if (tmp != percent) {
  281.         percent = tmp;
  282.         printf("Completed: %d%%\r", percent);
  283.         fflush(stdout);
  284.     }
  285.     if (0 != (rc = read_raw_frame(cdrom, block, buf))) {
  286.         perror("read error (hei! the disk is 99.9%% ok if we are in the last part of the disk)");
  287.         exit(1);
  288.     }
  289.     }
  290.     printf("PSX data track dump complete.\n");
  291.     free(buf);
  292.     exit(0);
  293. }
  294.