⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat16.cpp

📁 我自己实现的fat16文件系统驱动
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	BYTE* Cache;
	struct _DIR *dir;
	unsigned int j;

	Cache = GetSectorData(Sector);
	if(Cache == NULL)
		return 0xffffffff;
	
	dir = (struct _DIR *)Cache;
	for(j=0; (dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)
	{
		if(memcmp((const char*)dir->Name, dirname, 11) == 0 && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
		{
			if(file != NULL)
			{
				memset(file, 0, sizeof(struct _file));
				file->DirSectorNum = Sector;
				file->DirIndex = j;
				memcpy(&file->dir, dir, sizeof(struct _DIR));
			}
			
			return ClusterNum2SectorNum(dir->FstClusLO);
		}
		
		dir++;
	}

	return 0xffffffff;
}

int SectorGet(DWORD Sector, struct FatGet *fat_get)
{
	BYTE* Cache;
	struct _DIR *dir;
	unsigned int j;

	Cache = GetSectorData(Sector);
	if(Cache == NULL)
		return 1;

	dir = (struct _DIR *)Cache;
	dir += fat_get->DirIndex;

	for(j=fat_get->DirIndex; (dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)
	{
		if(dir->Name[0] != ERCHAR && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
		{
			fat_get->DirSectorNum = Sector;
			fat_get->DirIndex = j + 1;
			unformat_name(fat_get->filename, dir->Name);

			return 0;
		}

		dir++;
	}

	return 2;
}

// return the first sector number of dir/file content.
// 0xffffffff indicate failed.
DWORD fat_search(DWORD Sector, const char dirname[11], struct _file *file)
{	
	unsigned int i;
	WORD Cluster;
	DWORD FirstSectorOfFile;

	//if(dirname == NULL)
		//return 0xffffffff;
	
	if(Sector == FirstRootDirSecNum)
	{
		for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
		{
			FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
			if(FirstSectorOfFile != 0xffffffff)
				return FirstSectorOfFile;
		}
	}

	else
	{
		Cluster = SectorNum2ClusterNum(Sector);

		// because arg Sector is the first sector of parent dir content,
		// so it is the first sector of the cluster.
		/*
		i = (Sector - FirstDataSector) % Bpb.SecPerClus;
		
		if(i != 0)
		{
			for(; i< Bpb.SecPerClus; i++)
			{
				FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
				if(FirstSectorOfFile != 0xffffffff)
					return FirstSectorOfFile;
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}*/
		
		while(Cluster != 0xffff)
		{
			for(i=0; i< Bpb.SecPerClus; i++)
			{
				FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
				if(FirstSectorOfFile != 0xffffffff)
					return FirstSectorOfFile;
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}
	}

	return 0xffffffff;
}

// return the first sector number of dir/file content.
// 0xffffffff indicate failed.
// if path is root dir, file arg is ignore.
DWORD fat_locate(const char *path, struct _file *file)
{
	DWORD Sector = FirstRootDirSecNum;
	char *p;

	p = get_valid_format(path);
	if(p == NULL)
		return 0xffffffff;

	// locate first sub dir.
	p++;

	// locate next sub dir(s).
	for(;;)
	{
		if(*p == NULL)
			return Sector;

		Sector = fat_search(Sector, p, file);
		if(Sector == 0xffffffff)
			return 0xffffffff;

		p+=12;
	}

	// we never go here.
	return 0xffffffff;
}

void fat_datetime(struct FatDateTime *fatdatetime)
{
	SYSTEMTIME systm;
	struct FatDate* pdate = &fatdatetime->Date.fatdate;
	struct FatTime *ptm = &fatdatetime->Time.fattime;

	GetSystemTime(&systm);

	pdate->Day = systm.wDay;
	pdate->Month = systm.wMonth;
	pdate->Year = systm.wYear - 1980;

	ptm->Hours = systm.wHour;
	ptm->Minutes = systm.wMinute;
	ptm->Second_2s = systm.wSecond / 2;

	fatdatetime->TimeTenth = (systm.wSecond % 2) * 100 + systm.wMilliseconds / 10;
}

///////////////////////////////////////////////////////////////////
// fat apis
///////////////////////////////////////////////////////////////////

int fat_mkdir( const char *dirname)
{
	struct _DIR dir;
	DWORD SectorNum;
	char path[512];
	char name[11];
	char *p;
	struct FatDateTime tm;
	struct _file file;	
	BYTE* Cache;
	struct _DIR *pdir;
	WORD NewCluster;
	char dot[11] = {'.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
	char dotdot[11] = {'.', '.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};

	// is path format correct ?
	p = get_valid_format(dirname);
	if(p == NULL)
		return 1;

	//if exist this dir ?
	if(fat_locate(dirname, NULL) != 0xffffffff)
		return 4;

	//separate path into parent and name
	strncpy(name, &p[strlen(p)-11], 11);

	strcpy(path, dirname);
	p = strrchr(path, '\\');
	if(p == path) // it is root dir.
		*(p+1) = '\0';
	else
		*p = '\0';

	//locate parent path
	SectorNum = fat_locate(path, NULL);
	if(SectorNum == 0xffffffff)
		return 2;

	//fill dir attributes
	memset(&dir, 0, sizeof(dir));
	memcpy(dir.Name, name, 11);
	dir.Attr = ATTR_DIRECTORY;
	fat_datetime(&tm);
	dir.CrtDate = dir.LstAccDate = dir.WrtDate = tm.Date.Date;
	dir.CrtTime = dir.WrtTime = tm.Time.Time;
	dir.CrtTimeTenth = tm.TimeTenth;

	//alloc one dir
	if(AllocDir(SectorNum, &dir, &file) != 0)
		return 3;

	//alloc a cluster
	NewCluster = AllocCluster(0);
	if(NewCluster == 0xffff)
		return 4;

	//flush to disk
	Cache = GetSectorData(file.DirSectorNum);
	if(Cache == NULL)
		return 6;

	pdir = (struct _DIR *)Cache;
	pdir += file.DirIndex;

	pdir->FstClusLO = NewCluster;
	Flush();

	//create . and .. dir items.
	Cache = GetSectorData(ClusterNum2SectorNum(NewCluster));
	if(Cache == NULL)
		return 6;

	pdir = (struct _DIR *)Cache;
	memset(pdir, 0, sizeof(struct _DIR));
	memcpy(pdir->Name, dot, 11);
	pdir->Attr = ATTR_DIRECTORY;
	fat_datetime(&tm);
	pdir->CrtDate = pdir->LstAccDate = pdir->WrtDate = tm.Date.Date;
	pdir->CrtTime = pdir->WrtTime = tm.Time.Time;
	pdir->CrtTimeTenth = tm.TimeTenth;
	pdir->FstClusLO = NewCluster;

	pdir++;
	memset(pdir, 0, sizeof(struct _DIR));
	memcpy(pdir->Name, dotdot, 11);
	pdir->Attr = ATTR_DIRECTORY;
	fat_datetime(&tm);
	pdir->CrtDate = pdir->LstAccDate = pdir->WrtDate = tm.Date.Date;
	pdir->CrtTime = pdir->WrtTime = tm.Time.Time;
	pdir->CrtTimeTenth = tm.TimeTenth;
	pdir->FstClusLO = SectorNum2ClusterNum(SectorNum);

	Flush();

	return 0;
}

int fat_rmdir( const char *dirname)
{
	DWORD SectorNum;
	struct _file file;
	char filename[13];

	//is dir have no sub dir or file ?
	if(fat_getfirst(dirname, filename) == 0)
		return 3;

	//locate
	SectorNum = fat_locate(dirname, &file);
	if(SectorNum == 0xffffffff)
		return 4;

	// is it a dir ?
	if(!(file.dir.Attr & ATTR_DIRECTORY))
		return 6;

	if(DeleteDir(&file) != 0)
		return 5;

	FreeCluster(file.dir.FstClusLO);

	return 0;
}

struct FatGet fat_get;

int fat_getfirst(const char *path, char* filename)
{
	DWORD Sector;
	unsigned int i;
	WORD Cluster;

	//if exist this dir ?
	Sector = fat_locate(path, NULL);
	if(Sector == 0xffffffff)
		return 1;

	if(Sector == FirstRootDirSecNum)
	{
		fat_get.IsRootDir = 1;
		fat_get.DirIndex = 2;

		for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
		{
			if(SectorGet(Sector++, &fat_get) == 0)
			{
				strcpy(filename, fat_get.filename);
				return 0;
			}
		}
	}

	else
	{
		fat_get.IsRootDir = 0;
		fat_get.DirIndex = 2;

		Cluster = SectorNum2ClusterNum(Sector);

		// because the sector is the first sector of parent dir,
		// so it is the first sector of cluster.
		/*
		i = (Sector - FirstDataSector) % Bpb.SecPerClus;
		
		if(i != 0)
		{
			for(; i< Bpb.SecPerClus; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}*/
		
		while(Cluster != 0xffff)
		{
			for(i=0; i< Bpb.SecPerClus; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}
	}

	return 2;
}

int fat_getnext(char* filename)
{
	DWORD Sector;
	unsigned int i;
	WORD Cluster;

	Sector = fat_get.DirSectorNum;

	if(fat_get.IsRootDir)
	{
		i=(Sector - FirstRootDirSecNum) * Bpb.BytsPerSec / sizeof(struct _DIR) + fat_get.DirIndex +1;

		for(; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
		{
			if(SectorGet(Sector++, &fat_get) == 0)
			{
				strcpy(filename, fat_get.filename);
				return 0;
			}
		}
	}

	else
	{
		Cluster = SectorNum2ClusterNum(Sector);

		i = (Sector - FirstDataSector) % Bpb.SecPerClus;

		if(i != 0)
		{
			for(; i< Bpb.SecPerClus; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}

		while(Cluster != 0xffff)
		{
			for(i=0; i< Bpb.SecPerClus; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}
	}

	return 2;
}

struct _file handles[16];

int fat_close(int handle)
{
	struct _file *fp;
	struct FatDateTime tm;
	BYTE* Cache;
	struct _DIR *dir;

	if(handle <0 || handle >= sizeof(handles)/sizeof(struct _file))
		return -1;

	fp = &handles[handle];

	fat_datetime(&tm);
	fp->dir.LstAccDate = fp->dir.WrtDate = tm.Date.Date;
	fp->dir.WrtTime = tm.Time.Time;

	Cache = GetSectorData(fp->DirSectorNum);
	if(Cache == NULL)
		return -2;

	dir = (struct _DIR *)Cache;
	dir += fp->DirIndex;

	memcpy(dir, &fp->dir, sizeof(struct _DIR));
	Flush();

	handles[handle].valid = 0;
	return 0;
}

int fat_creat(const char* filename, BYTE attribute)
{
	struct _DIR dir;
	char path[512];
	char name[11];
	char *p;
	DWORD ParentDirSectorNum;
	struct FatDateTime tm;
	struct _file file;
	struct _DIR *pdir;
	WORD NewCluster;
	BYTE* Cache;

	// is path format correct ?
	p = get_valid_format(filename);
	if(p == NULL)
		return -2;

	//if exist this file ?
	if(fat_locate(filename, NULL) != 0xffffffff)
		return -3;

	//separate path into parent and name
	strncpy(name, &p[strlen(p)-11], 11);

	strcpy(path, filename);
	p = strrchr(path, '\\');
	*p = '\0';

	//locate parent path
	ParentDirSectorNum = fat_locate(path, NULL);
	if(ParentDirSectorNum == 0xffffffff)
		return -4;

	//fill dir attributes
	memset(&dir, 0, sizeof(dir));
	memcpy(dir.Name, name, 11);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -