mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[FASTFAT]
Fix coding style and indentation in remaining files. No code changes! svn path=/trunk/; revision=61254
This commit is contained in:
parent
c031a44d65
commit
771254a62c
8 changed files with 2246 additions and 2101 deletions
|
@ -16,8 +16,10 @@
|
|||
/*
|
||||
* FUNCTION: Cleans up after a file has been closed.
|
||||
*/
|
||||
static NTSTATUS
|
||||
VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
|
||||
static
|
||||
NTSTATUS
|
||||
VfatCleanupFile(
|
||||
PVFAT_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PVFATFCB pFcb;
|
||||
PFILE_OBJECT FileObject = IrpContext->FileObject;
|
||||
|
@ -26,7 +28,7 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
|
|||
IrpContext->DeviceExt, FileObject);
|
||||
|
||||
/* FIXME: handle file/directory deletion here */
|
||||
pFcb = (PVFATFCB) FileObject->FsContext;
|
||||
pFcb = (PVFATFCB)FileObject->FsContext;
|
||||
if (!pFcb)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
|
@ -41,15 +43,15 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(!ExAcquireResourceExclusiveLite (&pFcb->MainResource,
|
||||
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
|
||||
if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource,
|
||||
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
|
||||
{
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
if(!ExAcquireResourceExclusiveLite (&pFcb->PagingIoResource,
|
||||
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
|
||||
if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
|
||||
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
|
||||
{
|
||||
ExReleaseResourceLite (&pFcb->MainResource);
|
||||
ExReleaseResourceLite(&pFcb->MainResource);
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
|
@ -80,9 +82,9 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
|
|||
pFcb->FileObject = NULL;
|
||||
CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
|
||||
ObDereferenceObject(tmpFileObject);
|
||||
}
|
||||
}
|
||||
|
||||
CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
|
||||
CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
|
||||
}
|
||||
|
||||
/* Uninitialize the cache (should be done even if caching was never initialized) */
|
||||
|
@ -95,8 +97,8 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
|
|||
|
||||
FileObject->Flags |= FO_CLEANUP_COMPLETE;
|
||||
|
||||
ExReleaseResourceLite (&pFcb->PagingIoResource);
|
||||
ExReleaseResourceLite (&pFcb->MainResource);
|
||||
ExReleaseResourceLite(&pFcb->PagingIoResource);
|
||||
ExReleaseResourceLite(&pFcb->MainResource);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -105,7 +107,9 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
|
|||
/*
|
||||
* FUNCTION: Cleans up after a file has been closed.
|
||||
*/
|
||||
NTSTATUS VfatCleanup(PVFAT_IRP_CONTEXT IrpContext)
|
||||
NTSTATUS
|
||||
VfatCleanup(
|
||||
PVFAT_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
|
@ -117,15 +121,15 @@ NTSTATUS VfatCleanup(PVFAT_IRP_CONTEXT IrpContext)
|
|||
goto ByeBye;
|
||||
}
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource,
|
||||
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
|
||||
if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
|
||||
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
|
||||
{
|
||||
return VfatQueueRequest (IrpContext);
|
||||
return VfatQueueRequest(IrpContext);
|
||||
}
|
||||
|
||||
Status = VfatCleanupFile(IrpContext);
|
||||
|
||||
ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
|
||||
ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
|
@ -136,9 +140,9 @@ ByeBye:
|
|||
IrpContext->Irp->IoStatus.Status = Status;
|
||||
IrpContext->Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
|
||||
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
|
||||
VfatFreeIrpContext(IrpContext);
|
||||
return (Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -49,7 +49,7 @@ VfatCloseFile(
|
|||
{
|
||||
if (pFcb->Flags & FCB_DELETE_PENDING)
|
||||
{
|
||||
VfatDelEntry (DeviceExt, pFcb);
|
||||
VfatDelEntry(DeviceExt, pFcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ VfatCloseFile(
|
|||
}
|
||||
}
|
||||
|
||||
vfatReleaseFCB (DeviceExt, pFcb);
|
||||
vfatReleaseFCB(DeviceExt, pFcb);
|
||||
}
|
||||
|
||||
FileObject->FsContext2 = NULL;
|
||||
|
@ -106,7 +106,7 @@ VfatClose(
|
|||
ByeBye:
|
||||
IrpContext->Irp->IoStatus.Status = Status;
|
||||
IrpContext->Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
|
||||
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
|
||||
VfatFreeIrpContext(IrpContext);
|
||||
|
||||
return Status;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,10 +17,11 @@
|
|||
|
||||
/* Function like DosDateTimeToFileTime */
|
||||
BOOLEAN
|
||||
FsdDosDateTimeToSystemTime(PDEVICE_EXTENSION DeviceExt,
|
||||
USHORT DosDate,
|
||||
USHORT DosTime,
|
||||
PLARGE_INTEGER SystemTime)
|
||||
FsdDosDateTimeToSystemTime(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
USHORT DosDate,
|
||||
USHORT DosTime,
|
||||
PLARGE_INTEGER SystemTime)
|
||||
{
|
||||
PDOSTIME pdtime = (PDOSTIME)&DosTime;
|
||||
PDOSDATE pddate = (PDOSDATE)&DosDate;
|
||||
|
@ -47,10 +48,11 @@ FsdDosDateTimeToSystemTime(PDEVICE_EXTENSION DeviceExt,
|
|||
|
||||
/* Function like FileTimeToDosDateTime */
|
||||
BOOLEAN
|
||||
FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt,
|
||||
PLARGE_INTEGER SystemTime,
|
||||
PUSHORT pDosDate,
|
||||
PUSHORT pDosTime)
|
||||
FsdSystemTimeToDosDateTime(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PLARGE_INTEGER SystemTime,
|
||||
PUSHORT pDosDate,
|
||||
PUSHORT pDosTime)
|
||||
{
|
||||
PDOSTIME pdtime = (PDOSTIME)pDosTime;
|
||||
PDOSDATE pddate = (PDOSDATE)pDosDate;
|
||||
|
@ -82,10 +84,12 @@ FsdSystemTimeToDosDateTime(PDEVICE_EXTENSION DeviceExt,
|
|||
|
||||
#define ULONG_ROUND_UP(x) ROUND_UP((x), (sizeof(ULONG)))
|
||||
|
||||
static NTSTATUS
|
||||
VfatGetFileNameInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PFILE_NAMES_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
static
|
||||
NTSTATUS
|
||||
VfatGetFileNameInformation(
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PFILE_NAMES_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
if ((sizeof(FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
@ -101,11 +105,13 @@ VfatGetFileNameInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
VfatGetFileDirectoryInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_DIRECTORY_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
static
|
||||
NTSTATUS
|
||||
VfatGetFileDirectoryInformation(
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_DIRECTORY_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
if ((sizeof(FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
@ -191,11 +197,13 @@ VfatGetFileDirectoryInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
VfatGetFileFullDirectoryInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_FULL_DIR_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
static
|
||||
NTSTATUS
|
||||
VfatGetFileFullDirectoryInformation(
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_FULL_DIR_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
if ((sizeof(FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
@ -262,11 +270,13 @@ VfatGetFileFullDirectoryInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
VfatGetFileBothInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_BOTH_DIR_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
static
|
||||
NTSTATUS
|
||||
VfatGetFileBothInformation(
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_BOTH_DIR_INFORMATION pInfo,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
if ((sizeof(FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
@ -372,8 +382,10 @@ VfatGetFileBothInformation(PVFAT_DIRENTRY_CONTEXT DirContext,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
DoQuery(PVFAT_IRP_CONTEXT IrpContext)
|
||||
static
|
||||
NTSTATUS
|
||||
DoQuery(
|
||||
PVFAT_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
LONG BufferLength = 0;
|
||||
|
@ -575,7 +587,8 @@ DoQuery(PVFAT_IRP_CONTEXT IrpContext)
|
|||
* FUNCTION: directory control : read/write directory informations
|
||||
*/
|
||||
NTSTATUS
|
||||
VfatDirectoryControl(PVFAT_IRP_CONTEXT IrpContext)
|
||||
VfatDirectoryControl(
|
||||
PVFAT_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
#include "vfat.h"
|
||||
|
||||
ULONG
|
||||
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||
PDIR_ENTRY pFatDirEntry)
|
||||
vfatDirEntryGetFirstCluster(
|
||||
PDEVICE_EXTENSION pDeviceExt,
|
||||
PDIR_ENTRY pFatDirEntry)
|
||||
{
|
||||
ULONG cluster;
|
||||
|
||||
|
@ -38,7 +39,8 @@ vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
|||
|
||||
static
|
||||
BOOLEAN
|
||||
FATIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
FATIsDirectoryEmpty(
|
||||
PVFATFCB Fcb)
|
||||
{
|
||||
LARGE_INTEGER FileOffset;
|
||||
PVOID Context = NULL;
|
||||
|
@ -101,7 +103,8 @@ FATIsDirectoryEmpty(PVFATFCB Fcb)
|
|||
|
||||
static
|
||||
BOOLEAN
|
||||
FATXIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
FATXIsDirectoryEmpty(
|
||||
PVFATFCB Fcb)
|
||||
{
|
||||
LARGE_INTEGER FileOffset;
|
||||
PVOID Context = NULL;
|
||||
|
@ -154,7 +157,8 @@ FATXIsDirectoryEmpty(PVFATFCB Fcb)
|
|||
}
|
||||
|
||||
BOOLEAN
|
||||
VfatIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
VfatIsDirectoryEmpty(
|
||||
PVFATFCB Fcb)
|
||||
{
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
return FATXIsDirectoryEmpty(Fcb);
|
||||
|
@ -163,11 +167,12 @@ VfatIsDirectoryEmpty(PVFATFCB Fcb)
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
FATGetNextDirEntry(PVOID *pContext,
|
||||
PVOID *pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
BOOLEAN First)
|
||||
FATGetNextDirEntry(
|
||||
PVOID *pContext,
|
||||
PVOID *pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
BOOLEAN First)
|
||||
{
|
||||
ULONG dirMap;
|
||||
PWCHAR pName;
|
||||
|
@ -404,112 +409,112 @@ FATGetNextDirEntry(PVOID *pContext,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FATXGetNextDirEntry(PVOID * pContext,
|
||||
PVOID * pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
BOOLEAN First)
|
||||
NTSTATUS
|
||||
FATXGetNextDirEntry(
|
||||
PVOID *pContext,
|
||||
PVOID *pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
BOOLEAN First)
|
||||
{
|
||||
LARGE_INTEGER FileOffset;
|
||||
PFATX_DIR_ENTRY fatxDirEntry;
|
||||
OEM_STRING StringO;
|
||||
ULONG DirIndex = DirContext->DirIndex;
|
||||
LARGE_INTEGER FileOffset;
|
||||
PFATX_DIR_ENTRY fatxDirEntry;
|
||||
OEM_STRING StringO;
|
||||
ULONG DirIndex = DirContext->DirIndex;
|
||||
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.HighPart = 0;
|
||||
|
||||
UNREFERENCED_PARAMETER(First);
|
||||
UNREFERENCED_PARAMETER(First);
|
||||
|
||||
if (!vfatFCBIsRoot(pDirFcb))
|
||||
{
|
||||
/* need to add . and .. entries */
|
||||
switch (DirContext->DirIndex)
|
||||
{
|
||||
case 0: /* entry . */
|
||||
{
|
||||
DirContext->ShortNameU.Buffer[0] = 0;
|
||||
DirContext->ShortNameU.Length = 0;
|
||||
wcscpy(DirContext->LongNameU.Buffer, L".");
|
||||
DirContext->LongNameU.Length = sizeof(WCHAR);
|
||||
RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
|
||||
DirContext->DirEntry.FatX.Filename[0] = '.';
|
||||
DirContext->DirEntry.FatX.FilenameLength = 1;
|
||||
DirContext->StartIndex = 0;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
case 1: /* entry .. */
|
||||
{
|
||||
DirContext->ShortNameU.Buffer[0] = 0;
|
||||
DirContext->ShortNameU.Length = 0;
|
||||
wcscpy(DirContext->LongNameU.Buffer, L"..");
|
||||
DirContext->LongNameU.Length = 2 * sizeof(WCHAR);
|
||||
RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
|
||||
DirContext->DirEntry.FatX.Filename[0] = DirContext->DirEntry.FatX.Filename[1] = '.';
|
||||
DirContext->DirEntry.FatX.FilenameLength = 2;
|
||||
DirContext->StartIndex = 1;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
default:
|
||||
DirIndex -= 2;
|
||||
}
|
||||
}
|
||||
if (!vfatFCBIsRoot(pDirFcb))
|
||||
{
|
||||
/* need to add . and .. entries */
|
||||
switch (DirContext->DirIndex)
|
||||
{
|
||||
case 0: /* entry . */
|
||||
DirContext->ShortNameU.Buffer[0] = 0;
|
||||
DirContext->ShortNameU.Length = 0;
|
||||
wcscpy(DirContext->LongNameU.Buffer, L".");
|
||||
DirContext->LongNameU.Length = sizeof(WCHAR);
|
||||
RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
|
||||
DirContext->DirEntry.FatX.Filename[0] = '.';
|
||||
DirContext->DirEntry.FatX.FilenameLength = 1;
|
||||
DirContext->StartIndex = 0;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
if (*pContext != NULL)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
}
|
||||
FileOffset.u.LowPart = ROUND_DOWN(DirIndex * sizeof(FATX_DIR_ENTRY), PAGE_SIZE);
|
||||
if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
|
||||
!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
}
|
||||
case 1: /* entry .. */
|
||||
DirContext->ShortNameU.Buffer[0] = 0;
|
||||
DirContext->ShortNameU.Length = 0;
|
||||
wcscpy(DirContext->LongNameU.Buffer, L"..");
|
||||
DirContext->LongNameU.Length = 2 * sizeof(WCHAR);
|
||||
RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
|
||||
DirContext->DirEntry.FatX.Filename[0] = DirContext->DirEntry.FatX.Filename[1] = '.';
|
||||
DirContext->DirEntry.FatX.FilenameLength = 2;
|
||||
DirContext->StartIndex = 1;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
fatxDirEntry = (PFATX_DIR_ENTRY)(*pPage) + DirIndex % FATX_ENTRIES_PER_PAGE;
|
||||
default:
|
||||
DirIndex -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
DirContext->StartIndex = DirContext->DirIndex;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (FATX_ENTRY_END(fatxDirEntry))
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
if (!FATX_ENTRY_DELETED(fatxDirEntry))
|
||||
{
|
||||
RtlCopyMemory(&DirContext->DirEntry.FatX, fatxDirEntry, sizeof(FATX_DIR_ENTRY));
|
||||
break;
|
||||
}
|
||||
DirContext->DirIndex++;
|
||||
DirContext->StartIndex++;
|
||||
DirIndex++;
|
||||
if ((DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
|
||||
!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
if (*pContext != NULL)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
}
|
||||
FileOffset.u.LowPart = ROUND_DOWN(DirIndex * sizeof(FATX_DIR_ENTRY), PAGE_SIZE);
|
||||
if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
|
||||
!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
fatxDirEntry = (PFATX_DIR_ENTRY)*pPage;
|
||||
}
|
||||
else
|
||||
{
|
||||
fatxDirEntry++;
|
||||
}
|
||||
}
|
||||
DirContext->ShortNameU.Buffer[0] = 0;
|
||||
DirContext->ShortNameU.Length = 0;
|
||||
StringO.Buffer = (PCHAR)fatxDirEntry->Filename;
|
||||
StringO.Length = StringO.MaximumLength = fatxDirEntry->FilenameLength;
|
||||
RtlOemStringToUnicodeString(&DirContext->LongNameU, &StringO, FALSE);
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
}
|
||||
|
||||
fatxDirEntry = (PFATX_DIR_ENTRY)(*pPage) + DirIndex % FATX_ENTRIES_PER_PAGE;
|
||||
|
||||
DirContext->StartIndex = DirContext->DirIndex;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (FATX_ENTRY_END(fatxDirEntry))
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
if (!FATX_ENTRY_DELETED(fatxDirEntry))
|
||||
{
|
||||
RtlCopyMemory(&DirContext->DirEntry.FatX, fatxDirEntry, sizeof(FATX_DIR_ENTRY));
|
||||
break;
|
||||
}
|
||||
DirContext->DirIndex++;
|
||||
DirContext->StartIndex++;
|
||||
DirIndex++;
|
||||
if ((DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
|
||||
!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
fatxDirEntry = (PFATX_DIR_ENTRY)*pPage;
|
||||
}
|
||||
else
|
||||
{
|
||||
fatxDirEntry++;
|
||||
}
|
||||
}
|
||||
DirContext->ShortNameU.Buffer[0] = 0;
|
||||
DirContext->ShortNameU.Length = 0;
|
||||
StringO.Buffer = (PCHAR)fatxDirEntry->Filename;
|
||||
StringO.Length = StringO.MaximumLength = fatxDirEntry->FilenameLength;
|
||||
RtlOemStringToUnicodeString(&DirContext->LongNameU, &StringO, FALSE);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -11,15 +11,18 @@
|
|||
|
||||
static FAST_IO_CHECK_IF_POSSIBLE VfatFastIoCheckIfPossible;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoCheckIfPossible(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN ULONG LockKey,
|
||||
IN BOOLEAN CheckForReadOperation,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoCheckIfPossible(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN ULONG LockKey,
|
||||
IN BOOLEAN CheckForReadOperation,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
/* Prevent all Fast I/O requests */
|
||||
DPRINT("VfatFastIoCheckIfPossible(): returning FALSE.\n");
|
||||
|
@ -38,15 +41,18 @@ VfatFastIoCheckIfPossible(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_READ VfatFastIoRead;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoRead(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN ULONG LockKey,
|
||||
OUT PVOID Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoRead(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN ULONG LockKey,
|
||||
OUT PVOID Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoRead()\n");
|
||||
|
||||
|
@ -64,15 +70,18 @@ VfatFastIoRead(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_WRITE VfatFastIoWrite;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoWrite(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN ULONG LockKey,
|
||||
OUT PVOID Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoWrite(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN ULONG LockKey,
|
||||
OUT PVOID Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoWrite()\n");
|
||||
|
||||
|
@ -90,12 +99,15 @@ VfatFastIoWrite(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_QUERY_BASIC_INFO VfatFastIoQueryBasicInfo;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoQueryBasicInfo(IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
OUT PFILE_BASIC_INFORMATION Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoQueryBasicInfo(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
OUT PFILE_BASIC_INFORMATION Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoQueryBasicInfo()\n");
|
||||
|
||||
|
@ -110,12 +122,15 @@ VfatFastIoQueryBasicInfo(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_QUERY_STANDARD_INFO VfatFastIoQueryStandardInfo;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoQueryStandardInfo(IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
OUT PFILE_STANDARD_INFORMATION Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoQueryStandardInfo(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
OUT PFILE_STANDARD_INFORMATION Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoQueryStandardInfo\n");
|
||||
|
||||
|
@ -130,16 +145,19 @@ VfatFastIoQueryStandardInfo(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_LOCK VfatFastIoLock;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoLock(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PLARGE_INTEGER Length,
|
||||
PEPROCESS ProcessId,
|
||||
ULONG Key,
|
||||
BOOLEAN FailImmediately,
|
||||
BOOLEAN ExclusiveLock,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoLock(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PLARGE_INTEGER Length,
|
||||
PEPROCESS ProcessId,
|
||||
ULONG Key,
|
||||
BOOLEAN FailImmediately,
|
||||
BOOLEAN ExclusiveLock,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoLock\n");
|
||||
|
||||
|
@ -158,14 +176,17 @@ VfatFastIoLock(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_UNLOCK_SINGLE VfatFastIoUnlockSingle;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoUnlockSingle(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PLARGE_INTEGER Length,
|
||||
PEPROCESS ProcessId,
|
||||
ULONG Key,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoUnlockSingle(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PLARGE_INTEGER Length,
|
||||
PEPROCESS ProcessId,
|
||||
ULONG Key,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoUnlockSingle\n");
|
||||
|
||||
|
@ -182,11 +203,14 @@ VfatFastIoUnlockSingle(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_UNLOCK_ALL VfatFastIoUnlockAll;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoUnlockAll(IN PFILE_OBJECT FileObject,
|
||||
PEPROCESS ProcessId,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoUnlockAll(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
PEPROCESS ProcessId,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoUnlockAll\n");
|
||||
|
||||
|
@ -200,12 +224,15 @@ VfatFastIoUnlockAll(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_UNLOCK_ALL_BY_KEY VfatFastIoUnlockAllByKey;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoUnlockAllByKey(IN PFILE_OBJECT FileObject,
|
||||
PVOID ProcessId,
|
||||
ULONG Key,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoUnlockAllByKey(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
PVOID ProcessId,
|
||||
ULONG Key,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoUnlockAllByKey\n");
|
||||
|
||||
|
@ -220,16 +247,19 @@ VfatFastIoUnlockAllByKey(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_DEVICE_CONTROL VfatFastIoDeviceControl;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoDeviceControl(IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
IN PVOID InputBuffer OPTIONAL,
|
||||
IN ULONG InputBufferLength,
|
||||
OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN ULONG OutputBufferLength,
|
||||
IN ULONG IoControlCode,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoDeviceControl(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
IN PVOID InputBuffer OPTIONAL,
|
||||
IN ULONG InputBufferLength,
|
||||
OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN ULONG OutputBufferLength,
|
||||
IN ULONG IoControlCode,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoDeviceControl\n");
|
||||
|
||||
|
@ -248,8 +278,11 @@ VfatFastIoDeviceControl(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_ACQUIRE_FILE VfatAcquireFileForNtCreateSection;
|
||||
|
||||
static VOID NTAPI
|
||||
VfatAcquireFileForNtCreateSection(IN PFILE_OBJECT FileObject)
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
VfatAcquireFileForNtCreateSection(
|
||||
IN PFILE_OBJECT FileObject)
|
||||
{
|
||||
DPRINT("VfatAcquireFileForNtCreateSection\n");
|
||||
UNREFERENCED_PARAMETER(FileObject);
|
||||
|
@ -257,8 +290,11 @@ VfatAcquireFileForNtCreateSection(IN PFILE_OBJECT FileObject)
|
|||
|
||||
static FAST_IO_RELEASE_FILE VfatReleaseFileForNtCreateSection;
|
||||
|
||||
static VOID NTAPI
|
||||
VfatReleaseFileForNtCreateSection(IN PFILE_OBJECT FileObject)
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
VfatReleaseFileForNtCreateSection(
|
||||
IN PFILE_OBJECT FileObject)
|
||||
{
|
||||
DPRINT("VfatReleaseFileForNtCreateSection\n");
|
||||
UNREFERENCED_PARAMETER(FileObject);
|
||||
|
@ -266,9 +302,12 @@ VfatReleaseFileForNtCreateSection(IN PFILE_OBJECT FileObject)
|
|||
|
||||
static FAST_IO_DETACH_DEVICE VfatFastIoDetachDevice;
|
||||
|
||||
static VOID NTAPI
|
||||
VfatFastIoDetachDevice(IN PDEVICE_OBJECT SourceDevice,
|
||||
IN PDEVICE_OBJECT TargetDevice)
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
VfatFastIoDetachDevice(
|
||||
IN PDEVICE_OBJECT SourceDevice,
|
||||
IN PDEVICE_OBJECT TargetDevice)
|
||||
{
|
||||
DPRINT("VfatFastIoDetachDevice\n");
|
||||
UNREFERENCED_PARAMETER(SourceDevice);
|
||||
|
@ -277,12 +316,15 @@ VfatFastIoDetachDevice(IN PDEVICE_OBJECT SourceDevice,
|
|||
|
||||
static FAST_IO_QUERY_NETWORK_OPEN_INFO VfatFastIoQueryNetworkOpenInfo;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoQueryNetworkOpenInfo(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN Wait,
|
||||
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoQueryNetworkOpenInfo\n");
|
||||
|
||||
|
@ -297,11 +339,14 @@ VfatFastIoQueryNetworkOpenInfo(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_ACQUIRE_FOR_MOD_WRITE VfatAcquireForModWrite;
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
VfatAcquireForModWrite(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER EndingOffset,
|
||||
OUT PERESOURCE* ResourceToRelease,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VfatAcquireForModWrite(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER EndingOffset,
|
||||
OUT PERESOURCE* ResourceToRelease,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatAcquireForModWrite\n");
|
||||
|
||||
|
@ -315,14 +360,17 @@ VfatAcquireForModWrite(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_MDL_READ VfatMdlRead;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatMdlRead(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatMdlRead(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatMdlRead\n");
|
||||
|
||||
|
@ -339,10 +387,13 @@ VfatMdlRead(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_MDL_READ_COMPLETE VfatMdlReadComplete;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatMdlReadComplete(IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatMdlReadComplete(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatMdlReadComplete\n");
|
||||
|
||||
|
@ -355,14 +406,17 @@ VfatMdlReadComplete(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_PREPARE_MDL_WRITE VfatPrepareMdlWrite;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatPrepareMdlWrite(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatPrepareMdlWrite\n");
|
||||
|
||||
|
@ -379,11 +433,14 @@ VfatPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_MDL_WRITE_COMPLETE VfatMdlWriteComplete;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatMdlWriteComplete(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatMdlWriteComplete(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatMdlWriteComplete\n");
|
||||
|
||||
|
@ -397,17 +454,20 @@ VfatMdlWriteComplete(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_READ_COMPRESSED VfatFastIoReadCompressed;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoReadCompressed(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
OUT PVOID Buffer,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
||||
IN ULONG CompressedDataInfoLength,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoReadCompressed(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
OUT PVOID Buffer,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
||||
IN ULONG CompressedDataInfoLength,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoReadCompressed\n");
|
||||
|
||||
|
@ -427,17 +487,20 @@ VfatFastIoReadCompressed(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_WRITE_COMPRESSED VfatFastIoWriteCompressed;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoWriteCompressed(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
IN PVOID Buffer,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
||||
IN ULONG CompressedDataInfoLength,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoWriteCompressed(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG LockKey,
|
||||
IN PVOID Buffer,
|
||||
OUT PMDL* MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
|
||||
IN ULONG CompressedDataInfoLength,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoWriteCompressed\n");
|
||||
|
||||
|
@ -457,10 +520,13 @@ VfatFastIoWriteCompressed(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_MDL_READ_COMPLETE_COMPRESSED VfatMdlReadCompleteCompressed;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatMdlReadCompleteCompressed(IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatMdlReadCompleteCompressed(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatMdlReadCompleteCompressed\n");
|
||||
|
||||
|
@ -473,11 +539,14 @@ VfatMdlReadCompleteCompressed(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_MDL_WRITE_COMPLETE_COMPRESSED VfatMdlWriteCompleteCompressed;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatMdlWriteCompleteCompressed(IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatMdlWriteCompleteCompressed(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatMdlWriteCompleteCompressed\n");
|
||||
|
||||
|
@ -491,12 +560,15 @@ VfatMdlWriteCompleteCompressed(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_QUERY_OPEN VfatFastIoQueryOpen;
|
||||
|
||||
static BOOLEAN NTAPI
|
||||
VfatFastIoQueryOpen(IN PIRP Irp,
|
||||
OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatFastIoQueryOpen(
|
||||
IN PIRP Irp,
|
||||
OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatFastIoQueryOpen\n");
|
||||
DPRINT("VfatFastIoQueryOpen\n");
|
||||
|
||||
UNREFERENCED_PARAMETER(Irp);
|
||||
UNREFERENCED_PARAMETER(NetworkInformation);
|
||||
|
@ -507,10 +579,13 @@ VfatFastIoQueryOpen(IN PIRP Irp,
|
|||
|
||||
static FAST_IO_RELEASE_FOR_MOD_WRITE VfatReleaseForModWrite;
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
VfatReleaseForModWrite(IN PFILE_OBJECT FileObject,
|
||||
IN PERESOURCE ResourceToRelease,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VfatReleaseForModWrite(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PERESOURCE ResourceToRelease,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
DPRINT("VfatReleaseForModWrite\n");
|
||||
|
||||
|
@ -523,128 +598,143 @@ VfatReleaseForModWrite(IN PFILE_OBJECT FileObject,
|
|||
|
||||
static FAST_IO_ACQUIRE_FOR_CCFLUSH VfatAcquireForCcFlush;
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
VfatAcquireForCcFlush(IN PFILE_OBJECT FileObject,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VfatAcquireForCcFlush(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
|
||||
PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
|
||||
|
||||
DPRINT("VfatAcquireForCcFlush\n");
|
||||
DPRINT("VfatAcquireForCcFlush\n");
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
/* Make sure it is not a volume lock */
|
||||
ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
|
||||
/* Make sure it is not a volume lock */
|
||||
ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
|
||||
|
||||
/* Acquire the resource */
|
||||
ExAcquireResourceExclusiveLite(&(Fcb->MainResource), TRUE);
|
||||
/* Acquire the resource */
|
||||
ExAcquireResourceExclusiveLite(&(Fcb->MainResource), TRUE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static FAST_IO_RELEASE_FOR_CCFLUSH VfatReleaseForCcFlush;
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
VfatReleaseForCcFlush(IN PFILE_OBJECT FileObject,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VfatReleaseForCcFlush(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
|
||||
PVFATFCB Fcb = (PVFATFCB)FileObject->FsContext;
|
||||
|
||||
DPRINT("VfatReleaseForCcFlush\n");
|
||||
DPRINT("VfatReleaseForCcFlush\n");
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
/* Make sure it is not a volume lock */
|
||||
ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
|
||||
/* Make sure it is not a volume lock */
|
||||
ASSERT(!(Fcb->Flags & FCB_IS_VOLUME));
|
||||
|
||||
/* Release the resource */
|
||||
ExReleaseResourceLite(&(Fcb->MainResource));
|
||||
/* Release the resource */
|
||||
ExReleaseResourceLite(&(Fcb->MainResource));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN NTAPI
|
||||
VfatAcquireForLazyWrite(IN PVOID Context,
|
||||
IN BOOLEAN Wait)
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatAcquireForLazyWrite(
|
||||
IN PVOID Context,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatAcquireForLazyWrite(): Fcb %p\n", Fcb);
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatAcquireForLazyWrite(): Fcb %p\n", Fcb);
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
|
||||
{
|
||||
DPRINT("VfatAcquireForLazyWrite(): ExReleaseResourceLite failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
VfatReleaseFromLazyWrite(IN PVOID Context)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatReleaseFromLazyWrite(): Fcb %p\n", Fcb);
|
||||
|
||||
ExReleaseResourceLite(&(Fcb->MainResource));
|
||||
}
|
||||
|
||||
BOOLEAN NTAPI
|
||||
VfatAcquireForReadAhead(IN PVOID Context,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatAcquireForReadAhead(): Fcb %p\n", Fcb);
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
|
||||
{
|
||||
DPRINT("VfatAcquireForReadAhead(): ExReleaseResourceLite failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
VfatReleaseFromReadAhead(IN PVOID Context)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatReleaseFromReadAhead(): Fcb %p\n", Fcb);
|
||||
|
||||
ExReleaseResourceLite(&(Fcb->MainResource));
|
||||
if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
|
||||
{
|
||||
DPRINT("VfatAcquireForLazyWrite(): ExReleaseResourceLite failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
VfatInitFastIoRoutines(PFAST_IO_DISPATCH FastIoDispatch)
|
||||
NTAPI
|
||||
VfatReleaseFromLazyWrite(
|
||||
IN PVOID Context)
|
||||
{
|
||||
FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
|
||||
FastIoDispatch->FastIoCheckIfPossible = VfatFastIoCheckIfPossible;
|
||||
FastIoDispatch->FastIoRead = VfatFastIoRead;
|
||||
FastIoDispatch->FastIoWrite = VfatFastIoWrite;
|
||||
FastIoDispatch->FastIoQueryBasicInfo = VfatFastIoQueryBasicInfo;
|
||||
FastIoDispatch->FastIoQueryStandardInfo = VfatFastIoQueryStandardInfo;
|
||||
FastIoDispatch->FastIoLock = VfatFastIoLock;
|
||||
FastIoDispatch->FastIoUnlockSingle = VfatFastIoUnlockSingle;
|
||||
FastIoDispatch->FastIoUnlockAll = VfatFastIoUnlockAll;
|
||||
FastIoDispatch->FastIoUnlockAllByKey = VfatFastIoUnlockAllByKey;
|
||||
FastIoDispatch->FastIoDeviceControl = VfatFastIoDeviceControl;
|
||||
FastIoDispatch->AcquireFileForNtCreateSection = VfatAcquireFileForNtCreateSection;
|
||||
FastIoDispatch->ReleaseFileForNtCreateSection = VfatReleaseFileForNtCreateSection;
|
||||
FastIoDispatch->FastIoDetachDevice = VfatFastIoDetachDevice;
|
||||
FastIoDispatch->FastIoQueryNetworkOpenInfo = VfatFastIoQueryNetworkOpenInfo;
|
||||
FastIoDispatch->MdlRead = VfatMdlRead;
|
||||
FastIoDispatch->MdlReadComplete = VfatMdlReadComplete;
|
||||
FastIoDispatch->PrepareMdlWrite = VfatPrepareMdlWrite;
|
||||
FastIoDispatch->MdlWriteComplete = VfatMdlWriteComplete;
|
||||
FastIoDispatch->FastIoReadCompressed = VfatFastIoReadCompressed;
|
||||
FastIoDispatch->FastIoWriteCompressed = VfatFastIoWriteCompressed;
|
||||
FastIoDispatch->MdlReadCompleteCompressed = VfatMdlReadCompleteCompressed;
|
||||
FastIoDispatch->MdlWriteCompleteCompressed = VfatMdlWriteCompleteCompressed;
|
||||
FastIoDispatch->FastIoQueryOpen = VfatFastIoQueryOpen;
|
||||
FastIoDispatch->AcquireForModWrite = VfatAcquireForModWrite;
|
||||
FastIoDispatch->ReleaseForModWrite = VfatReleaseForModWrite;
|
||||
FastIoDispatch->AcquireForCcFlush = VfatAcquireForCcFlush;
|
||||
FastIoDispatch->ReleaseForCcFlush = VfatReleaseForCcFlush;
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatReleaseFromLazyWrite(): Fcb %p\n", Fcb);
|
||||
|
||||
ExReleaseResourceLite(&(Fcb->MainResource));
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VfatAcquireForReadAhead(
|
||||
IN PVOID Context,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatAcquireForReadAhead(): Fcb %p\n", Fcb);
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(&(Fcb->MainResource), Wait))
|
||||
{
|
||||
DPRINT("VfatAcquireForReadAhead(): ExReleaseResourceLite failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
VfatReleaseFromReadAhead(
|
||||
IN PVOID Context)
|
||||
{
|
||||
PVFATFCB Fcb = (PVFATFCB)Context;
|
||||
ASSERT(Fcb);
|
||||
DPRINT("VfatReleaseFromReadAhead(): Fcb %p\n", Fcb);
|
||||
|
||||
ExReleaseResourceLite(&(Fcb->MainResource));
|
||||
}
|
||||
|
||||
VOID
|
||||
VfatInitFastIoRoutines(
|
||||
PFAST_IO_DISPATCH FastIoDispatch)
|
||||
{
|
||||
FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
|
||||
FastIoDispatch->FastIoCheckIfPossible = VfatFastIoCheckIfPossible;
|
||||
FastIoDispatch->FastIoRead = VfatFastIoRead;
|
||||
FastIoDispatch->FastIoWrite = VfatFastIoWrite;
|
||||
FastIoDispatch->FastIoQueryBasicInfo = VfatFastIoQueryBasicInfo;
|
||||
FastIoDispatch->FastIoQueryStandardInfo = VfatFastIoQueryStandardInfo;
|
||||
FastIoDispatch->FastIoLock = VfatFastIoLock;
|
||||
FastIoDispatch->FastIoUnlockSingle = VfatFastIoUnlockSingle;
|
||||
FastIoDispatch->FastIoUnlockAll = VfatFastIoUnlockAll;
|
||||
FastIoDispatch->FastIoUnlockAllByKey = VfatFastIoUnlockAllByKey;
|
||||
FastIoDispatch->FastIoDeviceControl = VfatFastIoDeviceControl;
|
||||
FastIoDispatch->AcquireFileForNtCreateSection = VfatAcquireFileForNtCreateSection;
|
||||
FastIoDispatch->ReleaseFileForNtCreateSection = VfatReleaseFileForNtCreateSection;
|
||||
FastIoDispatch->FastIoDetachDevice = VfatFastIoDetachDevice;
|
||||
FastIoDispatch->FastIoQueryNetworkOpenInfo = VfatFastIoQueryNetworkOpenInfo;
|
||||
FastIoDispatch->MdlRead = VfatMdlRead;
|
||||
FastIoDispatch->MdlReadComplete = VfatMdlReadComplete;
|
||||
FastIoDispatch->PrepareMdlWrite = VfatPrepareMdlWrite;
|
||||
FastIoDispatch->MdlWriteComplete = VfatMdlWriteComplete;
|
||||
FastIoDispatch->FastIoReadCompressed = VfatFastIoReadCompressed;
|
||||
FastIoDispatch->FastIoWriteCompressed = VfatFastIoWriteCompressed;
|
||||
FastIoDispatch->MdlReadCompleteCompressed = VfatMdlReadCompleteCompressed;
|
||||
FastIoDispatch->MdlWriteCompleteCompressed = VfatMdlWriteCompleteCompressed;
|
||||
FastIoDispatch->FastIoQueryOpen = VfatFastIoQueryOpen;
|
||||
FastIoDispatch->AcquireForModWrite = VfatAcquireForModWrite;
|
||||
FastIoDispatch->ReleaseForModWrite = VfatReleaseForModWrite;
|
||||
FastIoDispatch->AcquireForCcFlush = VfatAcquireForCcFlush;
|
||||
FastIoDispatch->ReleaseForCcFlush = VfatReleaseForCcFlush;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ FAT16GetNextCluster(
|
|||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FATOffset = CurrentCluster * 2;
|
||||
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
|
||||
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
|
||||
if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
@ -193,527 +193,543 @@ FAT16FindAndMarkAvailableCluster(
|
|||
return STATUS_DISK_FULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FAT12FindAndMarkAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
|
||||
/*
|
||||
* FUNCTION: Finds the first available cluster in a FAT12 table
|
||||
*/
|
||||
NTSTATUS
|
||||
FAT12FindAndMarkAvailableCluster(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PULONG Cluster)
|
||||
{
|
||||
ULONG FatLength;
|
||||
ULONG StartCluster;
|
||||
ULONG Entry;
|
||||
PUSHORT CBlock;
|
||||
ULONG i, j;
|
||||
PVOID BaseAddress;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG FatLength;
|
||||
ULONG StartCluster;
|
||||
ULONG Entry;
|
||||
PUSHORT CBlock;
|
||||
ULONG i, j;
|
||||
PVOID BaseAddress;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
|
||||
FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
|
||||
*Cluster = 0;
|
||||
StartCluster = DeviceExt->LastAvailableCluster;
|
||||
Offset.QuadPart = 0;
|
||||
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
|
||||
{
|
||||
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = StartCluster; i < FatLength; i++)
|
||||
FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
|
||||
*Cluster = 0;
|
||||
StartCluster = DeviceExt->LastAvailableCluster;
|
||||
Offset.QuadPart = 0;
|
||||
if (!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
|
||||
{
|
||||
CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
Entry = *CBlock & 0xfff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry = *CBlock >> 4;
|
||||
}
|
||||
if (Entry == 0)
|
||||
{
|
||||
DPRINT("Found available cluster 0x%x\n", i);
|
||||
DeviceExt->LastAvailableCluster = *Cluster = i;
|
||||
if ((i % 2) == 0)
|
||||
*CBlock = (*CBlock & 0xf000) | 0xfff;
|
||||
else
|
||||
*CBlock = (*CBlock & 0xf) | 0xfff0;
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
if (DeviceExt->AvailableClustersValid)
|
||||
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
FatLength = StartCluster;
|
||||
StartCluster = 2;
|
||||
}
|
||||
CcUnpinData(Context);
|
||||
return (STATUS_DISK_FULL);
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = StartCluster; i < FatLength; i++)
|
||||
{
|
||||
CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
Entry = *CBlock & 0xfff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry = *CBlock >> 4;
|
||||
}
|
||||
|
||||
if (Entry == 0)
|
||||
{
|
||||
DPRINT("Found available cluster 0x%x\n", i);
|
||||
DeviceExt->LastAvailableCluster = *Cluster = i;
|
||||
if ((i % 2) == 0)
|
||||
*CBlock = (*CBlock & 0xf000) | 0xfff;
|
||||
else
|
||||
*CBlock = (*CBlock & 0xf) | 0xfff0;
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
if (DeviceExt->AvailableClustersValid)
|
||||
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
FatLength = StartCluster;
|
||||
StartCluster = 2;
|
||||
}
|
||||
CcUnpinData(Context);
|
||||
return STATUS_DISK_FULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FAT32FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
|
||||
/*
|
||||
* FUNCTION: Finds the first available cluster in a FAT32 table
|
||||
*/
|
||||
NTSTATUS
|
||||
FAT32FindAndMarkAvailableCluster(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PULONG Cluster)
|
||||
{
|
||||
ULONG FatLength;
|
||||
ULONG StartCluster;
|
||||
ULONG i, j;
|
||||
PVOID BaseAddress;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
PULONG Block;
|
||||
PULONG BlockEnd;
|
||||
ULONG FatLength;
|
||||
ULONG StartCluster;
|
||||
ULONG i, j;
|
||||
PVOID BaseAddress;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
PULONG Block;
|
||||
PULONG BlockEnd;
|
||||
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
|
||||
*Cluster = 0;
|
||||
StartCluster = DeviceExt->LastAvailableCluster;
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
|
||||
*Cluster = 0;
|
||||
StartCluster = DeviceExt->LastAvailableCluster;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = StartCluster; i < FatLength;)
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
|
||||
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
|
||||
BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
|
||||
|
||||
/* Now process the whole block */
|
||||
while (Block < BlockEnd && i < FatLength)
|
||||
{
|
||||
if ((*Block & 0x0fffffff) == 0)
|
||||
for (i = StartCluster; i < FatLength;)
|
||||
{
|
||||
DPRINT("Found available cluster 0x%x\n", i);
|
||||
DeviceExt->LastAvailableCluster = *Cluster = i;
|
||||
*Block = 0x0fffffff;
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
if (DeviceExt->AvailableClustersValid)
|
||||
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
return(STATUS_SUCCESS);
|
||||
Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
|
||||
if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
|
||||
BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
|
||||
|
||||
/* Now process the whole block */
|
||||
while (Block < BlockEnd && i < FatLength)
|
||||
{
|
||||
if ((*Block & 0x0fffffff) == 0)
|
||||
{
|
||||
DPRINT("Found available cluster 0x%x\n", i);
|
||||
DeviceExt->LastAvailableCluster = *Cluster = i;
|
||||
*Block = 0x0fffffff;
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
if (DeviceExt->AvailableClustersValid)
|
||||
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Block++;
|
||||
i++;
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
|
||||
Block++;
|
||||
i++;
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
FatLength = StartCluster;
|
||||
StartCluster = 2;
|
||||
}
|
||||
FatLength = StartCluster;
|
||||
StartCluster = 2;
|
||||
}
|
||||
return (STATUS_DISK_FULL);
|
||||
return STATUS_DISK_FULL;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
||||
/*
|
||||
* FUNCTION: Counts free cluster in a FAT12 table
|
||||
*/
|
||||
static
|
||||
NTSTATUS
|
||||
FAT12CountAvailableClusters(
|
||||
PDEVICE_EXTENSION DeviceExt)
|
||||
{
|
||||
ULONG Entry;
|
||||
PVOID BaseAddress;
|
||||
ULONG ulCount = 0;
|
||||
ULONG i;
|
||||
ULONG numberofclusters;
|
||||
LARGE_INTEGER Offset;
|
||||
PVOID Context;
|
||||
PUSHORT CBlock;
|
||||
ULONG Entry;
|
||||
PVOID BaseAddress;
|
||||
ULONG ulCount = 0;
|
||||
ULONG i;
|
||||
ULONG numberofclusters;
|
||||
LARGE_INTEGER Offset;
|
||||
PVOID Context;
|
||||
PUSHORT CBlock;
|
||||
|
||||
Offset.QuadPart = 0;
|
||||
if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
|
||||
|
||||
for (i = 2; i < numberofclusters; i++)
|
||||
Offset.QuadPart = 0;
|
||||
if (!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
|
||||
{
|
||||
CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
Entry = *CBlock & 0x0fff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry = *CBlock >> 4;
|
||||
}
|
||||
if (Entry == 0)
|
||||
ulCount++;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
DeviceExt->AvailableClusters = ulCount;
|
||||
DeviceExt->AvailableClustersValid = TRUE;
|
||||
numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
for (i = 2; i < numberofclusters; i++)
|
||||
{
|
||||
CBlock = (PUSHORT)((char*)BaseAddress + (i * 12) / 8);
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
Entry = *CBlock & 0x0fff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry = *CBlock >> 4;
|
||||
}
|
||||
|
||||
if (Entry == 0)
|
||||
ulCount++;
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
DeviceExt->AvailableClusters = ulCount;
|
||||
DeviceExt->AvailableClustersValid = TRUE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
||||
/*
|
||||
* FUNCTION: Counts free clusters in a FAT16 table
|
||||
*/
|
||||
static
|
||||
NTSTATUS
|
||||
FAT16CountAvailableClusters(
|
||||
PDEVICE_EXTENSION DeviceExt)
|
||||
{
|
||||
PUSHORT Block;
|
||||
PUSHORT BlockEnd;
|
||||
PVOID BaseAddress = NULL;
|
||||
ULONG ulCount = 0;
|
||||
ULONG i;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context = NULL;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG FatLength;
|
||||
PUSHORT Block;
|
||||
PUSHORT BlockEnd;
|
||||
PVOID BaseAddress = NULL;
|
||||
ULONG ulCount = 0;
|
||||
ULONG i;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context = NULL;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG FatLength;
|
||||
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
|
||||
|
||||
for (i = 2; i < FatLength; )
|
||||
{
|
||||
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
|
||||
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
for (i = 2; i < FatLength; )
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
|
||||
BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
|
||||
Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
|
||||
if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
|
||||
BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);
|
||||
|
||||
/* Now process the whole block */
|
||||
while (Block < BlockEnd && i < FatLength)
|
||||
{
|
||||
if (*Block == 0)
|
||||
ulCount++;
|
||||
Block++;
|
||||
i++;
|
||||
/* Now process the whole block */
|
||||
while (Block < BlockEnd && i < FatLength)
|
||||
{
|
||||
if (*Block == 0)
|
||||
ulCount++;
|
||||
Block++;
|
||||
i++;
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
DeviceExt->AvailableClusters = ulCount;
|
||||
DeviceExt->AvailableClustersValid = TRUE;
|
||||
|
||||
DeviceExt->AvailableClusters = ulCount;
|
||||
DeviceExt->AvailableClustersValid = TRUE;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
||||
/*
|
||||
* FUNCTION: Counts free clusters in a FAT32 table
|
||||
*/
|
||||
static
|
||||
NTSTATUS
|
||||
FAT32CountAvailableClusters(
|
||||
PDEVICE_EXTENSION DeviceExt)
|
||||
{
|
||||
PULONG Block;
|
||||
PULONG BlockEnd;
|
||||
PVOID BaseAddress = NULL;
|
||||
ULONG ulCount = 0;
|
||||
ULONG i;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context = NULL;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG FatLength;
|
||||
PULONG Block;
|
||||
PULONG BlockEnd;
|
||||
PVOID BaseAddress = NULL;
|
||||
ULONG ulCount = 0;
|
||||
ULONG i;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context = NULL;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG FatLength;
|
||||
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
|
||||
|
||||
for (i = 2; i < FatLength; )
|
||||
{
|
||||
Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
|
||||
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
for (i = 2; i < FatLength; )
|
||||
{
|
||||
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
|
||||
BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
|
||||
Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
|
||||
if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
DPRINT1("CcMapData(Offset %x, Length %u) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
|
||||
BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);
|
||||
|
||||
/* Now process the whole block */
|
||||
while (Block < BlockEnd && i < FatLength)
|
||||
{
|
||||
if ((*Block & 0x0fffffff) == 0)
|
||||
ulCount++;
|
||||
Block++;
|
||||
i++;
|
||||
/* Now process the whole block */
|
||||
while (Block < BlockEnd && i < FatLength)
|
||||
{
|
||||
if ((*Block & 0x0fffffff) == 0)
|
||||
ulCount++;
|
||||
Block++;
|
||||
i++;
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
DeviceExt->AvailableClusters = ulCount;
|
||||
DeviceExt->AvailableClustersValid = TRUE;
|
||||
|
||||
DeviceExt->AvailableClusters = ulCount;
|
||||
DeviceExt->AvailableClustersValid = TRUE;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
|
||||
PLARGE_INTEGER Clusters)
|
||||
CountAvailableClusters(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PLARGE_INTEGER Clusters)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
|
||||
if (!DeviceExt->AvailableClustersValid)
|
||||
{
|
||||
if (DeviceExt->FatInfo.FatType == FAT12)
|
||||
Status = FAT12CountAvailableClusters(DeviceExt);
|
||||
else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
|
||||
Status = FAT16CountAvailableClusters(DeviceExt);
|
||||
else
|
||||
Status = FAT32CountAvailableClusters(DeviceExt);
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
|
||||
if (!DeviceExt->AvailableClustersValid)
|
||||
{
|
||||
if (DeviceExt->FatInfo.FatType == FAT12)
|
||||
Status = FAT12CountAvailableClusters(DeviceExt);
|
||||
else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
|
||||
Status = FAT16CountAvailableClusters(DeviceExt);
|
||||
else
|
||||
Status = FAT32CountAvailableClusters(DeviceExt);
|
||||
}
|
||||
Clusters->QuadPart = DeviceExt->AvailableClusters;
|
||||
ExReleaseResourceLite (&DeviceExt->FatResource);
|
||||
Clusters->QuadPart = DeviceExt->AvailableClusters;
|
||||
ExReleaseResourceLite (&DeviceExt->FatResource);
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue,
|
||||
PULONG OldValue)
|
||||
/*
|
||||
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
|
||||
*/
|
||||
NTSTATUS
|
||||
FAT12WriteCluster(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue,
|
||||
PULONG OldValue)
|
||||
{
|
||||
ULONG FATOffset;
|
||||
PUCHAR CBlock;
|
||||
PVOID BaseAddress;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG FATOffset;
|
||||
PUCHAR CBlock;
|
||||
PVOID BaseAddress;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
|
||||
Offset.QuadPart = 0;
|
||||
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
CBlock = (PUCHAR)BaseAddress;
|
||||
Offset.QuadPart = 0;
|
||||
if (!CcPinRead(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
CBlock = (PUCHAR)BaseAddress;
|
||||
|
||||
FATOffset = (ClusterToWrite * 12) / 8;
|
||||
DPRINT("Writing 0x%x for 0x%x at 0x%x\n",
|
||||
NewValue, ClusterToWrite, FATOffset);
|
||||
if ((ClusterToWrite % 2) == 0)
|
||||
FATOffset = (ClusterToWrite * 12) / 8;
|
||||
DPRINT("Writing 0x%x for 0x%x at 0x%x\n",
|
||||
NewValue, ClusterToWrite, FATOffset);
|
||||
if ((ClusterToWrite % 2) == 0)
|
||||
{
|
||||
*OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
|
||||
CBlock[FATOffset] = (UCHAR)NewValue;
|
||||
CBlock[FATOffset + 1] &= 0xf0;
|
||||
CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
|
||||
*OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
|
||||
CBlock[FATOffset] = (UCHAR)NewValue;
|
||||
CBlock[FATOffset + 1] &= 0xf0;
|
||||
CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
*OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
|
||||
CBlock[FATOffset] &= 0x0f;
|
||||
CBlock[FATOffset] |= (NewValue & 0xf) << 4;
|
||||
CBlock[FATOffset + 1] = (UCHAR)(NewValue >> 4);
|
||||
*OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
|
||||
CBlock[FATOffset] &= 0x0f;
|
||||
CBlock[FATOffset] |= (NewValue & 0xf) << 4;
|
||||
CBlock[FATOffset + 1] = (UCHAR)(NewValue >> 4);
|
||||
}
|
||||
/* Write the changed FAT sector(s) to disk */
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
return(STATUS_SUCCESS);
|
||||
/* Write the changed FAT sector(s) to disk */
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue,
|
||||
PULONG OldValue)
|
||||
/*
|
||||
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
|
||||
*/
|
||||
NTSTATUS
|
||||
FAT16WriteCluster(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue,
|
||||
PULONG OldValue)
|
||||
{
|
||||
PVOID BaseAddress;
|
||||
ULONG FATOffset;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
PUSHORT Cluster;
|
||||
PVOID BaseAddress;
|
||||
ULONG FATOffset;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
PUSHORT Cluster;
|
||||
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FATOffset = ClusterToWrite * 2;
|
||||
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
|
||||
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
|
||||
ClusterToWrite);
|
||||
Cluster = ((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
|
||||
*OldValue = *Cluster;
|
||||
*Cluster = (USHORT)NewValue;
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
return(STATUS_SUCCESS);
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
FATOffset = ClusterToWrite * 2;
|
||||
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
|
||||
if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
|
||||
ClusterToWrite);
|
||||
Cluster = ((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
|
||||
*OldValue = *Cluster;
|
||||
*Cluster = (USHORT)NewValue;
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue,
|
||||
PULONG OldValue)
|
||||
/*
|
||||
* FUNCTION: Writes a cluster to the FAT32 physical tables
|
||||
*/
|
||||
NTSTATUS
|
||||
FAT32WriteCluster(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue,
|
||||
PULONG OldValue)
|
||||
{
|
||||
PVOID BaseAddress;
|
||||
ULONG FATOffset;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
PULONG Cluster;
|
||||
PVOID BaseAddress;
|
||||
ULONG FATOffset;
|
||||
ULONG ChunkSize;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Offset;
|
||||
PULONG Cluster;
|
||||
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
ChunkSize = CACHEPAGESIZE(DeviceExt);
|
||||
|
||||
FATOffset = (ClusterToWrite * 4);
|
||||
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
|
||||
if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
|
||||
ClusterToWrite);
|
||||
Cluster = ((PULONG)((char*)BaseAddress + (FATOffset % ChunkSize)));
|
||||
*OldValue = *Cluster & 0x0fffffff;
|
||||
*Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
|
||||
FATOffset = (ClusterToWrite * 4);
|
||||
Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
|
||||
if (!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
|
||||
ClusterToWrite);
|
||||
Cluster = ((PULONG)((char*)BaseAddress + (FATOffset % ChunkSize)));
|
||||
*OldValue = *Cluster & 0x0fffffff;
|
||||
*Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
/*
|
||||
* FUNCTION: Write a changed FAT entry
|
||||
*/
|
||||
NTSTATUS
|
||||
WriteCluster(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG OldValue;
|
||||
ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
|
||||
Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
|
||||
if (DeviceExt->AvailableClustersValid)
|
||||
{
|
||||
if (OldValue && NewValue == 0)
|
||||
InterlockedIncrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
else if (OldValue == 0 && NewValue)
|
||||
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
}
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return(Status);
|
||||
NTSTATUS Status;
|
||||
ULONG OldValue;
|
||||
|
||||
ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
|
||||
Status = DeviceExt->WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
|
||||
if (DeviceExt->AvailableClustersValid)
|
||||
{
|
||||
if (OldValue && NewValue == 0)
|
||||
InterlockedIncrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
else if (OldValue == 0 && NewValue)
|
||||
InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
|
||||
}
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return Status;
|
||||
}
|
||||
|
||||
ULONGLONG
|
||||
ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG Cluster)
|
||||
/*
|
||||
* FUNCTION: Converts the cluster number to a sector number for this physical
|
||||
* device
|
||||
*/
|
||||
ULONGLONG
|
||||
ClusterToSector(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG Cluster)
|
||||
{
|
||||
return DeviceExt->FatInfo.dataStart +
|
||||
((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
|
||||
return DeviceExt->FatInfo.dataStart +
|
||||
((ULONGLONG)(Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
GetNextCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG CurrentCluster,
|
||||
PULONG NextCluster)
|
||||
/*
|
||||
* FUNCTION: Retrieve the next cluster depending on the FAT type
|
||||
*/
|
||||
NTSTATUS
|
||||
GetNextCluster(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG CurrentCluster,
|
||||
PULONG NextCluster)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
|
||||
DeviceExt, CurrentCluster);
|
||||
DPRINT("GetNextCluster(DeviceExt %p, CurrentCluster %x)\n",
|
||||
DeviceExt, CurrentCluster);
|
||||
|
||||
if (CurrentCluster == 0)
|
||||
return(STATUS_INVALID_PARAMETER);
|
||||
if (CurrentCluster == 0)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
|
||||
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
|
||||
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
GetNextClusterExtend(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG CurrentCluster,
|
||||
PULONG NextCluster)
|
||||
/*
|
||||
* FUNCTION: Retrieve the next cluster depending on the FAT type
|
||||
*/
|
||||
NTSTATUS
|
||||
GetNextClusterExtend(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG CurrentCluster,
|
||||
PULONG NextCluster)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
|
||||
DeviceExt, CurrentCluster);
|
||||
|
||||
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
|
||||
/*
|
||||
* If the file hasn't any clusters allocated then we need special
|
||||
* handling
|
||||
*/
|
||||
if (CurrentCluster == 0)
|
||||
{
|
||||
ULONG NewCluster;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
|
||||
if (!NT_SUCCESS(Status))
|
||||
DPRINT("GetNextClusterExtend(DeviceExt %p, CurrentCluster %x)\n",
|
||||
DeviceExt, CurrentCluster);
|
||||
|
||||
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
|
||||
/*
|
||||
* If the file hasn't any clusters allocated then we need special
|
||||
* handling
|
||||
*/
|
||||
if (CurrentCluster == 0)
|
||||
{
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return Status;
|
||||
Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return Status;
|
||||
}
|
||||
|
||||
*NextCluster = NewCluster;
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
|
||||
|
||||
if ((*NextCluster) == 0xFFFFFFFF)
|
||||
{
|
||||
/* We are after last existing cluster, we must add one to file */
|
||||
/* Firstly, find the next available open allocation unit and
|
||||
mark it as end of file */
|
||||
Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Now, write the AU of the LastCluster with the value of the newly
|
||||
found AU */
|
||||
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
|
||||
*NextCluster = NewCluster;
|
||||
}
|
||||
|
||||
*NextCluster = NewCluster;
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
|
||||
|
||||
if ((*NextCluster) == 0xFFFFFFFF)
|
||||
{
|
||||
ULONG NewCluster;
|
||||
|
||||
/* We are after last existing cluster, we must add one to file */
|
||||
/* Firstly, find the next available open allocation unit and
|
||||
mark it as end of file */
|
||||
Status = DeviceExt->FindAndMarkAvailableCluster(DeviceExt, &NewCluster);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Now, write the AU of the LastCluster with the value of the newly
|
||||
found AU */
|
||||
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
|
||||
*NextCluster = NewCluster;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue