home *** CD-ROM | disk | FTP | other *** search
-
- /********************************************************************
- **
- ** Rigids v1.0 beta © 1997 by Tadek Knapik. Freeware.
- ** Send comments, bug reports etc to
- ** <tadek@malenstwo.iinf.polsl.gliwice.pl>
- **
- ** This piece of code is probably something I sould be ashame of.
- ** But it's my first "platform" C program, first disk access, first
- ** job I had deadline on (let's say so:) and... still I decided to
- ** show it. Comments appreciated, but please don't hurt me :)
- **
- ********************************************************************/
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
-
- #include <dos/dos.h>
- #include <exec/io.h>
- #include <exec/memory.h>
- #include <devices/hardblocks.h>
- #include <devices/scsidisk.h>
- #include <devices/trackdisk.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
-
- /*
- #define DEBUG
- */
-
- #define IDNAME_OLDRIGID 0xD2CFCCC4 /* 'ROLD' */
- #define BYTESONBLOCK 512
-
- struct RigidDiskBlock *memrdb = NULL;
- struct FileInfoBlock *fib = NULL;
- struct RDArgs *rdargs = NULL; /* for ReadArgs() */
- struct MsgPort *ioport = NULL;
- struct IOExtTD *ioreq = NULL;
- long *buffer = NULL;
- long *memdata = NULL;
- long *iodata = NULL;
- long theunit = NULL;
- long theoffset = NULL;
- long rdbstart = NULL;
- long rdbsize = NULL;
- long rdbshift = NULL;
- long rdbblock = NULL;
- long current = NULL;
- int scsiok = NULL;
- int writeok = NULL;
- int rdbok = NULL;
-
- long BytesPerBlock = BYTESONBLOCK; /* fixed as for now, but... */
-
- char DevName[80] = "scsi.device";
-
- char argstring[] = "D=DEVICE/K,U=UNIT/K/N,O=OFFSET/K/N,RDB=RDBONLY/S,WRITE/S,FORCE/S,F=FILE/A";
- char verstring[] = "$VER: Rigids v1.0b (14.12.97) © 1997 by Tadek Knapik.";
-
- enum {DEVNAME = 0, DEVUNIT, NOFFSET, RDBONLY, DEVWRITE, RDBFORCE, FILENAME};
- long argarray[] = {0, 0, 0, 0, 0, 0, 0};
-
- void ParseBBB(struct BadBlockBlock *BBB);
- void ParsePB(struct PartitionBlock *PB);
- void ParseFHB(struct FileSysHeaderBlock *FHB);
- void ParseLSB(struct LoadSegBlock *LSB);
- long CountChkSum(ULONG *data, ULONG nr);
- int ChkRDBSum(struct RigidDiskBlock *RDB);
- int ChkBBBSum(struct BadBlockBlock *BBB);
- int ChkPBSum(struct PartitionBlock *PB);
- int ChkFHBSum(struct FileSysHeaderBlock *FHB);
- int ChkLSBSum(struct LoadSegBlock *LSB);
-
- void OpenDev(void);
- void CloseAll(void);
- int scandev(long block, long *rdbfound);
- int SumOK(ULONG *p);
-
- void main(int argc, char **argv)
- {
-
- BPTR thefile; /* file pointer */
-
- if(!(rdargs=ReadArgs(argstring, argarray, NULL)))
- {
- printf(" %s\n", &verstring[6]);
- return;
- }
-
- if (argarray[DEVNAME])
- strcpy(DevName, (STRPTR) argarray[DEVNAME]);
-
- if (argarray[DEVUNIT])
- theunit = * (ULONG *) argarray[DEVUNIT];
-
- if (argarray[NOFFSET])
- theoffset = * (ULONG *) argarray[NOFFSET];
-
- if ((theoffset >= 0) && (theoffset < RDB_LOCATION_LIMIT))
- {
-
- #ifdef DEBUG
- printf("* Device: %s\n", DevName);
- printf("* Unit: %ld\n", theunit);
- printf("* Offset: %ld\n", theoffset);
- printf("* RDBOnly: %s\n", argarray[RDBONLY]? "Yes": "No");
- printf("* Mode: %s\n", argarray[DEVWRITE]? "Write": "Read");
- printf("* Force: %s\n", argarray[RDBFORCE]? "Yes": "No");
- printf("* File: %s\n", argarray[FILENAME]);
- printf("\n");
- #endif
-
- OpenDev();
-
- #ifdef DEBUG
- printf("* %s unit %ld %s\n", DevName, theunit, scsiok? "opened": "not opened");
- #endif
-
- if(scsiok)
- {
- if((buffer=malloc(BytesPerBlock))) /* buffer to read blocks into */
- {
- if(argarray[DEVWRITE]) /* write */
- {
- if(thefile=Open((STRPTR) argarray[FILENAME], MODE_OLDFILE))
- {
- if(fib=malloc(sizeof(struct FileInfoBlock)))
- {
- if(ExamineFH(thefile, fib))
- {
- if(memdata=malloc(fib->fib_Size))
- {
- if((fib->fib_Size) && !((fib->fib_Size)%BytesPerBlock))
- {
- if(FRead(thefile, (STRPTR) memdata, (ULONG) fib->fib_Size, (ULONG) 1))
- {
- current = 0;
- memrdb = (struct RigidDiskBlock *) memdata;
-
- while((current < (fib->fib_Size)/BytesPerBlock) && (current < RDB_LOCATION_LIMIT))
- {
- if(memrdb->rdb_ID==IDNAME_RIGIDDISK)
- break;
-
- /* to the next "block" */
-
- memrdb += BytesPerBlock/sizeof(struct RigidDiskBlock);
- ++current;
- }
-
- if(memrdb->rdb_ID==IDNAME_RIGIDDISK)
- {
- #ifdef DEBUG
- printf("* RDB found in the file on \"block\" %ld.\n", current);
- #endif
-
- /* to know when the user has specified offset 0, and when he/she did not */
-
- if(!argarray[NOFFSET])
- theoffset = -1;
-
- if(argarray[RDBONLY] || (theoffset!=-1))
- {
- argarray[RDBONLY] = TRUE;
- iodata = (long *) memrdb;
- rdbsize = (fib->fib_Size)-(current*BytesPerBlock);
- }
- else
- {
- iodata = memdata;
- rdbsize = (fib->fib_Size);
- }
-
- /* data write start is counted from HighRDSKBlock and RDB size, not in-file position */
- /* rdbstart and rdbsize are start and size of all data, not RDB structure only! */
-
- if((rdbstart=(memrdb->rdb_HighRDSKBlock)-(rdbsize/BytesPerBlock)+1) < 0)
- rdbstart = 0;
-
- /* real starting block of RDB, needed for checksum checking */
- /* when OFFSET specified, fixed later */
-
- rdbblock = ((UBYTE *)memrdb-(UBYTE*)memdata)/BytesPerBlock;
-
- /* RDB shifting and checksumming all lists */
-
- if(theoffset!=-1)
- {
-
- rdbshift = rdbstart-theoffset;
- #ifdef DEBUG
- printf("* Shift value is %ld\n", rdbshift);
- #endif
-
- if(memrdb->rdb_SummedLongs <= 555)
- {
- #ifdef DEBUG
- printf("%ld longs to checksum in RDB.\n", memrdb->rdb_SummedLongs);
- #endif
-
- if(memrdb->rdb_BadBlockList != -1)
- {
- ParseBBB((struct BadBlockBlock *) &((UBYTE *)memrdb)[((memrdb->rdb_BadBlockList)-rdbstart)*BytesPerBlock]);
- memrdb->rdb_BadBlockList -= rdbshift;
- }
-
- if(memrdb->rdb_PartitionList != -1)
- {
- ParsePB((struct PartitionBlock *) &((UBYTE *)memrdb)[((memrdb->rdb_PartitionList)-rdbstart)*BytesPerBlock]);
- memrdb->rdb_PartitionList -= rdbshift;
- }
-
- if(memrdb->rdb_FileSysHeaderList != -1)
- {
- ParseFHB((struct FileSysHeaderBlock *) &((UBYTE *) memrdb)[((memrdb->rdb_FileSysHeaderList)-rdbstart)*BytesPerBlock]);
- memrdb->rdb_FileSysHeaderList -= rdbshift;
- }
-
- if(memrdb->rdb_DriveInit != -1)
- {
- memrdb->rdb_DriveInit -= rdbshift;
- }
-
- memrdb->rdb_HighRDSKBlock -= rdbshift;
-
- memrdb->rdb_ChkSum = 0;
- memrdb->rdb_ChkSum = CountChkSum((ULONG *) memrdb, (ULONG) memrdb->rdb_SummedLongs);
-
- rdbstart = theoffset;
- rdbblock = theoffset;
-
- }
- else
- printf("Can't calculate checksum.\n");
-
- }
-
- #ifdef DEBUG
- printf("* Checksum is %s.\n", SumOK((ULONG *) memrdb)? "OK": "wrong");
- printf("* Writing RDB at block %ld, size %ld\n", rdbstart, rdbsize);
- #endif
-
- if((ChkRDBSum(memrdb)) || argarray[RDBFORCE])
- {
-
- current=0;
- while((scandev(current, &theoffset)) && (theoffset<rdbstart))
- {
- #ifdef DEBUG
- printf("* Replacing old 'RDSK' with 'ROLD' at block %ld\n", theoffset);
- #endif
-
- buffer[0] = IDNAME_OLDRIGID;
- ioreq->iotd_Req.io_Command = CMD_WRITE;
- ioreq->iotd_Req.io_Flags = 0;
- ioreq->iotd_Req.io_Data = buffer;
- ioreq->iotd_Req.io_Length = BytesPerBlock;
- ioreq->iotd_Req.io_Offset = theoffset * BytesPerBlock;
- DoIO((struct IORequest *) ioreq);
- current = theoffset+1;
- }
-
- ioreq->iotd_Req.io_Command = CMD_WRITE;
- ioreq->iotd_Req.io_Flags = 0;
- ioreq->iotd_Req.io_Data = iodata;
- ioreq->iotd_Req.io_Length = rdbsize;
- ioreq->iotd_Req.io_Offset = rdbstart * BytesPerBlock;
-
-
- if(!rdbok)
- printf("Checksum is corrupt. Forcing write...\n");
-
- if(!DoIO((struct IORequest *) ioreq))
- printf("%ld bytes%s written at block %ld\n", rdbsize, argarray[RDBONLY]? " (RDB only)": "", rdbstart);
- else
- printf("Device error. File not written.\n");
- }
- else
- printf("Checksum is corrupt. RDB not written (you can use FORCE switch though).\n");
-
- }
- else
- printf("RDB not found in file %s\n", (STRPTR) argarray[FILENAME]);
-
- }
- else
- printf("Error reading from file %s\n", (STRPTR) argarray[FILENAME]);
-
- }
- else
- printf("Error: size of %s is not a multipler of BytesPerBlock.\n", (STRPTR) argarray[FILENAME]);
-
- free(memdata);
-
- }
- else
- printf("Not enough memory.\n");
-
- }
- else
- printf("Can't get file size.\n");
-
- free(fib);
-
- }
- else
- printf("Not enough memory.\n");
-
- Close(thefile);
-
- }
- else
- printf("Can't open file %s\n", (STRPTR) argarray[FILENAME]);
-
- }
- else /* read */
- {
-
- /* first we search for the start of RDB on the disk... and read its length */
-
- if(scandev(theoffset, &rdbstart)) /* search for RDB on the disk */
- {
-
- /* remember the real offset of RDB structure */
-
- rdbblock = rdbstart;
-
- /* now we can open the file and fill it with the data */
-
- if(thefile=Open((STRPTR) argarray[FILENAME], MODE_NEWFILE))
- {
- if(!argarray[RDBONLY])
- rdbstart = theoffset;
- rdbsize = ((((struct RigidDiskBlock *)buffer)->rdb_HighRDSKBlock)-rdbstart+1) * BytesPerBlock;
-
- #ifdef DEBUG
- printf("* RDB size is %ld bytes\n", rdbsize);
- #endif
-
- if(memdata=malloc(rdbsize))
- {
-
- ioreq->iotd_Req.io_Command = CMD_READ;
- ioreq->iotd_Req.io_Flags = 0;
- ioreq->iotd_Req.io_Data = memdata;
- ioreq->iotd_Req.io_Length = rdbsize;
- ioreq->iotd_Req.io_Offset = rdbstart * BytesPerBlock;
-
- if(!DoIO((struct IORequest *) ioreq))
- {
-
- /* memrdb pointer for checksumming */
-
- memrdb = (struct RigidDiskBlock *) &((UBYTE *)memdata)[(rdbblock-rdbstart)*BytesPerBlock];
-
- if(ChkRDBSum(memrdb) || argarray[RDBFORCE])
- {
- if(!rdbok)
- printf("Checksum is corrupt. Forcing read...\n");
-
- if(writeok=FWrite(thefile, (STRPTR) memdata, (ULONG) rdbsize, (ULONG) 1))
- printf("%ld bytes%s written to %s\n", rdbsize, argarray[RDBONLY]? " (RDB only)": "", (STRPTR) argarray[FILENAME]);
- else
- printf("Write error\n");
-
- }
- else
- printf("RDB checksum is corrupt. Use FORCE to read it.\n");
-
- }
- else
- printf("Device error. File not written.\n");
-
- free(memdata);
-
- }
- else
- printf("Not enough memory.\n");
-
- Close(thefile);
- if(!writeok)
- DeleteFile((STRPTR) argarray[FILENAME]);
-
- }
- else
- printf("Can't open file %s\n", argarray[FILENAME]);
- }
- else
- printf("Can't find RDB on the disk.\n");
- }
-
- }
- else
- printf("Not enough memory.\n");
-
- }
- else
- printf("Cant't open %s unit %ld\n", DevName, theunit);
-
- CloseAll();
- }
- else
- printf("Invalid offset value (must be from 0 to %ld).\n", RDB_LOCATION_LIMIT-1);
-
- }
-
-
- int scandev(long block, long *rdbfound)
- {
- while (block < RDB_LOCATION_LIMIT)
- {
- ioreq->iotd_Req.io_Command = CMD_READ;
- ioreq->iotd_Req.io_Flags = 0;
- ioreq->iotd_Req.io_Data = buffer;
- ioreq->iotd_Req.io_Length = BytesPerBlock;
- ioreq->iotd_Req.io_Offset = block * BytesPerBlock;
-
- if(DoIO((struct IORequest *) ioreq))
- {
- #ifdef DEBUG
- printf("* Error number %ld\n", ioreq->iotd_Req.io_Error);
- #endif
-
- printf("Disk error. ");
- return FALSE;
- }
- else if (((struct RigidDiskBlock *)buffer)->rdb_ID==IDNAME_RIGIDDISK)
- {
-
- *rdbfound = block;
-
- #ifdef DEBUG
- printf("* RDB found on block %ld\n", block);
- printf("* RDB last block is %ld\n", ((struct RigidDiskBlock *)buffer)->rdb_HighRDSKBlock);
- #endif
-
- return TRUE;
- }
- else
- ++block;
-
- }
- return FALSE;
-
- }
-
-
-
- /* list parsing... hope I didn't make a mistake here */
-
- void ParseBBB(struct BadBlockBlock *BBB)
- {
- if((BBB->bbb_Next)!=-1)
- {
- ParseBBB((struct BadBlockBlock *) &((UBYTE *) memrdb)[((BBB->bbb_Next)-rdbstart)*BytesPerBlock]);
- BBB->bbb_Next -= rdbshift;
-
- BBB->bbb_ChkSum = 0;
- BBB->bbb_ChkSum = CountChkSum((ULONG *) BBB, (ULONG) BBB->bbb_SummedLongs);
- }
- }
-
- void ParsePB(struct PartitionBlock *PB)
- {
- if((PB->pb_Next)!=-1)
- {
- ParsePB((struct PartitionBlock *) &((UBYTE *) memrdb)[((PB->pb_Next)-rdbstart)*BytesPerBlock]);
- PB->pb_Next -= rdbshift;
-
- PB->pb_ChkSum = 0;
- PB->pb_ChkSum = CountChkSum((ULONG *) PB, (ULONG) PB->pb_SummedLongs);
- }
- }
-
- void ParseFHB(struct FileSysHeaderBlock *FHB)
- {
- if((FHB->fhb_Next)!=-1)
- {
- ParseFHB((struct FileSysHeaderBlock *) &((UBYTE *) memrdb)[((FHB->fhb_Next)-rdbstart)*BytesPerBlock]);
- FHB->fhb_Next -= rdbshift;
- }
-
- if((FHB->fhb_SegListBlocks)!=-1)
- {
- ParseLSB((struct LoadSegBlock *) &((UBYTE *) memrdb)[((FHB->fhb_SegListBlocks)-rdbstart)*BytesPerBlock]);
- FHB->fhb_SegListBlocks -= rdbshift;
- }
-
- FHB->fhb_ChkSum = 0;
- FHB->fhb_ChkSum = CountChkSum((ULONG *) FHB, (ULONG) FHB->fhb_SummedLongs);
-
- }
-
- void ParseLSB(struct LoadSegBlock *LSB)
- {
- if((LSB->lsb_Next)!=-1)
- {
- ParseLSB((struct LoadSegBlock *) &((UBYTE *) memrdb)[((LSB->lsb_Next)-rdbstart)*BytesPerBlock]);
- LSB->lsb_Next -= rdbshift;
-
- LSB->lsb_ChkSum = 0;
- LSB->lsb_ChkSum = CountChkSum((ULONG *) LSB, (ULONG) LSB->lsb_SummedLongs);
- }
- }
-
-
-
- /* checksum checking for all RDB structures */
-
- int ChkRDBSum(struct RigidDiskBlock *RDB)
- {
- rdbok = TRUE;
-
- if(!SumOK((ULONG *) RDB))
- {
- rdbok = FALSE;
- return FALSE;
- }
-
- if((RDB->rdb_BadBlockList) != -1)
- ChkBBBSum((struct BadBlockBlock *) &((UBYTE *)memrdb)[((RDB->rdb_BadBlockList)-rdbblock)*BytesPerBlock]);
-
- if((RDB->rdb_PartitionList) != -1)
- ChkPBSum((struct PartitionBlock *) &((UBYTE *)memrdb)[((RDB->rdb_PartitionList)-rdbblock)*BytesPerBlock]);
-
- if((RDB->rdb_FileSysHeaderList) != -1)
- ChkFHBSum((struct FileSysHeaderBlock *) &((UBYTE *)memrdb)[((RDB->rdb_FileSysHeaderList)-rdbblock)*BytesPerBlock]);
-
- return rdbok;
- }
-
- int ChkBBBSum(struct BadBlockBlock *BBB)
- {
- if(!rdbok)
- return FALSE;
-
- if(!SumOK((ULONG *) BBB))
- rdbok = FALSE;
-
- if((BBB->bbb_Next) != -1)
- ChkBBBSum((struct BadBlockBlock *) &((UBYTE *)memrdb)[((BBB->bbb_Next)-rdbblock)*BytesPerBlock]);
-
- return rdbok;
- }
-
-
- int ChkPBSum(struct PartitionBlock *PB)
- {
- if(!rdbok)
- return FALSE;
-
- if(!SumOK((ULONG *) PB))
- rdbok = FALSE;
-
- if((PB->pb_Next) != -1)
- ChkPBSum((struct PartitionBlock *) &((UBYTE *)memrdb)[((PB->pb_Next)-rdbblock)*BytesPerBlock]);
-
- return rdbok;
- }
-
-
- int ChkFHBSum(struct FileSysHeaderBlock *FHB)
- {
- if(!rdbok)
- return FALSE;
-
- if(!SumOK((ULONG *) FHB))
- rdbok = FALSE;
-
- if((FHB->fhb_Next) != -1)
- ChkFHBSum((struct FileSysHeaderBlock *) &((UBYTE *)memrdb)[((FHB->fhb_Next)-rdbblock)*BytesPerBlock]);
-
- if((FHB->fhb_SegListBlocks) != -1)
- ChkLSBSum((struct LoadSegBlock *) &((UBYTE *)memrdb)[((FHB->fhb_SegListBlocks)-rdbblock)*BytesPerBlock]);
-
- return rdbok;
- }
-
- int ChkLSBSum(struct LoadSegBlock *LSB)
- {
- if(!rdbok)
- return FALSE;
-
- if(!SumOK((ULONG *) LSB))
- rdbok = FALSE;
-
- if((LSB->lsb_Next) != -1)
- ChkLSBSum((struct LoadSegBlock *) &((UBYTE *)memrdb)[((LSB->lsb_Next)-rdbblock)*BytesPerBlock]);
-
- return rdbok;
- }
-
-
- /* Next two functions had been written looking at David Balazic's
- RDBInformer v0.2. */
-
- long CountChkSum(ULONG *data, ULONG nr)
- {
- long i;
- long chksum = 0;
-
- for(i=0; i<nr; i++)
- chksum -= (*data++);
- return chksum;
-
- }
-
- void CloseAll(void)
- {
- if(scsiok)
- CloseDevice((struct IORequest *) ioreq);
- if(ioreq)
- DeleteIORequest(ioreq);
- if(ioport)
- DeleteMsgPort(ioport);
- if (buffer)
- free(buffer);
- if (rdargs)
- FreeArgs(rdargs);
- }
-
-
- /* The source below is took from David Balazic's RDBInformer v0.2 */
-
- void OpenDev(void)
- {
- if (ioport=CreateMsgPort())
- {
- #ifdef DEBUG
- printf("* MsgPort created\n");
- #endif
- if(ioreq=CreateIORequest(ioport,sizeof(struct IOExtTD)))
- #ifdef DEBUG
- printf("* IORequest created\n");
- #endif
- {
- if(!OpenDevice(DevName, theunit, (struct IORequest *) ioreq, 0))
- {
- scsiok=TRUE;
- return;
- }
- }
- }
- scsiok=FALSE;
- }
-
- int SumOK(ULONG *p)
- {
- int i;
- LONG chk=0;
- ULONG nr=((struct RigidDiskBlock *)p)->rdb_SummedLongs;
-
- if(nr>555) return FALSE;
-
- for(i=0;i<nr;i++)
- chk+=(*p++);
- if (chk) return FALSE;
- return TRUE;
- }
-
-