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

📄 fat.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		ThisFatEntOffset = (FatOffset % BytesPerSector);

		if (!FatReadVolumeSectors(FatDriveNumber, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER))
		{
			return FALSE;
		}

		// Get the fat entry
		fat = (*((ULONG *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset))) & 0x0FFFFFFF;

		break;

	}

	DbgPrint((DPRINT_FILESYSTEM, "FAT entry is 0x%x.\n", fat));

	*ClusterPointer = fat;

	return TRUE;
}

/*
 * FatOpenFile()
 * Tries to open the file 'name' and returns true or false
 * for success and failure respectively
 */
FILE* FatOpenFile(PCSTR FileName)
{
	FAT_FILE_INFO		TempFatFileInfo;
	PFAT_FILE_INFO		FileHandle;

	DbgPrint((DPRINT_FILESYSTEM, "FatOpenFile() FileName = %s\n", FileName));

	if (!FatLookupFile(FileName, &TempFatFileInfo))
	{
		return NULL;
	}

	FileHandle = MmAllocateMemory(sizeof(FAT_FILE_INFO));

	if (FileHandle == NULL)
	{
		return NULL;
	}

	memcpy(FileHandle, &TempFatFileInfo, sizeof(FAT_FILE_INFO));

	return (FILE*)FileHandle;
}

ULONG FatCountClustersInChain(ULONG StartCluster)
{
	ULONG	ClusterCount = 0;

	DbgPrint((DPRINT_FILESYSTEM, "FatCountClustersInChain() StartCluster = %d\n", StartCluster));

	while (1)
	{
		//
		// If end of chain then break out of our cluster counting loop
		//
		if (((FatType == FAT12) && (StartCluster >= 0xff8)) ||
			((FatType == FAT16 || FatType == FATX16) && (StartCluster >= 0xfff8)) ||
			((FatType == FAT32 || FatType == FATX32) && (StartCluster >= 0x0ffffff8)))
		{
			break;
		}

		//
		// Increment count
		//
		ClusterCount++;

		//
		// Get next cluster
		//
		if (!FatGetFatEntry(StartCluster, &StartCluster))
		{
			return 0;
		}
	}

	DbgPrint((DPRINT_FILESYSTEM, "FatCountClustersInChain() ClusterCount = %d\n", ClusterCount));

	return ClusterCount;
}

ULONG* FatGetClusterChainArray(ULONG StartCluster)
{
	ULONG	ClusterCount;
	ULONG		ArraySize;
	ULONG*	ArrayPointer;
	ULONG		Idx;

	DbgPrint((DPRINT_FILESYSTEM, "FatGetClusterChainArray() StartCluster = %d\n", StartCluster));

	ClusterCount = FatCountClustersInChain(StartCluster) + 1; // Lets get the 0x0ffffff8 on the end of the array
	ArraySize = ClusterCount * sizeof(ULONG);

	//
	// Allocate array memory
	//
	ArrayPointer = MmAllocateMemory(ArraySize);

	if (ArrayPointer == NULL)
	{
		return NULL;
	}

	//
	// Loop through and set array values
	//
	for (Idx=0; Idx<ClusterCount; Idx++)
	{
		//
		// Set current cluster
		//
		ArrayPointer[Idx] = StartCluster;

		//
		// Don't try to get next cluster for last cluster
		//
		if (((FatType == FAT12) && (StartCluster >= 0xff8)) ||
			((FatType == FAT16 || FatType == FATX16) && (StartCluster >= 0xfff8)) ||
			((FatType == FAT32 || FatType == FATX32) && (StartCluster >= 0x0ffffff8)))
		{
			Idx++;
			break;
		}

		//
		// Get next cluster
		//
		if (!FatGetFatEntry(StartCluster, &StartCluster))
		{
			MmFreeMemory(ArrayPointer);
			return NULL;
		}
	}

	return ArrayPointer;
}

/*
 * FatReadCluster()
 * Reads the specified cluster into memory
 */
BOOLEAN FatReadCluster(ULONG ClusterNumber, PVOID Buffer)
{
	ULONG		ClusterStartSector;

	ClusterStartSector = ((ClusterNumber - 2) * SectorsPerCluster) + DataSectorStart;

	DbgPrint((DPRINT_FILESYSTEM, "FatReadCluster() ClusterNumber = %d Buffer = 0x%x ClusterStartSector = %d\n", ClusterNumber, Buffer, ClusterStartSector));

	if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, SectorsPerCluster, (PVOID)FILESYSBUFFER))
	{
		return FALSE;
	}

	memcpy(Buffer, (PVOID)FILESYSBUFFER, SectorsPerCluster * BytesPerSector);

	return TRUE;
}

