home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / imdisp / source / fileio.c < prev    next >
C/C++ Source or Header  |  1990-09-04  |  14KB  |  521 lines

  1. /*************************************************************/
  2. /*  Copyright (C) 1989, California Institute of Technology   */
  3. /*  U. S. Government Sponsorship under NASA Contract         */
  4. /*  NAS7-918 is acknowledged.                                */
  5. /*************************************************************/
  6.  
  7. /***  IMDISP module FILEIO.C
  8.  
  9.      Contains block level I/O routines for both MS-DOS files
  10.      and absolute CD-ROM reads.
  11.  
  12. ***/
  13.  
  14. /* * * * INCLUDE files * * * */
  15.  
  16. #include <ctype.h>
  17. #include <dos.h>
  18. #include <fcntl.h>
  19. #include <io.h>
  20. #include <process.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <sys\types.h>
  25. #include <sys\stat.h>
  26. #include "imdef.h"
  27. #include "imdisp.h"
  28.  
  29. /* * * * External functions * * * */
  30.  
  31. /* * * * Function declarations * * * */
  32.  
  33. int OpenDisk (char *,int ,char *,int *,char *);
  34. int ReadDisk (int ,unsigned char *,long ,int ,int *,char *);
  35. int WriteDisk (int ,unsigned char *,long ,int ,char *);
  36. int CloseDisk (int ,char *);
  37. int OpenCD (char *,int ,int *,char *);
  38. int ReadCD (int ,unsigned char *,long ,int ,int *,char *);
  39. int CloseCD (int ,char *);
  40. int InitializeCD (int *, char *);
  41. int ReadBlocksCD (unsigned char *, long, int, char *);
  42.  
  43. /* * * * Global Variables * * * */
  44.  
  45. struct FCBtype
  46.           {
  47.             char     filename[80];
  48.             int      handle;
  49.           }                    FCB[MaxOpenFiles];
  50.  
  51. /***********************************************************/
  52.  
  53.         /* CD-ROM File I/O Routines */
  54.  
  55. struct CDControlBlock
  56.           {
  57.            char     filename[80];
  58.            long int StartLBN;
  59.           }           CDFCB[MaxOpenFiles];
  60.  
  61. int    PBsize;
  62. int    CDInitFlag = 0;
  63. int    CDdrivenum;
  64.  
  65. int OpenCD (char * filename,  int unit, int * p_blocksize, char * status)
  66.  
  67. /*  OpenCD opens an absolute CD-ROM file (i.e. on a non standard CD-ROM).
  68.     The file name is of the form "CD:mm:ss:bb", where mm is the minute
  69.     of the starting sector, ss is the second, and bb is the block number
  70.     within the second.  The logical blocksize to be used is returned.
  71.  
  72. */
  73.  
  74. {
  75.     int  minute, second, blockno;
  76.     char temp[80];
  77.  
  78.  
  79.     strcpy (status, "");
  80.  
  81.     if (CDInitFlag != 17)
  82.     {
  83.         CDInitFlag = 17;
  84.         InitializeCD (&PBsize, status);
  85.         if (strlen(status) > 0)  return;
  86.     }
  87.     *p_blocksize = PBsize;
  88.  
  89.     strcpy (CDFCB[unit].filename, filename);
  90.  
  91.     minute = -1;
  92.     sscanf (strncpy(temp,&filename[3],2), "%2d", &minute);
  93.     if ((minute < 0) || (minute > 59))   goto ErrExit;
  94.  
  95.     second = -1;
  96.     sscanf (strncpy(temp,&filename[6],2), "%2d", &second);
  97.     if ((second < 0) || (second > 59))   goto ErrExit;
  98.  
  99.     blockno = -1;
  100.     sscanf (strncpy(temp,&filename[9],2), "%2d", &blockno);
  101.     if ((blockno < 0) || (blockno > 74))   goto ErrExit;
  102.     CDFCB[unit].StartLBN = (minute*4500L + second*75L
  103.                               + blockno - 150L)*2048L/PBsize;
  104.     return;
  105.  
  106.  
  107.     ErrExit:
  108.         strcpy (status, "Illegal CD-ROM time code");
  109. }
  110.  
  111. int ReadCD ( int unit, unsigned char * buffer, long int StartBlock,
  112.              int NumBlocks, int * p_BlocksRead, char * status)
  113.  
  114. /* ReadCD reads blocks from the CD-ROM to the buffer.
  115. */
  116. /*
  117. int     unit, NumBlocks, *p_BlocksRead;
  118. long int    StartBlock;
  119. unsigned char  buffer[];
  120. char   status[];
  121. */
  122. {
  123.     long int start;
  124.  
  125.     strcpy (status, "");
  126.  
  127.     start = StartBlock;
  128.     if (start < 0)
  129.         start = 0;
  130.  
  131.     *p_BlocksRead = NumBlocks;
  132.  
  133.     start += CDFCB[unit].StartLBN;
  134.  
  135.     if (*p_BlocksRead > 0)
  136.         ReadBlocksCD (buffer, start, *p_BlocksRead, status);
  137. }
  138.  
  139. int CloseCD (int unit, char * status)
  140. /*
  141. int   unit;
  142. char  status[];
  143. */
  144. {
  145.     strcpy (CDFCB[unit].filename, "");
  146.     strcpy (status, "");
  147. }
  148.  
  149. /*****************************************************************************/
  150.  
  151.      /* Magnetic disk I/O using MS-DOS */
  152.  
  153. int OpenDisk (char * filename, int unit, char * IOmode, int * p_blocksize,
  154.               char * status)
  155.  
  156. /* OpenDisk opens a MS-DOS file using standard I/O.
  157. */
  158. /*
  159. char   filename[], IOmode[], status[];
  160. int    unit, *p_blocksize;
  161. */
  162. {
  163.  
  164.     char   accessmode;
  165.     int    filehandle;
  166.  
  167.  
  168.     strcpy (status, "");
  169.     *p_blocksize = 128;
  170.  
  171.     strcpy (FCB[unit].filename, filename);
  172.  
  173.     accessmode = toupper(IOmode[0]);
  174.     if (accessmode != 'W')  accessmode = 'R';
  175.  
  176.  
  177.     if (accessmode == 'W')
  178.         filehandle = open(filename,
  179.                     O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
  180.     else
  181.         filehandle = open(filename, O_RDONLY|O_BINARY);
  182.  
  183.     if (filehandle == -1)
  184.     {   strcpy (status, "Error opening file : ");
  185.         strcat (status, FCB[unit].filename);
  186.     }
  187.     FCB[unit].handle = filehandle;
  188.  
  189. }
  190.  
  191. int ReadDisk (int unit, unsigned char * buffer, long startblock, int numblocks,
  192.               int * p_blocksread, char * status)
  193. /* ReadDisk reads blocks from MS-DOS file to buffer.
  194. */
  195. /*
  196. int            unit, numblocks, *p_blocksread;
  197. long           startblock;
  198. unsigned char  *buffer;
  199. char           status[];
  200. */
  201. {
  202.     long  pos;
  203.     int   i,bytesread;
  204.  
  205.     strcpy(status, "");
  206.  
  207.                               /* if Microsoft = 1 it means that the data
  208.                                  we are reading is and extended attr record
  209.                                  on a cdrom - so add 2048 bytes to the
  210.                                  beginning of the file */
  211.     pos = lseek (FCB[unit].handle, 128*startblock+(2048*Microsoft), SEEK_SET);
  212.  
  213. /*    pos = lseek (FCB[unit].handle, 128*startblock, SEEK_SET); old line */
  214.     if (pos == -1)
  215.     {   strcpy (status, "Error reading from file : ");
  216.         strcat (status, FCB[unit].filename);
  217.         return;
  218.     }
  219.  
  220.     bytesread = read (FCB[unit].handle, buffer, 128*numblocks);
  221.  
  222.     /* patch for quick look tiles with filler bytes - mdm 12-15-88 */
  223.     if (strnicmp(FCB[unit].filename+(strlen(FCB[unit].filename)-4),
  224.         ".QLK",4) == 0 && buffer[1892] == 94)
  225.       {
  226.          for (i=0;i<bytesread/2048;i++)
  227.          memmove(buffer+(i*2048)+1892-i*156,
  228.                  buffer+(i*2048)+2048-i*156,bytesread-(i+1)*2048);
  229. /*         bytesread -= i*156; */
  230.          read (FCB[unit].handle, buffer+28380,1892);
  231.  
  232.       }
  233.  
  234.  
  235.     if (bytesread == 0)
  236.     {   strcpy (status, "Seek beyond end of file : ");
  237.         strcat (status, FCB[unit].filename);
  238.         return;
  239.     }
  240.     if (bytesread == -1)
  241.     {   strcpy (status, "Error reading from file : ");
  242.         strcat (status, FCB[unit].filename);
  243.     }
  244.  
  245.     *p_blocksread = (bytesread-1)/128 + 1;
  246. }
  247.  
  248. int WriteDisk (int unit, unsigned char * buffer, long startblock, int numblocks,
  249.                char * status)
  250.  
  251. /* WriteDisk writes blocks to MS-DOS file from buffer.
  252. */
  253. /*
  254. int            unit, numblocks;
  255. long           startblock;
  256. unsigned char  *buffer;
  257. char           status[];
  258. */
  259. {
  260.     long  pos;
  261.     int   byteswritten;
  262.  
  263.     strcpy(status,"");
  264.  
  265.     pos = lseek (FCB[unit].handle, 128*startblock, SEEK_SET);
  266.     if (pos == -1)
  267.     {   strcpy (status, "Error writing to file : ");
  268.         strcat (status, FCB[unit].filename);
  269.         return;
  270.     }
  271.  
  272.     byteswritten = write (FCB[unit].handle, buffer, 128*numblocks);
  273.     if (byteswritten == -1)
  274.     {   strcpy (status, "Error writing to file : ");
  275.         strcat (status, FCB[unit].filename);
  276.     }
  277. }
  278.  
  279. int CloseDisk (int unit, char * status)
  280. /*  CloseDisk close MS-DOS file.
  281. */
  282. /*
  283. int            unit;
  284. char           status[];
  285. */
  286. {
  287.     strcpy(status, "");
  288.     if (close (FCB[unit].handle) == -1)
  289.     {   strcpy (status, "Error closing file : ");
  290.         strcat (status, FCB[unit].filename);
  291.     }
  292.  
  293. }
  294.  
  295. /*****************************************************************************/
  296.  
  297.  /* General block I/O routines: both CDROM and magnetic disk */
  298.  
  299. int  FileType[MaxOpenFiles];   /* 1 for CD-ROM,  0 for MS-DOS */
  300.  
  301. int OpenFile (char * filename, int unit, char * IOmode, int * p_blocksize,
  302.               char * status)
  303.  
  304. /***  OpenFile opens a file with the given file name.
  305.     The file may be open for reading or writing.
  306.     If the file name begins with "CD:" then it is assumed to be an
  307.     absolute CD-ROM file on a non-standard CD-ROM.  The file name is
  308.     of the form "CD:mm:ss:bb", where mm is the minute of the starting
  309.     sector, ss is the second, and bb is the block number within the second.
  310.     The logical blocksize to be used in the image I/O routines
  311.     is returned.
  312.  
  313.    Parameter    Type    In/out   Description
  314.     filename   char ptr  in      File name string
  315.     unit        int      in      Unit number (0,1,2...)
  316.     IOmode     char ptr  in      "r..." for reading, 'w...' for writing
  317.    p_blocksize  int ptr  out     The returned logical blocksize to use
  318.     status     char ptr  out     The error message string
  319.                                      (0 length for no error)
  320.  
  321. ***/
  322. /*
  323. char   filename[], IOmode[], status[];
  324. int    unit, *p_blocksize;
  325. */
  326. {
  327.     char   device[80];
  328.     int    i;
  329.  
  330.     strncpy (device, filename, 3);
  331.     device[3] = 0;
  332.  
  333.     if (stricmp(device, "CD:") == 0)
  334.     {
  335.         if (toupper(IOmode[0]) == 'W')
  336.         {
  337.             strcpy (status, "Cannot open CD file for writing");
  338.             return;
  339.         }
  340.         FileType[unit] = 1;
  341.         OpenCD (filename, unit, p_blocksize, status);
  342.     }
  343.     else
  344.     {
  345.         FileType[unit] = 0;
  346.         OpenDisk (filename, unit, IOmode, p_blocksize, status);
  347.     }
  348. }
  349.  
  350. int ReadBlocks (int unit, char * buffer, long startblock, int numblocks,
  351.                 int * p_blocksread, char * status)
  352.  
  353. /***  ReadBlocks reads blocks from the file into the buffer.
  354.  
  355.    Parameter    Type    In/out   Description
  356.     unit        int      in      Unit number from open
  357.     buffer     char ptr  out     The output buffer of data
  358.     startblock long int  in      The starting logical block
  359.     numblocks   int      in      The number of blocks to read
  360.  p_blocksread  int ptr   out     The number of blocks actually read
  361.     status     char ptr  out     The error message string
  362.                                      (0 length for no error)
  363.  
  364. ***/
  365. /*
  366. int            unit, numblocks, *p_blocksread;
  367. long           startblock;
  368. char           *buffer;
  369. char           status[];
  370. */
  371. {
  372.     if (FileType[unit] == 1)
  373.         ReadCD (unit, buffer, startblock, numblocks, p_blocksread, status);
  374.     else
  375.         ReadDisk (unit, buffer, startblock, numblocks, p_blocksread, status);
  376. }
  377.  
  378. int WriteBlocks (int unit, char * buffer, long startblock, int numblocks,
  379.                  char * status)
  380.  
  381. /***  WriteBlocks writes blocks from the buffer to the file.
  382.  
  383.    Parameter    Type    In/out   Description
  384.     unit        int      in      Unit number from open
  385.     buffer     char ptr  in      The input buffer of data
  386.     startblock long int  in      The starting logical block
  387.     numblocks   int      in      The number of blocks to write
  388.     status     char ptr  out     The error message string
  389.                                      (0 length for no error)
  390. ***/
  391. /*
  392. int            unit, numblocks;
  393. long           startblock;
  394. char           *buffer;
  395. char           status[];
  396. */
  397. {
  398.     long  pos;
  399.     int   byteswritten;
  400.  
  401.     strcpy(status,"");
  402.  
  403.  
  404.     pos = lseek (FCB[unit].handle, 128*startblock, SEEK_SET);
  405.     if (pos == -1)
  406.     {   strcpy (status, "Error writing to file : ");
  407.         strcat (status, FCB[unit].filename);
  408.         return;
  409.     }
  410.  
  411.     byteswritten = write (FCB[unit].handle, buffer, 128*numblocks);
  412.     if (byteswritten == -1)
  413.     {   strcpy (status, "Error writing to file : ");
  414.         strcat (status, FCB[unit].filename);
  415.     }
  416. }
  417.  
  418. int CloseFile (int unit, char * status)
  419.  
  420. /*** CloseFile closes the file.
  421.  
  422.    Parameter    Type    In/out   Description
  423.     unit        int      in      Unit number from open
  424.     status     char ptr  out     The error message string
  425.                                      (0 length for no error)
  426. ***/
  427. /*
  428. int            unit;
  429. char           status[];
  430. */
  431. {
  432.     if (FileType[unit] == 1)
  433.         CloseCD (unit, status);
  434.     else
  435.         CloseDisk (unit, status);
  436. }
  437.  
  438. /*****************************************************************************/
  439.  
  440. /*** Module MSCDIO 
  441.      Low Level Block I/O with MS-DOS for non-standard CD-ROM's
  442.  
  443. ***/
  444.  
  445. int InitializeCD (int * p_PB_size, char * status)
  446.  
  447. /***  InitializeCD initializes the CD player and returns the
  448.     physical block size.
  449.  
  450.     Parameter   Type      Description
  451.     p_PB_size   int ptr   The size of the physical blocks for this driver.
  452.                           (in this case 2048 bytes)
  453.     status      char ptr  Error message string (0 length if no error)
  454.  
  455. ***/
  456. /*
  457. int     *p_PB_size;
  458. char    status[];
  459. */
  460. {
  461.     union  REGS  inreg, outreg;
  462.  
  463.     *p_PB_size = 2048;
  464.     strcpy (status,"");
  465.  
  466.     inreg.x.ax = 0x1500;
  467.     inreg.x.bx = 0;
  468.     int86 (0x2f, &inreg, &outreg);
  469.     CDdrivenum = outreg.x.cx;
  470.     if (outreg.x.bx == 0) 
  471.       {
  472.        printf("MSCDEX not installed.\n");
  473.        exit(0);
  474.       }
  475. }
  476.  
  477. int ReadBlocksCD (unsigned char * buffer, long int StartPB, int NumPB,
  478.                   char * status)
  479.  
  480. /***  ReadBlocksCD reads blocks from the CD-ROM to the user's buffer.
  481.  
  482.    Parameter    Type      Description
  483.     buffer     char ptr   Buffer to receive data
  484.     StartPB    long int   The starting absolute physical block
  485.     NumPB      int        The number of physical blocks to read
  486.     status     char ptr   Error message string (0 length if no error)
  487.  
  488. ***/
  489. /*
  490. unsigned char  buffer[];
  491. long int   StartPB;
  492. int        NumPB;
  493. char       status[];
  494. */
  495. {
  496.     union  REGS  inreg, outreg;
  497.     struct SREGS segregs;
  498.     int  error;
  499.  
  500.  
  501.  
  502.     strcpy (status, "");
  503.  
  504.            /* Call the Absolute Read function */
  505.     /*segread (&segregs);*/
  506.     segregs.es = FP_SEG(buffer);
  507.     inreg.x.ax = 0x1508;
  508.     inreg.x.bx = (unsigned)buffer;
  509.     inreg.x.cx = CDdrivenum;
  510.     inreg.x.dx = NumPB;
  511.     inreg.x.si = StartPB >> 16;
  512.     inreg.x.di = StartPB;
  513.     int86x (0x2f, &inreg, &outreg, &segregs);
  514.     error = outreg.x.ax & 0x0ff;
  515.     if (error != 0)
  516.     {
  517.         strcpy (status, "Error reading from CD player");
  518.         return;
  519.     }
  520. }
  521.