Esempio n. 1
0
File: fat.c Progetto: d33tah/whitix
DWORD FatAccess(struct VfsSuperBlock* sBlock,DWORD clusterNum,int newVal)
{
	struct FatSbInfo* fatInfo=FatGetSbPriv(sBlock);
	DWORD first=0,last=0,retVal=0;
	BYTE *pFirst=NULL,*pLast=NULL;
	struct Buffer* buff,*buff2,*copyBuff,*copyBuff2;
	DWORD i;
	int block;

	if (clusterNum > fatInfo->totalDataSectors)
	{
		KePrint("PANIC: FatAccess : cluster number (%#X) > totalDataSectors from %#X\n",clusterNum,__builtin_return_address(0));
		KernelPanic("FatAccess: cluster number > total data sectors");
		cli(); hlt();
	}

	/* Due to the lovely FAT12 format, where entries can strech over blocks, 
	 * 2 blocks have to be read in in the worst case scenario */

	/* Get the index number into the FAT */
	if (fatInfo->fatType == 12)
	{
		first=clusterNum*3/2;
		last=first+1;
	}else if (fatInfo->fatType == 16)
		last=first=clusterNum*2; /* Never goes over a sector boundary */
	else
		/* FAT32 */
		last = first = clusterNum * 4;

	/* Read in the FAT sector(s) concerned */
	buff=BlockRead(sBlock->sDevice,fatInfo->fatStart+(first/BYTES_PER_SECTOR(sBlock)));
	if (!buff)
	{
		KePrint("Failed to read buffer in FatAccess\n");
		return 0;
	}

	/* Is the entry on the same sector? */
	if ((first/BYTES_PER_SECTOR(sBlock)) == (last/BYTES_PER_SECTOR(sBlock)))
		buff2=buff;
	else{
		buff2=BlockRead(sBlock->sDevice,(fatInfo->fatStart+(first/BYTES_PER_SECTOR(sBlock)))+1);
		if (!buff2)
		{
			BlockFree(buff);
			KePrint("Failed to read buffer 2 in FatAccess\n");
			return 0;
		}
	}

	if (fatInfo->fatType == 12)
	{
		/* Slightly confusing */
		pFirst=&((BYTE*)buff->data)[first % BYTES_PER_SECTOR(sBlock)];
		pLast=&((BYTE*)buff2->data)[(first+1) % BYTES_PER_SECTOR(sBlock)];
		if (clusterNum & 1)
			retVal=((*pFirst >> 4) | (*pLast << 4)) & 0xFFF;
		else
Esempio n. 2
0
int FatReadFsInfo(struct VfsSuperBlock* superBlock, unsigned long fsInfoSector)
{
	struct Buffer* buff;
	struct FatFsInfo* info;
	struct FatSbInfo* sbInfo;
	BYTE* data;
	int ret = 0;
		
	buff = BlockRead(superBlock->sDevice, fsInfoSector);
	
	if (!buff)
		return -EIO;

	data = (BYTE*)(buff->data);
	info = (struct FatFsInfo*)(data + 0x1E0);
		
	/* Four byte signature at start of fsInfo sector. */
	if (data[0] != 0x52 || data[1] != 0x52 || data[2] != 0x61 || data[3] != 0x41)
	{
		ret = -EINVAL;
		goto out;
	}
	
	/* TODO: Check info->signature? */
	
	/* Boot record signature at end of fsInfo sector. */
	if (data[510] != 0x55 || data[511] != 0xAA)
	{
		ret = -EINVAL;
		goto out;
	}
	
	/* Store the number of free clusters, and update it again in WriteSuper. */
	sbInfo = FatGetSbPriv(superBlock);
	
	sbInfo->freeClusters = info->freeClusters;
	sbInfo->fsInfoSector = fsInfoSector;
		
out:
	if (ret)
		KePrint(KERN_DEBUG "FAT: Invalid FAT32 filesystem.\n");
		
	BlockFree(buff);
	return ret;
}
void CreateMyBitmap()
{
    int bytesForBitmap;
    int i;

    bitMap = pDisk;
    bytesForBitmap = fileSystemSizeInBlocks / BYTE_SIZE;
    blocksForBitmap = (bytesForBitmap / BLOCK_SIZE) + 1;

    for (i = 0; i < blocksForBitmap; i++)
    {
        BlockOccupy(i);
    }

    for (i = blocksForBitmap; i < fileSystemSizeInBlocks; i ++)
    {
        BlockFree(i);
    }

}
Esempio n. 4
0
struct VfsSuperBlock* FatReadSuper(struct StorageDevice* dev,int flags,char* data)
{
	struct FatBootSector* bootSec;
	struct Buffer* buff;
	struct VfsSuperBlock* retVal;
	struct FatSbInfo* fatSbInfo;
	DWORD clusterCount,totalSectors;

	if (!dev)
		return NULL;

	/* This fixes issue #110. The soft block size at the start should be the
	 * device's sector size as we may read the second sector of the disk in 
	 * FatReadFsInfo. */
	 
	if (BlockSetSize(dev, dev->blockSize))
		return NULL;

	buff = BlockRead(dev, 0);
	
	if (!buff)
	{
		KePrint("FAT: Failed to read superblock\n");
		return NULL;
	}

	bootSec=(struct FatBootSector*)(buff->data);

	if (bootSec->bytesPerSec != 512 && bootSec->bytesPerSec != 1024 && bootSec->bytesPerSec != 2048 && bootSec->bytesPerSec != 4096)
	{
		BlockFree(buff);
		return NULL;
	}

	retVal=VfsAllocSuper(dev,flags);
	if (!retVal)
		goto end;

	retVal->sbOps=&fatSbOps;

	/* Allocate the FAT-specific superblock structure */
	fatSbInfo=(struct FatSbInfo*)MemAlloc(sizeof(struct FatSbInfo));
	if (!fatSbInfo)
		goto fail;

	retVal->privData=(void*)fatSbInfo;

	/* Fill the structure with info */
	fatSbInfo->fatStart=bootSec->reservedSectorCnt;

	if (bootSec->secsPerFat == 0 && bootSec->secsPerFat32 > 0)
	{
		/* Must be FAT32 then */
		fatSbInfo->rootDirStart = bootSec->rootClus;
		fatSbInfo->fatLength = bootSec->secsPerFat32;
	}else{
		fatSbInfo->rootDirStart = bootSec->reservedSectorCnt+(bootSec->numFats*bootSec->secsPerFat);
		fatSbInfo->fatLength = bootSec->secsPerFat;
	}

	totalSectors=(bootSec->totalSecSmall) ? bootSec->totalSecSmall : bootSec->totalSectorsLarge;
	fatSbInfo->rootDirEnts = bootSec->numRootDirEnts;
	fatSbInfo->rootDirLength=(bootSec->numRootDirEnts*sizeof(struct FatDirEntry))/bootSec->bytesPerSec; /* FAT32 doesn't use this */
 	fatSbInfo->firstDataSector=bootSec->reservedSectorCnt+
 		(bootSec->numFats*fatSbInfo->fatLength)+fatSbInfo->rootDirLength;
	fatSbInfo->clusterLength=bootSec->bytesPerSec*bootSec->sectorsPerClus;
	fatSbInfo->secsPerClus=bootSec->sectorsPerClus;
	fatSbInfo->totalDataSectors=totalSectors-fatSbInfo->firstDataSector;
	fatSbInfo->numFats=bootSec->numFats;

	clusterCount=fatSbInfo->totalDataSectors/bootSec->sectorsPerClus;

	/* Set the FAT type and end of cluster marker, depending on the number of clusters */
	if (clusterCount < 4085)
	{
		fatSbInfo->fatType=12;
		fatSbInfo->invalidCluster=0xFF8;
	}else if (clusterCount < 65525)
	{
		fatSbInfo->fatType=16;
		fatSbInfo->invalidCluster=0xFFF8;
	}else{
		fatSbInfo->fatType = 32;
		fatSbInfo->invalidCluster=0x0FFFFFF8;
	}
	
	/* Read the FsInfo structure if this is a FAT32 filesystem, so we can keep
	 * track of the free clusters and update it when necessary. */
	if (fatSbInfo->fatType == 32)
	{
		if (FatReadFsInfo(retVal, bootSec->fsInfo))
			goto fail;
	}
	
	KePrint(KERN_DEBUG "FAT: drive is a FAT%u volume\n",(DWORD)fatSbInfo->fatType);

	if (BlockSetSize(dev,bootSec->bytesPerSec))
		goto fail;

	retVal->mount = VNodeGet(retVal, FAT_ROOT_ID);

	if (!retVal->mount)
		goto fail;

end:
	if (buff->refs)
		BlockFree(buff);
	return retVal;

fail:
	/* privData is freed in VfsFreeSuper */
	VfsFreeSuper(retVal);
	retVal=NULL;
	goto end;
}
Esempio n. 5
0
struct VfsSuperBlock* Ext3ReadSuper(struct StorageDevice* dev,int flags,char* data)
{
	struct VfsSuperBlock* retVal;
	struct Buffer* buff;
	struct Ext3SuperBlock sb;
	struct Ext3SbInfo* sbInfo;
	int descCount,i;

	/* Must have a storage device */
	if (!dev || BlockSetSize(dev,1024))
		return NULL;

	/* The Ext3 superblock is located after the first block, which is reserved for boot-
	 * related data. */
	buff=BlockRead(dev, 1);
	if (!buff)
		goto error;

	/* The buffer will be freed if we set the block size to something other than
	 * 1024, so save the data off now.
	 */

	memcpy(&sb, buff->data, sizeof(struct Ext3SuperBlock));

	/* Sanity check. */
	if (sb.magic != EXT3_SB_MAGIC)
		goto blockReadError;

	retVal=VfsAllocSuper(dev,flags);
	if (!retVal)
		goto blockReadError;

	/* Ext3 block sizes are a multiple of 1024. */
	BlockSetSize(dev,1024 << sb.logBlockSize);

	/* Copy some useful information over into the private superblock structure. */
	sbInfo=(struct Ext3SbInfo*)MemAlloc(sizeof(struct Ext3SbInfo));
	if (!sbInfo)
		goto superFreeError;

	sbInfo->iNodesCount=sb.iNodesCount;
	sbInfo->blocksPerGrp=sb.blocksPerGrp;
	sbInfo->groupCount=(sb.blocksCount-sb.firstDataBlock+sb.blocksPerGrp-1)/sb.blocksPerGrp;
	sbInfo->iNodesPerGrp=sb.iNodesPerGrp;

	sbInfo->firstDataBlock=sb.firstDataBlock;
	
	/* Read in the superblock again. */
	Ext3ReadSuperBlock(retVal, sbInfo);

	/* And set the Ext3-specific parts of the superblock structure. */
	retVal->privData=sbInfo;
	retVal->sbOps=&ext3SbOps;

	/* Read in the block descriptors as pointers to buffers. */
	descCount=(sbInfo->groupCount+DESCS_PER_BLOCK(retVal)-1)/DESCS_PER_BLOCK(retVal);
	sbInfo->descs=(struct Buffer**)MemAlloc(descCount*sizeof(struct Buffer*));

	if (!descCount)
		goto superFreeError;

	for (i=0; i<descCount; i++)
		sbInfo->descs[i]=BlockRead(dev, Ext3GetDescriptorLoc(retVal, i));

	/* If we have a journal, read it in. We read the journal in before the root
	 * node, because it may have been modified in the journal. */

	if (EXT3_FEATURE_COMPAT(&sb, EXT3_FEATURE_COMPAT_JOURNAL))
	{
		if (Ext3JournalInit(retVal, &sb))
			goto descsFree;
		
		/* Write journal superblock. */
	}

	retVal->mount=VNodeGet(retVal, EXT3_ROOT_VNO);
	if (!retVal->mount)
		goto descsFree;

	BlockFree(buff);
	return retVal;

descsFree:
	for (i=0; i<descCount; i++)
		BlockFree(sbInfo->descs[i]);

	MemFree(sbInfo->descs);
	/* sbInfo is freed in VfsFreeSuper */
superFreeError:
	VfsFreeSuper(retVal);
blockReadError:
	BlockFree(buff);
error:
	return NULL;
}