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

📄 fat16.cpp

📁 XOSL 多操作系统管理工具 源代码 多系统引导工具
💻 CPP
字号:
/*
 * Extended Operating System Loader (XOSL)
 * Copyright (c) 1999 by Geurt Vos
 *
 * This code is distributed under GNU General Public License (GPL)
 *
 * The full text of the license can be found in the GPL.TXT file,
 * or at http://www.gnu.org
 */

#include <fat16.h>
#include <disk.h>
#include <memory.h>
#include <string.h>
#include <ctype.h>

#define INMEMORY_CLUSTERS 4096
#define FAT_SECTOR_COUNT  (INMEMORY_CLUSTERS / 256) // 256 clusters/sector

#define INMEMORY_ENTRIES 32
#define DIR_SECTOR_COUNT (INMEMORY_ENTRIES / 16)

#define FILE_DELETED 0xe5


CFAT16::CFAT16(): CFileSystem()
{
	FAT = new unsigned short[INMEMORY_CLUSTERS];
}

CFAT16::~CFAT16()
{
	delete[] FAT;
}

int CFAT16::Mount(int Drive, long StartSector)
{
	int Status;

	Status = CFileSystem::Mount(Drive,StartSector);
	if (Status != -1) {
		Disk.Read(0,&BootSector,1);
		if (MemCompare(BootSector.FSID,"FAT16   ",8) != 0)
			Status = -1;
		else {
			ClusterSize = (unsigned short)BootSector.ClusterSize << 9;
			FATStart = BootSector.ReservedSectors;
			DirStart = FATStart + BootSector.FATSize * (int)BootSector.FATCopies;
			DataStart = DirStart + (BootSector.RootEntries >> 4);
			LastCluster = 0;
		}
	}
	return Status;
}

unsigned short CFAT16::ReadFile(const char *FileName, void *Buffer)
{
	unsigned short Cluster;
	CFAT16DirEntry Entry;
	void *ClusterData;
	unsigned long SizeLeft;

	if (Locate(FileName,Entry) == -1)
		return 0;

	if (Entry.FileSize) {
		ClusterData = new char[ClusterSize];
		SizeLeft = Entry.FileSize;
		for (Cluster = Entry.StartCluster; Cluster != 0xffff; GetNextCluster(Cluster)) {
			ReadCluster(Cluster,ClusterData);
			MemCopy(Buffer,ClusterData,SizeLeft > ClusterSize ? ClusterSize : SizeLeft);
			(char *)Buffer += ClusterSize;
			SizeLeft -= ClusterSize;
		}
		delete ClusterData;
	}
	return Entry.FileSize;
}

int CFAT16::WriteFile(const char *FileName, const void *Buffer)
{
	unsigned short Cluster;
	CFAT16DirEntry Entry;

	if (Locate(FileName,Entry) == -1)
		return -1;
	if (Entry.FileSize) {
		for (Cluster = Entry.StartCluster; Cluster != 0xffff; GetNextCluster(Cluster)) {
			WriteCluster(Cluster,Buffer);
			(const char *)Buffer += ClusterSize;
		}
	}
	return 0;
}

void CFAT16::ReadFAT(unsigned short Cluster)
{
	unsigned long Sector;

	Sector = (Cluster / INMEMORY_CLUSTERS) * FAT_SECTOR_COUNT + FATStart;
	Disk.Read(Sector,FAT,FAT_SECTOR_COUNT);

	FirstCluster = (Cluster / INMEMORY_CLUSTERS) * INMEMORY_CLUSTERS;
	LastCluster = FirstCluster + 4095;
}

void CFAT16::ReadDirectory(unsigned short Index, CFAT16DirEntry *Root)
{
	unsigned long Sector;

	Sector = DirStart + (Index / INMEMORY_ENTRIES) * DIR_SECTOR_COUNT;
	Disk.Read(Sector,Root,DIR_SECTOR_COUNT);
}

int CFAT16::Locate(const char *FileName, CFAT16DirEntry &Entry)
{
	CFAT16DirEntry Root[INMEMORY_ENTRIES];
	unsigned short ABSIndex;
	int Index;

	Index = INMEMORY_ENTRIES;
	for (ABSIndex = 0; ABSIndex < BootSector.RootEntries; ++Index, ++ABSIndex) {
		if (Index == INMEMORY_ENTRIES) {
			Index = 0;
			ReadDirectory(ABSIndex,Root);
		}
		if (!Root[Index].FileName[0])
			return -1;
		if (*Root[Index].FileName != 0xe5)
			if (MemCompare(Root[Index].FileName,FileName,8) == 0 &&
				 MemCompare(Root[Index].Extension,FileName + 8,3) == 0) {
				MemCopy(&Entry,&Root[Index],sizeof (CFAT16DirEntry));
				return 0;
			 }
	}
	return -1;
}


void CFAT16::GetNextCluster(unsigned short &Cluster)
{
	if (Cluster < FirstCluster || Cluster > LastCluster)
		ReadFAT(Cluster);
	Cluster = FAT[Cluster - FirstCluster];
}

void CFAT16::ReadCluster(unsigned short Cluster, void *Buffer)
{
	unsigned long Sector;

	Sector = DataStart + (long)(Cluster - 2) * (long)BootSector.ClusterSize;
	Disk.Read(Sector,Buffer,BootSector.ClusterSize);
}

void CFAT16::WriteCluster(unsigned short Cluster, const void *Buffer)
{
	unsigned long Sector;

	Sector = DataStart + (long)(Cluster - 2) * (long)BootSector.ClusterSize;
	Disk.Write(Sector,Buffer,BootSector.ClusterSize);
}

void CFAT16::DosFileToRawFile(char *RawFile, const char *DosFile)
{
	const char *DotPtr;
	int DotIndex;
	int Index;

	MemSet(RawFile,' ',11);
	RawFile[11] = 0;

	DotPtr = strchr(DosFile,'.');
	DotIndex = DotPtr - DosFile;

	for (Index = 0; Index < DotIndex; ++Index) {
		RawFile[Index] = toupper(DosFile[Index]);
	}
	++DotIndex;
	for (Index = 0; DosFile[Index + DotIndex]; ++Index) {
		RawFile[Index + 8] = toupper(DosFile[Index + DotIndex]);
	}		
}

⌨️ 快捷键说明

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