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

📄 fat.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  FreeLoader
 *  Copyright (C) 1998-2003  Brian Palmer  <brianp@sginet.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <freeldr.h>
#include <debug.h>

ULONG			BytesPerSector;			/* Number of bytes per sector */
ULONG			SectorsPerCluster;		/* Number of sectors per cluster */
ULONG			FatVolumeStartSector;		/* Absolute starting sector of the partition */
ULONG			FatSectorStart;			/* Starting sector of 1st FAT table */
ULONG			ActiveFatSectorStart;		/* Starting sector of active FAT table */
ULONG			NumberOfFats;			/* Number of FAT tables */
ULONG			SectorsPerFat;			/* Sectors per FAT table */
ULONG			RootDirSectorStart;		/* Starting sector of the root directory (non-fat32) */
ULONG			RootDirSectors;			/* Number of sectors of the root directory (non-fat32) */
ULONG			RootDirStartCluster;		/* Starting cluster number of the root directory (fat32 only) */
ULONG			DataSectorStart;		/* Starting sector of the data area */

ULONG			FatType = 0;			/* FAT12, FAT16, FAT32, FATX16 or FATX32 */
ULONG			FatDriveNumber = 0;

BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG PartitionSectorCount)
{
	char ErrMsg[80];
	ULONG FatSize;
	PFAT_BOOTSECTOR	FatVolumeBootSector;
	PFAT32_BOOTSECTOR Fat32VolumeBootSector;
	PFATX_BOOTSECTOR FatXVolumeBootSector;

	DbgPrint((DPRINT_FILESYSTEM, "FatOpenVolume() DriveNumber = 0x%x VolumeStartSector = %d\n", DriveNumber, VolumeStartSector));

	// Store the drive number
	FatDriveNumber = DriveNumber;

	//
	// Allocate the memory to hold the boot sector
	//
	FatVolumeBootSector = (PFAT_BOOTSECTOR) MmAllocateMemory(512);
	Fat32VolumeBootSector = (PFAT32_BOOTSECTOR) FatVolumeBootSector;
	FatXVolumeBootSector = (PFATX_BOOTSECTOR) FatVolumeBootSector;

	//
	// Make sure we got the memory
	//
	if (FatVolumeBootSector == NULL)
	{
		FileSystemError("Out of memory.");
		return FALSE;
	}

	// Now try to read the boot sector
	// If this fails then abort
	if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, (PVOID)DISKREADBUFFER))
	{
		MmFreeMemory(FatVolumeBootSector);
		return FALSE;
	}
	RtlCopyMemory(FatVolumeBootSector, (PVOID)DISKREADBUFFER, 512);

	// Get the FAT type
	FatType = FatDetermineFatType(FatVolumeBootSector, PartitionSectorCount);

	DbgPrint((DPRINT_FILESYSTEM, "Dumping boot sector:\n"));

	if (ISFATX(FatType))
	{
		DbgPrint((DPRINT_FILESYSTEM, "sizeof(FATX_BOOTSECTOR) = 0x%x.\n", sizeof(FATX_BOOTSECTOR)));

		DbgPrint((DPRINT_FILESYSTEM, "FileSystemType: %c%c%c%c.\n", FatXVolumeBootSector->FileSystemType[0], FatXVolumeBootSector->FileSystemType[1], FatXVolumeBootSector->FileSystemType[2], FatXVolumeBootSector->FileSystemType[3]));
		DbgPrint((DPRINT_FILESYSTEM, "VolumeSerialNumber: 0x%x\n", FatXVolumeBootSector->VolumeSerialNumber));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerCluster: %d\n", FatXVolumeBootSector->SectorsPerCluster));
		DbgPrint((DPRINT_FILESYSTEM, "NumberOfFats: %d\n", FatXVolumeBootSector->NumberOfFats));
		DbgPrint((DPRINT_FILESYSTEM, "Unknown: 0x%x\n", FatXVolumeBootSector->Unknown));

		DbgPrint((DPRINT_FILESYSTEM, "FatType %s\n", FatType == FATX16 ? "FATX16" : "FATX32"));

	}
	else if (FatType == FAT32)
	{
		DbgPrint((DPRINT_FILESYSTEM, "sizeof(FAT32_BOOTSECTOR) = 0x%x.\n", sizeof(FAT32_BOOTSECTOR)));

		DbgPrint((DPRINT_FILESYSTEM, "JumpBoot: 0x%x 0x%x 0x%x\n", Fat32VolumeBootSector->JumpBoot[0], Fat32VolumeBootSector->JumpBoot[1], Fat32VolumeBootSector->JumpBoot[2]));
		DbgPrint((DPRINT_FILESYSTEM, "OemName: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->OemName[0], Fat32VolumeBootSector->OemName[1], Fat32VolumeBootSector->OemName[2], Fat32VolumeBootSector->OemName[3], Fat32VolumeBootSector->OemName[4], Fat32VolumeBootSector->OemName[5], Fat32VolumeBootSector->OemName[6], Fat32VolumeBootSector->OemName[7]));
		DbgPrint((DPRINT_FILESYSTEM, "BytesPerSector: %d\n", Fat32VolumeBootSector->BytesPerSector));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerCluster: %d\n", Fat32VolumeBootSector->SectorsPerCluster));
		DbgPrint((DPRINT_FILESYSTEM, "ReservedSectors: %d\n", Fat32VolumeBootSector->ReservedSectors));
		DbgPrint((DPRINT_FILESYSTEM, "NumberOfFats: %d\n", Fat32VolumeBootSector->NumberOfFats));
		DbgPrint((DPRINT_FILESYSTEM, "RootDirEntries: %d\n", Fat32VolumeBootSector->RootDirEntries));
		DbgPrint((DPRINT_FILESYSTEM, "TotalSectors: %d\n", Fat32VolumeBootSector->TotalSectors));
		DbgPrint((DPRINT_FILESYSTEM, "MediaDescriptor: 0x%x\n", Fat32VolumeBootSector->MediaDescriptor));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerFat: %d\n", Fat32VolumeBootSector->SectorsPerFat));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerTrack: %d\n", Fat32VolumeBootSector->SectorsPerTrack));
		DbgPrint((DPRINT_FILESYSTEM, "NumberOfHeads: %d\n", Fat32VolumeBootSector->NumberOfHeads));
		DbgPrint((DPRINT_FILESYSTEM, "HiddenSectors: %d\n", Fat32VolumeBootSector->HiddenSectors));
		DbgPrint((DPRINT_FILESYSTEM, "TotalSectorsBig: %d\n", Fat32VolumeBootSector->TotalSectorsBig));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerFatBig: %d\n", Fat32VolumeBootSector->SectorsPerFatBig));
		DbgPrint((DPRINT_FILESYSTEM, "ExtendedFlags: 0x%x\n", Fat32VolumeBootSector->ExtendedFlags));
		DbgPrint((DPRINT_FILESYSTEM, "FileSystemVersion: 0x%x\n", Fat32VolumeBootSector->FileSystemVersion));
		DbgPrint((DPRINT_FILESYSTEM, "RootDirStartCluster: %d\n", Fat32VolumeBootSector->RootDirStartCluster));
		DbgPrint((DPRINT_FILESYSTEM, "FsInfo: %d\n", Fat32VolumeBootSector->FsInfo));
		DbgPrint((DPRINT_FILESYSTEM, "BackupBootSector: %d\n", Fat32VolumeBootSector->BackupBootSector));
		DbgPrint((DPRINT_FILESYSTEM, "Reserved: 0x%x\n", Fat32VolumeBootSector->Reserved));
		DbgPrint((DPRINT_FILESYSTEM, "DriveNumber: 0x%x\n", Fat32VolumeBootSector->DriveNumber));
		DbgPrint((DPRINT_FILESYSTEM, "Reserved1: 0x%x\n", Fat32VolumeBootSector->Reserved1));
		DbgPrint((DPRINT_FILESYSTEM, "BootSignature: 0x%x\n", Fat32VolumeBootSector->BootSignature));
		DbgPrint((DPRINT_FILESYSTEM, "VolumeSerialNumber: 0x%x\n", Fat32VolumeBootSector->VolumeSerialNumber));
		DbgPrint((DPRINT_FILESYSTEM, "VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->VolumeLabel[0], Fat32VolumeBootSector->VolumeLabel[1], Fat32VolumeBootSector->VolumeLabel[2], Fat32VolumeBootSector->VolumeLabel[3], Fat32VolumeBootSector->VolumeLabel[4], Fat32VolumeBootSector->VolumeLabel[5], Fat32VolumeBootSector->VolumeLabel[6], Fat32VolumeBootSector->VolumeLabel[7], Fat32VolumeBootSector->VolumeLabel[8], Fat32VolumeBootSector->VolumeLabel[9], Fat32VolumeBootSector->VolumeLabel[10]));
		DbgPrint((DPRINT_FILESYSTEM, "FileSystemType: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->FileSystemType[0], Fat32VolumeBootSector->FileSystemType[1], Fat32VolumeBootSector->FileSystemType[2], Fat32VolumeBootSector->FileSystemType[3], Fat32VolumeBootSector->FileSystemType[4], Fat32VolumeBootSector->FileSystemType[5], Fat32VolumeBootSector->FileSystemType[6], Fat32VolumeBootSector->FileSystemType[7]));
		DbgPrint((DPRINT_FILESYSTEM, "BootSectorMagic: 0x%x\n", Fat32VolumeBootSector->BootSectorMagic));
	}
	else
	{
		DbgPrint((DPRINT_FILESYSTEM, "sizeof(FAT_BOOTSECTOR) = 0x%x.\n", sizeof(FAT_BOOTSECTOR)));

		DbgPrint((DPRINT_FILESYSTEM, "JumpBoot: 0x%x 0x%x 0x%x\n", FatVolumeBootSector->JumpBoot[0], FatVolumeBootSector->JumpBoot[1], FatVolumeBootSector->JumpBoot[2]));
		DbgPrint((DPRINT_FILESYSTEM, "OemName: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->OemName[0], FatVolumeBootSector->OemName[1], FatVolumeBootSector->OemName[2], FatVolumeBootSector->OemName[3], FatVolumeBootSector->OemName[4], FatVolumeBootSector->OemName[5], FatVolumeBootSector->OemName[6], FatVolumeBootSector->OemName[7]));
		DbgPrint((DPRINT_FILESYSTEM, "BytesPerSector: %d\n", FatVolumeBootSector->BytesPerSector));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerCluster: %d\n", FatVolumeBootSector->SectorsPerCluster));
		DbgPrint((DPRINT_FILESYSTEM, "ReservedSectors: %d\n", FatVolumeBootSector->ReservedSectors));
		DbgPrint((DPRINT_FILESYSTEM, "NumberOfFats: %d\n", FatVolumeBootSector->NumberOfFats));
		DbgPrint((DPRINT_FILESYSTEM, "RootDirEntries: %d\n", FatVolumeBootSector->RootDirEntries));
		DbgPrint((DPRINT_FILESYSTEM, "TotalSectors: %d\n", FatVolumeBootSector->TotalSectors));
		DbgPrint((DPRINT_FILESYSTEM, "MediaDescriptor: 0x%x\n", FatVolumeBootSector->MediaDescriptor));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerFat: %d\n", FatVolumeBootSector->SectorsPerFat));
		DbgPrint((DPRINT_FILESYSTEM, "SectorsPerTrack: %d\n", FatVolumeBootSector->SectorsPerTrack));
		DbgPrint((DPRINT_FILESYSTEM, "NumberOfHeads: %d\n", FatVolumeBootSector->NumberOfHeads));
		DbgPrint((DPRINT_FILESYSTEM, "HiddenSectors: %d\n", FatVolumeBootSector->HiddenSectors));
		DbgPrint((DPRINT_FILESYSTEM, "TotalSectorsBig: %d\n", FatVolumeBootSector->TotalSectorsBig));
		DbgPrint((DPRINT_FILESYSTEM, "DriveNumber: 0x%x\n", FatVolumeBootSector->DriveNumber));
		DbgPrint((DPRINT_FILESYSTEM, "Reserved1: 0x%x\n", FatVolumeBootSector->Reserved1));
		DbgPrint((DPRINT_FILESYSTEM, "BootSignature: 0x%x\n", FatVolumeBootSector->BootSignature));
		DbgPrint((DPRINT_FILESYSTEM, "VolumeSerialNumber: 0x%x\n", FatVolumeBootSector->VolumeSerialNumber));
		DbgPrint((DPRINT_FILESYSTEM, "VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", FatVolumeBootSector->VolumeLabel[0], FatVolumeBootSector->VolumeLabel[1], FatVolumeBootSector->VolumeLabel[2], FatVolumeBootSector->VolumeLabel[3], FatVolumeBootSector->VolumeLabel[4], FatVolumeBootSector->VolumeLabel[5], FatVolumeBootSector->VolumeLabel[6], FatVolumeBootSector->VolumeLabel[7], FatVolumeBootSector->VolumeLabel[8], FatVolumeBootSector->VolumeLabel[9], FatVolumeBootSector->VolumeLabel[10]));
		DbgPrint((DPRINT_FILESYSTEM, "FileSystemType: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->FileSystemType[0], FatVolumeBootSector->FileSystemType[1], FatVolumeBootSector->FileSystemType[2], FatVolumeBootSector->FileSystemType[3], FatVolumeBootSector->FileSystemType[4], FatVolumeBootSector->FileSystemType[5], FatVolumeBootSector->FileSystemType[6], FatVolumeBootSector->FileSystemType[7]));
		DbgPrint((DPRINT_FILESYSTEM, "BootSectorMagic: 0x%x\n", FatVolumeBootSector->BootSectorMagic));
	}

	//
	// Set the correct partition offset
	//
	FatVolumeStartSector = VolumeStartSector;

	//
	// Check the boot sector magic
	//
	if (! ISFATX(FatType) && FatVolumeBootSector->BootSectorMagic != 0xaa55)
	{
		sprintf(ErrMsg, "Invalid boot sector magic on drive 0x%x (expected 0xaa55 found 0x%x)",
                        DriveNumber, FatVolumeBootSector->BootSectorMagic);
		FileSystemError(ErrMsg);
		MmFreeMemory(FatVolumeBootSector);
		return FALSE;
	}

	//
	// Check the FAT cluster size
	// We do not support clusters bigger than 64k
	//
	if ((ISFATX(FatType) && 64 * 1024 < FatXVolumeBootSector->SectorsPerCluster * 512) ||
            (! ISFATX(FatType) && 64 * 1024 < FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector))
	{
		FileSystemError("This file system has cluster sizes bigger than 64k.\nFreeLoader does not support this.");
		MmFreeMemory(FatVolumeBootSector);
		return FALSE;
	}

	//
	// Clear our variables
	//
	FatSectorStart = 0;
	ActiveFatSectorStart = 0;
	NumberOfFats = 0;
	RootDirSectorStart = 0;
	DataSectorStart = 0;
	SectorsPerFat = 0;
	RootDirSectors = 0;

	//
	// Get the sectors per FAT,
	// root directory starting sector,
	// and data sector start
	//
	if (ISFATX(FatType))
	{
		BytesPerSector = 512;
		SectorsPerCluster = FatXVolumeBootSector->SectorsPerCluster;
		FatSectorStart = (4096 / BytesPerSector);
		ActiveFatSectorStart = FatSectorStart;
		NumberOfFats = 1;
		FatSize = PartitionSectorCount / SectorsPerCluster *
		          (FATX16 == FatType ? 2 : 4);
		SectorsPerFat = (((FatSize + 4095) / 4096) * 4096) / BytesPerSector;

		RootDirSectorStart = FatSectorStart + NumberOfFats * SectorsPerFat;
		RootDirSectors = FatXVolumeBootSector->SectorsPerCluster;

		DataSectorStart = RootDirSectorStart + RootDirSectors;
	}
	else if (FatType != FAT32)
	{
		BytesPerSector = FatVolumeBootSector->BytesPerSector;
		SectorsPerCluster = FatVolumeBootSector->SectorsPerCluster;
		FatSectorStart = FatVolumeBootSector->ReservedSectors;
		ActiveFatSectorStart = FatSectorStart;
		NumberOfFats = FatVolumeBootSector->NumberOfFats;
		SectorsPerFat = FatVolumeBootSector->SectorsPerFat;

		RootDirSectorStart = FatSectorStart + NumberOfFats * SectorsPerFat;
		RootDirSectors = ((FatVolumeBootSector->RootDirEntries * 32) + (BytesPerSector - 1)) / BytesPerSector;

		DataSectorStart = RootDirSectorStart + RootDirSectors;
	}
	else
	{
		BytesPerSector = Fat32VolumeBootSector->BytesPerSector;
		SectorsPerCluster = Fat32VolumeBootSector->SectorsPerCluster;
		FatSectorStart = Fat32VolumeBootSector->ReservedSectors;
		ActiveFatSectorStart = FatSectorStart +
		                       ((Fat32VolumeBootSector->ExtendedFlags & 0x80) ? ((Fat32VolumeBootSector->ExtendedFlags & 0x0f) * Fat32VolumeBootSector->SectorsPerFatBig) : 0);
		NumberOfFats = Fat32VolumeBootSector->NumberOfFats;
		SectorsPerFat = Fat32VolumeBootSector->SectorsPerFatBig;

		RootDirStartCluster = Fat32VolumeBootSector->RootDirStartCluster;
		DataSectorStart = FatSectorStart + NumberOfFats * SectorsPerFat;

		//
		// Check version
		// we only work with version 0
		//
		if (Fat32VolumeBootSector->FileSystemVersion != 0)
		{
			FileSystemError("FreeLoader is too old to work with this FAT32 filesystem.\nPlease update FreeLoader.");
			return FALSE;
		}
	}
	MmFreeMemory(FatVolumeBootSector);

	//
	// Initialize the disk cache for this drive
	//
	if (!CacheInitializeDrive(DriveNumber))
	{
		return FALSE;
	}

	//
	// Force the FAT sectors into the cache
	// as long as it is FAT12 or FAT16. FAT32 can
	// have a multi-megabyte FAT so we don't want that.
	//
	if (FatType != FAT32 && FatType != FATX32)
	{
		if (!CacheForceDiskSectorsIntoCache(DriveNumber, ActiveFatSectorStart, SectorsPerFat))
		{
			return FALSE;
		}
	}

	return TRUE;
}

ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONG PartitionSectorCount)
{
	ULONG			RootDirSectors;
	ULONG			DataSectorCount;
	ULONG			SectorsPerFat;
	ULONG			TotalSectors;
	ULONG			CountOfClusters;
	PFAT32_BOOTSECTOR	Fat32BootSector = (PFAT32_BOOTSECTOR)FatBootSector;
	PFATX_BOOTSECTOR	FatXBootSector = (PFATX_BOOTSECTOR)FatBootSector;

	if (0 == strncmp(FatXBootSector->FileSystemType, "FATX", 4))
	{
		CountOfClusters = PartitionSectorCount / FatXBootSector->SectorsPerCluster;
		if (CountOfClusters < 65525)
		{
			/* Volume is FATX16 */
			return FATX16;
		}
		else
		{
			/* Volume is FAT32 */
			return FATX32;
		}
	}
	else
	{
		RootDirSectors = ((FatBootSector->RootDirEntries * 32) + (FatBootSector->BytesPerSector - 1)) / FatBootSector->BytesPerSector;
		SectorsPerFat = FatBootSector->SectorsPerFat ? FatBootSector->SectorsPerFat : Fat32BootSector->SectorsPerFatBig;
		TotalSectors = FatBootSector->TotalSectors ? FatBootSector->TotalSectors : FatBootSector->TotalSectorsBig;
		DataSectorCount = TotalSectors - (FatBootSector->ReservedSectors + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors);

//mjl
		if (FatBootSector->SectorsPerCluster == 0)
			CountOfClusters = 0;
		else
			CountOfClusters = DataSectorCount / FatBootSector->SectorsPerCluster;

		if (CountOfClusters < 4085)
		{
			/* Volume is FAT12 */
			return FAT12;
		}
		else if (CountOfClusters < 65525)
		{
			/* Volume is FAT16 */
			return FAT16;
		}
		else
		{
			/* Volume is FAT32 */
			return FAT32;
		}
	}
}

PVOID FatBufferDirectory(ULONG DirectoryStartCluster, ULONG *DirectorySize, BOOLEAN RootDirectory)
{
	PVOID	DirectoryBuffer;

	DbgPrint((DPRINT_FILESYSTEM, "FatBufferDirectory() DirectoryStartCluster = %d RootDirectory = %s\n", DirectoryStartCluster, (RootDirectory ? "TRUE" : "FALSE")));

	/*
	 * For FAT32, the root directory is nothing special. We can treat it the same
	 * as a subdirectory.
	 */
	if (RootDirectory && FAT32 == FatType)
	{
		DirectoryStartCluster = RootDirStartCluster;
		RootDirectory = FALSE;
	}

	//
	// Calculate the size of the directory
	//
	if (RootDirectory)
	{
		*DirectorySize = RootDirSectors * BytesPerSector;
	}
	else
	{
		*DirectorySize = FatCountClustersInChain(DirectoryStartCluster) * SectorsPerCluster * BytesPerSector;
	}

	//
	// Attempt to allocate memory for directory buffer
	//
	DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectorySize) %d bytes.\n", *DirectorySize));
	DirectoryBuffer = MmAllocateMemory(*DirectorySize);

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

	//
	// Now read directory contents into DirectoryBuffer
	//
	if (RootDirectory)
	{
		if (!FatReadVolumeSectors(FatDriveNumber, RootDirSectorStart, RootDirSectors, DirectoryBuffer))
		{
			MmFreeMemory(DirectoryBuffer);
			return NULL;
		}
	}
	else
	{
		if (!FatReadClusterChain(DirectoryStartCluster, 0xFFFFFFFF, DirectoryBuffer))
		{
			MmFreeMemory(DirectoryBuffer);
			return NULL;
		}
	}

	return DirectoryBuffer;
}

BOOLEAN FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
{
	ULONG		EntryCount;
	ULONG		CurrentEntry;
	PDIRENTRY	DirEntry;
	PLFN_DIRENTRY	LfnDirEntry;
	CHAR		LfnNameBuffer[265];
	CHAR		ShortNameBuffer[20];
	ULONG		StartCluster;

	EntryCount = DirectorySize / sizeof(DIRENTRY);

	DbgPrint((DPRINT_FILESYSTEM, "FatSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName));

	memset(ShortNameBuffer, 0, 13 * sizeof(CHAR));
	memset(LfnNameBuffer, 0, 261 * sizeof(CHAR));

	DirEntry = (PDIRENTRY) DirectoryBuffer;
	for (CurrentEntry=0; CurrentEntry<EntryCount; CurrentEntry++, DirEntry++)
	{
		LfnDirEntry = (PLFN_DIRENTRY)DirEntry;

		//DbgPrint((DPRINT_FILESYSTEM, "Dumping directory entry %d:\n", CurrentEntry));
		//DbgDumpBuffer(DPRINT_FILESYSTEM, DirEntry, sizeof(DIRENTRY));

		//
		// Check if this is the last file in the directory
		// If DirEntry[0] == 0x00 then that means all the
		// entries after this one are unused. If this is the
		// last entry then we didn't find the file in this directory.
		//
		if (DirEntry->FileName[0] == '\0')
		{
			return FALSE;
		}

		//
		// Check if this is a deleted entry or not
		//
		if (DirEntry->FileName[0] == '\xE5')
		{
			memset(ShortNameBuffer, 0, 13 * sizeof(CHAR));
			memset(LfnNameBuffer, 0, 261 * sizeof(CHAR));
			continue;
		}

⌨️ 快捷键说明

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