/* Revision 2.1 tomehlert 2001/4/26

changed the file system detection code.
*/

/* Revision 2.0 tomehlert 2001/4/26

   no direct access to the disk any more, this is FORMAT's job
   no floppy.asm anymore, no segmentation problems.
   no access to partition tables

   instead copy boot sector using int25/int26 = absdiskread()/write

   if xxDOS is able to handle the disk, SYS should work

   additionally some space savers:

   replaced fopen() by open()

   included (slighly modified) PRF.c from kernel

   size is no ~7500 byte vs. ~13690 before
*/


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@217 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2001-04-29 17:34:41 +00:00
parent 64474e1dd4
commit f52e31f5c5

573
sys/sys.c
View File

@ -25,11 +25,55 @@
675 Mass Ave, Cambridge, MA 02139, USA. 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************/ ***************************************************************/
/* Revision 2.0 tomehlert 2001/4/26
no direct access to the disk any more, this is FORMAT's job
no floppy.asm anymore, no segmentation problems.
no access to partition tables
instead copy boot sector using int25/int26 = absdiskread()/write
if xxDOS is able to handle the disk, SYS should work
additionally some space savers:
replaced fopen() by open()
included (slighly modified) PRF.c from kernel
size is no ~7500 byte vs. ~13690 before
*/
/* $Log$ /* $Log$
* Revision 1.5 2001/03/25 17:11:54 bartoldeman * Revision 1.6 2001/04/29 17:34:41 bartoldeman
* Fixed sys.com compilation. Updated to 2023. Also: see history.txt. * /* Revision 2.1 tomehlert 2001/4/26
* *
* changed the file system detection code.
* */
*
* /* Revision 2.0 tomehlert 2001/4/26
*
* no direct access to the disk any more, this is FORMAT's job
* no floppy.asm anymore, no segmentation problems.
* no access to partition tables
*
* instead copy boot sector using int25/int26 = absdiskread()/write
*
* if xxDOS is able to handle the disk, SYS should work
*
* additionally some space savers:
*
* replaced fopen() by open()
*
* included (slighly modified) PRF.c from kernel
*
* size is no ~7500 byte vs. ~13690 before
* */
*
/* Revision 1.5 2001/03/25 17:11:54 bartoldeman
/* Fixed sys.com compilation. Updated to 2023. Also: see history.txt.
/*
/* Revision 1.4 2000/08/06 05:50:17 jimtabor /* Revision 1.4 2000/08/06 05:50:17 jimtabor
/* Add new files and update cvs with patches and changes /* Add new files and update cvs with patches and changes
/* /*
@ -80,108 +124,42 @@
* *
*/ */
/*
TE thinks, that the boot info storage should be done by FORMAT, noone else
unfortunately, that doesn't work ???
*/
#define STORE_BOOT_INFO #define STORE_BOOT_INFO
#define DEBUG
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
/*#include <sys/stat.h>*/ #include <sys/stat.h>
#include <io.h> #include <io.h>
#include <dos.h> #include <dos.h>
#include <ctype.h> #include <ctype.h>
#include <mem.h> #include <mem.h>
#include "portab.h" #include "portab.h"
#include "device.h"
#include "b_fat12.h" #include "b_fat12.h"
#include "b_fat16.h" #include "b_fat16.h"
BYTE *pgm = "sys"; BYTE pgm[] = "sys";
BOOL fl_reset(WORD); void put_boot(COUNT);
COUNT fl_rd_status(WORD);
COUNT fl_read(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
COUNT fl_write(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
BOOL fl_verify(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
BOOL fl_format(WORD, BYTE FAR *);
VOID get_boot(COUNT);
VOID put_boot(COUNT);
BOOL check_space(COUNT, BYTE *); BOOL check_space(COUNT, BYTE *);
COUNT ltop(WORD *, WORD *, WORD *, COUNT, COUNT, LONG, byteptr);
BOOL copy(COUNT, BYTE *); BOOL copy(COUNT, BYTE *);
BOOL DiskReset(COUNT);
COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
/* special word packing prototypes */
#ifdef NATIVE
#define getlong(vp, lp) (*(LONG *)(lp)=*(LONG *)(vp))
#define getword(vp, wp) (*(WORD *)(wp)=*(WORD *)(vp))
#define getbyte(vp, bp) (*(BYTE *)(bp)=*(BYTE *)(vp))
#define fgetlong(vp, lp) (*(LONG FAR *)(lp)=*(LONG FAR *)(vp))
#define fgetword(vp, wp) (*(WORD FAR *)(wp)=*(WORD FAR *)(vp))
#define fgetbyte(vp, bp) (*(BYTE FAR *)(bp)=*(BYTE FAR *)(vp))
#define fputlong(lp, vp) (*(LONG FAR *)(vp)=*(LONG FAR *)(lp))
#define fputword(wp, vp) (*(WORD FAR *)(vp)=*(WORD FAR *)(wp))
#define fputbyte(bp, vp) (*(BYTE FAR *)(vp)=*(BYTE FAR *)(bp))
#else
VOID getword(VOID *, WORD *);
VOID getbyte(VOID *, BYTE *);
VOID fgetlong(VOID FAR *, LONG FAR *);
VOID fgetword(VOID FAR *, WORD FAR *);
VOID fgetbyte(VOID FAR *, BYTE FAR *);
VOID fputlong(LONG FAR *, VOID FAR *);
VOID fputword(WORD FAR *, VOID FAR *);
VOID fputbyte(BYTE FAR *, VOID FAR *);
#endif
#define SEC_SIZE 512 #define SEC_SIZE 512
#define NDEV 4
#define COPY_SIZE 32768 #define COPY_SIZE 32768
#define NRETRY 5
static struct media_info
{
ULONG mi_size; /* physical sector size */
UWORD mi_heads; /* number of heads (sides) */
UWORD mi_cyls; /* number of cyl/drive */
UWORD mi_sectors; /* number of sectors/cyl */
ULONG mi_offset; /* relative partition offset */
};
union
{
BYTE bytes[2 * SEC_SIZE];
boot boot_sector;
}
buffer;
static struct media_info miarray[NDEV] =
{
{720l, 2, 40, 9, 0l},
{720l, 2, 40, 9, 0l},
{720l, 2, 40, 9, 0l},
{720l, 2, 40, 9, 0l}
};
#define PARTOFF 0x1be
#define N_PART 4
static struct
{
BYTE peBootable;
BYTE peBeginHead;
BYTE peBeginSector;
UWORD peBeginCylinder;
BYTE peFileSystem;
BYTE peEndHead;
BYTE peEndSector;
UWORD peEndCylinder;
LONG peStartSector;
LONG peSectors;
} partition[N_PART];
struct bootsectortype struct bootsectortype
{ {
@ -213,164 +191,87 @@ struct bootsectortype
}; };
static int DrvMap[4] =
{0, 1, 0x80, 0x81};
COUNT drive, active; COUNT drive;
UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE]; UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE];
#ifdef DEBUG
FILE *log;
#endif
#define SBSIZE 51
#define SBOFFSET 11 #define SBOFFSET 11
#define SBSIZE (sizeof(struct bootsectortype) - SBOFFSET)
#define SIZEOF_PARTENT 16
#define FAT12 0x01
#define FAT16SMALL 0x04
#define EXTENDED 0x05
#define FAT16LARGE 0x06
#define N_RETRY 5
COUNT get_part(COUNT drive, COUNT idx)
{
REG retry = N_RETRY;
REG BYTE *p = (BYTE *) & buffer.bytes[PARTOFF + (idx * SIZEOF_PARTENT)];
REG ret;
BYTE packed_byte, pb1;
do
{
ret = fl_read((WORD) DrvMap[drive], (WORD) 0, (WORD) 0, (WORD) 1, (WORD) 1, (byteptr) & buffer);
}
while (ret != 0 && --retry > 0);
if (ret != 0)
return FALSE;
getbyte((VOID *) p, &partition[idx].peBootable);
++p;
getbyte((VOID *) p, &partition[idx].peBeginHead);
++p;
getbyte((VOID *) p, &packed_byte);
partition[idx].peBeginSector = packed_byte & 0x3f;
++p;
getbyte((VOID *) p, &pb1);
++p;
partition[idx].peBeginCylinder = pb1 + ((0xc0 & packed_byte) << 2);
getbyte((VOID *) p, &partition[idx].peFileSystem);
++p;
getbyte((VOID *) p, &partition[idx].peEndHead);
++p;
getbyte((VOID *) p, &packed_byte);
partition[idx].peEndSector = packed_byte & 0x3f;
++p;
getbyte((VOID *) p, &pb1);
++p;
partition[idx].peEndCylinder = pb1 + ((0xc0 & packed_byte) << 2);
getlong((VOID *) p, &partition[idx].peStartSector);
p += sizeof(LONG);
getlong((VOID *) p, &partition[idx].peSectors);
return TRUE;
}
VOID main(COUNT argc, char **argv) VOID main(COUNT argc, char **argv)
{ {
printf("FreeDOS System Installer v1.0\n\n"); printf("FreeDOS System Installer v1.0\n\n");
if (argc != 2) if (argc != 2)
{ {
fprintf(stderr, "Usage: %s drive\n drive = A,B,etc.\n", pgm); printf("Usage: %s drive\n drive = A,B,etc.\n", pgm);
exit(1); exit(1);
} }
drive = *argv[1] - (islower(*argv[1]) ? 'a' : 'A'); drive = toupper(*argv[1]) - 'A';
if (drive < 0 || drive >= NDEV) if (drive < 0 || drive >= 26)
{ {
fprintf(stderr, "%s: drive out of range\n", pgm); printf( "%s: drive %c must be A:..Z:\n", pgm,*argv[1]);
exit(1); exit(1);
} }
if (!DiskReset(drive))
{
fprintf(stderr, "%s: cannot reset drive %c:",
drive, 'A' + drive);
exit(1);
}
get_boot(drive);
if (!check_space(drive, oldboot)) if (!check_space(drive, oldboot))
{ {
fprintf(stderr, "%s: Not enough space to transfer system files\n", pgm); printf("%s: Not enough space to transfer system files\n", pgm);
exit(1); exit(1);
} }
#ifdef DEBUG
if ((log = fopen("sys.log", "w")) == NULL)
{
printf("Can't write log file.\n");
log = NULL;
}
#endif
printf("Writing boot sector...\n");
put_boot(drive);
printf("\nCopying KERNEL.SYS..."); printf("\nCopying KERNEL.SYS...");
if (!copy(drive, "kernel.sys")) if (!copy(drive, "kernel.sys"))
{ {
fprintf(stderr, "\n%s: cannot copy \"KERNEL.SYS\"\n", pgm); printf("\n%s: cannot copy \"KERNEL.SYS\"\n", pgm);
#ifdef DEBUG
fclose(log);
#endif
exit(1); exit(1);
} }
printf("\nCopying COMMAND.COM..."); printf("\nCopying COMMAND.COM...");
if (!copy(drive, "command.com")) if (!copy(drive, "command.com"))
{ {
fprintf(stderr, "\n%s: cannot copy \"COMMAND.COM\"\n", pgm); printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm);
#ifdef DEBUG
fclose(log);
#endif
exit(1); exit(1);
} }
printf("\nSystem transfered.\n");
#ifdef DEBUG printf("\nWriting boot sector...\n");
fclose(log); put_boot(drive);
#endif
printf("\nSystem transferred.\n");
exit(0); exit(0);
} }
#ifdef DEBUG #ifdef DEBUG
VOID dump_sector(unsigned char far * sec) VOID dump_sector(unsigned char far * sec)
{ {
if (log)
{
COUNT x, y; COUNT x, y;
char c; char c;
for (x = 0; x < 32; x++) for (x = 0; x < 32; x++)
{ {
fprintf(log, "%03X ", x * 16); printf("%03X ", x * 16);
for (y = 0; y < 16; y++) for (y = 0; y < 16; y++)
{ {
fprintf(log, "%02X ", sec[x * 16 + y]); printf("%02X ", sec[x * 16 + y]);
} }
for (y = 0; y < 16; y++) for (y = 0; y < 16; y++)
{ {
c = oldboot[x * 16 + y]; c = oldboot[x * 16 + y];
if (isprint(c)) if (isprint(c))
fprintf(log, "%c", c); printf( "%c", c);
else else
fprintf(log, "."); printf( ".");
} }
fprintf(log, "\n"); printf( "\n");
} }
fprintf(log, "\n");
} printf( "\n");
} }
#endif #endif
@ -383,306 +284,154 @@ VOID put_boot(COUNT drive)
WORD count; WORD count;
ULONG temp; ULONG temp;
struct bootsectortype *bs; struct bootsectortype *bs;
if (drive >= 2)
{
head = partition[active].peBeginHead;
sector = partition[active].peBeginSector;
track = partition[active].peBeginCylinder;
}
else
{
head = 0;
sector = 1;
track = 0;
}
/* Read current boot sector */
if ((i = DiskRead(DrvMap[drive], head, track, sector, 1, (BYTE far *) oldboot)) != 0)
{
fprintf(stderr, "%s: disk read error (code = 0x%02x)\n", pgm, i & 0xff);
exit(1);
}
#ifdef DEBUG #ifdef DEBUG
fprintf(log, "Old Boot Sector:\n"); printf("Reading old bootsector from drive %c:\n",drive+'A');
#endif
if (absread(drive, 1, 0, oldboot) != 0)
{
printf("can't read old boot sector for drive %c:\n", drive +'A');
exit(1);
}
#ifdef DDEBUG
printf("Old Boot Sector:\n");
dump_sector(oldboot); dump_sector(oldboot);
#endif #endif
bs = (struct bootsectortype *) & oldboot; bs = (struct bootsectortype *) & oldboot;
if ((bs->bsFileSysType[4] == '6') && (bs->bsBootSignature == 0x29)) if ((bs->bsFileSysType[4] == '6') && (bs->bsBootSignature == 0x29))
{ {
memcpy(newboot, b_fat16, SEC_SIZE); /* copy FAT16 boot sector */ memcpy(newboot, b_fat16, SEC_SIZE); /* copy FAT16 boot sector */
printf("FAT type: FAT16\n"); printf("FAT type: FAT16\n");
#ifdef DEBUG
fprintf(log, "FAT type: FAT16\n");
#endif
} }
else else
{ {
memcpy(newboot, b_fat12, SEC_SIZE); /* copy FAT12 boot sector */ memcpy(newboot, b_fat12, SEC_SIZE); /* copy FAT12 boot sector */
printf("FAT type: FAT12\n"); printf("FAT type: FAT12\n");
#ifdef DEBUG
fprintf(log, "FAT type: FAT12\n");
#endif
} }
/* Copy disk parameter from old sector to new sector */ /* Copy disk parameter from old sector to new sector */
memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE); memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE);
bs = (struct bootsectortype *) & newboot; bs = (struct bootsectortype *) & newboot;
/* root directory sectors */
#ifdef STORE_BOOT_INFO #ifdef STORE_BOOT_INFO
/* TE thinks : never, see above */
/* temporary HACK for the load segment (0x0060): it is in unused */
/* only needed for older kernels */
*((UWORD *)(bs->unused)) = *((UWORD *)(((struct bootsectortype *)&b_fat16)->unused));
/* end of HACK */
/* root directory sectors */
bs->sysRootDirSecs = bs->bsRootDirEnts / 16; bs->sysRootDirSecs = bs->bsRootDirEnts / 16;
#endif
#ifdef DEBUG
fprintf(log, "root dir entries = %u\n", bs->bsRootDirEnts);
fprintf(log, "root dir sectors = %u\n", bs->sysRootDirSecs);
#endif
/* sector FAT starts on */ /* sector FAT starts on */
temp = bs->bsHiddenSecs + bs->bsResSectors; temp = bs->bsHiddenSecs + bs->bsResSectors;
#ifdef STORE_BOOT_INFO
bs->sysFatStart = temp; bs->sysFatStart = temp;
#endif
#ifdef DEBUG /* sector root directory starts on */
fprintf(log, "FAT starts at sector %lu = (%lu + %u)\n", temp,
bs->bsHiddenSecs, bs->bsResSectors);
#endif
/* sector root directory starts on */
temp = temp + bs->bsFATsecs * bs->bsFATs; temp = temp + bs->bsFATsecs * bs->bsFATs;
#ifdef STORE_BOOT_INFO
bs->sysRootDirStart = temp; bs->sysRootDirStart = temp;
#endif
#ifdef DEBUG /* sector data starts on */
fprintf(log, "Root directory starts at sector %lu = (PREVIOUS + %u * %u)\n",
temp, bs->bsFATsecs, bs->bsFATs);
#endif
/* sector data starts on */
temp = temp + bs->sysRootDirSecs; temp = temp + bs->sysRootDirSecs;
#ifdef STORE_BOOT_INFO
bs->sysDataStart = temp; bs->sysDataStart = temp;
#endif
#ifdef DEBUG #ifdef DEBUG
fprintf(log, "DATA starts at sector %lu = (PREVIOUS + %u)\n", temp, printf("Root dir entries = %u\n", bs->bsRootDirEnts);
printf("Root dir sectors = %u\n", bs->sysRootDirSecs);
printf( "FAT starts at sector %lu = (%lu + %u)\n", bs->sysFatStart,
bs->bsHiddenSecs, bs->bsResSectors);
printf("Root directory starts at sector %lu = (PREVIOUS + %u * %u)\n",
bs->sysRootDirStart, bs->bsFATsecs, bs->bsFATs);
printf("DATA starts at sector %lu = (PREVIOUS + %u)\n", bs->sysDataStart,
bs->sysRootDirSecs); bs->sysRootDirSecs);
#endif #endif
#endif
#ifdef DEBUG #ifdef DDEBUG
fprintf(log, "\nNew Boot Sector:\n"); printf("\nNew Boot Sector:\n");
dump_sector(newboot); dump_sector(newboot);
#endif #endif
if ((i = DiskWrite(DrvMap[drive], head, track, sector, 1, (BYTE far *) newboot)) != 0) #ifdef DEBUG
{ printf("writing new bootsector to drive %c:\n",drive+'A');
fprintf(stderr, "%s: disk write error (code = 0x%02x)\n", pgm, i & 0xff); #endif
if (abswrite(drive, 1, 0, newboot) != 0)
{
printf("Can't write new boot sector to drive %c:\n", drive +'A');
exit(1); exit(1);
} }
} }
VOID get_boot(COUNT drive)
{
COUNT i;
COUNT ifd;
WORD head, track, sector, ret;
WORD count;
if (drive >= 2)
{
head = partition[active].peBeginHead;
sector = partition[active].peBeginSector;
track = partition[active].peBeginCylinder;
}
else
{
head = 0;
sector = 1;
track = 0;
}
if ((i = DiskRead(DrvMap[drive], head, track, sector, 1, (BYTE far *) oldboot)) != 0)
{
fprintf(stderr, "%s: disk read error (code = 0x%02x)\n", pgm, i & 0xff);
exit(1);
}
}
BOOL check_space(COUNT drive, BYTE * BlkBuffer) BOOL check_space(COUNT drive, BYTE * BlkBuffer)
{ {
BYTE *bpbp; /* this should check, if on destination is enough space
#if 0 /* these local variables are never used */ to hold command.com+ kernel.sys */
BYTE nfat;
UWORD nfsect; if (drive);
ULONG hidden; if (BlkBuffer);
UBYTE nreserved;
#endif
ULONG count;
ULONG block;
UCOUNT i;
WORD track, head, sector;
UBYTE buffer[SEC_SIZE];
ULONG bpb_huge;
UWORD bpb_nsize;
/* get local information */
#if 0 /* these local variables are never used */
getbyte((VOID *) & BlkBuffer[BT_BPB + BPB_NFAT], &nfat);
getword((VOID *) & BlkBuffer[BT_BPB + BPB_NFSECT], &nfsect);
getlong((VOID *) & BlkBuffer[BT_BPB + BPB_HIDDEN], &hidden);
getbyte((VOID *) & BlkBuffer[BT_BPB + BPB_NRESERVED], &nreserved);
#endif
getlong((VOID *) & BlkBuffer[BT_BPB + BPB_HUGE], &bpb_huge);
getword((VOID *) & BlkBuffer[BT_BPB + BPB_NSIZE], &bpb_nsize);
count = miarray[drive].mi_size = bpb_nsize == 0 ?
bpb_huge : bpb_nsize;
/* Fix media information for disk */
getword((&(((BYTE *) & BlkBuffer[BT_BPB])[BPB_NHEADS])), &miarray[drive].mi_heads);
head = miarray[drive].mi_heads;
getword((&(((BYTE *) & BlkBuffer[BT_BPB])[BPB_NSECS])), &miarray[drive].mi_sectors);
if (miarray[drive].mi_size == 0)
getlong(&((((BYTE *) & BlkBuffer[BT_BPB])[BPB_HUGE])), &miarray[drive].mi_size);
sector = miarray[drive].mi_sectors;
if (head == 0 || sector == 0)
{
fprintf(stderr, "Drive initialization failure.\n");
exit(1);
}
miarray[drive].mi_cyls = count / (head * sector);
return 1; return 1;
} }
/* */
/* Do logical block number to physical head/track/sector mapping */
/* */
static COUNT ltop(trackp, sectorp, headp, unit, count, strt_sect, strt_addr)
WORD *trackp, *sectorp, *headp;
REG COUNT unit;
LONG strt_sect;
COUNT count;
byteptr strt_addr;
{
#ifdef I86
ULONG ltemp;
#endif
REG ls, ps;
#ifdef I86
/* Adjust for segmented architecture */
ltemp = (((ULONG) mk_segment(strt_addr) << 4) + mk_offset(strt_addr)) & 0xffff;
/* Test for 64K boundary crossing and return count large */
/* enough not to exceed the threshold. */
count = (((ltemp + SEC_SIZE * count) & 0xffff0000l) != 0l)
? (0xffffl - ltemp) / SEC_SIZE
: count;
#endif
*trackp = strt_sect / (miarray[unit].mi_heads * miarray[unit].mi_sectors);
*sectorp = strt_sect % miarray[unit].mi_sectors + 1;
*headp = (strt_sect % (miarray[unit].mi_sectors * miarray[unit].mi_heads))
/ miarray[unit].mi_sectors;
if (((ls = *headp * miarray[unit].mi_sectors + *sectorp - 1) + count) >
(ps = miarray[unit].mi_heads * miarray[unit].mi_sectors))
count = ps - ls;
return count;
}
BOOL copy(COUNT drive, BYTE * file) BOOL copy(COUNT drive, BYTE * file)
{ {
BYTE dest[64]; BYTE dest[64];
COUNT ifd, ofd, ret; COUNT ifd, ofd;
FILE *s, *d; unsigned ret;
int fdin, fdout;
BYTE buffer[COPY_SIZE]; BYTE buffer[COPY_SIZE];
struct ftime ftime; struct ftime ftime;
ULONG copied = 0;
sprintf(dest, "%c:\\%s", 'A' + drive, file); sprintf(dest, "%c:\\%s", 'A' + drive, file);
if ((s = fopen(file, "rb")) == NULL) if ((fdin = open(file, O_RDONLY|O_BINARY)) < 0)
{ {
fprintf(stderr, "%s: \"%s\" not found\n", pgm, file); printf( "%s: \"%s\" not found\n", pgm, file);
return FALSE; return FALSE;
} }
_fmode = O_BINARY; if ((fdout = open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0)
if ((d = fopen(dest, "wb")) == NULL)
{ {
fclose(s); printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
fprintf(stderr, "%s: can't create\"%s\"\n", pgm, dest); close(fdin);
return FALSE; return FALSE;
} }
while ((ret = fread(buffer, 1, COPY_SIZE, s)) != 0) while ((ret = read(fdin, buffer,COPY_SIZE)) > 0)
fwrite(buffer, 1, ret, d);
getftime(fileno(s), &ftime);
setftime(fileno(d), &ftime);
fclose(s);
fclose(d);
return TRUE;
}
BOOL DiskReset(COUNT Drive)
{
REG COUNT idx;
/* Reset the drives */
fl_reset(DrvMap[drive]);
if (Drive >= 2 && Drive < NDEV)
{
COUNT RetCode;
/* Retrieve all the partition information */
for (RetCode = TRUE, idx = 0; RetCode && (idx < N_PART); idx++)
RetCode = get_part(Drive, idx);
if (!RetCode)
return FALSE;
/* Search for the first DOS partition and start */
/* building the map for the hard drive */
for (idx = 0; idx < N_PART; idx++)
{ {
if (partition[idx].peFileSystem == FAT12 if (write(fdout, buffer, ret) != ret)
|| partition[idx].peFileSystem == FAT16SMALL {
|| partition[idx].peFileSystem == FAT16LARGE) printf("Can't write %u bytes to %s\n",dest);
{ close(fdout);
miarray[Drive].mi_offset unlink(dest);
= partition[idx].peStartSector; break;
active = idx; }
break; copied += ret;
} }
}
} getftime(fdin, &ftime);
setftime(fdout, &ftime);
close(fdin);
close(fdout);
printf("%lu Bytes transferred", copied);
return TRUE; return TRUE;
} }
COUNT DiskRead(WORD drive, WORD head, WORD track, WORD sector, WORD count, BYTE FAR * buffer)
{
int nRetriesLeft;
for (nRetriesLeft = NRETRY; nRetriesLeft > 0; --nRetriesLeft)
{
if (fl_read(drive, head, track, sector, count, buffer) == count)
return count;
}
return 0;
}
COUNT DiskWrite(WORD drive, WORD head, WORD track, WORD sector, WORD count, BYTE FAR * buffer)
{
int nRetriesLeft;
for (nRetriesLeft = NRETRY; nRetriesLeft > 0; --nRetriesLeft)
{
if (fl_write(drive, head, track, sector, count, buffer) == count)
return count;
}
return 0;
}