Commits (5)
  • Robert Sprowson's avatar
    Fix a few potential memory leaks · af080143
    Robert Sprowson authored
    Some of the long filenames handling added in DOSFS-0_79 (DOSFSops.c revision 4.10) introduced extra points to return in the face of error, but didn't free memory allocated earlier in the function.
    Add missing free()'s.
    From a tip off from Dominic Plunkett in http://www.riscosopen.org/forum/forums/4/topics/3990#posts-51013
    
    Version 1.09. Tagged as 'DOSFS-1_09'
    af080143
  • Robert Sprowson's avatar
    Allow mounting discs with 1 letter names, and 2x buffer overrun fixes · 8e566c40
    Robert Sprowson authored
    DOSFS would prefer to use the disc title from the volume name entry in the root directory, even if this reduced to 1 letter, which would then lead to "Disc drive not known" errors. Since the disc couldn't be mounted it couldn't be renamed either, requiring a trip to a PC to do so.
    Now, if the cleaned up name is < 2 characters long, ignore it and use the one based on the volumeid, and if that doesn't exist, use the default one ("Untitled") from the Messages file.
    In OpsFunc.c used memset() in place of a byte set loop.
    
    Ref https://www.riscosopen.org/forum/forums/4/topics/9503
    DOSFS.c, line 621: remove the excess NULL so the sprintf fits into the 10 byte buffer, not 11.
    DOSFS.c, line 1556: restore the original intent for *CopyBoot in light of the structure/union reorg DOSshape.h revision 4.7 in DOSFS-0_79. Previously the boot code was copied in its entirity as an opaque blob, but the loop was left unchanged, overrunning the sector buffer.
    
    A useful example of the extent of the boot code is given in
      http://thestarman.pcministry.com/asm/mbr/DOS50FDB.htm
    which shows the code uses up every last byte of the sector.
    
    Tested with a disc called "R", which can now be mounted. A floppy with no name and no volume id, and one with no name and a volume id.
    
    Version 1.10. Tagged as 'DOSFS-1_10'
    8e566c40
  • Robert Sprowson's avatar
    No longer offer PCMCIA SRAM card as a format option · c030e516
    Robert Sprowson authored
    Untangle the PCMCIATRUE misnomer - what it really meant was "offer PCMCIA card as an option for *Format AND allow non floppy geometries".
    Nothing has shipped with PCCardFS since October 1994, so stop offering it as a possible *Format.
    However, we do rely on the non floppy geometries for things like SD cards and USB sticks, so retain that with a new switch (permanently enabled) called NONFLOPPIES.
    
    Tested with a Pi SD card and a 4GB USB stick.
    
    Version 1.11. Tagged as 'DOSFS-1_11'
    c030e516
  • Jeffrey Lee's avatar
    Reject overly-large discs, and other invalid things · eb3e3485
    Jeffrey Lee authored
    Detail:
      c/Accessors, h/Accessors, Makefile - Added some simple 'image accessor' routines to abstract over accessing the underlying disc/image file. These accept 64bit disc addresses and will check to make sure any size limits imposed by the lower-level API are adhered to (512MB limit for FileCore_DiscOp, or extent of image file for OS_GBPB)
      h/MsgTrans, Resources/Germany/Messages, Resources/UK/Messages - Add a couple of new error messages
      h/Helpers - Add a couple of macros to simplify reading 16/32bit values that are split into multiple bytes in struct definitions. Change writeWORD & loadWORD to accept void* instead of char* so they can be used with other types like 'byte'
      h/DOSshape - Add '0' suffix to some struct members so they can be used with new READ_0123 macro
      h/ADFSshape - Make sure put_doublestep is safe to use with bools
      c/DOSdirs - Remove pointless malloc of small temporary array
      c/DOSclusters - Use new READ_ macros in max_sector()
      c/DOSFS - Use new READ_ macros so code is less painful to read. Use new image accessor system to get rid of some boilerplate for reading from the disc (+ extra error checks). Change 32bit values to 64bit where it looks like it's necessary, and use bools in place of a couple of 0/1 ints. Reject any discs which are too big for the 32bit fields in the ADFS disc record.
      c/OpsFunc - Update DOSFS_image_open in ways similar to the code in c/DOSFS, making use of READ_, image accessor, 64bit values, and adding extra error checks.
    Admin:
      Tested with assorted large & small image files & SD cards on a BB-xM, and some DOS/Atari floppy discs on a RiscPC
      FAT partitions larger than 4GB (or which extend past the 4GB FileSwitch limit) are now rejected, as are image files which have been truncated
      A future improvement could be to lift the disc/partition identification code out of c/DOSFS and c/OpsFunc and unify it, since both files contain fairly similar code
      German messages are in need of translation
    
    
    Version 1.12. Tagged as 'DOSFS-1_12'
    eb3e3485
  • Jeffrey Lee's avatar
    Remove redundant NULL pointer check · 9f6e8ade
    Jeffrey Lee authored
    Detail:
      c/DOSdirs - Now that nbuff is an array held on the stack, there's no need for findSUBDIR to check whether it's a null pointer
    Admin:
      Builds, untested
      Issue spotted by Dominic Plunkett
    
    
    Version 1.13. Tagged as 'DOSFS-1_13'
    9f6e8ade
