Exemple #1
0
/*
 * 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);
}