/*
 * FatReadClusterChain()
 * Reads the specified clusters into memory
 */
BOOLEAN FatReadClusterChain(ULONG StartClusterNumber, ULONG NumberOfClusters, PVOID Buffer)
{
	ULONG		ClusterStartSector;

	DbgPrint((DPRINT_FILESYSTEM, "FatReadClusterChain() StartClusterNumber = %d NumberOfClusters = %d Buffer = 0x%x\n", StartClusterNumber, NumberOfClusters, Buffer));

	while (NumberOfClusters > 0)
	{

		DbgPrint((DPRINT_FILESYSTEM, "FatReadClusterChain() StartClusterNumber = %d NumberOfClusters = %d Buffer = 0x%x\n", StartClusterNumber, NumberOfClusters, Buffer));
		//
		// Calculate starting sector for cluster
		//
		ClusterStartSector = ((StartClusterNumber - 2) * SectorsPerCluster) + DataSectorStart;

		//
		// Read cluster into memory
		//
		if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, SectorsPerCluster, (PVOID)FILESYSBUFFER))
		{
			return FALSE;
		}

		memcpy(Buffer, (PVOID)FILESYSBUFFER, SectorsPerCluster * BytesPerSector);

		//
		// Decrement count of clusters left to read
		//
		NumberOfClusters--;

		//
		// Increment buffer address by cluster size
		//
		Buffer = (PVOID)((ULONG_PTR)Buffer + (SectorsPerCluster * BytesPerSector));

		//
		// Get next cluster
		//
		if (!FatGetFatEntry(StartClusterNumber, &StartClusterNumber))
		{
			return FALSE;
		}

		//
		// If end of chain then break out of our cluster reading loop
		//
		if (((FatType == FAT12) && (StartClusterNumber >= 0xff8)) ||
			((FatType == FAT16 || FatType == FATX16) && (StartClusterNumber >= 0xfff8)) ||
			((FatType == FAT32 || FatType == FATX32) && (StartClusterNumber >= 0x0ffffff8)))
		{
			break;
		}
	}

	return TRUE;
}

/*
 * FatReadPartialCluster()
 * Reads part of a cluster into memory
 */
BOOLEAN FatReadPartialCluster(ULONG ClusterNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
{
	ULONG		ClusterStartSector;

	DbgPrint((DPRINT_FILESYSTEM, "FatReadPartialCluster() ClusterNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", ClusterNumber, StartingOffset, Length, Buffer));

	ClusterStartSector = ((ClusterNumber - 2) * SectorsPerCluster) + DataSectorStart;

	if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, SectorsPerCluster, (PVOID)FILESYSBUFFER))
	{
		return FALSE;
	}

	memcpy(Buffer, (PVOID)((ULONG_PTR)FILESYSBUFFER + StartingOffset), Length);

	return TRUE;
}

/*
 * FatReadFile()
 * Reads BytesToRead from open file and
 * returns the number of bytes read in BytesRead
 */
