Belarusian
[AROS.git] / tools / adflib / adf_disk.c
blob4acfb5c6b699947dace118344d11a70ea26fbbbe
1 /*
2 * ADF Library. (C) 1997-1999 Laurent Clevy
4 * adf_disk.c
6 * logical disk/volume code
7 */
9 #include <limits.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "adf_str.h"
14 #include "adf_disk.h"
15 #include "adf_raw.h"
16 #include "adf_hd.h"
17 #include "adf_bitm.h"
18 #include "adf_util.h"
19 #include "adf_nativ.h"
20 #include "adf_dump.h"
21 #include "adf_err.h"
22 #include "adf_cache.h"
24 extern struct Env adfEnv;
26 unsigned long bitMask[32] = {
27 0x1, 0x2, 0x4, 0x8,
28 0x10, 0x20, 0x40, 0x80,
29 0x100, 0x200, 0x400, 0x800,
30 0x1000, 0x2000, 0x4000, 0x8000,
31 0x10000, 0x20000, 0x40000, 0x80000,
32 0x100000, 0x200000, 0x400000, 0x800000,
33 0x1000000, 0x2000000, 0x4000000, 0x8000000,
34 0x10000000, 0x20000000, 0x40000000, 0x80000000 };
37 RETCODE adfInstallBootBlock(struct Volume *vol, unsigned char* code)
39 int i;
40 struct bBootBlock boot;
42 if (vol->dev->devType!=DEVTYPE_FLOPDD && vol->dev->devType!=DEVTYPE_FLOPHD)
43 return RC_ERROR;
45 if (adfReadBootBlock(vol, &boot)!=RC_OK)
46 return RC_ERROR;
48 boot.rootBlock = 880;
49 for(i=0; i<1024-12; i++) /* bootcode */
50 boot.data[i] = code[i+12];
52 if (adfWriteBootBlock(vol, &boot)!=RC_OK)
53 return RC_ERROR;
55 vol->bootCode = TRUE;
57 return RC_OK;
62 * isSectNumValid
65 BOOL isSectNumValid(struct Volume *vol, SECTNUM nSect)
67 return( 0<=nSect && nSect<=(vol->lastBlock - vol->firstBlock) );
73 * adfVolumeInfo
76 void adfVolumeInfo(struct Volume *vol)
78 struct bRootBlock root;
79 char diskName[35];
80 int days,month,year;
82 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
83 return;
85 memset(diskName, 0, 35);
86 memcpy(diskName, root.diskName, root.nameLen);
88 printf ("Name : %-30s\n",vol->volName);
89 printf ("Type : ");
90 switch(vol->dev->devType) {
91 case DEVTYPE_FLOPDD:
92 printf ("Floppy Double Density : 880 KBytes\n");
93 break;
94 case DEVTYPE_FLOPHD:
95 printf ("Floppy High Density : 1760 KBytes\n");
96 break;
97 case DEVTYPE_HARDDISK:
98 printf ("Hard Disk partition : %3.1f KBytes\n",
99 (vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
100 break;
101 case DEVTYPE_HARDFILE:
102 printf ("HardFile : %3.1f KBytes\n",
103 (vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
104 break;
105 default:
106 printf ("Unknown devType!\n");
108 printf ("Filesystem : ");
109 printf("%s ",isFFS(vol->dosType) ? "FFS" : "OFS");
110 if (isINTL(vol->dosType))
111 printf ("INTL ");
112 if (isDIRCACHE(vol->dosType))
113 printf ("DIRCACHE ");
114 putchar('\n');
116 printf("Free blocks = %ld\n", adfCountFreeBlocks(vol));
117 if (vol->readOnly)
118 printf("Read only\n");
119 else
120 printf("Read/Write\n");
122 /* created */
123 adfDays2Date(root.coDays, &year, &month, &days);
124 printf ("created %d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
125 root.coMins/60,root.coMins%60,root.coTicks/50);
126 adfDays2Date(root.days, &year, &month, &days);
127 printf ("last access %d/%02d/%02d %ld:%02ld:%02ld, ",days,month,year,
128 root.mins/60,root.mins%60,root.ticks/50);
129 adfDays2Date(root.cDays, &year, &month, &days);
130 printf ("%d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
131 root.cMins/60,root.cMins%60,root.cTicks/50);
137 * adfMount
141 struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly )
143 long nBlock;
144 struct bRootBlock root;
145 struct bBootBlock boot;
146 struct Volume* vol;
148 if (dev==NULL || nPart<nPart || nPart >= dev->nVol) {
149 (*adfEnv.eFct)("adfMount : invalid parameter(s)");
150 return NULL;
153 vol = dev->volList[nPart];
154 vol->dev = dev;
155 vol->mounted = TRUE;
157 /*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
158 vol->lastBlock, vol->rootBlock);
160 if (adfReadBootBlock(vol, &boot)!=RC_OK) {
161 (*adfEnv.wFct)("adfMount : BootBlock invalid");
162 return NULL;
165 vol->dosType = boot.dosType[3];
166 if (isFFS(vol->dosType))
167 vol->datablockSize=512;
168 else
169 vol->datablockSize=488;
171 if (dev->readOnly /*|| isDIRCACHE(vol->dosType)*/)
172 vol->readOnly = TRUE;
173 else
174 vol->readOnly = readOnly;
176 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
177 (*adfEnv.wFct)("adfMount : RootBlock invalid");
178 return NULL;
181 nBlock = vol->lastBlock - vol->firstBlock +1 - 2;
183 adfReadBitmap( vol, nBlock, &root );
184 vol->curDirPtr = vol->rootBlock;
186 //printf("blockSize=%d\n",vol->blockSize);
188 return( vol );
194 * adfUnMount
196 * free bitmap structures
197 * free current dir
199 void adfUnMount(struct Volume *vol)
201 if (!vol) {
202 (*adfEnv.eFct)("adfUnMount : vol is null");
203 return;
206 adfFreeBitmap(vol);
208 vol->mounted = FALSE;
215 * adfCreateVol
219 struct Volume* adfCreateVol( struct Device* dev, long start, long len,
220 char* volName, int volType )
222 struct bBootBlock boot;
223 struct bRootBlock root;
224 // struct bDirCacheBlock dirc;
225 SECTNUM blkList[2];
226 struct Volume* vol;
227 int nlen;
229 if (adfEnv.useProgressBar)
230 (*adfEnv.progressBar)(0);
232 vol=(struct Volume*)malloc(sizeof(struct Volume));
233 if (!vol) {
234 (*adfEnv.eFct)("adfCreateVol : malloc vol");
235 return NULL;
238 vol->dev = dev;
239 vol->firstBlock = (dev->heads * dev->sectors)*start;
240 vol->lastBlock = (vol->firstBlock + (dev->heads * dev->sectors)*len)-1;
241 vol->rootBlock = ((vol->lastBlock - vol->firstBlock+1)-1+2)/2;
242 /*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
243 vol->lastBlock, vol->rootBlock);
245 vol->curDirPtr = vol->rootBlock;
247 vol->readOnly = dev->readOnly;
249 vol->mounted = TRUE;
251 nlen = min( MAXNAMELEN, strlen(volName) );
252 vol->volName = (char*)malloc(nlen+1);
253 if (!vol->volName) {
254 (*adfEnv.eFct)("adfCreateVol : malloc");
255 free(vol); return NULL;
257 memcpy(vol->volName, volName, nlen);
258 vol->volName[nlen]='\0';
260 if (adfEnv.useProgressBar)
261 (*adfEnv.progressBar)(25);
263 memset(&boot, 0, 1024);
264 boot.dosType[3] = volType;
265 /*printf("first=%d last=%d\n", vol->firstBlock, vol->lastBlock);
266 printf("name=%s root=%d\n", vol->volName, vol->rootBlock);
268 if (adfWriteBootBlock(vol, &boot)!=RC_OK) {
269 free(vol->volName); free(vol);
270 return NULL;
273 if (adfEnv.useProgressBar)
274 (*adfEnv.progressBar)(20);
276 if (adfCreateBitmap( vol )!=RC_OK) {
277 free(vol->volName); free(vol);
278 return NULL;
281 if (adfEnv.useProgressBar)
282 (*adfEnv.progressBar)(40);
285 /*for(i=0; i<127; i++)
286 printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]);
288 if ( isDIRCACHE(volType) )
289 adfGetFreeBlocks( vol, 2, blkList );
290 else
291 adfGetFreeBlocks( vol, 1, blkList );
294 /*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/
296 memset(&root, 0, LOGICAL_BLOCK_SIZE);
298 if (strlen(volName)>MAXNAMELEN)
299 volName[MAXNAMELEN]='\0';
300 root.nameLen = strlen(volName);
301 memcpy(root.diskName,volName,root.nameLen);
302 adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks));
304 /* dircache block */
305 if ( isDIRCACHE(volType) ) {
306 root.extension = 0L;
307 root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */
308 adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[1]);
311 if (adfEnv.useProgressBar)
312 (*adfEnv.progressBar)(60);
314 if (adfWriteRootBlock(vol, blkList[0], &root)!=RC_OK) {
315 free(vol->volName); free(vol);
316 return NULL;
319 /* fills root->bmPages[] and writes filled bitmapExtBlocks */
320 if (adfWriteNewBitmap(vol)!=RC_OK)
321 return NULL;
323 if (adfEnv.useProgressBar)
324 (*adfEnv.progressBar)(80);
326 if (adfUpdateBitmap(vol)!=RC_OK)
327 return NULL;
329 if (adfEnv.useProgressBar)
330 (*adfEnv.progressBar)(100);
331 //printf("free blocks %ld\n",adfCountFreeBlocks(vol));
333 /* will be managed by adfMount() later */
334 adfFreeBitmap(vol);
336 vol->mounted = FALSE;
338 return(vol);
342 /*-----*/
345 * adfReadBlock
347 * read logical block
349 RETCODE
350 adfReadBlock(struct Volume* vol, long nSect, unsigned char* buf)
352 /* char strBuf[80];*/
353 long pSect;
354 struct nativeFunctions *nFct;
355 RETCODE rc;
357 if (!vol->mounted) {
358 (*adfEnv.eFct)("the volume isn't mounted, adfReadBlock not possible");
359 return RC_ERROR;
362 /* translate logical sect to physical sect */
363 pSect = nSect+vol->firstBlock;
365 if (adfEnv.useRWAccess)
366 (*adfEnv.rwhAccess)(pSect,nSect,FALSE);
368 //printf("psect=%ld nsect=%ld\n",pSect,nSect);
369 /* sprintf(strBuf,"ReadBlock : accessing logical block #%ld", nSect);
370 (*adfEnv.vFct)(strBuf);
372 if (pSect<vol->firstBlock || pSect>vol->lastBlock) {
373 (*adfEnv.wFct)("adfReadBlock : nSect out of range");
376 //printf("pSect R =%ld\n",pSect);
377 nFct = adfEnv.nativeFct;
378 if (vol->dev->isNativeDev)
379 rc = (*nFct->adfNativeReadSector)(vol->dev, pSect, 512, buf);
380 else
381 rc = adfReadDumpSector(vol->dev, pSect, 512, buf);
382 //printf("rc=%ld\n",rc);
383 if (rc!=RC_OK)
384 return RC_ERROR;
385 else
386 return RC_OK;
391 * adfWriteBlock
394 RETCODE adfWriteBlock(struct Volume* vol, long nSect, unsigned char *buf)
396 long pSect;
397 struct nativeFunctions *nFct;
398 RETCODE rc;
400 if (!vol->mounted) {
401 (*adfEnv.eFct)("the volume isn't mounted, adfWriteBlock not possible");
402 return RC_ERROR;
405 if (vol->readOnly) {
406 (*adfEnv.wFct)("adfWriteBlock : can't write block, read only volume");
407 return RC_ERROR;
410 pSect = nSect+vol->firstBlock;
411 //printf("write nsect=%ld psect=%ld\n",nSect,pSect);
413 if (adfEnv.useRWAccess)
414 (*adfEnv.rwhAccess)(pSect,nSect,TRUE);
416 if (pSect<vol->firstBlock || pSect>vol->lastBlock) {
417 (*adfEnv.wFct)("adfWriteBlock : nSect out of range");
420 nFct = adfEnv.nativeFct;
421 //printf("nativ=%d\n",vol->dev->isNativeDev);
422 if (vol->dev->isNativeDev)
423 rc = (*nFct->adfNativeWriteSector)(vol->dev, pSect, 512, buf);
424 else
425 rc = adfWriteDumpSector(vol->dev, pSect, 512, buf);
427 if (rc!=RC_OK)
428 return RC_ERROR;
429 else
430 return RC_OK;
435 /*#######################################################################################*/