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
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); } }
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; }
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; }