Category : C Source Code
Archive   : IMDSRC78.ZIP
Filename : FILEIO.C

 
Output of file : FILEIO.C contained in archive : IMDSRC78.ZIP
/*** IMDISP module FILEIO.C

Contains block level I/O routines for both MS-DOS files
and absolute CD-ROM reads.

***/

#define __MSC

/* * * * INCLUDE files * * * */

#include
#include
#include
#include
#include
#include
#include
#include
#include
#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 *);
int OpenFile (char *, int, char *, int *, char *);
int ReadBlocks (int, char *, long, int, int *, char *);

int WriteBlocks (int, char *, long, int, char *);
int CloseFile (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 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;
}
}


  3 Responses to “Category : C Source Code
Archive   : IMDSRC78.ZIP
Filename : FILEIO.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/