Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / filesys / SFS / SFSdumpblock / SFSdumpblock.c
blob2bcf932f91cfef0c334b4df4760ffff41508b9cd
1 #include <clib/macros.h>
2 #include <devices/scsidisk.h>
3 #include <devices/trackdisk.h>
4 #include <dos/dos.h>
5 #include <dos/dosextens.h>
6 #include <dos/filehandler.h>
7 #include <exec/errors.h>
8 #include <exec/io.h>
9 #include <exec/memory.h>
10 #include <proto/dos.h>
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <string.h>
14 #include "stdio.h"
16 #include "/fs/deviceio.h"
17 #include "/fs/deviceio_protos.h"
18 #include "/fs/cachedio_protos.h"
20 #include "/fs/fs.h"
22 #include "/bitfuncs.c"
24 #define BLCKFACCURACY (5) /* 2^5 = 32 */
27 /* ASM prototypes */
29 extern ULONG __asm RANDOM(register __d0 ULONG);
30 extern LONG __asm STACKSWAP(void);
31 extern ULONG __asm CALCCHECKSUM(register __d0 ULONG,register __a0 ULONG *);
32 extern ULONG __asm MULU64(register __d0 ULONG,register __d1 ULONG,register __a0 ULONG *);
33 extern WORD __asm COMPRESSFROMZERO(register __a0 UWORD *,register __a1 UBYTE *,register __d0 ULONG);
36 const char version[]="\0$VER: SFSdumpblock 1.0 (" ADATE ")\r\n";
38 LONG read2(ULONG block);
39 BOOL checkchecksum(void *buffer);
40 void setchecksum(void *buffer);
41 void dumpblock(ULONG block, void *data, ULONG bytes);
42 ULONG calculatechecksum(void *buffer);
44 struct DosEnvec *dosenvec;
46 /* blocks_ = the number of blocks of something (blocks can contain 1 or more sectors)
47 block_ = a block number of something (relative to start of partition)
48 sectors_ = the number of sectors of something (1 or more sectors form a logical block)
49 sector_ = a sector number (relative to the start of the disk)
50 bytes_ = the number of bytes of something
51 byte_ = a byte number of something
52 shifts_ = the number of bytes written as 2^x of something
53 mask_ = a mask for something */
55 extern ULONG blocks_total; /* size of the partition in blocks */
57 extern ULONG byte_low; /* the byte offset of our partition on the disk */
58 extern ULONG byte_lowh; /* high 32 bits */
59 extern ULONG byte_high; /* the byte offset of the end of our partition (excluding) on the disk */
60 extern ULONG byte_highh; /* high 32 bits */
62 extern ULONG bytes_block; /* size of a block in bytes */
64 extern UWORD shifts_block; /* shift count needed to convert a blockoffset<->byteoffset */
66 extern ULONG bufmemtype;
68 UBYTE *buffer;
70 LONG main() {
71 struct RDArgs *readarg;
72 UBYTE template[]="DEVICE=DRIVE/A,BLOCK/N/A,BINARY/S\n";
74 struct {char *device;
75 ULONG *block;
76 ULONG binary;} arglist={NULL};
78 if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39))!=0) {
79 if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39))!=0) {
80 if((readarg=ReadArgs(template,(LONG *)&arglist,0))!=0) {
81 struct DosList *dl;
82 UBYTE *devname=arglist.device;
84 while(*devname!=0) {
85 if(*devname==':') {
86 *devname=0;
87 break;
89 devname++;
92 dl=LockDosList(LDF_DEVICES|LDF_READ);
93 if((dl=FindDosEntry(dl,arglist.device,LDF_DEVICES))!=0) {
94 struct FileSysStartupMsg *fssm;
95 struct MsgPort *msgport;
97 fssm=(struct FileSysStartupMsg *)BADDR(dl->dol_misc.dol_handler.dol_Startup);
98 dosenvec=(struct DosEnvec *)BADDR(fssm->fssm_Environ);
99 msgport=dl->dol_Task;
101 UnLockDosList(LDF_DEVICES|LDF_READ);
103 if((initcachedio((UBYTE *)BADDR(fssm->fssm_Device)+1, fssm->fssm_Unit, fssm->fssm_Flags, dosenvec))==0) {
105 // setiocache(arglist.lines!=0 ? *arglist.lines : 128, arglist.readaheadsize!=0 ? *arglist.readaheadsize : 8192, FALSE); /* 1 MB for read-ahead cache, no copyback mode. */
107 if((buffer=AllocVec(bytes_block, bufmemtype))!=0) {
109 /** *********************************************
110 * Here starts the code:
113 read2(*arglist.block);
115 if(arglist.binary!=0) {
116 Write(Output(), buffer, bytes_block);
118 else {
119 if(checkchecksum(buffer)!=DOSTRUE) {
120 printf("Warning: Checksum of block %ld is wrong. It is 0x%08lx while it should be 0x%08lx.\n", *arglist.block, ((struct fsBlockHeader *)buffer)->checksum, calculatechecksum(buffer));
122 if(((struct fsBlockHeader *)buffer)->ownblock != *arglist.block) {
123 printf("Warning: Block %ld indicates that it is actually block %ld (ownblock is wrong!)\n", *arglist.block, ((struct fsBlockHeader *)buffer)->ownblock);
125 dumpblock(*arglist.block,buffer,bytes_block);
129 * Here ends the code.
130 * ********************************************/
132 FreeVec(buffer);
134 else {
135 printf("Not enough memory\n");
138 cleanupcachedio();
141 else {
142 Printf("Unknown device %s\n",arglist.device);
143 UnLockDosList(LDF_DEVICES|LDF_READ);
146 FreeArgs(readarg);
148 CloseLibrary((struct Library *)IntuitionBase);
150 CloseLibrary((struct Library *)DOSBase);
152 return(0);
157 LONG read2(ULONG block) {
158 // return(transfer(DIO_READ, buffer, block, 1));
159 return(read(block, buffer, 1));
165 else if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
166 PutStr("\n***Break\n");
167 break;
173 void dumpblock(ULONG block, void *data, ULONG bytes) {
174 ULONG *d=(ULONG *)data;
175 UBYTE *d2=(UBYTE *)data;
176 UWORD off=0;
177 UBYTE s[40];
179 if(bytes<bytes_block) {
180 printf("Dump of first %ld bytes of block %ld.\n",bytes,block);
182 else {
183 printf("Dump of block %ld.\n",block);
186 while(bytes>0) {
187 WORD n;
188 UBYTE c;
189 UBYTE *s2;
191 n=16;
192 s2=s;
194 while(--n>=0) {
195 c=*d2++;
197 if(c<32) {
198 c+=64;
200 if(c>=127 && c<=160) {
201 c='.';
204 *s2++=c;
206 *s2=0;
208 printf("0x%04lx: %08lx %08lx %08lx %08lx %s\n",off,d[0],d[1],d[2],d[3],s);
210 bytes-=16;
211 d+=4;
212 off+=16;
218 LONG req(UBYTE *fmt, UBYTE *gads, ... ) {
219 ULONG args[5];
220 ULONG *arg=args;
221 UBYTE *fmt2;
222 LONG gadget=0;
224 /* Simple requester function which is called by deviceio.o
225 for displaying low-level device errors and accesses outside
226 the partition. */
228 *arg=(ULONG)fmt;
230 if((fmt2=AllocVec(strlen(fmt)+100,0))!=0) {
232 RawDoFmt("%s",args,(void (*)())"\x16\xC0\x4E\x75",fmt2);
235 struct EasyStruct es;
236 ULONG *args=(ULONG *)&gads;
238 args++;
240 es.es_StructSize=sizeof(struct EasyStruct);
241 es.es_Flags=0;
242 es.es_Title="SFScheck request";
243 es.es_TextFormat=fmt2;
244 es.es_GadgetFormat=gads;
246 gadget=EasyRequestArgs(0,&es,0,args);
249 FreeVec(fmt2);
252 return(gadget);
257 void starttimeout(void) {
258 /* Called by deviceio.o each time there is a physical
259 disk access. You can use this to start a timer and
260 call motoroff() when the disk hasn't been accessed
261 for a specific amount of time (SFS uses 1 second).
263 SFScheck doesn't use this function. */
268 BOOL checkchecksum(void *buffer) {
269 if(CALCCHECKSUM(bytes_block, buffer)==0) {
270 return(DOSTRUE);
272 return(DOSFALSE);
276 ULONG calculatechecksum(void *buffer) {
277 ULONG oldchecksum,checksum;
279 struct fsBlockHeader *bh=(struct fsBlockHeader *)buffer;
281 oldchecksum=bh->checksum;
282 bh->checksum=0; /* Important! */
283 checksum=-CALCCHECKSUM(bytes_block, (ULONG *)buffer);
284 bh->checksum=oldchecksum;
285 return checksum;
289 void setchecksum(void *buffer) {
290 struct fsBlockHeader *bh=(struct fsBlockHeader *)buffer;
292 bh->checksum=0; /* Important! */
293 bh->checksum=-CALCCHECKSUM(bytes_block, (ULONG *)buffer);