grub2: bring back build of aros-side grub2 tools
[AROS.git] / tools / adflib / adf_file.c
blobd0c8bb31c2f59de42b1065b6b6e7693b2f4f201d
1 /*
2 * ADF Library. (C) 1997-1999 Laurent Clevy
4 * adf_file.c
6 * file code
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "adf_util.h"
14 #include "adf_file.h"
15 #include "adf_str.h"
16 #include "defendian.h"
17 #include "adf_raw.h"
18 #include "adf_disk.h"
19 #include "adf_dir.h"
20 #include "adf_bitm.h"
21 #include "adf_cache.h"
23 extern struct Env adfEnv;
25 void adfFileTruncate(struct Volume *vol, SECTNUM nParent, char *name)
32 * adfFileFlush
35 void adfFlushFile(struct File *file)
37 struct bEntryBlock parent;
38 struct bOFSDataBlock *data;
40 if (file->currentExt) {
41 if (file->writeMode)
42 adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
43 file->currentExt);
45 if (file->currentData) {
46 if (file->writeMode) {
47 file->fileHdr->byteSize = file->pos;
48 if (isOFS(file->volume->dosType)) {
49 data = (struct bOFSDataBlock *)file->currentData;
50 data->dataSize = file->posInDataBlk;
52 if (file->fileHdr->byteSize>0)
53 adfWriteDataBlock(file->volume, file->curDataPtr,
54 file->currentData);
57 if (file->writeMode) {
58 file->fileHdr->byteSize = file->pos;
59 //printf("pos=%ld\n",file->pos);
60 adfTime2AmigaTime(adfGiveCurrentTime(),
61 &(file->fileHdr->days),&(file->fileHdr->mins),&(file->fileHdr->ticks) );
62 adfWriteFileHdrBlock(file->volume, file->fileHdr->headerKey, file->fileHdr);
64 if (isDIRCACHE(file->volume->dosType)) {
65 //printf("parent=%ld\n",file->fileHdr->parent);
66 adfReadEntryBlock(file->volume, file->fileHdr->parent, &parent);
67 adfUpdateCache(file->volume, &parent, (struct bEntryBlock*)file->fileHdr,FALSE);
69 adfUpdateBitmap(file->volume);
75 * adfGetFileBlocks
78 RETCODE adfGetFileBlocks(struct Volume* vol, struct bFileHeaderBlock* entry,
79 struct FileBlocks* fileBlocks)
81 ULONG n, m;
82 SECTNUM nSect;
83 struct bFileExtBlock extBlock;
84 ULONG i;
86 fileBlocks->header = entry->headerKey;
87 adfFileRealSize( entry->byteSize, vol->datablockSize,
88 &(fileBlocks->nbData), &(fileBlocks->nbExtens) );
90 fileBlocks->data=(SECTNUM*)malloc(fileBlocks->nbData * sizeof(SECTNUM));
91 if (!fileBlocks->data) {
92 (*adfEnv.eFct)("adfGetFileBlocks : malloc");
93 return RC_MALLOC;
96 fileBlocks->extens=(SECTNUM*)malloc(fileBlocks->nbExtens * sizeof(SECTNUM));
97 if (!fileBlocks->extens) {
98 (*adfEnv.eFct)("adfGetFileBlocks : malloc");
99 return RC_MALLOC;
102 n = m = 0;
103 /* in file header block */
104 for(i=0; i<entry->highSeq; i++)
105 fileBlocks->data[n++] = entry->dataBlocks[MAX_DATABLK-1-i];
107 /* in file extension blocks */
108 nSect = entry->extension;
109 while(nSect!=0) {
110 fileBlocks->extens[m++] = nSect;
111 adfReadFileExtBlock(vol, nSect, &extBlock);
112 for(i=0; i<extBlock.highSeq; i++)
113 fileBlocks->data[n++] = extBlock.dataBlocks[MAX_DATABLK-1-i];
114 nSect = extBlock.extension;
116 if ( (fileBlocks->nbExtens+fileBlocks->nbData) != (n+m) )
117 (*adfEnv.wFct)("adfGetFileBlocks : less blocks than expected");
119 return RC_OK;
123 * adfFreeFileBlocks
126 RETCODE adfFreeFileBlocks(struct Volume* vol, struct bFileHeaderBlock *entry)
128 int i;
129 struct FileBlocks fileBlocks;
130 RETCODE rc = RC_OK;
132 adfGetFileBlocks(vol,entry,&fileBlocks);
134 for(i=0; i<fileBlocks.nbData; i++) {
135 adfSetBlockFree(vol, fileBlocks.data[i]);
137 for(i=0; i<fileBlocks.nbExtens; i++) {
138 adfSetBlockFree(vol, fileBlocks.extens[i]);
141 free(fileBlocks.data);
142 free(fileBlocks.extens);
144 return rc;
149 * adfFileRealSize
151 * Compute and return real number of block used by one file
152 * Compute number of datablocks and file extension blocks
155 ULONG adfFileRealSize(ULONG size, int blockSize, ULONG *dataN, ULONG *extN)
157 ULONG data, ext;
159 /*--- number of data blocks ---*/
160 data = size / blockSize;
161 if ( size % blockSize )
162 data++;
164 /*--- number of header extension blocks ---*/
165 ext = 0;
166 if (data>MAX_DATABLK) {
167 ext = (data-MAX_DATABLK) / MAX_DATABLK;
168 if ( (data-MAX_DATABLK) % MAX_DATABLK )
169 ext++;
172 if (dataN)
173 *dataN = data;
174 if (extN)
175 *extN = ext;
177 return(ext+data+1);
182 * adfWriteFileHdrBlock
185 RETCODE adfWriteFileHdrBlock(struct Volume *vol, SECTNUM nSect, struct bFileHeaderBlock* fhdr)
187 unsigned char buf[512];
188 ULONG newSum;
189 RETCODE rc = RC_OK;
190 //printf("adfWriteFileHdrBlock %ld\n",nSect);
191 fhdr->type = T_HEADER;
192 fhdr->dataSize = 0;
193 fhdr->secType = ST_FILE;
195 memcpy(buf, fhdr, sizeof(struct bFileHeaderBlock));
196 #ifdef LITT_ENDIAN
197 swapEndian(buf, SWBL_FILE);
198 #endif
199 newSum = adfNormalSum(buf,20,sizeof(struct bFileHeaderBlock));
200 swLong(buf+20, newSum);
201 // *(ULONG*)(buf+20) = swapLong((unsigned char*)&newSum);
203 adfWriteBlock(vol, nSect, buf);
205 return rc;
210 * adfFileSeek
213 void adfFileSeek(struct File *file, ULONG pos)
215 SECTNUM extBlock, nSect;
216 ULONG nPos;
217 int i;
219 nPos = min(pos, file->fileHdr->byteSize);
220 file->pos = nPos;
221 extBlock = adfPos2DataBlock(nPos, file->volume->datablockSize,
222 &(file->posInExtBlk), &(file->posInDataBlk), &(file->curDataPtr) );
223 if (extBlock==-1) {
224 adfReadDataBlock(file->volume,
225 file->fileHdr->dataBlocks[MAX_DATABLK-1-file->curDataPtr],
226 file->currentData);
228 else {
229 nSect = file->fileHdr->extension;
230 i = 0;
231 while( i<extBlock && nSect!=0 ) {
232 adfReadFileExtBlock(file->volume, nSect, file->currentExt );
233 nSect = file->currentExt->extension;
235 if (i!=extBlock)
236 (*adfEnv.wFct)("error");
237 adfReadDataBlock(file->volume,
238 file->currentExt->dataBlocks[file->posInExtBlk], file->currentData);
244 * adfFileOpen
247 struct File* adfOpenFile(struct Volume *vol, char* name, char *mode)
249 struct File *file;
250 SECTNUM nSect;
251 struct bEntryBlock entry, parent;
252 BOOL write;
253 char filename[200];
255 write=( strcmp("w",mode)==0 || strcmp("a",mode)==0 );
257 if (write && vol->dev->readOnly) {
258 (*adfEnv.wFct)("adfFileOpen : device is mounted 'read only'");
259 return NULL;
262 adfReadEntryBlock(vol, vol->curDirPtr, &parent);
264 nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, NULL);
265 if (!write && nSect==-1) {
266 sprintf(filename,"adfFileOpen : file \"%s\" not found.",name);
267 (*adfEnv.wFct)(filename);
268 //fprintf(stdout,"filename %s %d, parent =%d\n",name,strlen(name),vol->curDirPtr);
269 return NULL;
271 if (!write && hasR(entry.access)) {
272 (*adfEnv.wFct)("adfFileOpen : access denied"); return NULL; }
273 /* if (entry.secType!=ST_FILE) {
274 (*adfEnv.wFct)("adfFileOpen : not a file"); return NULL; }
275 if (write && (hasE(entry.access)||hasW(entry.access))) {
276 (*adfEnv.wFct)("adfFileOpen : access denied"); return NULL; }
277 */ if (write && nSect!=-1) {
278 (*adfEnv.wFct)("adfFileOpen : file already exists"); return NULL; }
280 file = (struct File*)malloc(sizeof(struct File));
281 if (!file) { (*adfEnv.wFct)("adfFileOpen : malloc"); return NULL; }
282 file->fileHdr = (struct bFileHeaderBlock*)malloc(sizeof(struct bFileHeaderBlock));
283 if (!file->fileHdr) {
284 (*adfEnv.wFct)("adfFileOpen : malloc");
285 free(file); return NULL;
287 file->currentData = malloc(512*sizeof(unsigned char));
288 if (!file->currentData) {
289 (*adfEnv.wFct)("adfFileOpen : malloc");
290 free(file->fileHdr); free(file); return NULL;
293 memset(file->currentData, 0xff, 512);
295 file->volume = vol;
296 file->pos = 0;
297 file->posInExtBlk = 0;
298 file->posInDataBlk = 0;
299 file->writeMode = write;
300 file->currentExt = NULL;
301 file->nDataBlock = 0;
303 if (strcmp("w",mode)==0) {
304 memset(file->fileHdr,0,512);
305 adfCreateFile(vol,vol->curDirPtr,name,file->fileHdr);
306 file->eof = TRUE;
308 else if (strcmp("a",mode)==0) {
309 memcpy(file->fileHdr,&entry,sizeof(struct bFileHeaderBlock));
310 file->eof = TRUE;
311 adfFileSeek(file, file->fileHdr->byteSize);
313 else if (strcmp("r",mode)==0) {
314 memcpy(file->fileHdr,&entry,sizeof(struct bFileHeaderBlock));
315 file->eof = FALSE;
318 //puts("adfOpenFile");
319 return(file);
324 * adfCloseFile
327 void adfCloseFile(struct File *file)
330 if (file==0)
331 return;
332 //puts("adfCloseFile in");
334 adfFlushFile(file);
336 if (file->currentExt)
337 free(file->currentExt);
339 if (file->currentData)
340 free(file->currentData);
342 free(file->fileHdr);
343 free(file);
345 //puts("adfCloseFile out");
350 * adfReadFile
353 ULONG adfReadFile(struct File* file, ULONG n, unsigned char *buffer)
355 ULONG bytesRead;
356 unsigned char *dataPtr, *bufPtr;
357 int blockSize, size;
359 if (n==0) return(n);
360 blockSize = file->volume->datablockSize;
361 /*puts("adfReadFile");*/
362 if (file->pos+n > file->fileHdr->byteSize)
363 n = file->fileHdr->byteSize - file->pos;
365 if (isOFS(file->volume->dosType))
366 dataPtr = (unsigned char*)(file->currentData)+24;
367 else
368 dataPtr = file->currentData;
370 if (file->pos==0 || file->posInDataBlk==blockSize) {
371 adfReadNextFileBlock(file);
372 file->posInDataBlk = 0;
375 bytesRead = 0; bufPtr = buffer;
376 size = 0;
377 while ( bytesRead < n ) {
378 size = min(n-bytesRead, blockSize-file->posInDataBlk);
379 memcpy(bufPtr, dataPtr+file->posInDataBlk, size);
380 bufPtr += size;
381 file->pos += size;
382 bytesRead += size;
383 file->posInDataBlk += size;
384 if (file->posInDataBlk==blockSize && bytesRead<n) {
385 adfReadNextFileBlock(file);
386 file->posInDataBlk = 0;
389 file->eof = (file->pos==file->fileHdr->byteSize);
390 return( bytesRead );
395 * adfEndOfFile
398 BOOL adfEndOfFile(struct File* file)
400 return(file->eof);
405 * adfReadNextFileBlock
408 RETCODE adfReadNextFileBlock(struct File* file)
410 SECTNUM nSect;
411 struct bOFSDataBlock *data;
412 RETCODE rc = RC_OK;
414 data =(struct bOFSDataBlock *) file->currentData;
416 if (file->nDataBlock==0) {
417 nSect = file->fileHdr->firstData;
419 else if (isOFS(file->volume->dosType)) {
420 nSect = data->nextData;
422 else {
423 if (file->nDataBlock<MAX_DATABLK)
424 nSect = file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock];
425 else {
426 if (file->nDataBlock==MAX_DATABLK) {
427 file->currentExt=(struct bFileExtBlock*)malloc(sizeof(struct bFileExtBlock));
428 if (!file->currentExt) (*adfEnv.eFct)("adfReadNextFileBlock : malloc");
429 adfReadFileExtBlock(file->volume, file->fileHdr->extension,
430 file->currentExt);
431 file->posInExtBlk = 0;
433 else if (file->posInExtBlk==MAX_DATABLK) {
434 adfReadFileExtBlock(file->volume, file->currentExt->extension,
435 file->currentExt);
436 file->posInExtBlk = 0;
438 nSect = file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk];
439 file->posInExtBlk++;
442 adfReadDataBlock(file->volume,nSect,file->currentData);
444 if (isOFS(file->volume->dosType) && data->seqNum!=file->nDataBlock+1)
445 (*adfEnv.wFct)("adfReadNextFileBlock : seqnum incorrect");
447 file->nDataBlock++;
449 return rc;
454 * adfWriteFile
457 ULONG adfWriteFile(struct File *file, ULONG n, unsigned char *buffer)
459 ULONG bytesWritten;
460 unsigned char *dataPtr, *bufPtr;
461 int size, blockSize;
462 struct bOFSDataBlock *dataB;
464 if (n==0) return (n);
465 //puts("adfWriteFile");
466 blockSize = file->volume->datablockSize;
467 if (isOFS(file->volume->dosType)) {
468 dataB =(struct bOFSDataBlock *)file->currentData;
469 dataPtr = dataB->data;
471 else
472 dataPtr = file->currentData;
474 if (file->pos==0 || file->posInDataBlk==blockSize) {
475 if (adfCreateNextFileBlock(file)==-1)
476 (*adfEnv.wFct)("adfWritefile : no more free sector availbale");
477 file->posInDataBlk = 0;
480 bytesWritten = 0; bufPtr = buffer;
481 while( bytesWritten<n ) {
482 size = min(n-bytesWritten, blockSize-file->posInDataBlk);
483 memcpy(dataPtr+file->posInDataBlk, bufPtr, size);
484 bufPtr += size;
485 file->pos += size;
486 bytesWritten += size;
487 file->posInDataBlk += size;
488 if (file->posInDataBlk==blockSize && bytesWritten<n) {
489 if (adfCreateNextFileBlock(file)==-1)
490 (*adfEnv.wFct)("adfWritefile : no more free sector availbale");
491 file->posInDataBlk = 0;
494 return( bytesWritten );
499 * adfCreateNextFileBlock
502 SECTNUM adfCreateNextFileBlock(struct File* file)
504 SECTNUM nSect, extSect;
505 struct bOFSDataBlock *data;
506 unsigned int blockSize;
507 int i;
508 //puts("adfCreateNextFileBlock");
509 blockSize = file->volume->datablockSize;
510 data = file->currentData;
512 /* the first data blocks pointers are inside the file header block */
513 if (file->nDataBlock<MAX_DATABLK) {
514 nSect = adfGet1FreeBlock(file->volume);
515 if (nSect==-1) return -1;
516 //printf("adfCreateNextFileBlock fhdr %ld\n",nSect);
517 if (file->nDataBlock==0)
518 file->fileHdr->firstData = nSect;
519 file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock] = nSect;
520 file->fileHdr->highSeq++;
522 else {
523 /* one more sector is needed for one file extension block */
524 if ((file->nDataBlock%MAX_DATABLK)==0) {
525 extSect = adfGet1FreeBlock(file->volume);
526 //printf("extSect=%ld\n",extSect);
527 if (extSect==-1) return -1;
529 /* the future block is the first file extension block */
530 if (file->nDataBlock==MAX_DATABLK) {
531 file->currentExt=(struct bFileExtBlock*)malloc(sizeof(struct bFileExtBlock));
532 if (!file->currentExt) {
533 adfSetBlockFree(file->volume, extSect);
534 (*adfEnv.eFct)("adfCreateNextFileBlock : malloc");
535 return -1;
537 file->fileHdr->extension = extSect;
540 /* not the first : save the current one, and link it with the future */
541 if (file->nDataBlock>=2*MAX_DATABLK) {
542 file->currentExt->extension = extSect;
543 //printf ("write ext=%d\n",file->currentExt->headerKey);
544 adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
545 file->currentExt);
548 /* initializes a file extension block */
549 for(i=0; i<MAX_DATABLK; i++)
550 file->currentExt->dataBlocks[i] = 0L;
551 file->currentExt->headerKey = extSect;
552 file->currentExt->parent = file->fileHdr->headerKey;
553 file->currentExt->highSeq = 0L;
554 file->currentExt->extension = 0L;
555 file->posInExtBlk = 0L;
556 //printf("extSect=%ld\n",extSect);
558 nSect = adfGet1FreeBlock(file->volume);
559 if (nSect==-1)
560 return -1;
562 //printf("adfCreateNextFileBlock ext %ld\n",nSect);
564 file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk] = nSect;
565 file->currentExt->highSeq++;
566 file->posInExtBlk++;
569 /* builds OFS header */
570 if (isOFS(file->volume->dosType)) {
571 /* writes previous data block and link it */
572 if (file->pos>=blockSize) {
573 data->nextData = nSect;
574 adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
575 //printf ("writedata=%d\n",file->curDataPtr);
577 /* initialize a new data block */
578 for(i=0; i<(int)blockSize; i++)
579 data->data[i]=~0;
580 data->seqNum = file->nDataBlock+1;
581 data->dataSize = blockSize;
582 data->nextData = 0L;
583 data->headerKey = file->fileHdr->headerKey;
585 else
586 if (file->pos>=blockSize) {
587 adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
588 //printf ("writedata=%d\n",file->curDataPtr);
589 memset(file->currentData,0xff,512);
592 //printf("datablk=%d\n",nSect);
593 file->curDataPtr = nSect;
594 file->nDataBlock++;
596 return(nSect);
601 * adfPos2DataBlock
604 ULONG adfPos2DataBlock(ULONG pos, int blockSize,
605 int *posInExtBlk, int *posInDataBlk, ULONG *curDataN )
607 ULONG extBlock;
609 *posInDataBlk = pos%blockSize;
610 *curDataN = pos/blockSize;
611 if (*posInDataBlk==0)
612 (*curDataN)++;
613 if (*curDataN<72) {
614 *posInExtBlk = 0;
615 return -1;
617 else {
618 *posInExtBlk = (pos-72*blockSize)%blockSize;
619 extBlock = (pos-72*blockSize)/blockSize;
620 if (*posInExtBlk==0)
621 extBlock++;
622 return extBlock;
628 * adfReadDataBlock
631 RETCODE adfReadDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
633 unsigned char buf[512];
634 struct bOFSDataBlock *dBlock;
635 RETCODE rc = RC_OK;
637 adfReadBlock(vol, nSect,buf);
639 memcpy(data,buf,512);
641 if (isOFS(vol->dosType)) {
642 #ifdef LITT_ENDIAN
643 swapEndian(data, SWBL_DATA);
644 #endif
645 dBlock = (struct bOFSDataBlock*)data;
646 //printf("adfReadDataBlock %ld\n",nSect);
648 if (dBlock->checkSum!=adfNormalSum(buf,20,sizeof(struct bOFSDataBlock)))
649 (*adfEnv.wFct)("adfReadDataBlock : invalid checksum");
650 if (dBlock->type!=T_DATA)
651 (*adfEnv.wFct)("adfReadDataBlock : id T_DATA not found");
652 if (dBlock->dataSize>488)
653 (*adfEnv.wFct)("adfReadDataBlock : dataSize incorrect");
654 if ( !isSectNumValid(vol,dBlock->headerKey) )
655 (*adfEnv.wFct)("adfReadDataBlock : headerKey out of range");
656 if ( !isSectNumValid(vol,dBlock->nextData) )
657 (*adfEnv.wFct)("adfReadDataBlock : nextData out of range");
660 return rc;
665 * adfWriteDataBlock
668 RETCODE adfWriteDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
670 unsigned char buf[512];
671 ULONG newSum;
672 struct bOFSDataBlock *dataB;
673 RETCODE rc = RC_OK;
675 newSum = 0L;
676 if (isOFS(vol->dosType)) {
677 dataB = (struct bOFSDataBlock *)data;
678 dataB->type = T_DATA;
679 memcpy(buf,dataB,512);
680 #ifdef LITT_ENDIAN
681 swapEndian(buf, SWBL_DATA);
682 #endif
683 newSum = adfNormalSum(buf,20,512);
684 swLong(buf+20,newSum);
685 // *(ULONG*)(buf+20) = swapLong((unsigned char*)&newSum);
686 adfWriteBlock(vol,nSect,buf);
688 else {
689 adfWriteBlock(vol,nSect,data);
691 //printf("adfWriteDataBlock %ld\n",nSect);
693 return rc;
698 * adfReadFileExtBlock
701 RETCODE adfReadFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext)
703 unsigned char buf[sizeof(struct bFileExtBlock)];
704 RETCODE rc = RC_OK;
706 adfReadBlock(vol, nSect,buf);
707 /*printf("read fext=%d\n",nSect);*/
708 memcpy(fext,buf,sizeof(struct bFileExtBlock));
709 #ifdef LITT_ENDIAN
710 swapEndian((unsigned char*)fext, SWBL_FEXT);
711 #endif
712 if (fext->checkSum!=adfNormalSum(buf,20,sizeof(struct bFileExtBlock)))
713 (*adfEnv.wFct)("adfReadFileExtBlock : invalid checksum");
714 if (fext->type!=T_LIST)
715 (*adfEnv.wFct)("adfReadFileExtBlock : type T_LIST not found");
716 if (fext->secType!=ST_FILE)
717 (*adfEnv.wFct)("adfReadFileExtBlock : stype ST_FILE not found");
718 if (fext->headerKey!=nSect)
719 (*adfEnv.wFct)("adfReadFileExtBlock : headerKey!=nSect");
720 if (fext->highSeq>MAX_DATABLK)
721 (*adfEnv.wFct)("adfReadFileExtBlock : highSeq out of range");
722 if ( !isSectNumValid(vol, fext->parent) )
723 (*adfEnv.wFct)("adfReadFileExtBlock : parent out of range");
724 if ( fext->extension!=0 && !isSectNumValid(vol, fext->extension) )
725 (*adfEnv.wFct)("adfReadFileExtBlock : extension out of range");
727 return rc;
732 * adfWriteFileExtBlock
735 RETCODE adfWriteFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext)
737 unsigned char buf[512];
738 ULONG newSum;
739 RETCODE rc = RC_OK;
741 fext->type = T_LIST;
742 fext->secType = ST_FILE;
743 fext->dataSize = 0L;
744 fext->firstData = 0L;
746 memcpy(buf,fext,512);
747 #ifdef LITT_ENDIAN
748 swapEndian(buf, SWBL_FEXT);
749 #endif
750 newSum = adfNormalSum(buf,20,512);
751 swLong(buf+20,newSum);
752 // *(ULONG*)(buf+20) = swapLong((unsigned char*)&newSum);
754 adfWriteBlock(vol,nSect,buf);
756 return rc;
758 /*###########################################################################*/