home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************/
- /* Copyright (C) 1989, California Institute of Technology */
- /* U. S. Government Sponsorship under NASA Contract */
- /* NAS7-918 is acknowledged. */
- /*************************************************************/
-
- /*** IMDISP module FILEIO.C
-
- Contains block level I/O routines for both MS-DOS files
- and absolute CD-ROM reads.
-
- ***/
-
- /* * * * INCLUDE files * * * */
-
- #include <ctype.h>
- #include <dos.h>
- #include <fcntl.h>
- #include <io.h>
- #include <process.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include "imdef.h"
- #include "imdisp.h"
-
- /* * * * External functions * * * */
-
- /* * * * Function declarations * * * */
-
- int OpenDisk (char *,int ,char *,int *,char *);
- int ReadDisk (int ,unsigned char *,long ,int ,int *,char *);
- int WriteDisk (int ,unsigned char *,long ,int ,char *);
- int CloseDisk (int ,char *);
- int OpenCD (char *,int ,int *,char *);
- int ReadCD (int ,unsigned char *,long ,int ,int *,char *);
- int CloseCD (int ,char *);
- int InitializeCD (int *, char *);
- int ReadBlocksCD (unsigned char *, long, int, char *);
-
- /* * * * Global Variables * * * */
-
- struct FCBtype
- {
- char filename[80];
- int handle;
- } FCB[MaxOpenFiles];
-
- /***********************************************************/
-
- /* CD-ROM File I/O Routines */
-
- struct CDControlBlock
- {
- char filename[80];
- long int StartLBN;
- } CDFCB[MaxOpenFiles];
-
- int PBsize;
- int CDInitFlag = 0;
- int CDdrivenum;
-
- int OpenCD (char * filename, int unit, int * p_blocksize, char * status)
-
- /* OpenCD opens an absolute CD-ROM file (i.e. on a non standard CD-ROM).
- The file name is of the form "CD:mm:ss:bb", where mm is the minute
- of the starting sector, ss is the second, and bb is the block number
- within the second. The logical blocksize to be used is returned.
-
- */
-
- {
- int minute, second, blockno;
- char temp[80];
-
-
- strcpy (status, "");
-
- if (CDInitFlag != 17)
- {
- CDInitFlag = 17;
- InitializeCD (&PBsize, status);
- if (strlen(status) > 0) return;
- }
- *p_blocksize = PBsize;
-
- strcpy (CDFCB[unit].filename, filename);
-
- minute = -1;
- sscanf (strncpy(temp,&filename[3],2), "%2d", &minute);
- if ((minute < 0) || (minute > 59)) goto ErrExit;
-
- second = -1;
- sscanf (strncpy(temp,&filename[6],2), "%2d", &second);
- if ((second < 0) || (second > 59)) goto ErrExit;
-
- blockno = -1;
- sscanf (strncpy(temp,&filename[9],2), "%2d", &blockno);
- if ((blockno < 0) || (blockno > 74)) goto ErrExit;
- CDFCB[unit].StartLBN = (minute*4500L + second*75L
- + blockno - 150L)*2048L/PBsize;
- return;
-
-
- ErrExit:
- strcpy (status, "Illegal CD-ROM time code");
- }
-
- int ReadCD ( int unit, unsigned char * buffer, long int StartBlock,
- int NumBlocks, int * p_BlocksRead, char * status)
-
- /* ReadCD reads blocks from the CD-ROM to the buffer.
- */
- /*
- int unit, NumBlocks, *p_BlocksRead;
- long int StartBlock;
- unsigned char buffer[];
- char status[];
- */
- {
- long int start;
-
- strcpy (status, "");
-
- start = StartBlock;
- if (start < 0)
- start = 0;
-
- *p_BlocksRead = NumBlocks;
-
- start += CDFCB[unit].StartLBN;
-
- if (*p_BlocksRead > 0)
- ReadBlocksCD (buffer, start, *p_BlocksRead, status);
- }
-
- int CloseCD (int unit, char * status)
- /*
- int unit;
- char status[];
- */
- {
- strcpy (CDFCB[unit].filename, "");
- strcpy (status, "");
- }
-
- /*****************************************************************************/
-
- /* Magnetic disk I/O using MS-DOS */
-
- int OpenDisk (char * filename, int unit, char * IOmode, int * p_blocksize,
- char * status)
-
- /* OpenDisk opens a MS-DOS file using standard I/O.
- */
- /*
- char filename[], IOmode[], status[];
- int unit, *p_blocksize;
- */
- {
-
- char accessmode;
- int filehandle;
-
-
- strcpy (status, "");
- *p_blocksize = 128;
-
- strcpy (FCB[unit].filename, filename);
-
- accessmode = toupper(IOmode[0]);
- if (accessmode != 'W') accessmode = 'R';
-
-
- if (accessmode == 'W')
- filehandle = open(filename,
- O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
- else
- filehandle = open(filename, O_RDONLY|O_BINARY);
-
- if (filehandle == -1)
- { strcpy (status, "Error opening file : ");
- strcat (status, FCB[unit].filename);
- }
- FCB[unit].handle = filehandle;
-
- }
-
- int ReadDisk (int unit, unsigned char * buffer, long startblock, int numblocks,
- int * p_blocksread, char * status)
- /* ReadDisk reads blocks from MS-DOS file to buffer.
- */
- /*
- int unit, numblocks, *p_blocksread;
- long startblock;
- unsigned char *buffer;
- char status[];
- */
- {
- long pos;
- int i,bytesread;
-
- strcpy(status, "");
-
- /* if Microsoft = 1 it means that the data
- we are reading is and extended attr record
- on a cdrom - so add 2048 bytes to the
- beginning of the file */
- pos = lseek (FCB[unit].handle, 128*startblock+(2048*Microsoft), SEEK_SET);
-
- /* pos = lseek (FCB[unit].handle, 128*startblock, SEEK_SET); old line */
- if (pos == -1)
- { strcpy (status, "Error reading from file : ");
- strcat (status, FCB[unit].filename);
- return;
- }
-
- bytesread = read (FCB[unit].handle, buffer, 128*numblocks);
-
- /* patch for quick look tiles with filler bytes - mdm 12-15-88 */
- if (strnicmp(FCB[unit].filename+(strlen(FCB[unit].filename)-4),
- ".QLK",4) == 0 && buffer[1892] == 94)
- {
- for (i=0;i<bytesread/2048;i++)
- memmove(buffer+(i*2048)+1892-i*156,
- buffer+(i*2048)+2048-i*156,bytesread-(i+1)*2048);
- /* bytesread -= i*156; */
- read (FCB[unit].handle, buffer+28380,1892);
-
- }
-
-
- if (bytesread == 0)
- { strcpy (status, "Seek beyond end of file : ");
- strcat (status, FCB[unit].filename);
- return;
- }
- if (bytesread == -1)
- { strcpy (status, "Error reading from file : ");
- strcat (status, FCB[unit].filename);
- }
-
- *p_blocksread = (bytesread-1)/128 + 1;
- }
-
- int WriteDisk (int unit, unsigned char * buffer, long startblock, int numblocks,
- char * status)
-
- /* WriteDisk writes blocks to MS-DOS file from buffer.
- */
- /*
- int unit, numblocks;
- long startblock;
- unsigned char *buffer;
- char status[];
- */
- {
- long pos;
- int byteswritten;
-
- strcpy(status,"");
-
- pos = lseek (FCB[unit].handle, 128*startblock, SEEK_SET);
- if (pos == -1)
- { strcpy (status, "Error writing to file : ");
- strcat (status, FCB[unit].filename);
- return;
- }
-
- byteswritten = write (FCB[unit].handle, buffer, 128*numblocks);
- if (byteswritten == -1)
- { strcpy (status, "Error writing to file : ");
- strcat (status, FCB[unit].filename);
- }
- }
-
- int CloseDisk (int unit, char * status)
- /* CloseDisk close MS-DOS file.
- */
- /*
- int unit;
- char status[];
- */
- {
- strcpy(status, "");
- if (close (FCB[unit].handle) == -1)
- { strcpy (status, "Error closing file : ");
- strcat (status, FCB[unit].filename);
- }
-
- }
-
- /*****************************************************************************/
-
- /* General block I/O routines: both CDROM and magnetic disk */
-
- int FileType[MaxOpenFiles]; /* 1 for CD-ROM, 0 for MS-DOS */
-
- int OpenFile (char * filename, int unit, char * IOmode, int * p_blocksize,
- char * status)
-
- /*** OpenFile opens a file with the given file name.
- The file may be open for reading or writing.
- If the file name begins with "CD:" then it is assumed to be an
- absolute CD-ROM file on a non-standard CD-ROM. The file name is
- of the form "CD:mm:ss:bb", where mm is the minute of the starting
- sector, ss is the second, and bb is the block number within the second.
- The logical blocksize to be used in the image I/O routines
- is returned.
-
- Parameter Type In/out Description
- filename char ptr in File name string
- unit int in Unit number (0,1,2...)
- IOmode char ptr in "r..." for reading, 'w...' for writing
- p_blocksize int ptr out The returned logical blocksize to use
- status char ptr out The error message string
- (0 length for no error)
-
- ***/
- /*
- char filename[], IOmode[], status[];
- int unit, *p_blocksize;
- */
- {
- char device[80];
- int i;
-
- strncpy (device, filename, 3);
- device[3] = 0;
-
- if (stricmp(device, "CD:") == 0)
- {
- if (toupper(IOmode[0]) == 'W')
- {
- strcpy (status, "Cannot open CD file for writing");
- return;
- }
- FileType[unit] = 1;
- OpenCD (filename, unit, p_blocksize, status);
- }
- else
- {
- FileType[unit] = 0;
- OpenDisk (filename, unit, IOmode, p_blocksize, status);
- }
- }
-
- int ReadBlocks (int unit, char * buffer, long startblock, int numblocks,
- int * p_blocksread, char * status)
-
- /*** ReadBlocks reads blocks from the file into the buffer.
-
- Parameter Type In/out Description
- unit int in Unit number from open
- buffer char ptr out The output buffer of data
- startblock long int in The starting logical block
- numblocks int in The number of blocks to read
- p_blocksread int ptr out The number of blocks actually read
- status char ptr out The error message string
- (0 length for no error)
-
- ***/
- /*
- int unit, numblocks, *p_blocksread;
- long startblock;
- char *buffer;
- char status[];
- */
- {
- if (FileType[unit] == 1)
- ReadCD (unit, buffer, startblock, numblocks, p_blocksread, status);
- else
- ReadDisk (unit, buffer, startblock, numblocks, p_blocksread, status);
- }
-
- int WriteBlocks (int unit, char * buffer, long startblock, int numblocks,
- char * status)
-
- /*** WriteBlocks writes blocks from the buffer to the file.
-
- Parameter Type In/out Description
- unit int in Unit number from open
- buffer char ptr in The input buffer of data
- startblock long int in The starting logical block
- numblocks int in The number of blocks to write
- status char ptr out The error message string
- (0 length for no error)
- ***/
- /*
- int unit, numblocks;
- long startblock;
- char *buffer;
- char status[];
- */
- {
- long pos;
- int byteswritten;
-
- strcpy(status,"");
-
-
- pos = lseek (FCB[unit].handle, 128*startblock, SEEK_SET);
- if (pos == -1)
- { strcpy (status, "Error writing to file : ");
- strcat (status, FCB[unit].filename);
- return;
- }
-
- byteswritten = write (FCB[unit].handle, buffer, 128*numblocks);
- if (byteswritten == -1)
- { strcpy (status, "Error writing to file : ");
- strcat (status, FCB[unit].filename);
- }
- }
-
- int CloseFile (int unit, char * status)
-
- /*** CloseFile closes the file.
-
- Parameter Type In/out Description
- unit int in Unit number from open
- status char ptr out The error message string
- (0 length for no error)
- ***/
- /*
- int unit;
- char status[];
- */
- {
- if (FileType[unit] == 1)
- CloseCD (unit, status);
- else
- CloseDisk (unit, status);
- }
-
- /*****************************************************************************/
-
- /*** Module MSCDIO
- Low Level Block I/O with MS-DOS for non-standard CD-ROM's
-
- ***/
-
- int InitializeCD (int * p_PB_size, char * status)
-
- /*** InitializeCD initializes the CD player and returns the
- physical block size.
-
- Parameter Type Description
- p_PB_size int ptr The size of the physical blocks for this driver.
- (in this case 2048 bytes)
- status char ptr Error message string (0 length if no error)
-
- ***/
- /*
- int *p_PB_size;
- char status[];
- */
- {
- union REGS inreg, outreg;
-
- *p_PB_size = 2048;
- strcpy (status,"");
-
- inreg.x.ax = 0x1500;
- inreg.x.bx = 0;
- int86 (0x2f, &inreg, &outreg);
- CDdrivenum = outreg.x.cx;
- if (outreg.x.bx == 0)
- {
- printf("MSCDEX not installed.\n");
- exit(0);
- }
- }
-
- int ReadBlocksCD (unsigned char * buffer, long int StartPB, int NumPB,
- char * status)
-
- /*** ReadBlocksCD reads blocks from the CD-ROM to the user's buffer.
-
- Parameter Type Description
- buffer char ptr Buffer to receive data
- StartPB long int The starting absolute physical block
- NumPB int The number of physical blocks to read
- status char ptr Error message string (0 length if no error)
-
- ***/
- /*
- unsigned char buffer[];
- long int StartPB;
- int NumPB;
- char status[];
- */
- {
- union REGS inreg, outreg;
- struct SREGS segregs;
- int error;
-
-
-
- strcpy (status, "");
-
- /* Call the Absolute Read function */
- /*segread (&segregs);*/
- segregs.es = FP_SEG(buffer);
- inreg.x.ax = 0x1508;
- inreg.x.bx = (unsigned)buffer;
- inreg.x.cx = CDdrivenum;
- inreg.x.dx = NumPB;
- inreg.x.si = StartPB >> 16;
- inreg.x.di = StartPB;
- int86x (0x2f, &inreg, &outreg, &segregs);
- error = outreg.x.ax & 0x0ff;
- if (error != 0)
- {
- strcpy (status, "Error reading from CD player");
- return;
- }
- }
-