2 * ADF Library. (C) 1997-1998 Laurent Clevy
6 * logical disk/volume code
20 #include "defendian.h"
22 extern struct Env adfEnv
;
24 int swapTable
[MAX_SWTYPE
+1][15]={
25 { 4, SW_CHAR
, 2, SW_LONG
, 1012, SW_CHAR
, 0, 1024 }, /* first bytes of boot */
26 { 108, SW_LONG
, 40, SW_CHAR
, 10, SW_LONG
, 0, 512 }, /* root */
27 { 6, SW_LONG
, 488, SW_CHAR
, 0, 512 }, /* data */
28 /* file, dir, entry */
29 { 82, SW_LONG
, 92, SW_CHAR
, 3, SW_LONG
, 36, SW_CHAR
, 11, SW_LONG
, 0, 512 },
30 { 6, SW_LONG
, 0, 24 }, /* cache */
31 { 128, SW_LONG
, 0, 512 }, /* bitmap, fext */
33 { 6, SW_LONG
, 64, SW_CHAR
, 86, SW_LONG
, 32, SW_CHAR
, 12, SW_LONG
, 0, 512 },
34 { 4, SW_CHAR
, 39, SW_LONG
, 56, SW_CHAR
, 10, SW_LONG
, 0, 256 }, /* RDSK */
35 { 4, SW_CHAR
, 127, SW_LONG
, 0, 512 }, /* BADB */
36 { 4, SW_CHAR
, 8, SW_LONG
, 32, SW_CHAR
, 31, SW_LONG
, 4, SW_CHAR
, /* PART */
37 15, SW_LONG
, 0, 256 },
38 { 4, SW_CHAR
, 7, SW_LONG
, 4, SW_CHAR
, 55, SW_LONG
, 0, 256 }, /* FSHD */
39 { 4, SW_CHAR
, 4, SW_LONG
, 492, SW_CHAR
, 0, 512 }, /* LSEG */
40 { 4, SW_CHAR
, 4, SW_LONG
, 492, SW_CHAR
, 0, 512 } /* BOOT */
47 * magic :-) endian swap function (big -> little for read, little to big for write)
51 swapEndian( UBYTE
*buf
, int type
)
59 if (type
>MAX_SWTYPE
|| type
<0)
60 adfEnv
.eFct("SwapEndian: type do not exist");
62 while( swapTable
[type
][i
]!=0 ) {
63 for(j
=0; j
<swapTable
[type
][i
]; j
++) {
64 switch( swapTable
[type
][i
+1] ) {
66 *(ULONG
*)(buf
+p
)=Long(buf
+p
);
70 *(USHORT
*)(buf
+p
)=Short(buf
+p
);
82 if (p
!=swapTable
[type
][i
+1])
83 (*adfEnv
.wFct
)("Warning: Endian Swapping length\n");
98 adfReadRootBlock(struct Volume
* vol
, ULONG nSect
, struct bRootBlock
* root
)
100 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
102 if (adfReadBlock(vol
, nSect
, buf
)!=RC_OK
)
105 memcpy(root
, buf
, LOGICAL_BLOCK_SIZE
);
107 swapEndian((unsigned char*)root
, SWBL_ROOT
);
110 if (root
->type
!=T_HEADER
|| root
->secType
!=ST_ROOT
) {
111 (*adfEnv
.wFct
)("adfReadRootBlock : id not found");
114 if (root
->checkSum
!=adfNormalSum(buf
, 20, LOGICAL_BLOCK_SIZE
)) {
115 (*adfEnv
.wFct
)("adfReadRootBlock : invalid checksum");
128 RETCODE
adfWriteRootBlock(struct Volume
* vol
, ULONG nSect
, struct bRootBlock
* root
)
130 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
134 root
->type
= T_HEADER
;
135 root
->headerKey
= 0L;
137 root
->hashTableSize
= HT_SIZE
;
138 root
->firstData
= 0L;
139 /* checkSum, hashTable */
142 root
->nextSameHash
= 0L;
144 root
->secType
= ST_ROOT
;
146 memcpy(buf
, root
, LOGICAL_BLOCK_SIZE
);
149 swapEndian(buf
, SWBL_ROOT
);
152 newSum
= adfNormalSum(buf
,20,LOGICAL_BLOCK_SIZE
);
153 swLong(buf
+20, newSum
);
156 if (adfWriteBlock(vol
, nSect
, buf
)!=RC_OK
)
158 //printf("adfWriteRootBlock %ld\n",nSect);
169 adfReadBootBlock(struct Volume
* vol
, struct bBootBlock
* boot
)
171 unsigned char buf
[1024];
174 if (adfReadBlock(vol
, 0, buf
)!=RC_OK
)
177 if (adfReadBlock(vol
, 1, buf
+LOGICAL_BLOCK_SIZE
)!=RC_OK
)
180 memcpy(boot
, buf
, LOGICAL_BLOCK_SIZE
*2);
182 swapEndian((unsigned char*)boot
,SWBL_BOOTBLOCK
);
184 if ( strncmp("DOS",boot
->dosType
,3)!=0 ) {
185 (*adfEnv
.wFct
)("adfReadBootBlock : DOS id not found");
189 if ( boot
->data
[0]!=0 && adfBootSum(buf
)!=boot
->checkSum
) {
190 printf("compsum=%lx sum=%lx\n", (long)adfBootSum(buf
),(long)boot
->checkSum
);
191 (*adfEnv
.wFct
)("adfReadBootBlock : incorrect checksum");
204 adfWriteBootBlock(struct Volume
* vol
, struct bBootBlock
* boot
)
206 unsigned char buf
[LOGICAL_BLOCK_SIZE
*2];
209 boot
->dosType
[0] = 'D';
210 boot
->dosType
[1] = 'O';
211 boot
->dosType
[2] = 'S';
212 boot
->dosType
[3] = vol
->dosType
;
214 boot
->rootBlock
= vol
->rootBlock
;
216 memcpy(buf
, boot
, LOGICAL_BLOCK_SIZE
*2);
218 swapEndian(buf
, SWBL_BOOTBLOCK
);
221 if (boot
->rootBlock
==880 || boot
->data
[0]!=0) {
222 newSum
= adfBootSum(buf
);
223 //fprintf(stderr,"sum %x %x\n",newSum,adfBootSum2(buf));
224 swLong(buf
+4,newSum
);
225 // *(ULONG*)(buf+4) = swapLong((unsigned char*)&newSum);
231 if (adfWriteBlock(vol
, 0, buf
)!=RC_OK
)
233 if (adfWriteBlock(vol
, 1, buf
+512)!=RC_OK
)
235 //puts("adfWriteBootBlock");
243 * buf = where the block is stored
244 * offset = checksum place (in bytes)
245 * bufLen = buffer length (in bytes)
248 adfNormalSum( UCHAR
* buf
, int offset
, int bufLen
)
254 for(i
=0; i
< (bufLen
/4); i
++)
255 if ( i
!= (offset
/4) ) /* old chksum */
256 newsum
+=Long(buf
+i
*4);
257 newsum
=(-newsum
); /* WARNING */
267 adfBitmapSum(unsigned char *buf
)
274 newSum
-=Long(buf
+i
*4);
284 adfBootSum(unsigned char *buf
)
290 for(i
=0; i
<256; i
++) {
293 if ( (ULONG_MAX
-newSum
)<d
)
298 newSum
= ~newSum
; /* not */
304 adfBootSum2(unsigned char *buf
)
306 ULONG prevsum
, newSum
;
310 for(i
=0; i
<1024/sizeof(ULONG
); i
++) {
313 newSum
+= Long(buf
+i
*4);
314 if (newSum
< prevsum
)
318 newSum
= ~newSum
; /* not */
324 /*#######################################################################################*/