/* * adfGet1FreeBlock * */ SECTNUM adfGet1FreeBlock(struct Volume *vol) { SECTNUM block[1]; if (!adfGetFreeBlocks(vol,1,block)) return(-1); else return(block[0]); }
/* * adfWriteNewBitmap * * write ext blocks and bitmap * * uses vol->bitmapSize, */ RETCODE adfWriteNewBitmap(struct Volume *vol) { struct bBitmapExtBlock bitme; SECTNUM *bitExtBlock; int n, i, k; int nExtBlock; int nBlock; SECTNUM *sectList; struct bRootBlock root; sectList=(SECTNUM*)malloc(sizeof(SECTNUM)*vol->bitmapSize); if (!sectList) { (*adfEnv.eFct)("adfCreateBitmap : sectList"); return RC_MALLOC; } if (!adfGetFreeBlocks(vol, vol->bitmapSize, sectList)) { free(sectList); return RC_ERROR; } if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) { free(sectList); return RC_ERROR; } nBlock = 0; n = min( vol->bitmapSize, BM_SIZE ); for(i=0; i<n; i++) { root.bmPages[i] = vol->bitmapBlocks[i] = sectList[i]; } nBlock = n; /* for devices with more than 25*127 blocks == hards disks */ if (vol->bitmapSize>BM_SIZE) { nExtBlock = (vol->bitmapSize-BM_SIZE)/127; if ((vol->bitmapSize-BM_SIZE)%127) nExtBlock++; bitExtBlock=(SECTNUM*)malloc(sizeof(SECTNUM)*nExtBlock); if (!bitExtBlock) { free(sectList); adfEnv.eFct("adfWriteNewBitmap : malloc failed"); return RC_MALLOC; } if (!adfGetFreeBlocks(vol, nExtBlock, bitExtBlock)) { free(sectList); free(bitExtBlock); return RC_MALLOC; } k = 0; root.bmExt = bitExtBlock[ k ]; while( nBlock<vol->bitmapSize ) { i=0; while( i<127 && nBlock<vol->bitmapSize ) { bitme.bmPages[i] = vol->bitmapBlocks[nBlock] = sectList[i]; i++; nBlock++; } if ( k+1<nExtBlock ) bitme.nextBlock = bitExtBlock[ k+1 ]; else bitme.nextBlock = 0; if (adfWriteBitmapExtBlock(vol, bitExtBlock[ k ], &bitme)!=RC_OK) { free(sectList); free(bitExtBlock); return RC_ERROR; } k++; } free( bitExtBlock ); } free( sectList); if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK) return RC_ERROR; return RC_OK; }
/* * adfCreateVol * * */ struct Volume* adfCreateVol( struct Device* dev, int32_t start, int32_t len, char* volName, int volType,struct DateTime * voldate ) { struct bBootBlock boot; struct bRootBlock root; /* struct bDirCacheBlock dirc;*/ SECTNUM blkList[2]; struct Volume* vol; int nlen; if (adfEnv.useProgressBar) (*adfEnv.progressBar)(0); vol=(struct Volume*)calloc(1,sizeof(struct Volume)); if (!vol) { (*adfEnv.eFct)("adfCreateVol : malloc vol"); return NULL; } vol->dev = dev; vol->firstBlock = (dev->heads * dev->sectors)*start; vol->lastBlock = (vol->firstBlock + (dev->heads * dev->sectors)*len)-1; vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2; /*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock, vol->lastBlock, vol->rootBlock); */ vol->curDirPtr = vol->rootBlock; vol->readOnly = dev->readOnly; vol->mounted = TRUE; nlen = min( MAXNAMELEN, strlen(volName) ); vol->volName = (char*)calloc(1,nlen+1); if (!vol->volName) { (*adfEnv.eFct)("adfCreateVol : malloc"); free(vol); return NULL; } memcpy(vol->volName, volName, nlen); vol->volName[nlen]='\0'; if (adfEnv.useProgressBar) (*adfEnv.progressBar)(25); memset(&boot, 0, 1024); boot.dosType[3] = volType; /*printf("first=%d last=%d\n", vol->firstBlock, vol->lastBlock); printf("name=%s root=%d\n", vol->volName, vol->rootBlock); */ if (adfWriteBootBlock(vol, &boot)!=RC_OK) { free(vol->volName); free(vol); return NULL; } if (adfEnv.useProgressBar) (*adfEnv.progressBar)(20); if (adfCreateBitmap( vol )!=RC_OK) { free(vol->volName); free(vol); return NULL; } if (adfEnv.useProgressBar) (*adfEnv.progressBar)(40); /*for(i=0; i<127; i++) printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]); */ if ( isDIRCACHE(volType) ) adfGetFreeBlocks( vol, 2, blkList ); else adfGetFreeBlocks( vol, 1, blkList ); /*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/ memset(&root, 0, LOGICAL_BLOCK_SIZE); if (strlen(volName)>MAXNAMELEN) volName[MAXNAMELEN]='\0'; root.nameLen = (char)strlen(volName); memcpy(root.diskName,volName,root.nameLen); if(voldate) { adfTime2AmigaTime(*voldate,&(root.coDays),&(root.coMins),&(root.coTicks)); } else { adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks)); } /* dircache block */ if ( isDIRCACHE(volType) ) { root.extension = 0L; root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */ adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[1]); } if (adfEnv.useProgressBar) (*adfEnv.progressBar)(60); if (adfWriteRootBlock(vol, blkList[0], &root)!=RC_OK) { free(vol->volName); free(vol); return NULL; } /* fills root->bmPages[] and writes filled bitmapExtBlocks */ if (adfWriteNewBitmap(vol)!=RC_OK) return NULL; if (adfEnv.useProgressBar) (*adfEnv.progressBar)(80); if (adfUpdateBitmap(vol)!=RC_OK) return NULL; if (adfEnv.useProgressBar) (*adfEnv.progressBar)(100); /*printf("free blocks %ld\n",adfCountFreeBlocks(vol));*/ /* will be managed by adfMount() later */ adfFreeBitmap(vol); vol->mounted = FALSE; return(vol); }