/* * adfUpdateBitmap * */ RETCODE adfUpdateBitmap(struct Volume *vol) { int i; struct bRootBlock root; /*printf("adfUpdateBitmap\n");*/ if (adfReadRootBlock(vol, vol->rootBlock,&root)!=RC_OK) return RC_ERROR; root.bmFlag = BM_INVALID; if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK) return RC_ERROR; for(i=0; i<vol->bitmapSize; i++) if (vol->bitmapBlocksChg[i]) { if (adfWriteBitmapBlock(vol, vol->bitmapBlocks[i], vol->bitmapTable[i])!=RC_OK) return RC_ERROR; vol->bitmapBlocksChg[i] = FALSE; } root.bmFlag = BM_VALID; adfTime2AmigaTime(adfGiveCurrentTime(),&(root.days),&(root.mins),&(root.ticks)); if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK) return RC_ERROR; return RC_OK; }
/* * adfCreateDir * */ RETCODE adfCreateDir(struct Volume* vol, SECTNUM nParent, char* name) { SECTNUM nSect; struct bDirBlock dir; struct bEntryBlock parent; if (adfReadEntryBlock(vol, nParent, &parent)!=RC_OK) return RC_ERROR; /* -1 : do not use a specific, already allocated sector */ nSect = adfCreateEntry(vol, &parent, name, -1); if (nSect==-1) { (*adfEnv.wFct)("adfCreateDir : no sector available"); return RC_ERROR; } memset(&dir, 0, sizeof(struct bDirBlock)); dir.nameLen = (char)min(MAXNAMELEN, strlen(name)); memcpy(dir.dirName,name,dir.nameLen); dir.headerKey = nSect; if (parent.secType==ST_ROOT) dir.parent = vol->rootBlock; else dir.parent = parent.headerKey; adfTime2AmigaTime(adfGiveCurrentTime(),&(dir.days),&(dir.mins),&(dir.ticks)); if (isDIRCACHE(vol->dosType)) { /* for adfCreateEmptyCache, will be added by adfWriteDirBlock */ dir.secType = ST_DIR; adfAddInCache(vol, &parent, (struct bEntryBlock *)&dir); adfCreateEmptyCache(vol, (struct bEntryBlock *)&dir, -1); } /* writes the dirblock, with the possible dircache assiocated */ if (adfWriteDirBlock(vol, nSect, &dir)!=RC_OK) return RC_ERROR; adfUpdateBitmap(vol); if (adfEnv.useNotify) (*adfEnv.notifyFct)(nParent,ST_DIR); return RC_OK; }
/* * adfCreateFile * */ RETCODE adfCreateFile(struct Volume* vol, SECTNUM nParent, char *name, struct bFileHeaderBlock *fhdr) { SECTNUM nSect; struct bEntryBlock parent; /*puts("adfCreateFile in");*/ if (adfReadEntryBlock(vol, nParent, &parent)!=RC_OK) return RC_ERROR; /* -1 : do not use a specific, already allocated sector */ nSect = adfCreateEntry(vol, &parent, name, -1); if (nSect==-1) return RC_ERROR; /*printf("new fhdr=%d\n",nSect);*/ memset(fhdr,0,512); fhdr->nameLen = (char)min(MAXNAMELEN, strlen(name)); memcpy(fhdr->fileName,name,fhdr->nameLen); fhdr->headerKey = nSect; if (parent.secType==ST_ROOT) fhdr->parent = vol->rootBlock; else if (parent.secType==ST_DIR) fhdr->parent = parent.headerKey; else (*adfEnv.wFct)("adfCreateFile : unknown parent secType"); adfTime2AmigaTime(adfGiveCurrentTime(), &(fhdr->days),&(fhdr->mins),&(fhdr->ticks)); if (adfWriteFileHdrBlock(vol,nSect,fhdr)!=RC_OK) return RC_ERROR; if (isDIRCACHE(vol->dosType)) adfAddInCache(vol, &parent, (struct bEntryBlock *)fhdr); adfUpdateBitmap(vol); if (adfEnv.useNotify) (*adfEnv.notifyFct)(nParent,ST_FILE); return RC_OK; }
/* * adfFileFlush * */ void adfFlushFile(struct File *file) { struct bEntryBlock parent; struct bOFSDataBlock *data; if (file->currentExt) { if (file->writeMode) adfWriteFileExtBlock(file->volume, file->currentExt->headerKey, file->currentExt); } if (file->currentData) { if (file->writeMode) { file->fileHdr->byteSize = file->pos; if (isOFS(file->volume->dosType)) { data = (struct bOFSDataBlock *)file->currentData; data->dataSize = file->posInDataBlk; } if (file->fileHdr->byteSize>0) adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData); } } if (file->writeMode) { file->fileHdr->byteSize = file->pos; /*printf("pos=%ld\n",file->pos);*/ adfTime2AmigaTime(adfGiveCurrentTime(), &(file->fileHdr->days),&(file->fileHdr->mins),&(file->fileHdr->ticks) ); adfWriteFileHdrBlock(file->volume, file->fileHdr->headerKey, file->fileHdr); if (isDIRCACHE(file->volume->dosType)) { /*printf("parent=%ld\n",file->fileHdr->parent);*/ adfReadEntryBlock(file->volume, file->fileHdr->parent, &parent); adfUpdateCache(file->volume, &parent, (struct bEntryBlock*)file->fileHdr,FALSE); } adfUpdateBitmap(file->volume); } }
/* * adfCreateEntry * * if 'thisSect'==-1, allocate a sector, and insert its pointer into the hashTable of 'dir', using the * name 'name'. if 'thisSect'!=-1, insert this sector pointer into the hashTable * (here 'thisSect' must be allocated before in the bitmap). */ SECTNUM adfCreateEntry(struct Volume *vol, struct bEntryBlock *dir, char *name, SECTNUM thisSect ) { BOOL intl; struct bEntryBlock updEntry; int len, hashValue; RETCODE rc; char name2[MAXNAMELEN+1], name3[MAXNAMELEN+1]; SECTNUM nSect, newSect, newSect2; struct bRootBlock* root; /*puts("adfCreateEntry in");*/ intl = isINTL(vol->dosType) || isDIRCACHE(vol->dosType); len = min(strlen(name), MAXNAMELEN) ; myToUpper((unsigned char*)name2, (unsigned char*)name, len, intl); hashValue = adfGetHashValue((unsigned char*)name, intl); nSect = dir->hashTable[ hashValue ]; if ( nSect==0 ) { if (thisSect!=-1) newSect = thisSect; else { newSect = adfGet1FreeBlock(vol); if (newSect==-1) { (*adfEnv.wFct)("adfCreateEntry : nSect==-1"); return -1; } } dir->hashTable[ hashValue ] = newSect; if (dir->secType==ST_ROOT) { root = (struct bRootBlock*)dir; adfTime2AmigaTime(adfGiveCurrentTime(), &(root->cDays),&(root->cMins),&(root->cTicks)); rc=adfWriteRootBlock(vol, vol->rootBlock, root); } else { adfTime2AmigaTime(adfGiveCurrentTime(),&(dir->days),&(dir->mins),&(dir->ticks)); rc=adfWriteDirBlock(vol, dir->headerKey, (struct bDirBlock*)dir); } /*puts("adfCreateEntry out, dir");*/ if (rc!=RC_OK) { adfSetBlockFree(vol, newSect); return -1; } else return( newSect ); } do { if (adfReadEntryBlock(vol, nSect, &updEntry)!=RC_OK) return -1; if (updEntry.nameLen==len) { myToUpper((unsigned char*)name3,(unsigned char*)updEntry.name,updEntry.nameLen,intl); if (strncmp(name3,name2,len)==0) { (*adfEnv.wFct)("adfCreateEntry : entry already exists"); return -1; } } nSect = updEntry.nextSameHash; }while(nSect!=0); if (thisSect!=-1) newSect2 = thisSect; else { newSect2 = adfGet1FreeBlock(vol); if (newSect2==-1) { (*adfEnv.wFct)("adfCreateEntry : nSect==-1"); return -1; } } rc = RC_OK; updEntry.nextSameHash = newSect2; if (updEntry.secType==ST_DIR) rc=adfWriteDirBlock(vol, updEntry.headerKey, (struct bDirBlock*)&updEntry); else if (updEntry.secType==ST_FILE) rc=adfWriteFileHdrBlock(vol, updEntry.headerKey, (struct bFileHeaderBlock*)&updEntry); else (*adfEnv.wFct)("adfCreateEntry : unknown entry type"); /*puts("adfCreateEntry out, hash");*/ if (rc!=RC_OK) { adfSetBlockFree(vol, newSect2); return -1; } else return(newSect2); }
/* * 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); }