BOOLEAN FatReadFile(FILE *FileHandle, ULONG BytesToRead, ULONG* BytesRead, PVOID Buffer)
{
	PFAT_FILE_INFO	FatFileInfo = (PFAT_FILE_INFO)FileHandle;
	ULONG			ClusterNumber;
	ULONG			OffsetInCluster;
	ULONG			LengthInCluster;
	ULONG			NumberOfClusters;
	ULONG			BytesPerCluster;

	DbgPrint((DPRINT_FILESYSTEM, "FatReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead, Buffer));

	if (BytesRead != NULL)
	{
		*BytesRead = 0;
	}

	//
	// If they are trying to read past the
	// end of the file then return success
	// with BytesRead == 0
	//
	if (FatFileInfo->FilePointer >= FatFileInfo->FileSize)
	{
		return TRUE;
	}

	//
	// If they are trying to read more than there is to read
	// then adjust the amount to read
	//
	if ((FatFileInfo->FilePointer + BytesToRead) > FatFileInfo->FileSize)
	{
		BytesToRead = (FatFileInfo->FileSize - FatFileInfo->FilePointer);
	}

	//
	// Ok, now we have to perform at most 3 calculations
	// I'll draw you a picture (using nifty ASCII art):
	//
	// CurrentFilePointer -+
	//                     |
	//    +----------------+
	//    |
	// +-----------+-----------+-----------+-----------+
	// | Cluster 1 | Cluster 2 | Cluster 3 | Cluster 4 |
	// +-----------+-----------+-----------+-----------+
	//    |                                    |
	//    +---------------+--------------------+
	//                    |
	// BytesToRead -------+
	//
	// 1 - The first calculation (and read) will align
	//     the file pointer with the next cluster.
	//     boundary (if we are supposed to read that much)
	// 2 - The next calculation (and read) will read
	//     in all the full clusters that the requested
	//     amount of data would cover (in this case
	//     clusters 2 & 3).
	// 3 - The last calculation (and read) would read
	//     in the remainder of the data requested out of
	//     the last cluster.
	//

	BytesPerCluster = SectorsPerCluster * BytesPerSector;

	//
	// Only do the first read if we
	// aren't aligned on a cluster boundary
	//
	if (FatFileInfo->FilePointer % BytesPerCluster)
	{
		//
		// Do the math for our first read
		//
		ClusterNumber = (FatFileInfo->FilePointer / BytesPerCluster);
		ClusterNumber = FatFileInfo->FileFatChain[ClusterNumber];
		OffsetInCluster = (FatFileInfo->FilePointer % BytesPerCluster);
		LengthInCluster = (BytesToRead > (BytesPerCluster - OffsetInCluster)) ? (BytesPerCluster - OffsetInCluster) : BytesToRead;

		//
		// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
		//
		if (!FatReadPartialCluster(ClusterNumber, OffsetInCluster, LengthInCluster, Buffer))
		{
			return FALSE;
		}
		if (BytesRead != NULL)
		{
			*BytesRead += LengthInCluster;
		}
		BytesToRead -= LengthInCluster;
		FatFileInfo->FilePointer += LengthInCluster;
		Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInCluster);
	}

	//
	// Do the math for our second read (if any data left)
	//
	if (BytesToRead > 0)
	{
		//
		// Determine how many full clusters we need to read
		//
		NumberOfClusters = (BytesToRead / BytesPerCluster);

		if (NumberOfClusters > 0)
		{
			ClusterNumber = (FatFileInfo->FilePointer / BytesPerCluster);
			ClusterNumber = FatFileInfo->FileFatChain[ClusterNumber];

			//
			// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
			//
			if (!FatReadClusterChain(ClusterNumber, NumberOfClusters, Buffer))
			{
				return FALSE;
			}
			if (BytesRead != NULL)
			{
				*BytesRead += (NumberOfClusters * BytesPerCluster);
			}
			BytesToRead -= (NumberOfClusters * BytesPerCluster);
			FatFileInfo->FilePointer += (NumberOfClusters * BytesPerCluster);
			Buffer = (PVOID)((ULONG_PTR)Buffer + (NumberOfClusters * BytesPerCluster));
		}
	}

	//
	// Do the math for our third read (if any data left)
	//
	if (BytesToRead > 0)
	{
		ClusterNumber = (FatFileInfo->FilePointer / BytesPerCluster);
		ClusterNumber = FatFileInfo->FileFatChain[ClusterNumber];

		//
		// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
		//
		if (!FatReadPartialCluster(ClusterNumber, 0, BytesToRead, Buffer))
		{
			return FALSE;
		}
		if (BytesRead != NULL)
		{
			*BytesRead += BytesToRead;
		}
		FatFileInfo->FilePointer += BytesToRead;
		BytesToRead -= BytesToRead;
		Buffer = (PVOID)((ULONG_PTR)Buffer + BytesToRead);
	}

	return TRUE;
}

ULONG FatGetFileSize(FILE *FileHandle)
{
	PFAT_FILE_INFO	FatFileHandle = (PFAT_FILE_INFO)FileHandle;

	DbgPrint((DPRINT_FILESYSTEM, "FatGetFileSize() FileSize = %d\n", FatFileHandle->FileSize));

	return FatFileHandle->FileSize;
}

VOID FatSetFilePointer(FILE *FileHandle, ULONG NewFilePointer)
{
	PFAT_FILE_INFO	FatFileHandle = (PFAT_FILE_INFO)FileHandle;

	DbgPrint((DPRINT_FILESYSTEM, "FatSetFilePointer() NewFilePointer = %d\n", NewFilePointer));

	FatFileHandle->FilePointer = NewFilePointer;
}

ULONG FatGetFilePointer(FILE *FileHandle)
{
	PFAT_FILE_INFO	FatFileHandle = (PFAT_FILE_INFO)FileHandle;

	DbgPrint((DPRINT_FILESYSTEM, "FatGetFilePointer() FilePointer = %d\n", FatFileHandle->FilePointer));

	return FatFileHandle->FilePointer;
}

BOOLEAN FatReadVolumeSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
	return CacheReadDiskSectors(DriveNumber, SectorNumber + FatVolumeStartSector, SectorCount, Buffer);
}

⌨️ 快捷键说明

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