......@@ -18,7 +18,7 @@
COMPONENT = DOSFS
OBJS = DOSFS DOSFSctl DOSclusters DOSdirs DOSnaming Helpers MsgTrans \
OpsArgs OpsFind OpsFunc OpsFile OpsGetPut \
Statics TIMEconv StaticDefs
Statics TIMEconv StaticDefs Accessors
ROM_OBJS = ${OBJS} init
ROMCDEFINES = -DROM
RES_AREA = dosfs_msgarea
......@@ -32,8 +32,7 @@ LIBS = ${ASMUTILS}
include CModule
DBG_LIBS += ${NET5LIBS}
ASFLAGS += -pd "PCMCIATRUE SETL {${PCMCIA}}"
CFLAGS += -DPCMCIA${PCMCIA}
CFLAGS += -DNONFLOPPIES
CDFLAGS += -DDEBUGLIB
# Dynamic dependencies:
No preview for this file type
/* (1.08)
/* (1.13)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 1.08
#define Module_MajorVersion_CMHG 1.13
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 02 Nov 2014
#define Module_Date_CMHG 19 Feb 2018
#define Module_MajorVersion "1.08"
#define Module_Version 108
#define Module_MajorVersion "1.13"
#define Module_Version 113
#define Module_MinorVersion ""
#define Module_Date "02 Nov 2014"
#define Module_Date "19 Feb 2018"
#define Module_ApplicationDate "02-Nov-14"
#define Module_ApplicationDate "19-Feb-18"
#define Module_ComponentName "DOSFS"
#define Module_ComponentPath "castle/RiscOS/Sources/FileSys/ImageFS/DOSFS"
#define Module_FullVersion "1.08"
#define Module_HelpVersion "1.08 (02 Nov 2014)"
#define Module_LibraryVersionInfo "1:8"
#define Module_FullVersion "1.13"
#define Module_HelpVersion "1.13 (19 Feb 2018)"
#define Module_LibraryVersionInfo "1:13"
/* Copyright 2018 Castle Technology Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Accessors.h"
#include "MsgTrans.h"
#include "Interface/HighFSI.h"
#include "swis.h"
#include "DebugLib/DebugLib.h"
static _kernel_oserror *readwrite_file(uint64_t addr,uint32_t len,void *buf,int flags,struct image_accessor *ctx)
{
image_accessor_file *a = (image_accessor_file *) ctx;
uint64_t end = addr + len;
if (end > (uint64_t) a->size)
{
return global_error(err_outofrange);
}
return _swix(OS_GBPB,_INR(0,4),((flags & ACC_WRITE)?OSGBPB_WriteAtGiven:OSGBPB_ReadFromGiven),a->fshand,buf,len,(uint32_t)addr);
}
image_accessor_file new_image_accessor_file(int fshand)
{
image_accessor_file a;
a.a.readwrite = readwrite_file;
a.fshand = fshand;
a.size = 0; /* Treat as 0 bytes if error from SWI below */
_kernel_oserror *e = _swix(OS_Args,_INR(0,1)|_OUT(2),OSArgs_ReadEXT,fshand,&a.size);
if (e)
{
dprintf(("","extent error: %08x %s\n",e->errnum,e->errmess));
}
else
{
dprintf(("","image extent: %x\n",a.size));
}
return a;
}
static _kernel_oserror *readwrite_disc(uint64_t addr,uint32_t len,void *buf,int flags,struct image_accessor *ctx)
{
image_accessor_disc *a = (image_accessor_disc *) ctx;
_kernel_swi_regs urset;
FS_discop64 opblock;
urset.r[3] = (int) buf;
urset.r[4] = len;
urset.r[6] = a->sector_cache_handle;
urset.r[8] = a->filecore_pw;
int op = (flags & ACC_WRITE) ? 2 : ((flags & ACC_USE_CACHE) ? 9 : 1);
op |= (4 << 4); /* Ignore escape */
if (discopswi==FileCore_DiscOp)
{
uint64_t end = addr + len;
if (end > 512<<20)
{
return global_error(err_outofrange);
}
urset.r[1] = (op | (((int)(a->dr) >> 2) << 8)) ;
urset.r[2] = (a->dr->dr_rootSIN & 0xE0000000) + ((int)addr); /* disc address */
}
else
{
opblock.drivenumber = (a->dr->dr_rootSIN & 0xE0000000) >> 29;
opblock.byteaddresslo = (word) addr;
opblock.byteaddresshi = (word) (addr >> 32);
urset.r[1] = op;
urset.r[2] = (int)&opblock;
urset.r[5] = (int)a->dr;
}
_kernel_oserror *e = _kernel_swi(discopswi,&urset,&urset);
/* Update cache handle */
a->sector_cache_handle = urset.r[6];
return e;
}
image_accessor_disc new_image_accessor_disc(ADFS_drecord *dr,int sector_cache_handle,int filecore_pw)
{
image_accessor_disc a;
a.a.readwrite = readwrite_disc;
a.dr = dr;
a.sector_cache_handle = sector_cache_handle;
a.filecore_pw = filecore_pw;
return a;
}
This diff is collapsed.
......@@ -957,12 +957,11 @@ int findCLUSTER(int offCLUSTER,char *namebuff,int blen,DOSdisc *ihand)
*/
word max_sector(DOS_bootsector *bb)
{
word max_sect = (bb->BOOT_max_sectHI << 8) | (bb->BOOT_max_sect);
word max_sect = READ_LOHI(bb->BOOT_max_sect);
if (max_sect == 0)
{
max_sect = (bb->big_sect3 << 24) | (bb->big_sect2 << 16) |
(bb->big_sect1 << 8) | bb->big_sect;
max_sect = READ_0123(bb->big_sect);
}
dprintf(("","max_sector: boot block at &%08X, max_sect = %d\n",(int)bb,max_sect));
......
......@@ -523,16 +523,10 @@ static DOS_direntry *findSUBDIR(char *wcname,DIR_info *cdir,int dir_size,int *in
{
DOS_direntry *dentry = NULL ;
DOS_direntry *dir = (DOS_direntry*)DI_Base(cdir);;
char *nbuff = malloc(DOSnamesize) ;
char *cfile;
char nbuff[DOSnamesize];
char *cfile = NULL;
int oldindex;
if (nbuff == NULL)
{
*index = -1 ;
return(NULL) ;
}
do
{
oldindex=*index;
......@@ -546,8 +540,6 @@ static DOS_direntry *findSUBDIR(char *wcname,DIR_info *cdir,int dir_size,int *in
if (dentry)
strcpy(wcname, cfile);
free(nbuff) ;
/* will either be NULL (index set to -1), or a valid directory entry */
return(dentry) ;
}
......
......@@ -555,6 +555,8 @@ int DOSFS_create_dir(char *fname, word ld, word ex, word size, DOSdisc *ihand)
dprintf(("","DOSFS_create_dir: numreq = %d\n",numreq));
if (get_dir_entry_array(lfn, ihand, numreq, &cdir, &pdir,NULL) < 0)
{
free(DOSname);
free(memaddr);
return -1;
}
......@@ -592,6 +594,8 @@ int DOSFS_create_dir(char *fname, word ld, word ex, word size, DOSdisc *ihand)
longfileholder = (char *)malloc(strlen(leafname) + 1);
if (longfileholder == NULL)
{
free(DOSname);
free(memaddr);
return_errorT(int, err_heapexhausted, tok_heapexhausted, 0, 0);
}
strcpy(longfileholder, leafname);
......
......@@ -21,6 +21,7 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include "kernel.h"
#include "swis.h"
#include "Interface/HighFSI.h"
......@@ -36,6 +37,7 @@
#include "DOSnaming.h"
#include "DOSshape.h"
#include "DOSdirs.h"
#include "Accessors.h"
/*!
* \param oldname NULL terminated ASCII pathname, relative to ROOT of image
......@@ -155,6 +157,7 @@ int DOSFS_rename(char *oldname,char *newname,DOSdisc *ihand)
if (get_dir_entry_array(lfn, ihand, numreq, &ndir, &dummy, &found) < 0)
{
free(DOSname) ;
return -1;
}
......@@ -188,6 +191,7 @@ int DOSFS_rename(char *oldname,char *newname,DOSdisc *ihand)
longfileholder = malloc(strlen(leafname) + 1);
if (longfileholder == NULL)
{
free(DOSname) ;
return_errorT(int, err_heapexhausted, tok_heapexhausted, 0, 0);
}
strcpy(longfileholder, leafname);
......@@ -267,10 +271,8 @@ FS_dir_block *DOSFS_read_dir_info(char *fname, void *dest, word num, word off, w
DOSdisc *DOSFS_image_open(word fshand, word buffsize)
{
DOS_bootsector *dboot = NULL ; /* cached disc boot block */
DOS_partition *DOSpart = NULL ; /* winchester partition information */
byte *pentry ; /* wini partition description pointer */
word winioffset = 0 ; /* partition start within wini images */
word winisize = 0 ; /* winchester media size */
uint64_t winioffset = 0 ; /* partition start within wini images */
DOSdisc *ddisc = NULL ; /* cached disc description */
byte numFATs ; /* number of FATs in the image */
word FATsize ; /* size of FAT in bytes */
......@@ -278,15 +280,16 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
word numRESVD ; /* number of reserved (unused) sectors */
word ROOTsize ; /* size of ROOT directory in sectors */
int loop ; /* general counter */
word discaddress = 0x00000000 ;
uint64_t discaddress = 0x00000000 ;
int totsec = 0, datasec = 0; /* Split of sectors */
int CountOfClusters = 0; /* Expressed as clusters */
int RootDirSectors;
_kernel_swi_regs reglist ; /* for SWI calls */
_kernel_oserror *rerror ; /* for standard RISC OS error structures */
#ifdef NO_FAT32
static const _kernel_oserror noFAT32support = { 0, "FAT32 support absent"};
#endif
image_accessor_file a = new_image_accessor_file(fshand);
word partsize = a.size/DOSsecsize; /* partition size (sectors) */
dprintf(("","\n\nDOSFS_image_open: fshand = &%08X, buffsize = &%08X\n",fshand,buffsize));
/* We can assume that FileSwitch has only called us with files of the correct
......@@ -323,26 +326,24 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
/* read the BOOT BLOCK from the image */
/* This code RELIES on (DOS_BOOT_sector == DOS_PARTITION_sector) */
discaddress = (DOS_BOOT_sector - 1) * DOSsecsize ;
reglist.r[0] = OSGBPB_ReadFromGiven ; /* read operation */
reglist.r[1] = fshand ; /* FileSwitch handle */
reglist.r[2] = (word)dboot ; /* destination address */
reglist.r[3] = DOSsecsize ; /* fixed in MS-DOS */
reglist.r[4] = discaddress ; /* offset within FileSwitch file */
reglist.r[5] = NULL ;
reglist.r[6] = NULL ;
if ((rerror = _kernel_swi(OS_GBPB,&reglist,&reglist)) != NULL)
if ((rerror = image_readwrite(discaddress, /* offset within FileSwitch file */
DOSsecsize, /* fixed in MS-DOS */
dboot, /* destination address */
ACC_READ, /* read operation */
&a.a)) != NULL)
{
free(dboot) ;
return_errorX(DOSdisc *, rerror) ; /* error already defined */
}
/* If this doesn't look like a BOOT block then try a partition. */
#ifdef PCMCIATRUE
#ifdef NONFLOPPIES
if (sector_size(dboot) != DOSsecsize)
#else
if (sector_size(dboot) != DOSsecsize || dboot->BOOT_num_fats != 2)
#endif
{
DOS_partition *DOSpart = NULL ; /* winchester partition information */
dprintf(("","DOSFS_image_open: not a BOOT block, could be a partition.\n"));
DOSpart = (DOS_partition *)dboot ;
......@@ -384,30 +385,20 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
* construct the "disc_winioffset" variable.
* DOS BOOT sector = WiniSector(pentry[3],pentry[1],pentry[2])
*/
winioffset = ((pentry[8] | (pentry[9] << 8) | (pentry[10] << 16) | (pentry[11] << 24)) * DOSsecsize) ;
dprintf(("","DOSFS_image_open: winioffset = &%08X\n",winioffset));
winioffset = ((uint64_t)loadWORD(pentry+8) * DOSsecsize);
dprintf(("","DOSFS_image_open: winioffset = &%016" PRIX64 "\n",winioffset));
/* Our system can now cope with winchester partitions with more than 0xFFFF
* sectors
*/
winisize = (pentry[12] | (pentry[13] << 8) | (pentry[14] << 16) | (pentry[15] << 24)) ;
/* We could add the following check: (winisize <= "size of FileSwitch file")
* to further check the validity of the partition information. If the
* calculated offset is outside the image file then the following BOOT
* BLOCK load will fail and give the user a "funny" error message, rather
* than a specific DOSFS one.
*/
partsize = loadWORD(pentry+12);
discaddress = ((DOS_BOOT_sector - 1) * DOSsecsize) + winioffset ;
reglist.r[0] = OSGBPB_ReadFromGiven ;
reglist.r[1] = fshand ;
reglist.r[2] = (word)dboot ;
reglist.r[3] = DOSsecsize ;
reglist.r[4] = discaddress ;
reglist.r[5] = NULL ;
reglist.r[6] = NULL ;
if ((rerror = _kernel_swi(OS_GBPB,&reglist,&reglist)) != NULL)
if ((rerror = image_readwrite(discaddress,
DOSsecsize,
dboot,
ACC_READ,
&a.a)) != NULL)
{
free(dboot) ;
return_errorX(DOSdisc *, rerror) ;
......@@ -419,11 +410,10 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
* BLOCK. **** research into this ****
*/
#ifdef PCMCIATRUE
/*if ((sector_size(dboot) != DOSsecsize) || (max_sector(dboot) != winisize))*/
#ifdef NONFLOPPIES
if (sector_size(dboot) != DOSsecsize)
#else
if ((sector_size(dboot) != DOSsecsize) || (dboot->BOOT_num_fats != 2) || (max_sector(dboot) != winisize))
if ((sector_size(dboot) != DOSsecsize) || (dboot->BOOT_num_fats != 2) || (max_sector(dboot) != partsize))
#endif
{
dprintf(("","DOSFS_image_open: invalid partition BOOT block\n"));
......@@ -446,8 +436,9 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
dboot->BOOT_FAT_sizeHI = 0x00;
dboot->BOOT_secstrack = 0x08;
dboot->BOOT_secstrackHI = 0x00;
dboot->hidden = 0x00;
dboot->hidden0 = 0x00;
dboot->hidden1 = 0x00;
partsize = a.size/DOSsecsize;
}
}
......@@ -455,40 +446,39 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
numFATs = dboot->BOOT_num_fats ;
/* number of reserved (unusable) sectors */
numRESVD = (dboot->BOOT_reserved | (dboot->BOOT_reservedHI << 8)) ;
numRESVD = READ_LOHI(dboot->BOOT_reserved);
dprintf(("","DOSFS_image_open: DOSsecsize = %x\n",DOSsecsize));
dprintf(("","DOSFS_image_open: numFATs = %d\n",numFATs));
dprintf(("","DOSFS_image_open: numRESVD = %d\n",numRESVD));
dprintf(("","DOSFS_image_open: sectors per cluster = %x\n",dboot->BOOT_secalloc));
dprintf(("","DOSFS_image_open: sector size = %d\n",((dboot->BOOT_secsize)|(dboot->BOOT_secsizeHI<<8))));
dprintf(("","DOSFS_image_open: cluster size = %d\n",dboot->BOOT_secalloc * ((dboot->BOOT_secsize)|(dboot->BOOT_secsizeHI<<8))));
dprintf(("","DOSFS_image_open: sector size = %d\n",READ_LOHI(dboot->BOOT_secsize)));
dprintf(("","DOSFS_image_open: cluster size = %d\n",dboot->BOOT_secalloc * READ_LOHI(dboot->BOOT_secsize)));
RootDirSectors = (dboot->BOOT_root_dir | (dboot->BOOT_root_dirHI << 8)) * sizeof(DOS_direntry); /* Bytes */
RootDirSectors = READ_LOHI(dboot->BOOT_root_dir) * sizeof(DOS_direntry); /* Bytes */
RootDirSectors = (RootDirSectors + (DOSsecsize - 1)) / DOSsecsize; /* Sectors */
dprintf(("","DOSFS_image_open: RootDirSectors = %d\n",RootDirSectors));
if ((dboot->BOOT_FAT_size | (dboot->BOOT_FAT_sizeHI<<8)) != 0)
if (READ_LOHI(dboot->BOOT_FAT_size) != 0)
{
FATsize = (dboot->BOOT_FAT_size|(dboot->BOOT_FAT_sizeHI<<8));
FATsize = READ_LOHI(dboot->BOOT_FAT_size);
}
else
{
/* It's FAT32 */
FATsize = (dboot->BOOT_extra.fat32.FAT_sz0 | (dboot->BOOT_extra.fat32.FAT_sz1<<8) |
(dboot->BOOT_extra.fat32.FAT_sz2<<16) | (dboot->BOOT_extra.fat32.FAT_sz3<<24));
FATsize = READ_0123(dboot->BOOT_extra.fat32.FAT_sz);
}
if( (dboot->BOOT_max_sect | (dboot->BOOT_max_sectHI<<8)) != 0)
if( READ_LOHI(dboot->BOOT_max_sect) != 0)
{
/* Limited 16 bit size */
totsec = dboot->BOOT_max_sect | (dboot->BOOT_max_sectHI<<8);
totsec = READ_LOHI(dboot->BOOT_max_sect);
}
else
{
totsec = dboot->big_sect | (dboot->big_sect1<<8) | (dboot->big_sect2<<16) | (dboot->big_sect3<<24);
totsec = READ_0123(dboot->big_sect);
}
datasec = totsec - ((dboot->BOOT_reserved | (dboot->BOOT_reservedHI<<8)) + (numFATs * FATsize) + RootDirSectors);
datasec = totsec - (READ_LOHI(dboot->BOOT_reserved) + (numFATs * FATsize) + RootDirSectors);
dprintf(("","DOSFS_image_open: FATsize = %x\n",FATsize));
dprintf(("","DOSFS_image_open: totsec = %x\n",totsec));
/* In the case where it's a 320K/160K floppy, we won't know secalloc until we
......@@ -498,6 +488,27 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
CountOfClusters = dboot->BOOT_secalloc > 0 ? datasec / dboot->BOOT_secalloc : datasec;
dprintf(("","DOSFS_image_open: CountOfClusters = %x\n",CountOfClusters));
/* Sanity check some values */
if (winioffset + (((uint64_t) totsec) * DOSsecsize) > a.size)
{
dprintf(("","DOSFS_image_open: filesystem exceeds extent of image file\n"));
free(dboot);
return_error0(DOSdisc *, err_notDOSimage);
}
if (totsec > partsize)
{
dprintf(("","DOSFS_image_open: filesystem larger than partition\n"));
free(dboot);
return_error0(DOSdisc *, err_notDOSimage);
}
if ((FATsize > ((1<<30) / DOSsecsize)) /* Arbitrary 1GB max FAT size (to avoid overflow in malloc calculation below) */
|| (winioffset > UINT32_MAX)) /* We use 32bit winioffset */
{
dprintf(("","DOSFS_image_open: disc too big\n"));
free(dboot) ;
return_error0(DOSdisc *, err_disctoobig) ;
}
/* allocate a DOS disc description structure large enough to hold a FAT
* copy. Note: the disc description structure already includes a single "FAT"
* sector.
......@@ -549,19 +560,18 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
if (ddisc->disc_FATentry == 32)
{
ddisc->disc_RootCluster = (dboot->BOOT_extra.fat32.RootClus0 | (dboot->BOOT_extra.fat32.RootClus1<<8) |
(dboot->BOOT_extra.fat32.RootClus2<<16) | (dboot->BOOT_extra.fat32.RootClus3<<24));
ddisc->disc_RootCluster = READ_0123(dboot->BOOT_extra.fat32.RootClus);
}
else
{
ddisc->disc_RootCluster = 0;
}
dprintf(("","DOSFS_image_open: No. of root entries = %x F32 cl:%x\n",
(dboot->BOOT_root_dir | (dboot->BOOT_root_dirHI << 8)),ddisc->disc_RootCluster));
READ_LOHI(dboot->BOOT_root_dir),ddisc->disc_RootCluster));
/* remember the FileSwitch handle */
ddisc->disc_fhand = fshand ; /* FileSwitch handle of image file */
ddisc->disc_winioffset = winioffset ; /* offset into image */
ddisc->disc_winioffset = (word) winioffset ; /* offset into image */
ddisc->disc_FATsecs = FATsize ; /* remember how many sectors the FAT is */
ddisc->disc_FATsize = FATsize * DOSsecsize;/* remember how big the FAT is */
......@@ -625,7 +635,7 @@ DOSdisc *DOSFS_image_open(word fshand, word buffsize)
}
/* size of the ROOT directory in sectors */
ROOTsize = (((dboot->BOOT_root_dir | (dboot->BOOT_root_dirHI << 8)) * sizeof(DOS_direntry))+(DOSsecsize-1)) / DOSsecsize ;
ROOTsize = ((READ_LOHI(dboot->BOOT_root_dir) * sizeof(DOS_direntry))+(DOSsecsize-1)) / DOSsecsize ;
ddisc->disc_ROOTsize = ROOTsize ; /* in sectors */
dprintf(("","DOSFS_image_open: ROOTsize = &%08X\n",ROOTsize));
......@@ -992,16 +1002,13 @@ int DOSFS_namedisc(char *newname,DOSdisc *ihand)
}
/* zero the directory entry before placing our information */
for (index = 0; (index < sizeof(DOS_direntry)); index++)
{
((char *)dentry)[index] = '\0' ;
}
memset(dentry, 0, sizeof(DOS_direntry));
/* write the given discname into the "dentry" */
namebuff = (char *)&(dentry->FILE_status) ;
/* copy upto the first space or NULL character */
for (index = 0; (index < (namsize + extsize)); index++)
{
/* copy upto the first space or NULL character */
if (*newname && (*newname != ' '))
{
*namebuff++ = *newname++ ;
......
......@@ -307,7 +307,10 @@ char *MSDOStoSTRING(word MSDOStime,word MSDOSdate)
reglist.r[1] = (word)buffer ;
reglist.r[2] = (MaxString - 1) ;
if ((rerror = _kernel_swi(OS_ConvertStandardDateAndTime,&reglist,&reglist)) != NULL)
{
free(buffer) ;
return(NULL) ;
}
return(buffer) ;
}
......
......@@ -131,8 +131,8 @@ typedef struct {
(drec)->dr_tracklow |= ((v) << 6) ; \
}
#define put_doublestep(drec,v) { \
(drec)->dr_tracklow &= ~0x80 ; \
(drec)->dr_tracklow |= ((v) << 7) ; \
if (v) (drec)->dr_tracklow |= 0x80 ; \
else (drec)->dr_tracklow &= ~0x80 ; \
}
/* construct the disc ID field */
......
/* Copyright 2018 Castle Technology Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ACCESSORS_H
#define ACCESSORS_H
#include <stdint.h>
#include <stdbool.h>
#include "kernel.h"
#include "DOSFS.h"
#include "ADFSshape.h"
/* Flags */
#define ACC_READ 0
#define ACC_WRITE 1
#define ACC_USE_CACHE 2
/* Struct used to abstract over accessing the underlying file */
typedef struct image_accessor {
/* Function pointer for reading/writing data from the underlying file */
_kernel_oserror *(*readwrite)(uint64_t addr,uint32_t len,void *buf,int flags,struct image_accessor *ctx);
} image_accessor_t;
#define image_readwrite(addr,len,buf,flags,ctx) (((ctx)->readwrite)(addr,len,buf,flags,ctx))
typedef struct {
image_accessor_t a;
int fshand;
uint32_t size;
} image_accessor_file;
extern image_accessor_file new_image_accessor_file(int fshand);
typedef struct {
image_accessor_t a;
ADFS_drecord *dr;
int sector_cache_handle;
int filecore_pw;
} image_accessor_disc;
extern image_accessor_disc new_image_accessor_disc(ADFS_drecord *dr,int sector_cache_handle,int filecore_pw);
#endif
......@@ -258,11 +258,11 @@ typedef struct {
byte BOOT_secstrackHI ;
byte BOOT_heads ; /* number of heads */
byte BOOT_headsHI ;
byte hidden ; /* number of hidden sectors */
byte hidden0 ; /* number of hidden sectors */
byte hidden1 ;
byte hidden2 ;
byte hidden3 ;
byte big_sect ; /* number of sectors for >32Mb partitions */
byte big_sect0 ; /* number of sectors for >32Mb partitions */
byte big_sect1 ;
byte big_sect2 ;
byte big_sect3 ;
......@@ -271,7 +271,7 @@ typedef struct {
byte driveno ; /* drive number */
byte unused ;
byte sig_rec ; /* extended boot record signature (0x29) */
byte volid ; /* 32 bit volume id */
byte volid0 ; /* 32 bit volume id */
byte volid1 ;
byte volid2 ;
byte volid3 ;
......
......@@ -20,9 +20,13 @@
#ifndef __h_Helpers
#define __h_Helpers
/* Macros for less painful reading of 16/32bit values that have been split into individual bytes */
#define READ_LOHI(VAR) ((word) (VAR | (VAR##HI << 8)))
#define READ_0123(VAR) ((word) (VAR##0 | (VAR##1 << 8) | (VAR##2 << 16) | (VAR##3 << 24)))
/* Unaligned word access */
extern void writeWORD(char *address,word datavalue) ;
extern word loadWORD(char *address) ;
extern void writeWORD(void *address,word datavalue) ;
extern word loadWORD(const void *address) ;
/* These are only exported to provide function addresses */
extern void DOSFS_Open(void);
......
......@@ -58,6 +58,8 @@
#define err_badswi (0x13) /* Uses Global message "BadSWI" */
#define err_buftoosmall (0x14) /* Uses Global message "BufOFlo" */
#define err_nostack (0x15) /* In assembler stubs */
#define err_disctoobig (0x16)
#define err_outofrange (0x17)
/* The following have been matched with FileCore error messages. */
#define err_notsupported (0xA5) /* In assembler stubs */
......
......@@ -104,12 +104,6 @@ func_DOS_formatinfo
DCD DOSsecsize, 50, 50, 84
DCB 9, Ddensity, SStepSSided, 1, 0, 0, 0, &4E
DCD 80, 0, 0, 0, 0, 0, 0, 0, 0, 0
[ PCMCIATRUE
; PCMCIA (Fixed Disk) variable numtrks, 8sec/trk: USUALLY ONLY AVAILABLE VIA PCCARDFS *CARDFORMAT
DCD DOSsecsize, 50, 50, 84
DCB 8, 0, 0, 0, 0, 0, 0, 0
DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
; Terminator
DCD 0, 0, 0, 0
DCB 0, 0, 0, 0, 0, 0, 0, 0
......@@ -140,9 +134,6 @@ Format5 DCB "DOS/T",0
Format6 DCB "DOS/U",0
Format7 DCB "Atari/M",0
Format8 DCB "Atari/N",0
[ PCMCIATRUE
Format9 DCB "PCMCIA",0
]
ALIGN
EXPORT func_DOS_formats
......@@ -182,11 +173,6 @@ func_DOS_formats
DCD Format8
DCB 7, 1, &F8, 2, 5, 112
ALIGN
;
[ PCMCIATRUE
DCD Format9
DCB 8, 0, &F8, 1, 1, 208 ; Last-but-1 value is just spacefiller
]
; Terminator
DCD 0
DCB 0, 0, 0, 0, 0, 0
......