Indentation fix, cleanup.
[AROS.git] / tools / adflib / adf_disk.c
blob6b90117215d5de412bd0247d00de66e43ded0ba7
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 RETCODE adfInstallBootBlock(struct Volume *vol, unsigned char* code)
28 int i;
29 struct bBootBlock boot;
31 if (vol->dev->devType!=DEVTYPE_FLOPDD && vol->dev->devType!=DEVTYPE_FLOPHD)
32 return RC_ERROR;
34 if (adfReadBootBlock(vol, &boot)!=RC_OK)
35 return RC_ERROR;
37 boot.rootBlock = vol->rootBlock;
38 for(i=0; i<1024-12; i++) /* bootcode */
39 boot.data[i] = code[i+12];
41 if (adfWriteBootBlock(vol, &boot)!=RC_OK)
42 return RC_ERROR;
44 vol->bootCode = TRUE;
46 return RC_OK;
51 * isSectNumValid
54 BOOL isSectNumValid(struct Volume *vol, SECTNUM nSect)
56 return( 0<=nSect && nSect < vol->totalBlocks);
62 * adfVolumeInfo
65 void adfVolumeInfo(struct Volume *vol)
67 struct bRootBlock root;
68 char diskName[35];
69 int days,month,year;
71 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
72 return;
74 memset(diskName, 0, 35);
75 memcpy(diskName, root.diskName, root.nameLen);
77 printf ("Name : %-30s\n",vol->volName);
78 printf ("Type : ");
79 switch(vol->dev->devType) {
80 case DEVTYPE_FLOPDD:
81 printf ("Floppy Double Density : 880 KBytes\n");
82 break;
83 case DEVTYPE_FLOPHD:
84 printf ("Floppy High Density : 1760 KBytes\n");
85 break;
86 case DEVTYPE_HARDDISK:
87 printf ("Hard Disk partition : %3.1f KBytes\n",
88 (vol->totalBlocks) * 512.0/1024.0);
89 break;
90 case DEVTYPE_HARDFILE:
91 printf ("HardFile : %3.1f KBytes\n",
92 (vol->totalBlocks) * 512.0/1024.0);
93 break;
94 default:
95 printf ("Unknown devType!\n");
97 printf ("Filesystem : ");
98 printf("%s ",isFFS(vol->dosType) ? "FFS" : "OFS");
99 if (isINTL(vol->dosType))
100 printf ("INTL ");
101 if (isDIRCACHE(vol->dosType))
102 printf ("DIRCACHE ");
103 putchar('\n');
105 printf("Free blocks = %ld\n", (long)adfCountFreeBlocks(vol));
106 if (vol->readOnly)
107 printf("Read only\n");
108 else
109 printf("Read/Write\n");
111 /* created */
112 adfDays2Date(root.coDays, &year, &month, &days);
113 printf ("created %d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
114 (long)root.coMins/60,(long)root.coMins%60,(long)root.coTicks/50);
115 adfDays2Date(root.days, &year, &month, &days);
116 printf ("last access %d/%02d/%02d %ld:%02ld:%02ld, ",days,month,year,
117 (long)root.mins/60,(long)root.mins%60,(long)root.ticks/50);
118 adfDays2Date(root.cDays, &year, &month, &days);
119 printf ("%d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
120 (long)root.cMins/60,(long)root.cMins%60,(long)root.cTicks/50);
126 * adfMount
130 struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly )
132 struct bRootBlock root;
133 struct bBootBlock boot;
134 struct Volume* vol;
136 if (dev==NULL || nPart >= dev->nVol) // removed "|| nPart<nPart " .... nonsense comparison?
138 (*adfEnv.eFct)("adfMount : invalid parameter(s)");
139 return NULL;
142 vol = dev->volList[nPart];
143 vol->dev = dev;
144 vol->mounted = TRUE;
146 if (adfReadBootBlock(vol, &boot)!=RC_OK) {
147 (*adfEnv.wFct)("adfMount : BootBlock invalid");
148 return NULL;
151 vol->dosType = boot.dosType[3];
152 if (isFFS(vol->dosType))
153 vol->datablockSize=512;
154 else
155 vol->datablockSize=488;
157 if (dev->readOnly /*|| isDIRCACHE(vol->dosType)*/)
158 vol->readOnly = TRUE;
159 else
160 vol->readOnly = readOnly;
162 vol->rootBlock = boot.rootBlock;
164 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
165 (*adfEnv.wFct)("adfMount : RootBlock invalid");
166 return NULL;
169 adfReadBitmap( vol, &root );
170 vol->curDirPtr = vol->rootBlock;
172 //printf("blockSize=%d\n",vol->blockSize);
174 return( vol );
180 * adfUnMount
182 * free bitmap structures
183 * free current dir
185 void adfUnMount(struct Volume *vol)
187 if (!vol) {
188 (*adfEnv.eFct)("adfUnMount : vol is null");
189 return;
192 adfFreeBitmap(vol);
194 vol->mounted = FALSE;
201 * adfCreateVol
205 struct Volume* adfCreateVol( struct Device* dev, ULONG start, ULONG len, int reserved,
206 char* volName, int dosType )
208 struct bBootBlock boot;
209 struct bRootBlock root;
210 // struct bDirCacheBlock dirc;
211 SECTNUM blkList[2];
212 struct Volume* vol;
213 int nlen;
215 if (adfEnv.useProgressBar)
216 (*adfEnv.progressBar)(0);
218 vol=(struct Volume*)malloc(sizeof(struct Volume));
219 if (!vol) {
220 (*adfEnv.eFct)("adfCreateVol : malloc vol");
221 return NULL;
224 /* It is illegal to have 0 reserved blocks */
225 if (reserved <= 0)
226 reserved = 2;
228 vol->dev = dev;
229 vol->firstBlock = (dev->heads * dev->sectors)*start;
230 vol->totalBlocks = (dev->heads * dev->sectors)*len;
231 vol->reservedBlocks = reserved;
232 vol->rootBlock = (vol->totalBlocks-1 + reserved)/2;
233 vol->curDirPtr = vol->rootBlock;
234 vol->dosType = dosType;
236 vol->readOnly = dev->readOnly;
238 vol->mounted = TRUE;
240 nlen = min( MAXNAMELEN, strlen(volName) );
241 vol->volName = (char*)malloc(nlen+1);
242 if (!vol->volName) {
243 (*adfEnv.eFct)("adfCreateVol : malloc");
244 free(vol); return NULL;
246 memcpy(vol->volName, volName, nlen);
247 vol->volName[nlen]='\0';
249 if (adfEnv.useProgressBar)
250 (*adfEnv.progressBar)(25);
252 memset(&boot, 0, sizeof(boot));
253 if (adfWriteBootBlock(vol, &boot)!=RC_OK) {
254 free(vol->volName); free(vol);
255 return NULL;
258 if (adfEnv.useProgressBar)
259 (*adfEnv.progressBar)(20);
261 if (adfCreateBitmap( vol )!=RC_OK) {
262 free(vol->volName); free(vol);
263 return NULL;
266 if (adfEnv.useProgressBar)
267 (*adfEnv.progressBar)(40);
270 /*for(i=0; i<127; i++)
271 printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]);
273 if ( isDIRCACHE(dosType) )
274 adfGetFreeBlocks( vol, 1, blkList );
277 /*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/
279 memset(&root, 0, sizeof(root));
281 if (strlen(volName)>MAXNAMELEN)
282 volName[MAXNAMELEN]='\0';
283 root.nameLen = strlen(volName);
284 memcpy(root.diskName,volName,root.nameLen);
285 adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks));
287 /* dircache block */
288 if ( isDIRCACHE(dosType) ) {
289 root.extension = 0L;
290 root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */
291 adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[0]);
294 if (adfEnv.useProgressBar)
295 (*adfEnv.progressBar)(60);
297 if (adfWriteRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
298 free(vol->volName); free(vol);
299 return NULL;
302 /* fills root->bmPages[] and writes filled bitmapExtBlocks */
303 if (adfWriteNewBitmap(vol)!=RC_OK)
304 return NULL;
306 if (adfEnv.useProgressBar)
307 (*adfEnv.progressBar)(80);
309 if (adfUpdateBitmap(vol)!=RC_OK)
310 return NULL;
312 if (adfEnv.useProgressBar)
313 (*adfEnv.progressBar)(100);
314 //printf("free blocks %ld\n",adfCountFreeBlocks(vol));
316 /* will be managed by adfMount() later */
317 adfFreeBitmap(vol);
319 vol->mounted = FALSE;
321 return(vol);
325 /*-----*/
328 * adfReadBlock
330 * read logical block
332 RETCODE
333 adfReadBlock(struct Volume* vol, ULONG nSect, unsigned char* buf)
335 /* char strBuf[80];*/
336 ULONG pSect;
337 struct nativeFunctions *nFct;
338 RETCODE rc;
340 if (!vol->mounted) {
341 (*adfEnv.eFct)("the volume isn't mounted, adfReadBlock not possible");
342 return RC_ERROR;
345 if (nSect >= vol->totalBlocks)
346 (*adfEnv.wFct)("adfReadBlock : nSect out of range");
348 /* translate logical sect to physical sect */
349 pSect = nSect+vol->firstBlock;
351 if (adfEnv.useRWAccess)
352 (*adfEnv.rwhAccess)(pSect,nSect,FALSE);
354 //printf("psect=%ld nsect=%ld\n",pSect,nSect);
355 /* sprintf(strBuf,"ReadBlock : accessing logical block #%ld", nSect);
356 (*adfEnv.vFct)(strBuf);
358 //printf("pSect R =%ld\n",pSect);
359 nFct = adfEnv.nativeFct;
360 if (vol->dev->isNativeDev)
361 rc = (*nFct->adfNativeReadSector)(vol->dev, pSect, 512, buf);
362 else
363 rc = adfReadDumpSector(vol->dev, pSect, 512, buf);
364 //printf("rc=%ld\n",rc);
366 if (rc!=RC_OK) {
367 (*adfEnv.wFct)("adfReadBlock : Can't read sector");
368 return RC_ERROR;
369 } else
370 return RC_OK;
375 * adfWriteBlock
378 RETCODE adfWriteBlock(struct Volume* vol, ULONG nSect, unsigned char *buf)
380 ULONG pSect;
381 struct nativeFunctions *nFct;
382 RETCODE rc;
384 if (!vol->mounted) {
385 (*adfEnv.eFct)("the volume isn't mounted, adfWriteBlock not possible");
386 return RC_ERROR;
389 if (vol->readOnly) {
390 (*adfEnv.wFct)("adfWriteBlock : can't write block, read only volume");
391 return RC_ERROR;
394 if (nSect >= vol->totalBlocks) {
395 (*adfEnv.wFct)("adfWriteBlock : nSect out of range");
398 pSect = nSect+vol->firstBlock;
399 //printf("write nsect=%ld psect=%ld\n",nSect,pSect);
401 if (adfEnv.useRWAccess)
402 (*adfEnv.rwhAccess)(pSect,nSect,TRUE);
404 nFct = adfEnv.nativeFct;
405 if (vol->dev->isNativeDev)
406 rc = (*nFct->adfNativeWriteSector)(vol->dev, pSect, 512, buf);
407 else
408 rc = adfWriteDumpSector(vol->dev, pSect, 512, buf);
410 if (rc!=RC_OK)
411 return RC_ERROR;
412 else
413 return RC_OK;
418 /*#######################################################################################*/