mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Added support for FAT16 partition with clustersize greater than page size.
Patch by Hartmut Birr. svn path=/trunk/; revision=2057
This commit is contained in:
parent
6d64efee46
commit
889f9e3c01
3 changed files with 58 additions and 33 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: direntry.c,v 1.1 2001/07/05 01:51:52 rex Exp $
|
/* $Id: direntry.c,v 1.2 2001/07/13 10:31:14 ekohl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* FILE: DirEntry.c
|
* FILE: DirEntry.c
|
||||||
|
@ -20,8 +20,12 @@
|
||||||
|
|
||||||
#include "vfat.h"
|
#include "vfat.h"
|
||||||
|
|
||||||
#define ENTRIES_PER_PAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
|
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
|
||||||
(PAGESIZE / ((pDeviceExt)->BytesPerSector)))
|
(pDeviceExt)->BytesPerCluster : PAGESIZE)
|
||||||
|
|
||||||
|
#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
|
||||||
|
(CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->BytesPerSector)))
|
||||||
|
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||||
|
@ -74,8 +78,8 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||||
PFAT_DIR_ENTRY pDirEntry)
|
PFAT_DIR_ENTRY pDirEntry)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_PAGE(pDeviceExt);
|
ULONG indexInPage = *pDirectoryIndex % ENTRIES_PER_CACHEPAGE(pDeviceExt);
|
||||||
ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_PAGE(pDeviceExt);
|
ULONG pageNumber = *pDirectoryIndex / ENTRIES_PER_CACHEPAGE(pDeviceExt);
|
||||||
PVOID currentPage = NULL;
|
PVOID currentPage = NULL;
|
||||||
PCACHE_SEGMENT cacheSegment = NULL;
|
PCACHE_SEGMENT cacheSegment = NULL;
|
||||||
FATDirEntry * fatDirEntry;
|
FATDirEntry * fatDirEntry;
|
||||||
|
@ -94,7 +98,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||||
DPRINT ("Validating current directory page\n");
|
DPRINT ("Validating current directory page\n");
|
||||||
status = vfatRequestAndValidateRegion (pDeviceExt,
|
status = vfatRequestAndValidateRegion (pDeviceExt,
|
||||||
pDirectoryFCB,
|
pDirectoryFCB,
|
||||||
pageNumber * PAGESIZE,
|
pageNumber * CACHEPAGESIZE(pDeviceExt),
|
||||||
(PVOID *) ¤tPage,
|
(PVOID *) ¤tPage,
|
||||||
&cacheSegment,
|
&cacheSegment,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
@ -139,7 +143,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||||
{
|
{
|
||||||
(*pDirectoryIndex)++;
|
(*pDirectoryIndex)++;
|
||||||
indexInPage++;
|
indexInPage++;
|
||||||
if (indexInPage == ENTRIES_PER_PAGE(pDeviceExt))
|
if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
|
||||||
{
|
{
|
||||||
indexInPage = 0;
|
indexInPage = 0;
|
||||||
pageNumber++;
|
pageNumber++;
|
||||||
|
@ -153,7 +157,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||||
}
|
}
|
||||||
status = vfatRequestAndValidateRegion (pDeviceExt,
|
status = vfatRequestAndValidateRegion (pDeviceExt,
|
||||||
pDirectoryFCB,
|
pDirectoryFCB,
|
||||||
pageNumber * PAGESIZE,
|
pageNumber * CACHEPAGESIZE(pDeviceExt),
|
||||||
(PVOID *) ¤tPage,
|
(PVOID *) ¤tPage,
|
||||||
&cacheSegment,
|
&cacheSegment,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
@ -181,7 +185,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||||
}
|
}
|
||||||
(*pDirectoryIndex)++;
|
(*pDirectoryIndex)++;
|
||||||
indexInPage++;
|
indexInPage++;
|
||||||
if (indexInPage == ENTRIES_PER_PAGE(pDeviceExt))
|
if (indexInPage == ENTRIES_PER_CACHEPAGE(pDeviceExt))
|
||||||
{
|
{
|
||||||
indexInPage = 0;
|
indexInPage = 0;
|
||||||
pageNumber++;
|
pageNumber++;
|
||||||
|
@ -195,7 +199,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
|
||||||
}
|
}
|
||||||
status = vfatRequestAndValidateRegion (pDeviceExt,
|
status = vfatRequestAndValidateRegion (pDeviceExt,
|
||||||
pDirectoryFCB,
|
pDirectoryFCB,
|
||||||
pageNumber * PAGESIZE,
|
pageNumber * CACHEPAGESIZE(pDeviceExt),
|
||||||
(PVOID *) ¤tPage,
|
(PVOID *) ¤tPage,
|
||||||
&cacheSegment,
|
&cacheSegment,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: fat.c,v 1.27 2001/06/15 11:14:53 ekohl Exp $
|
* $Id: fat.c,v 1.28 2001/07/13 10:31:14 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -20,6 +20,13 @@
|
||||||
|
|
||||||
#include "vfat.h"
|
#include "vfat.h"
|
||||||
|
|
||||||
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
|
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
|
||||||
|
|
||||||
|
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
|
||||||
|
(pDeviceExt)->BytesPerCluster : PAGESIZE)
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -83,11 +90,14 @@ Fat16GetNextCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PCACHE_SEGMENT CacheSeg;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
|
ULONG ChunkSize;
|
||||||
|
|
||||||
|
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||||
|
|
||||||
FATOffset = (DeviceExt->FATStart * BLOCKSIZE) + (CurrentCluster * 2);
|
FATOffset = (DeviceExt->FATStart * BLOCKSIZE) + (CurrentCluster * 2);
|
||||||
|
|
||||||
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
|
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
|
||||||
PAGE_ROUND_DOWN(FATOffset),
|
ROUND_DOWN(FATOffset, ChunkSize),
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&Valid,
|
&Valid,
|
||||||
&CacheSeg);
|
&CacheSeg);
|
||||||
|
@ -98,8 +108,8 @@ Fat16GetNextCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
||||||
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE,
|
ROUND_DOWN(FATOffset, ChunkSize) / BLOCKSIZE,
|
||||||
PAGESIZE / BLOCKSIZE,
|
ChunkSize / BLOCKSIZE,
|
||||||
BaseAddress);
|
BaseAddress);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -108,7 +118,7 @@ Fat16GetNextCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentCluster = *((PUSHORT)(BaseAddress + (FATOffset % PAGESIZE)));
|
CurrentCluster = *((PUSHORT)(BaseAddress + (FATOffset % ChunkSize)));
|
||||||
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
||||||
CurrentCluster = 0xffffffff;
|
CurrentCluster = 0xffffffff;
|
||||||
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
|
@ -191,6 +201,9 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PCACHE_SEGMENT CacheSeg;
|
||||||
BOOLEAN Valid;
|
BOOLEAN Valid;
|
||||||
ULONG FatStart;
|
ULONG FatStart;
|
||||||
|
ULONG ChunkSize;
|
||||||
|
|
||||||
|
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||||
|
|
||||||
FatStart = DeviceExt->FATStart * BLOCKSIZE;
|
FatStart = DeviceExt->FATStart * BLOCKSIZE;
|
||||||
FatLength = DeviceExt->Boot->FATSectors * BLOCKSIZE;
|
FatLength = DeviceExt->Boot->FATSectors * BLOCKSIZE;
|
||||||
|
@ -199,14 +212,14 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
for (i = 2; i < FatLength; i+=2)
|
for (i = 2; i < FatLength; i+=2)
|
||||||
{
|
{
|
||||||
if (((FatStart + i) % PAGESIZE) == 0 || CacheSeg == NULL)
|
if (((FatStart + i) % ChunkSize) == 0 || CacheSeg == NULL)
|
||||||
{
|
{
|
||||||
if (CacheSeg != NULL)
|
if (CacheSeg != NULL)
|
||||||
{
|
{
|
||||||
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
}
|
}
|
||||||
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
|
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
|
||||||
PAGE_ROUND_DOWN(FatStart + i),
|
ROUND_DOWN(FatStart + i, ChunkSize),
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&Valid,
|
&Valid,
|
||||||
&CacheSeg);
|
&CacheSeg);
|
||||||
|
@ -217,9 +230,9 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
||||||
PAGE_ROUND_DOWN(FatStart + i)
|
ROUND_DOWN(FatStart + i, ChunkSize)
|
||||||
/ BLOCKSIZE,
|
/ BLOCKSIZE,
|
||||||
PAGESIZE / BLOCKSIZE,
|
ChunkSize / BLOCKSIZE,
|
||||||
BaseAddress);
|
BaseAddress);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -229,7 +242,7 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*((PUSHORT)(BaseAddress + ((FatStart + i) % PAGESIZE))) == 0)
|
if (*((PUSHORT)(BaseAddress + ((FatStart + i) % ChunkSize))) == 0)
|
||||||
{
|
{
|
||||||
DPRINT("Found available cluster 0x%x\n", i);
|
DPRINT("Found available cluster 0x%x\n", i);
|
||||||
*Cluster = i / 2;
|
*Cluster = i / 2;
|
||||||
|
@ -609,6 +622,9 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
ULONG Start;
|
ULONG Start;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
ULONG ChunkSize;
|
||||||
|
|
||||||
|
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||||
|
|
||||||
Start = DeviceExt->FATStart;
|
Start = DeviceExt->FATStart;
|
||||||
|
|
||||||
|
@ -617,7 +633,7 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
for (i = 0; i < DeviceExt->Boot->FATCount; i++)
|
for (i = 0; i < DeviceExt->Boot->FATCount; i++)
|
||||||
{
|
{
|
||||||
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
|
Status = CcRosRequestCacheSegment(DeviceExt->StorageBcb,
|
||||||
PAGE_ROUND_DOWN(FATOffset),
|
ROUND_DOWN(FATOffset, ChunkSize),
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&Valid,
|
&Valid,
|
||||||
&CacheSeg);
|
&CacheSeg);
|
||||||
|
@ -628,8 +644,8 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
||||||
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE,
|
ROUND_DOWN(FATOffset, ChunkSize) / BLOCKSIZE,
|
||||||
PAGESIZE / BLOCKSIZE,
|
ChunkSize / BLOCKSIZE,
|
||||||
BaseAddress);
|
BaseAddress);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -640,10 +656,10 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
|
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
|
||||||
ClusterToWrite);
|
ClusterToWrite);
|
||||||
*((PUSHORT)(BaseAddress + (FATOffset % PAGESIZE))) = NewValue;
|
*((PUSHORT)(BaseAddress + (FATOffset % ChunkSize))) = NewValue;
|
||||||
Status = VfatWriteSectors(DeviceExt->StorageDevice,
|
Status = VfatWriteSectors(DeviceExt->StorageDevice,
|
||||||
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE,
|
ROUND_DOWN(FATOffset,ChunkSize) / BLOCKSIZE,
|
||||||
PAGESIZE / BLOCKSIZE,
|
ChunkSize / BLOCKSIZE,
|
||||||
BaseAddress);
|
BaseAddress);
|
||||||
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
CcRosReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
|
|
||||||
|
@ -957,3 +973,5 @@ GetNextSector (PDEVICE_EXTENSION DeviceExt,
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: iface.c,v 1.54 2001/07/05 01:51:52 rex Exp $
|
/* $Id: iface.c,v 1.55 2001/07/13 10:31:14 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -35,6 +35,9 @@
|
||||||
|
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
|
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
|
||||||
|
(pDeviceExt)->BytesPerCluster : PAGESIZE)
|
||||||
|
|
||||||
static PDRIVER_OBJECT VfatDriverObject;
|
static PDRIVER_OBJECT VfatDriverObject;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
@ -203,7 +206,7 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
|
||||||
DeviceExt->StorageDevice);
|
DeviceExt->StorageDevice);
|
||||||
Status = CcRosInitializeFileCache(DeviceExt->StreamStorageDevice,
|
Status = CcRosInitializeFileCache(DeviceExt->StreamStorageDevice,
|
||||||
&DeviceExt->StorageBcb,
|
&DeviceExt->StorageBcb,
|
||||||
PAGESIZE);
|
CACHEPAGESIZE(DeviceExt));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* FIXME: delete device object */
|
/* FIXME: delete device object */
|
||||||
|
|
Loading…
Reference in a new issue