2 * ADF Library. (C) 1997-1998 Laurent Clevy
6 * logical disk/volume code
19 #include "defendian.h"
21 extern struct Env adfEnv
;
23 int swapTable
[MAX_SWTYPE
+1][15]={
24 { 4, SW_CHAR
, 2, SW_LONG
, 1012, SW_CHAR
, 0, 1024 }, /* first bytes of boot */
25 { 108, SW_LONG
, 40, SW_CHAR
, 10, SW_LONG
, 0, 512 }, /* root */
26 { 6, SW_LONG
, 488, SW_CHAR
, 0, 512 }, /* data */
27 /* file, dir, entry */
28 { 82, SW_LONG
, 92, SW_CHAR
, 3, SW_LONG
, 36, SW_CHAR
, 11, SW_LONG
, 0, 512 },
29 { 6, SW_LONG
, 0, 24 }, /* cache */
30 { 128, SW_LONG
, 0, 512 }, /* bitmap, fext */
32 { 6, SW_LONG
, 64, SW_CHAR
, 86, SW_LONG
, 32, SW_CHAR
, 12, SW_LONG
, 0, 512 },
33 { 4, SW_CHAR
, 39, SW_LONG
, 56, SW_CHAR
, 10, SW_LONG
, 0, 256 }, /* RDSK */
34 { 4, SW_CHAR
, 127, SW_LONG
, 0, 512 }, /* BADB */
35 { 4, SW_CHAR
, 8, SW_LONG
, 32, SW_CHAR
, 31, SW_LONG
, 4, SW_CHAR
, /* PART */
36 15, SW_LONG
, 0, 256 },
37 { 4, SW_CHAR
, 7, SW_LONG
, 4, SW_CHAR
, 55, SW_LONG
, 0, 256 }, /* FSHD */
38 { 4, SW_CHAR
, 4, SW_LONG
, 492, SW_CHAR
, 0, 512 } /* LSEG */
45 * magic :-) endian swap function (big -> little for read, little to big for write)
49 swapEndian( unsigned char *buf
, int type
)
57 if (type
>MAX_SWTYPE
|| type
<0)
58 adfEnv
.eFct("SwapEndian: type do not exist");
60 while( swapTable
[type
][i
]!=0 ) {
61 for(j
=0; j
<swapTable
[type
][i
]; j
++) {
62 switch( swapTable
[type
][i
+1] ) {
64 *(unsigned long*)(buf
+p
)=Long(buf
+p
);
68 *(unsigned short*)(buf
+p
)=Short(buf
+p
);
80 if (p
!=swapTable
[type
][i
+1])
81 (*adfEnv
.wFct
)("Warning: Endian Swapping length\n");
96 adfReadRootBlock(struct Volume
* vol
, long nSect
, struct bRootBlock
* root
)
98 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
100 if (adfReadBlock(vol
, nSect
, buf
)!=RC_OK
)
103 memcpy(root
, buf
, LOGICAL_BLOCK_SIZE
);
105 swapEndian((unsigned char*)root
, SWBL_ROOT
);
108 if (root
->type
!=T_HEADER
|| root
->secType
!=ST_ROOT
) {
109 (*adfEnv
.wFct
)("adfReadRootBlock : id not found");
112 if (root
->checkSum
!=adfNormalSum(buf
, 20, LOGICAL_BLOCK_SIZE
)) {
113 (*adfEnv
.wFct
)("adfReadRootBlock : invalid checksum");
126 RETCODE
adfWriteRootBlock(struct Volume
* vol
, long nSect
, struct bRootBlock
* root
)
128 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
129 unsigned long newSum
;
132 root
->type
= T_HEADER
;
133 root
->headerKey
= 0L;
135 root
->hashTableSize
= HT_SIZE
;
136 root
->firstData
= 0L;
137 /* checkSum, hashTable */
140 root
->nextSameHash
= 0L;
142 root
->secType
= ST_ROOT
;
144 memcpy(buf
, root
, LOGICAL_BLOCK_SIZE
);
146 swapEndian(buf
, SWBL_ROOT
);
149 newSum
= adfNormalSum(buf
,20,LOGICAL_BLOCK_SIZE
);
150 swLong(buf
+20, newSum
);
151 // *(unsigned long*)(buf+20) = swapLong((unsigned char*)&newSum);
154 if (adfWriteBlock(vol
, nSect
, buf
)!=RC_OK
)
156 //printf("adfWriteRootBlock %ld\n",nSect);
167 adfReadBootBlock(struct Volume
* vol
, struct bBootBlock
* boot
)
169 unsigned char buf
[1024];
172 if (adfReadBlock(vol
, 0, buf
)!=RC_OK
)
175 if (adfReadBlock(vol
, 1, buf
+LOGICAL_BLOCK_SIZE
)!=RC_OK
)
178 memcpy(boot
, buf
, LOGICAL_BLOCK_SIZE
*2);
180 swapEndian((unsigned char*)boot
,SWBL_BOOT
);
182 if ( strncmp("DOS",boot
->dosType
,3)!=0 ) {
183 (*adfEnv
.wFct
)("adfReadBootBlock : DOS id not found");
187 if ( boot
->data
[0]!=0 && adfBootSum(buf
)!=boot
->checkSum
) {
188 printf("compsum=%lx sum=%lx\n", adfBootSum(buf
),boot
->checkSum
);
189 (*adfEnv
.wFct
)("adfReadBootBlock : incorrect checksum");
202 adfWriteBootBlock(struct Volume
* vol
, struct bBootBlock
* boot
)
204 unsigned char buf
[LOGICAL_BLOCK_SIZE
*2];
205 unsigned long newSum
;
207 boot
->dosType
[0] = 'D';
208 boot
->dosType
[1] = 'O';
209 boot
->dosType
[2] = 'S';
210 memcpy(buf
, boot
, LOGICAL_BLOCK_SIZE
*2);
212 swapEndian(buf
, SWBL_BOOT
);
215 if (boot
->rootBlock
==880 || boot
->data
[0]!=0) {
216 newSum
= adfBootSum(buf
);
217 //fprintf(stderr,"sum %x %x\n",newSum,adfBootSum2(buf));
218 swLong(buf
+4,newSum
);
219 // *(unsigned long*)(buf+4) = swapLong((unsigned char*)&newSum);
225 if (adfWriteBlock(vol
, 0, buf
)!=RC_OK
)
227 if (adfWriteBlock(vol
, 1, buf
+512)!=RC_OK
)
229 //puts("adfWriteBootBlock");
237 * buf = where the block is stored
238 * offset = checksum place (in bytes)
239 * bufLen = buffer length (in bytes)
242 adfNormalSum( UCHAR
* buf
, int offset
, int bufLen
)
248 for(i
=0; i
< (bufLen
/4); i
++)
249 if ( i
!= (offset
/4) ) /* old chksum */
250 newsum
+=Long(buf
+i
*4);
251 newsum
=(-newsum
); /* WARNING */
261 adfBitmapSum(unsigned char *buf
)
263 unsigned long newSum
;
268 newSum
-=Long(buf
+i
*4);
278 adfBootSum(unsigned char *buf
)
280 unsigned long d
, newSum
;
284 for(i
=0; i
<256; i
++) {
287 if ( (ULONG_MAX
-newSum
)<d
)
292 newSum
= ~newSum
; /* not */
298 adfBootSum2(unsigned char *buf
)
300 unsigned long prevsum
, newSum
;
304 for(i
=0; i
<1024/sizeof(unsigned long); i
++) {
307 newSum
+= Long(buf
+i
*4);
308 if (newSum
< prevsum
)
312 newSum
= ~newSum
; /* not */
318 /*#######################################################################################*/