version 2.1a jeremyd 2001/8/19
modified so takes optional 2nd parameter (similar to PC DOS) where if only 1 argument is given, assume to be destination drive, but if two arguments given, 1st is source (drive and/or path) and second is destination drive FAT32 support. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@306 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
048c87bbac
commit
a957122ff6
232
sys/sys.c
232
sys/sys.c
@ -26,9 +26,26 @@
|
|||||||
|
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
/* $Log$
|
/* $Log$
|
||||||
* Revision 1.7 2001/07/09 22:19:33 bartoldeman
|
* Revision 1.8 2001/09/23 20:39:44 bartoldeman
|
||||||
* LBA/FCB/FAT/SYS/Ctrl-C/ioctl fixes + memory savings
|
* version 2.1a jeremyd 2001/8/19
|
||||||
|
* modified so takes optional 2nd parameter (similar to PC DOS)
|
||||||
|
* where if only 1 argument is given, assume to be destination drive,
|
||||||
|
* but if two arguments given, 1st is source (drive and/or path)
|
||||||
|
* and second is destination drive
|
||||||
*
|
*
|
||||||
|
* FAT32 support.
|
||||||
|
*
|
||||||
|
|
||||||
|
/* version 2.1a jeremyd 2001/8/19
|
||||||
|
modified so takes optional 2nd parameter (similar to PC DOS)
|
||||||
|
where if only 1 argument is given, assume to be destination drive,
|
||||||
|
but if two arguments given, 1st is source (drive and/or path)
|
||||||
|
and second is destination drive
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Revision 1.7 2001/07/09 22:19:33 bartoldeman
|
||||||
|
/* LBA/FCB/FAT/SYS/Ctrl-C/ioctl fixes + memory savings
|
||||||
|
/*
|
||||||
/* Revision 2.1 tomehlert 2001/4/26
|
/* Revision 2.1 tomehlert 2001/4/26
|
||||||
|
|
||||||
changed the file system detection code.
|
changed the file system detection code.
|
||||||
@ -119,6 +136,9 @@
|
|||||||
#define STORE_BOOT_INFO
|
#define STORE_BOOT_INFO
|
||||||
|
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
|
/* #define DDEBUG */
|
||||||
|
|
||||||
|
#define SYS_VERSION "v2.1a"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -127,11 +147,20 @@
|
|||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <mem.h>
|
#ifdef __TURBOC__
|
||||||
|
#include <mem.h>
|
||||||
|
#else
|
||||||
|
#include <memory.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
#include <dir.h>
|
||||||
#include "portab.h"
|
#include "portab.h"
|
||||||
|
|
||||||
#include "b_fat12.h"
|
#include "b_fat12.h"
|
||||||
#include "b_fat16.h"
|
#include "b_fat16.h"
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
#include "b_fat32.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
BYTE pgm[] = "sys";
|
BYTE pgm[] = "sys";
|
||||||
|
|
||||||
@ -143,7 +172,7 @@ COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
|
|||||||
|
|
||||||
|
|
||||||
#define SEC_SIZE 512
|
#define SEC_SIZE 512
|
||||||
#define COPY_SIZE 32768
|
#define COPY_SIZE 32768u
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -177,28 +206,89 @@ struct bootsectortype
|
|||||||
ULONG sysDataStart; /* first data sector */
|
ULONG sysDataStart; /* first data sector */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bootsectortype32
|
||||||
|
{
|
||||||
|
UBYTE bsJump[3];
|
||||||
|
char OemName[8];
|
||||||
|
UWORD bsBytesPerSec;
|
||||||
|
UBYTE bsSecPerClust;
|
||||||
|
UWORD bsResSectors;
|
||||||
|
UBYTE bsFATs;
|
||||||
|
UWORD bsRootDirEnts;
|
||||||
|
UWORD bsSectors;
|
||||||
|
UBYTE bsMedia;
|
||||||
|
UWORD bsFATsecs;
|
||||||
|
UWORD bsSecPerTrack;
|
||||||
|
UWORD bsHeads;
|
||||||
|
ULONG bsHiddenSecs;
|
||||||
|
ULONG bsHugeSectors;
|
||||||
|
ULONG bsBigFatSize;
|
||||||
|
UBYTE bsFlags;
|
||||||
|
UBYTE bsMajorVersion;
|
||||||
|
UWORD bsMinorVersion;
|
||||||
|
ULONG bsRootCluster;
|
||||||
|
UWORD bsFSInfoSector;
|
||||||
|
UWORD bsBackupBoot;
|
||||||
|
ULONG bsReserved2[3];
|
||||||
|
UBYTE bsDriveNumber;
|
||||||
|
UBYTE bsReserved3;
|
||||||
|
UBYTE bsExtendedSignature;
|
||||||
|
ULONG bsSerialNumber;
|
||||||
|
char bsVolumeLabel[11];
|
||||||
|
char bsFileSystemID[8];
|
||||||
|
ULONG sysFatStart;
|
||||||
|
ULONG sysDataStart;
|
||||||
|
UWORD sysFatSecMask;
|
||||||
|
UWORD sysFatSecShift;
|
||||||
|
};
|
||||||
|
|
||||||
|
COUNT drive; /* destination drive */
|
||||||
COUNT drive;
|
BYTE srcPath[MAXPATH]; /* source drive and/or path */
|
||||||
|
BYTE *endOfSrcPath; /* marks start of filename */
|
||||||
UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE];
|
UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE];
|
||||||
|
|
||||||
|
|
||||||
#define SBOFFSET 11
|
#define SBOFFSET 11
|
||||||
#define SBSIZE (sizeof(struct bootsectortype) - SBOFFSET)
|
#define SBSIZE (sizeof(struct bootsectortype) - SBOFFSET)
|
||||||
|
#define SBSIZE32 (sizeof(struct bootsectortype32) - SBOFFSET)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID main(COUNT argc, char **argv)
|
VOID main(COUNT argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("FreeDOS System Installer v2.1\n\n");
|
WORD slen;
|
||||||
|
|
||||||
if (argc != 2)
|
printf("FreeDOS System Installer " SYS_VERSION "\n\n");
|
||||||
|
|
||||||
|
if (argc == 2)
|
||||||
{
|
{
|
||||||
printf("Usage: %s drive\n drive = A,B,etc.\n", pgm);
|
drive = toupper(*argv[1]) - 'A';
|
||||||
|
srcPath[0] = '\0';
|
||||||
|
endOfSrcPath = srcPath;
|
||||||
|
}
|
||||||
|
else if (argc == 3)
|
||||||
|
{
|
||||||
|
drive = toupper(*argv[2]) - 'A';
|
||||||
|
strncpy(srcPath, argv[1], MAXDIR);
|
||||||
|
/* make sure srcPath + "file" is a valid path */
|
||||||
|
slen = strlen(srcPath);
|
||||||
|
if ( (srcPath[slen-1] != ':') &&
|
||||||
|
((srcPath[slen-1] != '\\') || (srcPath[slen-1] != '/')) )
|
||||||
|
{
|
||||||
|
srcPath[slen] = '\\';
|
||||||
|
slen++;
|
||||||
|
srcPath[slen] = '\0';
|
||||||
|
}
|
||||||
|
endOfSrcPath = srcPath + slen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Usage: %s [source] drive\n", pgm);
|
||||||
|
printf(" source = A:,B:,C:\\KERNEL\\BIN\\,etc., or current directory if not given\n");
|
||||||
|
printf(" drive = A,B,etc.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
drive = toupper(*argv[1]) - 'A';
|
|
||||||
if (drive < 0 || drive >= 26)
|
if (drive < 0 || drive >= 26)
|
||||||
{
|
{
|
||||||
printf( "%s: drive %c must be A:..Z:\n", pgm,*argv[1]);
|
printf( "%s: drive %c must be A:..Z:\n", pgm,*argv[1]);
|
||||||
@ -213,14 +303,14 @@ VOID main(COUNT argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
printf("\nCopying KERNEL.SYS...");
|
printf("\nCopying KERNEL.SYS...\n");
|
||||||
if (!copy(drive, "kernel.sys"))
|
if (!copy(drive, "kernel.sys"))
|
||||||
{
|
{
|
||||||
printf("\n%s: cannot copy \"KERNEL.SYS\"\n", pgm);
|
printf("\n%s: cannot copy \"KERNEL.SYS\"\n", pgm);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nCopying COMMAND.COM...");
|
printf("\nCopying COMMAND.COM...\n");
|
||||||
if (!copy(drive, "command.com"))
|
if (!copy(drive, "command.com"))
|
||||||
{
|
{
|
||||||
printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm);
|
printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm);
|
||||||
@ -269,7 +359,7 @@ VOID dump_sector(unsigned char far * sec)
|
|||||||
MSDOS requires int25, CX=ffff for drives > 32MB
|
MSDOS requires int25, CX=ffff for drives > 32MB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int MyAbsReadWrite(char DosDrive, int count, ULONG sector, void *buffer, unsigned intno)
|
int MyAbsReadWrite(int DosDrive, int count, ULONG sector, void *buffer, unsigned intno)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
unsigned long sectorNumber;
|
unsigned long sectorNumber;
|
||||||
@ -284,13 +374,25 @@ int MyAbsReadWrite(char DosDrive, int count, ULONG sector, void *buffer, unsigne
|
|||||||
diskReadPacket.count = count;
|
diskReadPacket.count = count;
|
||||||
diskReadPacket.address = buffer;
|
diskReadPacket.address = buffer;
|
||||||
|
|
||||||
regs.h.al = DosDrive;
|
regs.h.al = (BYTE)DosDrive;
|
||||||
regs.x.bx = (short)&diskReadPacket;
|
regs.x.bx = (short)&diskReadPacket;
|
||||||
regs.x.cx = 0xffff;
|
regs.x.cx = 0xffff;
|
||||||
|
|
||||||
if (intno != 0x25 && intno != 0x26) return 0xff;
|
if (intno != 0x25 && intno != 0x26) return 0xff;
|
||||||
|
|
||||||
int86(intno,®s,®s);
|
int86(intno,®s,®s);
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (regs.x.cflag)
|
||||||
|
{
|
||||||
|
regs.x.ax = 0x7305;
|
||||||
|
regs.h.dl = DosDrive + 1;
|
||||||
|
regs.x.bx = (short)&diskReadPacket;
|
||||||
|
regs.x.cx = 0xffff;
|
||||||
|
regs.x.si = intno - 0x25;
|
||||||
|
int86(0x21, ®s, ®s);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return regs.x.cflag ? 0xff : 0;
|
return regs.x.cflag ? 0xff : 0;
|
||||||
}
|
}
|
||||||
@ -303,6 +405,9 @@ VOID put_boot(COUNT drive)
|
|||||||
WORD count;
|
WORD count;
|
||||||
ULONG temp;
|
ULONG temp;
|
||||||
struct bootsectortype *bs;
|
struct bootsectortype *bs;
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
struct bootsectortype32 *bs32;
|
||||||
|
#endif
|
||||||
int fs;
|
int fs;
|
||||||
union REGS regs;
|
union REGS regs;
|
||||||
struct SREGS sregs;
|
struct SREGS sregs;
|
||||||
@ -402,20 +507,53 @@ VOID put_boot(COUNT drive)
|
|||||||
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");
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
printf("FAT type: FAT32\n");
|
{
|
||||||
printf("Sorry, we don't have a FAT32 boot sector (yet)\n");
|
printf("FAT type: FAT32\n");
|
||||||
printf(" for this reason, we can't make the drive bootable\n");
|
#ifdef WITHFAT32
|
||||||
exit(1);
|
memcpy(newboot, b_fat32, SEC_SIZE); /* copy FAT32 boot sector */
|
||||||
|
#else
|
||||||
|
printf("SYS hasn't been compiled with FAT32 support.");
|
||||||
|
printf("Consider using -DWITHFAT32 option.\n");
|
||||||
|
exit(1);
|
||||||
|
#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);
|
#ifdef WITHFAT32
|
||||||
|
if (fs == 32)
|
||||||
|
memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE32);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE);
|
||||||
|
|
||||||
bs = (struct bootsectortype *) & newboot;
|
bs = (struct bootsectortype *) & newboot;
|
||||||
|
|
||||||
memcpy(bs->OemName, "FreeDOS ",8);
|
memcpy(bs->OemName, "FreeDOS ",8);
|
||||||
|
|
||||||
|
#ifdef WITHFAT32
|
||||||
|
if (fs == 32)
|
||||||
|
{
|
||||||
|
bs32 = (struct bootsectortype32 *) & newboot;
|
||||||
|
|
||||||
|
temp = bs32->bsHiddenSecs + bs32->bsResSectors;
|
||||||
|
bs32->sysFatStart = temp;
|
||||||
|
|
||||||
|
bs32->sysDataStart = temp + bs32->bsBigFatSize * bs32->bsFATs;
|
||||||
|
bs32->sysFatSecMask = bs32->bsBytesPerSec / 4 - 1;
|
||||||
|
|
||||||
|
temp = bs32->sysFatSecMask + 1;
|
||||||
|
for (bs32->sysFatSecShift = 0; temp != 1; bs32->sysFatSecShift++, temp >>= 1);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (fs == 32)
|
||||||
|
{
|
||||||
|
printf( "FAT starts at sector %lx = (%lx + %x)\n", bs32->sysFatStart,
|
||||||
|
bs32->bsHiddenSecs, bs32->bsResSectors);
|
||||||
|
printf("DATA starts at sector %lx\n", bs32->sysDataStart);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#ifdef STORE_BOOT_INFO
|
#ifdef STORE_BOOT_INFO
|
||||||
/* TE thinks : never, see above */
|
/* TE thinks : never, see above */
|
||||||
/* temporary HACK for the load segment (0x0060): it is in unused */
|
/* temporary HACK for the load segment (0x0060): it is in unused */
|
||||||
@ -438,7 +576,6 @@ VOID put_boot(COUNT drive)
|
|||||||
temp = temp + bs->sysRootDirSecs;
|
temp = temp + bs->sysRootDirSecs;
|
||||||
bs->sysDataStart = temp;
|
bs->sysDataStart = temp;
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Root dir entries = %u\n", bs->bsRootDirEnts);
|
printf("Root dir entries = %u\n", bs->bsRootDirEnts);
|
||||||
printf("Root dir sectors = %u\n", bs->sysRootDirSecs);
|
printf("Root dir sectors = %u\n", bs->sysRootDirSecs);
|
||||||
@ -451,6 +588,7 @@ VOID put_boot(COUNT drive)
|
|||||||
bs->sysRootDirSecs);
|
bs->sysRootDirSecs);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef DDEBUG
|
#ifdef DDEBUG
|
||||||
@ -476,13 +614,14 @@ BOOL check_space(COUNT drive, BYTE * BlkBuffer)
|
|||||||
/* this should check, if on destination is enough space
|
/* this should check, if on destination is enough space
|
||||||
to hold command.com+ kernel.sys */
|
to hold command.com+ kernel.sys */
|
||||||
|
|
||||||
if (drive);
|
UNREFERENCED_PARAMETER(drive);
|
||||||
if (BlkBuffer);
|
UNREFERENCED_PARAMETER(BlkBuffer);
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BYTE copybuffer[COPY_SIZE];
|
||||||
|
|
||||||
BOOL copy(COUNT drive, BYTE * file)
|
BOOL copy(COUNT drive, BYTE * file)
|
||||||
{
|
{
|
||||||
@ -490,16 +629,25 @@ BOOL copy(COUNT drive, BYTE * file)
|
|||||||
COUNT ifd, ofd;
|
COUNT ifd, ofd;
|
||||||
unsigned ret;
|
unsigned ret;
|
||||||
int fdin, fdout;
|
int fdin, fdout;
|
||||||
BYTE buffer[COPY_SIZE];
|
|
||||||
struct ftime ftime;
|
|
||||||
ULONG copied = 0;
|
ULONG copied = 0;
|
||||||
|
struct stat fstatbuf;
|
||||||
sprintf(dest, "%c:\\%s", 'A' + drive, file);
|
|
||||||
if ((fdin = open(file, O_RDONLY|O_BINARY)) < 0)
|
if (stat(file,&fstatbuf))
|
||||||
{
|
{
|
||||||
printf( "%s: \"%s\" not found\n", pgm, file);
|
printf( "%s: \"%s\" not found\n", pgm, file);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sprintf(dest, "%c:\\%s", 'A' + drive, file);
|
||||||
|
strcpy(endOfSrcPath, file);
|
||||||
|
if ((fdin = open(srcPath, O_RDONLY|O_BINARY)) < 0)
|
||||||
|
{
|
||||||
|
printf( "%s: \"%s\" not found\n", pgm, srcPath);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((fdout = open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0)
|
if ((fdout = open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0)
|
||||||
{
|
{
|
||||||
printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
|
printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
|
||||||
@ -507,9 +655,9 @@ BOOL copy(COUNT drive, BYTE * file)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ret = read(fdin, buffer,COPY_SIZE)) > 0)
|
while ((ret = read(fdin, copybuffer,COPY_SIZE)) > 0)
|
||||||
{
|
{
|
||||||
if (write(fdout, buffer, ret) != ret)
|
if (write(fdout, copybuffer, ret) != ret)
|
||||||
{
|
{
|
||||||
printf("Can't write %u bytes to %s\n",dest);
|
printf("Can't write %u bytes to %s\n",dest);
|
||||||
close(fdout);
|
close(fdout);
|
||||||
@ -519,12 +667,30 @@ BOOL copy(COUNT drive, BYTE * file)
|
|||||||
copied += ret;
|
copied += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
getftime(fdin, &ftime);
|
#ifdef __TURBO__
|
||||||
setftime(fdout, &ftime);
|
{
|
||||||
|
struct ftime ftime;
|
||||||
|
getftime(fdin, &ftime);
|
||||||
|
setftime(fdout, &ftime);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
close(fdin);
|
close(fdin);
|
||||||
close(fdout);
|
close(fdout);
|
||||||
|
|
||||||
|
#ifdef _MSV_VER
|
||||||
|
{
|
||||||
|
#include <utime.h>
|
||||||
|
struct utimbuf utimb;
|
||||||
|
|
||||||
|
utimb.actime = /* access time */
|
||||||
|
utimb.modtime = fstatbuf.st_mtime; /* modification time */
|
||||||
|
utime(dest,&utimb);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
printf("%lu Bytes transferred", copied);
|
printf("%lu Bytes transferred", copied);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user