mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
hpoussin <[email protected]>:
- Add full FATX support - Add volume label setting to FAT volumes - Change all ANSI_STRING to OEM_STRING (thanks Filip!) - Correct one bug in VfatUpdateEntry - Correct one bug in VfatShutdown Fixes bugs 286, 434 and 442 svn path=/trunk/; revision=11946
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: cleanup.c,v 1.15 2004/08/28 22:19:12 navaraf Exp $
|
||||
/* $Id: cleanup.c,v 1.16 2004/12/05 16:31:50 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -35,7 +35,7 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
|
||||
pFcb = (PVFATFCB) FileObject->FsContext;
|
||||
if (pFcb)
|
||||
{
|
||||
if (!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
|
||||
{
|
||||
/* remove all locks this process have on this file */
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: create.c,v 1.75 2004/11/06 13:44:56 ekohl Exp $
|
||||
/* $Id: create.c,v 1.76 2004/12/05 16:31:50 gvg Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/fs/vfat/create.c
|
||||
@@ -36,10 +36,6 @@
|
||||
|
||||
#include "vfat.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
void vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
|
||||
@@ -48,7 +44,7 @@ void vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
|
||||
ULONG Length;
|
||||
CHAR cString[12];
|
||||
|
||||
memcpy(cString, pEntry->Filename, 11);
|
||||
RtlCopyMemory(cString, pEntry->Filename, 11);
|
||||
cString[11] = 0;
|
||||
if (cString[0] == 0x05)
|
||||
{
|
||||
@@ -71,7 +67,7 @@ void vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
|
||||
{
|
||||
Length = NameU->Length;
|
||||
NameU->Buffer += Length / sizeof(WCHAR);
|
||||
if (!ENTRY_VOLUME(pEntry))
|
||||
if (!FAT_ENTRY_VOLUME(pEntry))
|
||||
{
|
||||
Length += sizeof(WCHAR);
|
||||
NameU->Buffer[0] = L'.';
|
||||
@@ -106,16 +102,30 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||
{
|
||||
PVOID Context = NULL;
|
||||
ULONG DirIndex = 0;
|
||||
FATDirEntry* Entry;
|
||||
PDIR_ENTRY Entry;
|
||||
PVFATFCB pFcb;
|
||||
LARGE_INTEGER FileOffset;
|
||||
UNICODE_STRING NameU;
|
||||
ULONG SizeDirEntry;
|
||||
ULONG EntriesPerPage;
|
||||
OEM_STRING StringO;
|
||||
|
||||
NameU.Buffer = Vpb->VolumeLabel;
|
||||
NameU.Length = 0;
|
||||
NameU.MaximumLength = sizeof(Vpb->VolumeLabel);
|
||||
*(Vpb->VolumeLabel) = 0;
|
||||
Vpb->VolumeLabelLength = 0;
|
||||
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
SizeDirEntry = sizeof(FATX_DIR_ENTRY);
|
||||
EntriesPerPage = FATX_ENTRIES_PER_PAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeDirEntry = sizeof(FAT_DIR_ENTRY);
|
||||
EntriesPerPage = FAT_ENTRIES_PER_PAGE;
|
||||
}
|
||||
|
||||
ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE);
|
||||
pFcb = vfatOpenRootFCB (DeviceExt);
|
||||
@@ -126,20 +136,29 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
if (ENTRY_VOLUME(Entry))
|
||||
if (ENTRY_VOLUME(DeviceExt, Entry))
|
||||
{
|
||||
/* copy volume label */
|
||||
vfat8Dot3ToString (Entry, &NameU);
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
StringO.Buffer = Entry->FatX.Filename;
|
||||
StringO.MaximumLength = StringO.Length = Entry->FatX.FilenameLength;
|
||||
RtlOemStringToUnicodeString(&NameU, &StringO, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
vfat8Dot3ToString (&Entry->Fat, &NameU);
|
||||
}
|
||||
Vpb->VolumeLabelLength = NameU.Length;
|
||||
break;
|
||||
}
|
||||
if (ENTRY_END(Entry))
|
||||
if (ENTRY_END(DeviceExt, Entry))
|
||||
{
|
||||
break;
|
||||
}
|
||||
DirIndex++;
|
||||
Entry++;
|
||||
if ((DirIndex % ENTRIES_PER_PAGE) == 0)
|
||||
Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
|
||||
if ((DirIndex % EntriesPerPage) == 0)
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
@@ -212,7 +231,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
|
||||
{
|
||||
RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
|
||||
RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
|
||||
memcpy(&DirContext->FatDirEntry, &rcFcb->entry, sizeof(FATDirEntry));
|
||||
RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
|
||||
DirContext->StartIndex = rcFcb->startIndex;
|
||||
DirContext->DirIndex = rcFcb->dirIndex;
|
||||
DPRINT("FindFile: new Name %wZ, DirIndex %d (%d)\n",
|
||||
@@ -231,13 +250,13 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
Status = vfatGetNextDirEntry(&Context, &Page, Parent, DirContext, First);
|
||||
Status = DeviceExt->GetNextDirEntry(&Context, &Page, Parent, DirContext, First);
|
||||
First = FALSE;
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (ENTRY_VOLUME(&DirContext->FatDirEntry))
|
||||
if (ENTRY_VOLUME(DeviceExt, &DirContext->DirEntry))
|
||||
{
|
||||
DirContext->DirIndex++;
|
||||
continue;
|
||||
@@ -269,7 +288,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
|
||||
rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
|
||||
if (rcFcb != NULL)
|
||||
{
|
||||
memcpy(&DirContext->FatDirEntry, &rcFcb->entry, sizeof(FATDirEntry));
|
||||
RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
|
||||
vfatReleaseFCB(DeviceExt, rcFcb);
|
||||
}
|
||||
}
|
||||
@@ -407,17 +426,26 @@ VfatSupersedeFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
ULONG Cluster, NextCluster;
|
||||
NTSTATUS Status;
|
||||
|
||||
Fcb->entry.FileSize = 0;
|
||||
if (DeviceExt->FatInfo.FatType == FAT32)
|
||||
{
|
||||
Cluster = Fcb->entry.FirstCluster + Fcb->entry.FirstClusterHigh * 65536;
|
||||
}
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
Fcb->entry.FatX.FileSize = 0;
|
||||
Cluster = Fcb->entry.FatX.FirstCluster;
|
||||
Fcb->entry.FatX.FirstCluster = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cluster = Fcb->entry.FirstCluster;
|
||||
}
|
||||
Fcb->entry.FirstCluster = 0;
|
||||
Fcb->entry.FirstClusterHigh = 0;
|
||||
{
|
||||
Fcb->entry.Fat.FileSize = 0;
|
||||
if (DeviceExt->FatInfo.FatType == FAT32)
|
||||
{
|
||||
Cluster = Fcb->entry.Fat.FirstCluster + Fcb->entry.Fat.FirstClusterHigh * 65536;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cluster = Fcb->entry.Fat.FirstCluster;
|
||||
}
|
||||
Fcb->entry.Fat.FirstCluster = 0;
|
||||
Fcb->entry.Fat.FirstClusterHigh = 0;
|
||||
}
|
||||
Fcb->LastOffset = Fcb->LastCluster = 0;
|
||||
VfatUpdateEntry (Fcb);
|
||||
if (Fcb->RFCB.FileSize.QuadPart > 0)
|
||||
@@ -496,7 +524,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
return (STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
memset(pCcb, 0, sizeof(VFATCCB));
|
||||
RtlZeroMemory(pCcb, sizeof(VFATCCB));
|
||||
FileObject->Flags |= FO_FCB_IS_VALID;
|
||||
FileObject->SectionObjectPointer = &pFcb->SectionObjectPointers;
|
||||
FileObject->FsContext = pFcb;
|
||||
@@ -626,13 +654,13 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
* Check the file has the requested attributes
|
||||
*/
|
||||
if (RequestedOptions & FILE_NON_DIRECTORY_FILE &&
|
||||
pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
VfatCloseFile (DeviceExt, FileObject);
|
||||
return(STATUS_FILE_IS_A_DIRECTORY);
|
||||
}
|
||||
if (RequestedOptions & FILE_DIRECTORY_FILE &&
|
||||
!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||
!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
VfatCloseFile (DeviceExt, FileObject);
|
||||
return(STATUS_NOT_A_DIRECTORY);
|
||||
|
||||
+156
-68
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: dir.c,v 1.35 2004/11/06 13:44:57 ekohl Exp $
|
||||
* $Id: dir.c,v 1.36 2004/12/05 16:31:50 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
// function like DosDateTimeToFileTime
|
||||
BOOL
|
||||
FsdDosDateTimeToSystemTime (WORD wDosDate, WORD wDosTime, PLARGE_INTEGER SystemTime)
|
||||
FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, WORD wDosDate, WORD wDosTime, PLARGE_INTEGER SystemTime)
|
||||
{
|
||||
PDOSTIME pdtime = (PDOSTIME) & wDosTime;
|
||||
PDOSDATE pddate = (PDOSDATE) & wDosDate;
|
||||
@@ -38,7 +38,7 @@ FsdDosDateTimeToSystemTime (WORD wDosDate, WORD wDosTime, PLARGE_INTEGER SystemT
|
||||
|
||||
TimeFields.Day = pddate->Day;
|
||||
TimeFields.Month = pddate->Month;
|
||||
TimeFields.Year = 1980 + pddate->Year;
|
||||
TimeFields.Year = DeviceExt->BaseDateYear + pddate->Year;
|
||||
|
||||
RtlTimeFieldsToTime (&TimeFields, &LocalTime);
|
||||
ExLocalTimeToSystemTime(&LocalTime, SystemTime);
|
||||
@@ -46,10 +46,9 @@ FsdDosDateTimeToSystemTime (WORD wDosDate, WORD wDosTime, PLARGE_INTEGER SystemT
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// function like FileTimeToDosDateTime
|
||||
BOOL
|
||||
FsdSystemTimeToDosDateTime (PLARGE_INTEGER SystemTime, WORD * pwDosDate, WORD * pwDosTime)
|
||||
FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, WORD * pwDosDate, WORD * pwDosTime)
|
||||
{
|
||||
PDOSTIME pdtime = (PDOSTIME) pwDosTime;
|
||||
PDOSDATE pddate = (PDOSDATE) pwDosDate;
|
||||
@@ -73,13 +72,12 @@ FsdSystemTimeToDosDateTime (PLARGE_INTEGER SystemTime, WORD * pwDosDate, WORD *
|
||||
{
|
||||
pddate->Day = TimeFields.Day;
|
||||
pddate->Month = TimeFields.Month;
|
||||
pddate->Year = TimeFields.Year - 1980;
|
||||
pddate->Year = TimeFields.Year - DeviceExt->BaseDateYear;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#define DWORD_ROUND_UP(x) ROUND_UP((x), (sizeof(DWORD)))
|
||||
|
||||
NTSTATUS
|
||||
@@ -91,7 +89,7 @@ VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
pInfo->FileNameLength = DirContext->LongNameU.Length;
|
||||
pInfo->NextEntryOffset =
|
||||
DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
|
||||
memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -106,31 +104,61 @@ VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
pInfo->FileNameLength = DirContext->LongNameU.Length;
|
||||
pInfo->NextEntryOffset =
|
||||
DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
|
||||
memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
// pInfo->FileIndex=;
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.CreationDate,
|
||||
DirContext->FatDirEntry.CreationTime,
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
|
||||
DirContext->DirEntry.FatX.CreationTime,
|
||||
&pInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.AccessDate, 0,
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
|
||||
DirContext->DirEntry.FatX.AccessTime,
|
||||
&pInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.UpdateDate,
|
||||
DirContext->FatDirEntry.UpdateTime,
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
|
||||
DirContext->DirEntry.FatX.UpdateTime,
|
||||
&pInfo->LastWriteTime);
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
if (DirContext->FatDirEntry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
pInfo->EndOfFile.QuadPart = 0LL;
|
||||
pInfo->AllocationSize.QuadPart = 0LL;
|
||||
}
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
pInfo->EndOfFile.QuadPart = 0LL;
|
||||
pInfo->AllocationSize.QuadPart = 0LL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
}
|
||||
pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
}
|
||||
pInfo->FileAttributes = DirContext->FatDirEntry.Attrib & 0x3f;
|
||||
{
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
|
||||
DirContext->DirEntry.Fat.CreationTime,
|
||||
&pInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0,
|
||||
&pInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
|
||||
DirContext->DirEntry.Fat.UpdateTime,
|
||||
&pInfo->LastWriteTime);
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
pInfo->EndOfFile.QuadPart = 0LL;
|
||||
pInfo->AllocationSize.QuadPart = 0LL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
}
|
||||
pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -146,23 +174,45 @@ VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
pInfo->FileNameLength = DirContext->LongNameU.Length;
|
||||
pInfo->NextEntryOffset =
|
||||
DWORD_ROUND_UP (sizeof (FILE_FULL_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
|
||||
memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
// pInfo->FileIndex=;
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.CreationDate,
|
||||
DirContext->FatDirEntry.CreationTime,
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
|
||||
DirContext->DirEntry.FatX.CreationTime,
|
||||
&pInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.AccessDate,
|
||||
0, &pInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.UpdateDate,
|
||||
DirContext->FatDirEntry.UpdateTime,
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
|
||||
DirContext->DirEntry.FatX.AccessTime,
|
||||
&pInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
|
||||
DirContext->DirEntry.FatX.UpdateTime,
|
||||
&pInfo->LastWriteTime);
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
pInfo->FileAttributes = DirContext->FatDirEntry.Attrib & 0x3f;
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
|
||||
}
|
||||
else
|
||||
{
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
|
||||
DirContext->DirEntry.Fat.CreationTime,
|
||||
&pInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate,
|
||||
0, &pInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
|
||||
DirContext->DirEntry.Fat.UpdateTime,
|
||||
&pInfo->LastWriteTime);
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
|
||||
}
|
||||
// pInfo->EaSize=;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -175,36 +225,74 @@ VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
{
|
||||
if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
pInfo->FileNameLength = DirContext->LongNameU.Length;
|
||||
pInfo->NextEntryOffset =
|
||||
DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
|
||||
memcpy(pInfo->ShortName, DirContext->ShortNameU.Buffer, DirContext->ShortNameU.Length);
|
||||
pInfo->ShortNameLength = DirContext->ShortNameU.Length;
|
||||
memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
// pInfo->FileIndex=;
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.CreationDate,
|
||||
DirContext->FatDirEntry.CreationDate,
|
||||
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
pInfo->FileNameLength = DirContext->LongNameU.Length;
|
||||
RtlCopyMemory(pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
pInfo->NextEntryOffset =
|
||||
DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
|
||||
pInfo->ShortName[0] = 0;
|
||||
pInfo->ShortNameLength = 0;
|
||||
// pInfo->FileIndex=;
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
|
||||
DirContext->DirEntry.FatX.CreationTime,
|
||||
&pInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.AccessDate, 0,
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
|
||||
DirContext->DirEntry.FatX.AccessTime,
|
||||
&pInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.UpdateDate,
|
||||
DirContext->FatDirEntry.UpdateTime,
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
|
||||
DirContext->DirEntry.FatX.UpdateTime,
|
||||
&pInfo->LastWriteTime);
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
if (DirContext->FatDirEntry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
pInfo->EndOfFile.QuadPart = 0LL;
|
||||
pInfo->AllocationSize.QuadPart = 0LL;
|
||||
}
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
pInfo->EndOfFile.QuadPart = 0LL;
|
||||
pInfo->AllocationSize.QuadPart = 0LL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
}
|
||||
pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
}
|
||||
pInfo->FileAttributes = DirContext->FatDirEntry.Attrib & 0x3f;
|
||||
{
|
||||
pInfo->FileNameLength = DirContext->LongNameU.Length;
|
||||
pInfo->NextEntryOffset =
|
||||
DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
|
||||
RtlCopyMemory(pInfo->ShortName, DirContext->ShortNameU.Buffer, DirContext->ShortNameU.Length);
|
||||
pInfo->ShortNameLength = DirContext->ShortNameU.Length;
|
||||
RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
|
||||
// pInfo->FileIndex=;
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
|
||||
DirContext->DirEntry.Fat.CreationTime,
|
||||
&pInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0,
|
||||
&pInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
|
||||
DirContext->DirEntry.Fat.UpdateTime,
|
||||
&pInfo->LastWriteTime);
|
||||
pInfo->ChangeTime = pInfo->LastWriteTime;
|
||||
if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
pInfo->EndOfFile.QuadPart = 0LL;
|
||||
pInfo->AllocationSize.QuadPart = 0LL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->EndOfFile.u.HighPart = 0;
|
||||
pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
pInfo->AllocationSize.u.HighPart = 0;
|
||||
pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
|
||||
}
|
||||
pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
|
||||
}
|
||||
pInfo->EaSize=0;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: direntry.c,v 1.17 2004/08/01 21:57:17 navaraf Exp $
|
||||
/* $Id: direntry.c,v 1.18 2004/12/05 16:31:50 gvg Exp $
|
||||
*
|
||||
*
|
||||
* FILE: DirEntry.c
|
||||
@@ -8,6 +8,7 @@
|
||||
* PROGRAMMER: Jason Filby ([email protected])
|
||||
* Rex Jolliff ([email protected])
|
||||
* Hartmut Birr
|
||||
* Herve Poussineau ([email protected])
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------- INCLUDES */
|
||||
@@ -21,28 +22,30 @@
|
||||
|
||||
#include "vfat.h"
|
||||
|
||||
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
|
||||
|
||||
ULONG
|
||||
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||
PFAT_DIR_ENTRY pFatDirEntry)
|
||||
PDIR_ENTRY pFatDirEntry)
|
||||
{
|
||||
ULONG cluster;
|
||||
|
||||
if (pDeviceExt->FatInfo.FatType == FAT32)
|
||||
{
|
||||
cluster = pFatDirEntry->FirstCluster +
|
||||
pFatDirEntry->FirstClusterHigh * 65536;
|
||||
cluster = pFatDirEntry->Fat.FirstCluster +
|
||||
pFatDirEntry->Fat.FirstClusterHigh * 65536;
|
||||
}
|
||||
else if (pDeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
cluster = pFatDirEntry->FatX.FirstCluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
cluster = pFatDirEntry->FirstCluster;
|
||||
cluster = pFatDirEntry->Fat.FirstCluster;
|
||||
}
|
||||
|
||||
return cluster;
|
||||
}
|
||||
|
||||
BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
BOOL FATIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
{
|
||||
LARGE_INTEGER FileOffset;
|
||||
PVOID Context = NULL;
|
||||
@@ -63,7 +66,7 @@ BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
|
||||
while (Index < MaxIndex)
|
||||
{
|
||||
if (Context == NULL || (Index % ENTRIES_PER_PAGE) == 0)
|
||||
if (Context == NULL || (Index % FAT_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
if (Context != NULL)
|
||||
{
|
||||
@@ -73,14 +76,14 @@ BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
FatDirEntry += Index % ENTRIES_PER_PAGE;
|
||||
FatDirEntry += Index % FAT_ENTRIES_PER_PAGE;
|
||||
}
|
||||
if (ENTRY_END(FatDirEntry))
|
||||
if (FAT_ENTRY_END(FatDirEntry))
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
return TRUE;
|
||||
}
|
||||
if (!ENTRY_DELETED(FatDirEntry))
|
||||
if (!FAT_ENTRY_DELETED(FatDirEntry))
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
return FALSE;
|
||||
@@ -95,7 +98,61 @@ BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
BOOL FATXIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
{
|
||||
LARGE_INTEGER FileOffset;
|
||||
PVOID Context = NULL;
|
||||
PFATX_DIR_ENTRY FatXDirEntry;
|
||||
ULONG Index, MaxIndex;
|
||||
|
||||
Index = 0;
|
||||
|
||||
FileOffset.QuadPart = 0LL;
|
||||
MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FATX_DIR_ENTRY);
|
||||
|
||||
while (Index < MaxIndex)
|
||||
{
|
||||
if (Context == NULL || (Index % FATX_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
if (Context != NULL)
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
if (!CcMapData(Fcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&FatXDirEntry))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
FatXDirEntry += Index % FATX_ENTRIES_PER_PAGE;
|
||||
}
|
||||
if (FATX_ENTRY_END(FatXDirEntry))
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
return TRUE;
|
||||
}
|
||||
if (!FATX_ENTRY_DELETED(FatXDirEntry))
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
return FALSE;
|
||||
}
|
||||
Index++;
|
||||
FatXDirEntry++;
|
||||
}
|
||||
if (Context)
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb)
|
||||
{
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
return FATXIsDirectoryEmpty(Fcb);
|
||||
else
|
||||
return FATIsDirectoryEmpty(Fcb);
|
||||
}
|
||||
|
||||
NTSTATUS FATGetNextDirEntry(PVOID * pContext,
|
||||
PVOID * pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
@@ -104,7 +161,7 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
ULONG dirMap;
|
||||
PWCHAR pName;
|
||||
LARGE_INTEGER FileOffset;
|
||||
FATDirEntry * fatDirEntry;
|
||||
PFAT_DIR_ENTRY fatDirEntry;
|
||||
slot * longNameEntry;
|
||||
ULONG index;
|
||||
|
||||
@@ -116,9 +173,9 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
DirContext->LongNameU.Buffer[0] = 0;
|
||||
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FATDirEntry), PAGE_SIZE);
|
||||
FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FAT_DIR_ENTRY), PAGE_SIZE);
|
||||
|
||||
if (*pContext == NULL || (DirContext->DirIndex % ENTRIES_PER_PAGE) == 0)
|
||||
if (*pContext == NULL || (DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
if (*pContext != NULL)
|
||||
{
|
||||
@@ -132,7 +189,7 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
}
|
||||
|
||||
|
||||
fatDirEntry = (FATDirEntry*)(*pPage) + DirContext->DirIndex % ENTRIES_PER_PAGE;
|
||||
fatDirEntry = (PFAT_DIR_ENTRY)(*pPage) + DirContext->DirIndex % FAT_ENTRIES_PER_PAGE;
|
||||
longNameEntry = (slot*) fatDirEntry;
|
||||
dirMap = 0;
|
||||
|
||||
@@ -142,14 +199,14 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
* into a long name or points to a short name with an assigned long name.
|
||||
* We must go back to the real start of the entry */
|
||||
while (DirContext->DirIndex > 0 &&
|
||||
!ENTRY_END(fatDirEntry) &&
|
||||
!ENTRY_DELETED(fatDirEntry) &&
|
||||
((!ENTRY_LONG(fatDirEntry) && !Back) ||
|
||||
(ENTRY_LONG(fatDirEntry) && !(longNameEntry->id & 0x40))))
|
||||
!FAT_ENTRY_END(fatDirEntry) &&
|
||||
!FAT_ENTRY_DELETED(fatDirEntry) &&
|
||||
((!FAT_ENTRY_LONG(fatDirEntry) && !Back) ||
|
||||
(FAT_ENTRY_LONG(fatDirEntry) && !(longNameEntry->id & 0x40))))
|
||||
{
|
||||
DirContext->DirIndex--;
|
||||
Back = TRUE;
|
||||
if ((DirContext->DirIndex % ENTRIES_PER_PAGE) == ENTRIES_PER_PAGE - 1)
|
||||
if ((DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == FAT_ENTRIES_PER_PAGE - 1)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
FileOffset.u.LowPart -= PAGE_SIZE;
|
||||
@@ -159,7 +216,7 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
fatDirEntry = (FATDirEntry*)(*pPage) + DirContext->DirIndex % ENTRIES_PER_PAGE;
|
||||
fatDirEntry = (PFAT_DIR_ENTRY)(*pPage) + DirContext->DirIndex % FAT_ENTRIES_PER_PAGE;
|
||||
longNameEntry = (slot*) fatDirEntry;
|
||||
}
|
||||
else
|
||||
@@ -169,11 +226,11 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (Back && !ENTRY_END(fatDirEntry) &&
|
||||
(ENTRY_DELETED(fatDirEntry) || !ENTRY_LONG(fatDirEntry)))
|
||||
if (Back && !FAT_ENTRY_END(fatDirEntry) &&
|
||||
(FAT_ENTRY_DELETED(fatDirEntry) || !FAT_ENTRY_LONG(fatDirEntry)))
|
||||
{
|
||||
DirContext->DirIndex++;
|
||||
if ((DirContext->DirIndex % ENTRIES_PER_PAGE) == 0)
|
||||
if ((DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
@@ -183,7 +240,7 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
fatDirEntry = (FATDirEntry*)*pPage;
|
||||
fatDirEntry = (PFAT_DIR_ENTRY)*pPage;
|
||||
longNameEntry = (slot*) *pPage;
|
||||
}
|
||||
else
|
||||
@@ -199,14 +256,14 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (ENTRY_END(fatDirEntry))
|
||||
if (FAT_ENTRY_END(fatDirEntry))
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
if (ENTRY_DELETED(fatDirEntry))
|
||||
if (FAT_ENTRY_DELETED(fatDirEntry))
|
||||
{
|
||||
dirMap = 0;
|
||||
DirContext->LongNameU.Buffer[0] = 0;
|
||||
@@ -214,12 +271,12 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ENTRY_LONG(fatDirEntry))
|
||||
if (FAT_ENTRY_LONG(fatDirEntry))
|
||||
{
|
||||
if (dirMap == 0)
|
||||
{
|
||||
DPRINT (" long name entry found at %d\n", DirContext->DirIndex);
|
||||
memset(DirContext->LongNameU.Buffer, 0, DirContext->LongNameU.MaximumLength);
|
||||
RtlZeroMemory(DirContext->LongNameU.Buffer, DirContext->LongNameU.MaximumLength);
|
||||
CheckSum = longNameEntry->alias_checksum;
|
||||
Valid = TRUE;
|
||||
}
|
||||
@@ -233,9 +290,9 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
dirMap |= 1 << index;
|
||||
pName = DirContext->LongNameU.Buffer + 13 * index;
|
||||
|
||||
memcpy(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR));
|
||||
memcpy(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR));
|
||||
memcpy(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR));
|
||||
RtlCopyMemory(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR));
|
||||
RtlCopyMemory(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR));
|
||||
RtlCopyMemory(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR));
|
||||
|
||||
DPRINT (" longName: [%S]\n", DirContext->LongNameU.Buffer);
|
||||
if (CheckSum != longNameEntry->alias_checksum)
|
||||
@@ -265,12 +322,12 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
DirContext->LongNameU.Buffer[0] = 0;
|
||||
}
|
||||
|
||||
memcpy (&DirContext->FatDirEntry, fatDirEntry, sizeof (FAT_DIR_ENTRY));
|
||||
RtlCopyMemory (&DirContext->DirEntry.Fat, fatDirEntry, sizeof (FAT_DIR_ENTRY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
DirContext->DirIndex++;
|
||||
if ((DirContext->DirIndex % ENTRIES_PER_PAGE) == 0)
|
||||
if ((DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
@@ -280,7 +337,7 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
fatDirEntry = (FATDirEntry*)*pPage;
|
||||
fatDirEntry = (PFAT_DIR_ENTRY)*pPage;
|
||||
longNameEntry = (slot*) *pPage;
|
||||
}
|
||||
else
|
||||
@@ -290,10 +347,116 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
}
|
||||
}
|
||||
DirContext->LongNameU.Length = wcslen(DirContext->LongNameU.Buffer) * sizeof(WCHAR);
|
||||
vfat8Dot3ToString(&DirContext->FatDirEntry, &DirContext->ShortNameU);
|
||||
vfat8Dot3ToString(&DirContext->DirEntry.Fat, &DirContext->ShortNameU);
|
||||
if (DirContext->LongNameU.Length == 0)
|
||||
{
|
||||
RtlCopyUnicodeString(&DirContext->LongNameU, &DirContext->ShortNameU);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FATX_DIR_ENTRY), PAGE_SIZE);
|
||||
|
||||
if (!vfatFCBIsRoot(pDirFcb))
|
||||
{
|
||||
/* need to add . and .. entries */
|
||||
switch (DirContext->DirIndex)
|
||||
{
|
||||
case 0: /* entry . */
|
||||
{
|
||||
DirContext->ShortNameU.Buffer[0] = 0;
|
||||
DirContext->ShortNameU.Length = 0;
|
||||
DirContext->LongNameU.Buffer[0] = 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;
|
||||
DirContext->LongNameU.Buffer[0] = DirContext->LongNameU.Buffer[1] = 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 (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
if (*pContext != NULL)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
}
|
||||
if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
*pContext = NULL;
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
}
|
||||
|
||||
fatxDirEntry = (PFATX_DIR_ENTRY)(*pPage) + DirIndex % FATX_ENTRIES_PER_PAGE;
|
||||
|
||||
DirContext->StartIndex = 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++;
|
||||
if ((DirContext->DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
|
||||
{
|
||||
CcUnpinData(*pContext);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
CHECKPOINT;
|
||||
*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 = fatxDirEntry->Filename;
|
||||
StringO.Length = StringO.MaximumLength = fatxDirEntry->FilenameLength;
|
||||
RtlOemStringToUnicodeString(&DirContext->LongNameU, &StringO, FALSE);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+274
-82
@@ -1,4 +1,4 @@
|
||||
/* $Id: dirwr.c,v 1.42 2004/11/06 13:44:57 ekohl Exp $
|
||||
/* $Id: dirwr.c,v 1.43 2004/12/05 16:31:50 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -26,21 +26,34 @@ VfatUpdateEntry (PVFATFCB pFcb)
|
||||
*/
|
||||
{
|
||||
PVOID Context;
|
||||
PFAT_DIR_ENTRY PinEntry;
|
||||
PDIR_ENTRY PinEntry;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG SizeDirEntry;
|
||||
ULONG dirIndex;
|
||||
|
||||
ASSERT(pFcb);
|
||||
ASSERT(pFcb->parentFcb);
|
||||
|
||||
if (pFcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
SizeDirEntry = sizeof(FATX_DIR_ENTRY);
|
||||
dirIndex = pFcb->startIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeDirEntry = sizeof(FAT_DIR_ENTRY);
|
||||
dirIndex = pFcb->dirIndex;
|
||||
}
|
||||
|
||||
DPRINT ("updEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
|
||||
DPRINT ("updEntry dirIndex %d, PathName \'%wZ\'\n", dirIndex, &pFcb->PathNameU);
|
||||
|
||||
Offset.u.HighPart = 0;
|
||||
Offset.u.LowPart = pFcb->dirIndex * sizeof(FATDirEntry);
|
||||
if (CcMapData (pFcb->parentFcb->FileObject, &Offset, sizeof(FATDirEntry),
|
||||
Offset.u.LowPart = dirIndex * SizeDirEntry;
|
||||
if (CcMapData (pFcb->parentFcb->FileObject, &Offset, SizeDirEntry,
|
||||
TRUE, &Context, (PVOID*)&PinEntry))
|
||||
{
|
||||
pFcb->Flags &= ~FCB_IS_DIRTY;
|
||||
*PinEntry = pFcb->entry;
|
||||
RtlCopyMemory(PinEntry, &pFcb->entry, SizeDirEntry);
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
return STATUS_SUCCESS;
|
||||
@@ -64,13 +77,20 @@ vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||
*/
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG i, count, size, nbFree = 0;
|
||||
FATDirEntry* pFatEntry;
|
||||
PDIR_ENTRY pFatEntry;
|
||||
PVOID Context = NULL;
|
||||
NTSTATUS Status;
|
||||
ULONG SizeDirEntry;
|
||||
FileOffset.QuadPart = 0;
|
||||
count = pDirFcb->RFCB.FileSize.u.LowPart / sizeof(FATDirEntry);
|
||||
size = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
|
||||
for (i = 0; i < count; i++, pFatEntry++)
|
||||
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
SizeDirEntry = sizeof(FATX_DIR_ENTRY);
|
||||
else
|
||||
SizeDirEntry = sizeof(FAT_DIR_ENTRY);
|
||||
|
||||
count = pDirFcb->RFCB.FileSize.u.LowPart / SizeDirEntry;
|
||||
size = DeviceExt->FatInfo.BytesPerCluster / SizeDirEntry;
|
||||
for (i = 0; i < count; i++, pFatEntry = (PDIR_ENTRY)((ULONG_PTR)pFatEntry + SizeDirEntry))
|
||||
{
|
||||
if (Context == NULL || (i % size) == 0)
|
||||
{
|
||||
@@ -83,11 +103,11 @@ vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||
TRUE, &Context, (PVOID*)&pFatEntry);
|
||||
FileOffset.u.LowPart += DeviceExt->FatInfo.BytesPerCluster;
|
||||
}
|
||||
if (ENTRY_END(pFatEntry))
|
||||
if (ENTRY_END(DeviceExt, pFatEntry))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (ENTRY_DELETED(pFatEntry))
|
||||
if (ENTRY_DELETED(DeviceExt, pFatEntry))
|
||||
{
|
||||
nbFree++;
|
||||
}
|
||||
@@ -120,7 +140,7 @@ vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||
// extend the directory
|
||||
if (vfatFCBIsRoot(pDirFcb) && DeviceExt->FatInfo.FatType != FAT32)
|
||||
{
|
||||
// We can't extend a root directory on a FAT12/FAT16 partition
|
||||
// We can't extend a root directory on a FAT12/FAT16/FATX partition
|
||||
return FALSE;
|
||||
}
|
||||
AllocationSize.QuadPart = pDirFcb->RFCB.FileSize.u.LowPart + DeviceExt->FatInfo.BytesPerCluster;
|
||||
@@ -135,15 +155,21 @@ vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||
DeviceExt->FatInfo.BytesPerCluster);
|
||||
CcMapData (pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster,
|
||||
TRUE, &Context, (PVOID*)&pFatEntry);
|
||||
RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
memset(pFatEntry, 0xff, DeviceExt->FatInfo.BytesPerCluster);
|
||||
else
|
||||
RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
|
||||
}
|
||||
else if (*start + nbSlots < count)
|
||||
{
|
||||
// clear the entry after the last new entry
|
||||
FileOffset.u.LowPart = (*start + nbSlots) * sizeof(FATDirEntry);
|
||||
CcMapData (pDirFcb->FileObject, &FileOffset, sizeof(FATDirEntry),
|
||||
FileOffset.u.LowPart = (*start + nbSlots) * SizeDirEntry;
|
||||
CcMapData (pDirFcb->FileObject, &FileOffset, SizeDirEntry,
|
||||
TRUE, &Context, (PVOID*)&pFatEntry);
|
||||
RtlZeroMemory(pFatEntry, sizeof(FATDirEntry));
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
memset(pFatEntry, 0xff, SizeDirEntry);
|
||||
else
|
||||
RtlZeroMemory(pFatEntry, SizeDirEntry);
|
||||
}
|
||||
if (Context)
|
||||
{
|
||||
@@ -156,7 +182,7 @@ vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
FATAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
PUNICODE_STRING PathNameU,
|
||||
PFILE_OBJECT pFileObject,
|
||||
ULONG RequestedOptions,
|
||||
@@ -166,7 +192,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
*/
|
||||
{
|
||||
PVOID Context = NULL;
|
||||
FATDirEntry *pFatEntry;
|
||||
PFAT_DIR_ENTRY pFatEntry;
|
||||
slot *pSlots;
|
||||
short nbSlots = 0, j, posCar;
|
||||
PUCHAR Buffer;
|
||||
@@ -180,7 +206,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG size;
|
||||
long i;
|
||||
|
||||
ANSI_STRING NameA;
|
||||
OEM_STRING NameA;
|
||||
CHAR aName[13];
|
||||
BOOLEAN IsNameLegal;
|
||||
BOOLEAN SpacesFound;
|
||||
@@ -212,8 +238,8 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
|
||||
nbSlots = (DirContext.LongNameU.Length / sizeof(WCHAR) + 12) / 13 + 1; //nb of entry needed for long name+normal entry
|
||||
DPRINT ("NameLen= %d, nbSlots =%d\n", DirContext.LongNameU.Length / sizeof(WCHAR), nbSlots);
|
||||
Buffer = ExAllocatePool (NonPagedPool, (nbSlots - 1) * sizeof (FATDirEntry));
|
||||
RtlZeroMemory (Buffer, (nbSlots - 1) * sizeof (FATDirEntry));
|
||||
Buffer = ExAllocatePool (NonPagedPool, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
|
||||
RtlZeroMemory (Buffer, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
|
||||
pSlots = (slot *) Buffer;
|
||||
|
||||
NameA.Buffer = aName;
|
||||
@@ -224,7 +250,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
DirContext.ShortNameU.Length = 0;
|
||||
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
|
||||
|
||||
memset(&DirContext.FatDirEntry, 0, sizeof(FATDirEntry));
|
||||
RtlZeroMemory(&DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
|
||||
|
||||
IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.LongNameU, &NameA, &SpacesFound);
|
||||
|
||||
@@ -235,7 +261,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
WCHAR ShortSearchName[13];
|
||||
needTilde = TRUE;
|
||||
needLong = TRUE;
|
||||
memset(&NameContext, 0, sizeof(GENERATE_NAME_CONTEXT));
|
||||
RtlZeroMemory(&NameContext, sizeof(GENERATE_NAME_CONTEXT));
|
||||
SearchContext.LongNameU.Buffer = LongNameBuffer;
|
||||
SearchContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
|
||||
SearchContext.ShortNameU.Buffer = ShortSearchName;
|
||||
@@ -257,7 +283,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
ExReleaseResourceLite(&pDirFcb->MainResource);
|
||||
vfatReleaseFCB(DeviceExt, pDirFcb);
|
||||
ExFreePool (Buffer);
|
||||
CHECKPOINT;
|
||||
CHECKPOINT;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.ShortNameU, &NameA, &SpacesFound);
|
||||
@@ -310,27 +336,27 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
}
|
||||
DPRINT ("'%s', '%wZ', needTilde=%d, needLong=%d\n",
|
||||
aName, &DirContext.LongNameU, needTilde, needLong);
|
||||
memset(DirContext.FatDirEntry.Filename, ' ', 11);
|
||||
memset(DirContext.DirEntry.Fat.Filename, ' ', 11);
|
||||
for (i = 0; i < 8 && aName[i] && aName[i] != '.'; i++)
|
||||
{
|
||||
DirContext.FatDirEntry.Filename[i] = aName[i];
|
||||
DirContext.DirEntry.Fat.Filename[i] = aName[i];
|
||||
}
|
||||
if (aName[i] == '.')
|
||||
{
|
||||
i++;
|
||||
for (j = 8; j < 11 && aName[i]; j++, i++)
|
||||
{
|
||||
DirContext.FatDirEntry.Filename[j] = aName[i];
|
||||
DirContext.DirEntry.Fat.Filename[j] = aName[i];
|
||||
}
|
||||
}
|
||||
if (DirContext.FatDirEntry.Filename[0] == 0xe5)
|
||||
if (DirContext.DirEntry.Fat.Filename[0] == 0xe5)
|
||||
{
|
||||
DirContext.FatDirEntry.Filename[0] = 0x05;
|
||||
DirContext.DirEntry.Fat.Filename[0] = 0x05;
|
||||
}
|
||||
|
||||
if (needLong)
|
||||
{
|
||||
memcpy(LongNameBuffer, DirContext.LongNameU.Buffer, DirContext.LongNameU.Length);
|
||||
RtlCopyMemory(LongNameBuffer, DirContext.LongNameU.Buffer, DirContext.LongNameU.Length);
|
||||
DirContext.LongNameU.Buffer = LongNameBuffer;
|
||||
DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
|
||||
DirContext.LongNameU.Buffer[DirContext.LongNameU.Length / sizeof(WCHAR)] = 0;
|
||||
@@ -342,39 +368,29 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
nbSlots = 1;
|
||||
if (lCaseBase)
|
||||
{
|
||||
DirContext.FatDirEntry.lCase |= VFAT_CASE_LOWER_BASE;
|
||||
DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_BASE;
|
||||
}
|
||||
if (lCaseExt)
|
||||
{
|
||||
DirContext.FatDirEntry.lCase |= VFAT_CASE_LOWER_EXT;
|
||||
DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_EXT;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT ("dos name=%11.11s\n", DirContext.FatDirEntry.Filename);
|
||||
DPRINT ("dos name=%11.11s\n", DirContext.DirEntry.Fat.Filename);
|
||||
|
||||
/* set attributes */
|
||||
DirContext.FatDirEntry.Attrib = ReqAttr;
|
||||
DirContext.DirEntry.Fat.Attrib = ReqAttr;
|
||||
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
DirContext.FatDirEntry.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
DirContext.DirEntry.Fat.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
/* set dates and times */
|
||||
KeQuerySystemTime (&SystemTime);
|
||||
#if 0
|
||||
{
|
||||
TIME_FIELDS tf;
|
||||
RtlTimeToTimeFields (&SystemTime, &tf);
|
||||
DPRINT1("%d.%d.%d %02d:%02d:%02d.%03d '%S'\n",
|
||||
tf.Day, tf.Month, tf.Year, tf.Hour,
|
||||
tf.Minute, tf.Second, tf.Milliseconds,
|
||||
pFileObject->FileName.Buffer);
|
||||
}
|
||||
#endif
|
||||
FsdSystemTimeToDosDateTime (&SystemTime, &DirContext.FatDirEntry.CreationDate,
|
||||
&DirContext.FatDirEntry.CreationTime);
|
||||
DirContext.FatDirEntry.UpdateDate = DirContext.FatDirEntry.CreationDate;
|
||||
DirContext.FatDirEntry.UpdateTime = DirContext.FatDirEntry.CreationTime;
|
||||
DirContext.FatDirEntry.AccessDate = DirContext.FatDirEntry.CreationDate;
|
||||
FsdSystemTimeToDosDateTime (DeviceExt, &SystemTime, &DirContext.DirEntry.Fat.CreationDate,
|
||||
&DirContext.DirEntry.Fat.CreationTime);
|
||||
DirContext.DirEntry.Fat.UpdateDate = DirContext.DirEntry.Fat.CreationDate;
|
||||
DirContext.DirEntry.Fat.UpdateTime = DirContext.DirEntry.Fat.CreationTime;
|
||||
DirContext.DirEntry.Fat.AccessDate = DirContext.DirEntry.Fat.CreationDate;
|
||||
|
||||
if (needLong)
|
||||
{
|
||||
@@ -383,7 +399,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
{
|
||||
pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
|
||||
| ((pSlots[0].alias_checksum & 0xfe) >> 1))
|
||||
+ DirContext.FatDirEntry.Filename[i]);
|
||||
+ DirContext.DirEntry.Fat.Filename[i]);
|
||||
}
|
||||
/* construct slots and entry */
|
||||
for (i = nbSlots - 2; i >= 0; i--)
|
||||
@@ -399,9 +415,9 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
pSlots[i].id = nbSlots - i - 1 + 0x40;
|
||||
}
|
||||
pSlots[i].alias_checksum = pSlots[0].alias_checksum;
|
||||
memcpy (pSlots[i].name0_4, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13, 10);
|
||||
memcpy (pSlots[i].name5_10, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 5, 12);
|
||||
memcpy (pSlots[i].name11_12, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 11, 4);
|
||||
RtlCopyMemory (pSlots[i].name0_4, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13, 10);
|
||||
RtlCopyMemory (pSlots[i].name5_10, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 5, 12);
|
||||
RtlCopyMemory (pSlots[i].name11_12, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 11, 4);
|
||||
}
|
||||
}
|
||||
/* try to find nbSlots contiguous entries frees in directory */
|
||||
@@ -430,47 +446,47 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
}
|
||||
if (DeviceExt->FatInfo.FatType == FAT32)
|
||||
{
|
||||
DirContext.FatDirEntry.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
|
||||
DirContext.DirEntry.Fat.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
|
||||
}
|
||||
DirContext.FatDirEntry.FirstCluster = (unsigned short)CurrentCluster;
|
||||
DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
|
||||
}
|
||||
|
||||
i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
|
||||
i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FAT_DIR_ENTRY);
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FATDirEntry);
|
||||
FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FAT_DIR_ENTRY);
|
||||
if (DirContext.StartIndex / i == DirContext.DirIndex / i)
|
||||
{
|
||||
/* one cluster */
|
||||
CHECKPOINT;
|
||||
CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FATDirEntry),
|
||||
CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY),
|
||||
TRUE, &Context, (PVOID*)&pFatEntry);
|
||||
if (nbSlots > 1)
|
||||
{
|
||||
memcpy(pFatEntry, Buffer, (nbSlots - 1) * sizeof(FATDirEntry));
|
||||
RtlCopyMemory(pFatEntry, Buffer, (nbSlots - 1) * sizeof(FAT_DIR_ENTRY));
|
||||
}
|
||||
memcpy(pFatEntry + (nbSlots - 1), &DirContext.FatDirEntry, sizeof(FATDirEntry));
|
||||
RtlCopyMemory(pFatEntry + (nbSlots - 1), &DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* two clusters */
|
||||
CHECKPOINT;
|
||||
size = DeviceExt->FatInfo.BytesPerCluster -
|
||||
(DirContext.StartIndex * sizeof(FATDirEntry)) % DeviceExt->FatInfo.BytesPerCluster;
|
||||
i = size / sizeof(FATDirEntry);
|
||||
(DirContext.StartIndex * sizeof(FAT_DIR_ENTRY)) % DeviceExt->FatInfo.BytesPerCluster;
|
||||
i = size / sizeof(FAT_DIR_ENTRY);
|
||||
CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
|
||||
&Context, (PVOID*)&pFatEntry);
|
||||
memcpy(pFatEntry, Buffer, size);
|
||||
RtlCopyMemory(pFatEntry, Buffer, size);
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
FileOffset.u.LowPart += size;
|
||||
CcMapData (pDirFcb->FileObject, &FileOffset,
|
||||
nbSlots * sizeof(FATDirEntry) - size,
|
||||
nbSlots * sizeof(FAT_DIR_ENTRY) - size,
|
||||
TRUE, &Context, (PVOID*)&pFatEntry);
|
||||
if (nbSlots - 1 > i)
|
||||
{
|
||||
memcpy(pFatEntry, (PVOID)(Buffer + size), (nbSlots - 1 - i) * sizeof(FATDirEntry));
|
||||
RtlCopyMemory(pFatEntry, (PVOID)(Buffer + size), (nbSlots - 1 - i) * sizeof(FAT_DIR_ENTRY));
|
||||
}
|
||||
memcpy(pFatEntry + nbSlots - 1 - i, &DirContext.FatDirEntry, sizeof(FATDirEntry));
|
||||
RtlCopyMemory(pFatEntry + nbSlots - 1 - i, &DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
|
||||
}
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
@@ -479,8 +495,8 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, &DirContext, &newFCB);
|
||||
vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
|
||||
|
||||
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
|
||||
DPRINT ("new : entry=%11.11s\n", DirContext.FatDirEntry.Filename);
|
||||
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Fat.Filename);
|
||||
DPRINT ("new : entry=%11.11s\n", DirContext.DirEntry.Fat.Filename);
|
||||
|
||||
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
@@ -490,12 +506,12 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
/* clear the new directory cluster */
|
||||
RtlZeroMemory (pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
|
||||
/* create '.' and '..' */
|
||||
memcpy (&pFatEntry[0].Attrib, &DirContext.FatDirEntry.Attrib, sizeof(FATDirEntry) - 11);
|
||||
memcpy (pFatEntry[0].Filename, ". ", 11);
|
||||
memcpy (&pFatEntry[1].Attrib, &DirContext.FatDirEntry.Attrib, sizeof(FATDirEntry) - 11);
|
||||
memcpy (pFatEntry[1].Filename, ".. ", 11);
|
||||
pFatEntry[1].FirstCluster = pDirFcb->entry.FirstCluster;
|
||||
pFatEntry[1].FirstClusterHigh = pDirFcb->entry.FirstClusterHigh;
|
||||
RtlCopyMemory (&pFatEntry[0].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
|
||||
RtlCopyMemory (pFatEntry[0].Filename, ". ", 11);
|
||||
RtlCopyMemory (&pFatEntry[1].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
|
||||
RtlCopyMemory (pFatEntry[1].Filename, ".. ", 11);
|
||||
pFatEntry[1].FirstCluster = pDirFcb->entry.Fat.FirstCluster;
|
||||
pFatEntry[1].FirstClusterHigh = pDirFcb->entry.Fat.FirstClusterHigh;
|
||||
if (vfatFCBIsRoot(pDirFcb))
|
||||
{
|
||||
pFatEntry[1].FirstCluster = 0;
|
||||
@@ -512,7 +528,129 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
|
||||
FATXAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
PUNICODE_STRING PathNameU,
|
||||
PFILE_OBJECT pFileObject,
|
||||
ULONG RequestedOptions,
|
||||
UCHAR ReqAttr)
|
||||
/*
|
||||
create a new FAT entry
|
||||
*/
|
||||
{
|
||||
PVOID Context = NULL;
|
||||
PVFATFCB newFCB;
|
||||
LARGE_INTEGER SystemTime, FileOffset;
|
||||
PVFATFCB pDirFcb;
|
||||
OEM_STRING NameA;
|
||||
VFAT_DIRENTRY_CONTEXT DirContext;
|
||||
PFATX_DIR_ENTRY pFatXDirEntry;
|
||||
UNICODE_STRING DirNameU;
|
||||
|
||||
DPRINT ("addEntry: Pathname='%wZ'\n", PathNameU);
|
||||
|
||||
vfatSplitPathName(PathNameU, &DirNameU, &DirContext.LongNameU);
|
||||
if (DirNameU.Length > sizeof(WCHAR))
|
||||
{
|
||||
DirNameU.Length -= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
if (DirContext.LongNameU.Length / sizeof(WCHAR) > 42)
|
||||
{
|
||||
/* name too long */
|
||||
CHECKPOINT;
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
pDirFcb = vfatGrabFCBFromTable(DeviceExt, &DirNameU);
|
||||
if (pDirFcb == NULL)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(&pDirFcb->MainResource, TRUE))
|
||||
{
|
||||
DPRINT("Failed acquiring lock\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* try to find 1 entry free in directory */
|
||||
if (!vfatFindDirSpace(DeviceExt, pDirFcb, 1, &DirContext.StartIndex))
|
||||
{
|
||||
ExReleaseResourceLite(&pDirFcb->MainResource);
|
||||
vfatReleaseFCB(DeviceExt, pDirFcb);
|
||||
return STATUS_DISK_FULL;
|
||||
}
|
||||
DirContext.DirIndex = DirContext.StartIndex;
|
||||
if (!vfatFCBIsRoot(pDirFcb))
|
||||
{
|
||||
DirContext.DirIndex += 2;
|
||||
}
|
||||
|
||||
DirContext.ShortNameU.Buffer = 0;
|
||||
DirContext.ShortNameU.Length = 0;
|
||||
DirContext.ShortNameU.MaximumLength = 0;
|
||||
RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
|
||||
memset(DirContext.DirEntry.FatX.Filename, 0xff, 42);
|
||||
DirContext.DirEntry.FatX.FirstCluster = 0;
|
||||
DirContext.DirEntry.FatX.FileSize = 0;
|
||||
|
||||
/* set file name */
|
||||
NameA.Buffer = DirContext.DirEntry.FatX.Filename;
|
||||
NameA.Length = 0;
|
||||
NameA.MaximumLength = 42;
|
||||
RtlUnicodeStringToOemString(&NameA, &DirContext.LongNameU, FALSE);
|
||||
DirContext.DirEntry.FatX.FilenameLength = NameA.Length;
|
||||
|
||||
/* set attributes */
|
||||
DirContext.DirEntry.FatX.Attrib = ReqAttr;
|
||||
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
DirContext.DirEntry.FatX.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
|
||||
/* set dates and times */
|
||||
KeQuerySystemTime (&SystemTime);
|
||||
FsdSystemTimeToDosDateTime(DeviceExt, &SystemTime, &DirContext.DirEntry.FatX.CreationDate,
|
||||
&DirContext.DirEntry.FatX.CreationTime);
|
||||
DirContext.DirEntry.FatX.UpdateDate = DirContext.DirEntry.FatX.CreationDate;
|
||||
DirContext.DirEntry.FatX.UpdateTime = DirContext.DirEntry.FatX.CreationTime;
|
||||
DirContext.DirEntry.FatX.AccessDate = DirContext.DirEntry.FatX.CreationDate;
|
||||
DirContext.DirEntry.FatX.AccessTime = DirContext.DirEntry.FatX.CreationTime;
|
||||
|
||||
/* add entry into parent directory */
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FATX_DIR_ENTRY);
|
||||
CcMapData(pDirFcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY),
|
||||
TRUE, &Context, (PVOID*)&pFatXDirEntry);
|
||||
RtlCopyMemory(pFatXDirEntry, &DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
|
||||
/* FIXME: check status */
|
||||
vfatMakeFCBFromDirEntry(DeviceExt, pDirFcb, &DirContext, &newFCB);
|
||||
vfatAttachFCBToFileObject(DeviceExt, newFCB, pFileObject);
|
||||
|
||||
ExReleaseResourceLite(&pDirFcb->MainResource);
|
||||
vfatReleaseFCB(DeviceExt, pDirFcb);
|
||||
DPRINT("addentry ok\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||
PUNICODE_STRING PathNameU,
|
||||
PFILE_OBJECT pFileObject,
|
||||
ULONG RequestedOptions,
|
||||
UCHAR ReqAttr)
|
||||
{
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
return FATXAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
|
||||
else
|
||||
return FATAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FATDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
|
||||
/*
|
||||
* deleting an existing FAT entry
|
||||
*/
|
||||
@@ -520,7 +658,7 @@ VfatDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
|
||||
ULONG CurrentCluster = 0, NextCluster, i;
|
||||
PVOID Context = NULL;
|
||||
LARGE_INTEGER Offset;
|
||||
FATDirEntry* pDirEntry;
|
||||
PFAT_DIR_ENTRY pDirEntry;
|
||||
|
||||
ASSERT(pFcb);
|
||||
ASSERT(pFcb->parentFcb);
|
||||
@@ -530,23 +668,23 @@ VfatDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
|
||||
Offset.u.HighPart = 0;
|
||||
for (i = pFcb->startIndex; i <= pFcb->dirIndex; i++)
|
||||
{
|
||||
if (Context == NULL || ((i * sizeof(FATDirEntry)) % PAGE_SIZE) == 0)
|
||||
if (Context == NULL || ((i * sizeof(FAT_DIR_ENTRY)) % PAGE_SIZE) == 0)
|
||||
{
|
||||
if (Context)
|
||||
{
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
Offset.u.LowPart = (i * sizeof(FATDirEntry) / PAGE_SIZE) * PAGE_SIZE;
|
||||
Offset.u.LowPart = (i * sizeof(FAT_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
|
||||
CcMapData (pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, TRUE,
|
||||
&Context, (PVOID*)&pDirEntry);
|
||||
}
|
||||
pDirEntry[i % (PAGE_SIZE / sizeof(FATDirEntry))].Filename[0] = 0xe5;
|
||||
pDirEntry[i % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))].Filename[0] = 0xe5;
|
||||
if (i == pFcb->dirIndex)
|
||||
{
|
||||
CurrentCluster =
|
||||
vfatDirEntryGetFirstCluster (DeviceExt,
|
||||
&pDirEntry[i % (PAGE_SIZE / sizeof(FATDirEntry))]);
|
||||
(PDIR_ENTRY)&pDirEntry[i % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))]);
|
||||
}
|
||||
}
|
||||
if (Context)
|
||||
@@ -565,4 +703,58 @@ VfatDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FATXDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
|
||||
/*
|
||||
* deleting an existing FAT entry
|
||||
*/
|
||||
{
|
||||
ULONG CurrentCluster = 0, NextCluster;
|
||||
PVOID Context = NULL;
|
||||
LARGE_INTEGER Offset;
|
||||
PFATX_DIR_ENTRY pDirEntry;
|
||||
ULONG StartIndex;
|
||||
|
||||
ASSERT(pFcb);
|
||||
ASSERT(pFcb->parentFcb);
|
||||
ASSERT(pFcb->Flags & FCB_IS_FATX_ENTRY);
|
||||
|
||||
StartIndex = pFcb->startIndex;
|
||||
|
||||
DPRINT ("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
|
||||
DPRINT ("delete entry: %d\n", StartIndex);
|
||||
Offset.u.HighPart = 0;
|
||||
Offset.u.LowPart = (StartIndex * sizeof(FATX_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
|
||||
if (!CcMapData (pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, TRUE,
|
||||
&Context, (PVOID*)&pDirEntry))
|
||||
{
|
||||
DPRINT1("CcMapData(Offset %x:%x, Length %d) failed\n", Offset.u.HighPart, Offset.u.LowPart, PAGE_SIZE);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
pDirEntry = &pDirEntry[StartIndex % (PAGE_SIZE / sizeof(FATX_DIR_ENTRY))];
|
||||
pDirEntry->FilenameLength = 0xe5;
|
||||
CurrentCluster = vfatDirEntryGetFirstCluster (DeviceExt,
|
||||
(PDIR_ENTRY)pDirEntry);
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
|
||||
while (CurrentCluster && CurrentCluster != 0xffffffff)
|
||||
{
|
||||
GetNextCluster (DeviceExt, CurrentCluster, &NextCluster);
|
||||
/* FIXME: check status */
|
||||
WriteCluster(DeviceExt, CurrentCluster, 0);
|
||||
CurrentCluster = NextCluster;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VfatDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
|
||||
{
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
return FATXDelEntry(DeviceExt, pFcb);
|
||||
else
|
||||
return FATDelEntry(DeviceExt, pFcb);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fat.c,v 1.46 2004/08/05 02:48:18 navaraf Exp $
|
||||
* $Id: fat.c,v 1.47 2004/12/05 16:31:50 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -459,7 +459,7 @@ CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
|
||||
{
|
||||
if (DeviceExt->FatInfo.FatType == FAT12)
|
||||
Status = FAT12CountAvailableClusters(DeviceExt);
|
||||
else if (DeviceExt->FatInfo.FatType == FAT16)
|
||||
else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
|
||||
Status = FAT16CountAvailableClusters(DeviceExt);
|
||||
else
|
||||
Status = FAT32CountAvailableClusters(DeviceExt);
|
||||
@@ -641,7 +641,7 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
DeviceExt, CurrentCluster);
|
||||
|
||||
if (CurrentCluster == 0)
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
return(STATUS_INVALID_PARAMETER);
|
||||
|
||||
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
|
||||
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: fcb.c,v 1.42 2004/11/06 13:44:57 ekohl Exp $
|
||||
/* $Id: fcb.c,v 1.43 2004/12/05 16:31:51 gvg Exp $
|
||||
*
|
||||
*
|
||||
* FILE: drivers/fs/vfat/fcb.c
|
||||
@@ -8,6 +8,7 @@
|
||||
* PROGRAMMER: Jason Filby ([email protected])
|
||||
* Rex Jolliff ([email protected])
|
||||
* Hartmut Birr
|
||||
* Herve Poussineau ([email protected])
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------- INCLUDES */
|
||||
@@ -38,6 +39,7 @@ ULONG vfatNameHash(ULONG hash, PUNICODE_STRING NameU)
|
||||
PWCHAR curr;
|
||||
register WCHAR c;
|
||||
|
||||
ASSERT(NameU->Buffer[0] != L'.');
|
||||
curr = NameU->Buffer;
|
||||
last = NameU->Buffer + NameU->Length / sizeof(WCHAR);
|
||||
|
||||
@@ -93,7 +95,7 @@ vfatInitFcb(PVFATFCB Fcb, PUNICODE_STRING NameU)
|
||||
}
|
||||
|
||||
PVFATFCB
|
||||
vfatNewFCB(PUNICODE_STRING pFileNameU)
|
||||
vfatNewFCB(PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU)
|
||||
{
|
||||
PVFATFCB rcFCB;
|
||||
|
||||
@@ -104,8 +106,15 @@ vfatNewFCB(PUNICODE_STRING pFileNameU)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(rcFCB, 0, sizeof(VFATFCB));
|
||||
RtlZeroMemory(rcFCB, sizeof(VFATFCB));
|
||||
vfatInitFcb(rcFCB, pFileNameU);
|
||||
if (pVCB->Flags & VCB_IS_FATX)
|
||||
{
|
||||
rcFCB->Flags |= FCB_IS_FATX_ENTRY;
|
||||
rcFCB->Attributes = &rcFCB->entry.FatX.Attrib;
|
||||
}
|
||||
else
|
||||
rcFCB->Attributes = &rcFCB->entry.Fat.Attrib;
|
||||
rcFCB->Hash.Hash = vfatNameHash(0, &rcFCB->PathNameU);
|
||||
rcFCB->Hash.self = rcFCB;
|
||||
rcFCB->ShortHash.self = rcFCB;
|
||||
@@ -138,7 +147,7 @@ vfatDestroyFCB(PVFATFCB pFCB)
|
||||
BOOL
|
||||
vfatFCBIsDirectory(PVFATFCB FCB)
|
||||
{
|
||||
return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY;
|
||||
return *FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
|
||||
BOOL
|
||||
@@ -312,7 +321,7 @@ vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memset (newCCB, 0, sizeof (VFATCCB));
|
||||
RtlZeroMemory(newCCB, sizeof (VFATCCB));
|
||||
|
||||
fileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
|
||||
fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
|
||||
@@ -347,28 +356,39 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
|
||||
|
||||
RtlRosInitUnicodeStringFromLiteral(&NameU, L"\\");
|
||||
|
||||
FCB = vfatNewFCB(&NameU);
|
||||
memset(FCB->entry.Filename, ' ', 11);
|
||||
FCB->ShortHash.Hash = FCB->Hash.Hash;
|
||||
FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
if (pVCB->FatInfo.FatType == FAT32)
|
||||
FCB = vfatNewFCB(pVCB, &NameU);
|
||||
if (FCB->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
|
||||
FCB->entry.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
|
||||
FCB->entry.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
|
||||
|
||||
while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
|
||||
{
|
||||
Size += pVCB->FatInfo.BytesPerCluster;
|
||||
Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
|
||||
}
|
||||
memset(FCB->entry.FatX.Filename, ' ', 42);
|
||||
FCB->entry.FatX.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
FCB->entry.FatX.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
FCB->entry.FatX.FirstCluster = 1;
|
||||
Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
}
|
||||
else
|
||||
{
|
||||
FCB->entry.FirstCluster = 1;
|
||||
Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
memset(FCB->entry.Fat.Filename, ' ', 11);
|
||||
FCB->entry.Fat.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
FCB->entry.Fat.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
if (pVCB->FatInfo.FatType == FAT32)
|
||||
{
|
||||
CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
|
||||
FCB->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
|
||||
FCB->entry.Fat.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
|
||||
|
||||
while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
|
||||
{
|
||||
Size += pVCB->FatInfo.BytesPerCluster;
|
||||
Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FCB->entry.Fat.FirstCluster = 1;
|
||||
Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
|
||||
}
|
||||
}
|
||||
FCB->ShortHash.Hash = FCB->Hash.Hash;
|
||||
FCB->RefCount = 2;
|
||||
FCB->dirIndex = 0;
|
||||
FCB->RFCB.FileSize.QuadPart = Size;
|
||||
@@ -435,10 +455,18 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
||||
RtlAppendUnicodeStringToString(&NameU, &DirContext->ShortNameU);
|
||||
}
|
||||
NameU.Buffer[NameU.Length / sizeof(WCHAR)] = 0;
|
||||
rcFCB = vfatNewFCB (&NameU);
|
||||
memcpy (&rcFCB->entry, &DirContext->FatDirEntry, sizeof (FAT_DIR_ENTRY));
|
||||
|
||||
rcFCB = vfatNewFCB (vcb, &NameU);
|
||||
RtlCopyMemory (&rcFCB->entry, &DirContext->DirEntry, sizeof (DIR_ENTRY));
|
||||
RtlCopyUnicodeString(&rcFCB->ShortNameU, &DirContext->ShortNameU);
|
||||
rcFCB->ShortHash.Hash = vfatNameHash(hash, &rcFCB->ShortNameU);
|
||||
if (vcb->Flags & VCB_IS_FATX)
|
||||
{
|
||||
rcFCB->ShortHash.Hash = rcFCB->Hash.Hash;
|
||||
}
|
||||
else
|
||||
{
|
||||
rcFCB->ShortHash.Hash = vfatNameHash(hash, &rcFCB->ShortNameU);
|
||||
}
|
||||
|
||||
if (vfatFCBIsDirectory(rcFCB))
|
||||
{
|
||||
@@ -450,7 +478,7 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
||||
{
|
||||
Size = vcb->FatInfo.rootDirectorySectors * vcb->FatInfo.BytesPerSector;
|
||||
}
|
||||
else
|
||||
else if (FirstCluster != 0)
|
||||
{
|
||||
CurrentCluster = FirstCluster;
|
||||
while (CurrentCluster != 0xffffffff)
|
||||
@@ -460,9 +488,13 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rcFCB->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
Size = rcFCB->entry.FatX.FileSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
Size = rcFCB->entry.FileSize;
|
||||
Size = rcFCB->entry.Fat.FileSize;
|
||||
}
|
||||
rcFCB->dirIndex = DirContext->DirIndex;
|
||||
rcFCB->startIndex = DirContext->StartIndex;
|
||||
@@ -494,7 +526,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
||||
CHECKPOINT;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memset (newCCB, 0, sizeof (VFATCCB));
|
||||
RtlZeroMemory (newCCB, sizeof (VFATCCB));
|
||||
|
||||
fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID |
|
||||
FO_DIRECT_CACHE_PAGING_READ;
|
||||
@@ -542,7 +574,7 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
status = vfatGetNextDirEntry(&Context,
|
||||
status = pDeviceExt->GetNextDirEntry(&Context,
|
||||
&Page,
|
||||
pDirectoryFCB,
|
||||
&DirContext,
|
||||
@@ -562,7 +594,7 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
|
||||
&DirContext.LongNameU);
|
||||
DirContext.LongNameU.Buffer[DirContext.LongNameU.Length / sizeof(WCHAR)] = 0;
|
||||
DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
|
||||
if (!ENTRY_VOLUME(&DirContext.FatDirEntry))
|
||||
if (!ENTRY_VOLUME(pDeviceExt, &DirContext.DirEntry))
|
||||
{
|
||||
FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);
|
||||
if (FoundLong == FALSE)
|
||||
@@ -646,7 +678,7 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
||||
curr = pFileNameU->Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
|
||||
last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
|
||||
}
|
||||
memcpy(pFileNameU->Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
|
||||
RtlCopyMemory(pFileNameU->Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -699,7 +731,7 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
|
||||
curr = prev + parentFCB->LongNameU.Length / sizeof(WCHAR);
|
||||
last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
|
||||
}
|
||||
memcpy(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
|
||||
RtlCopyMemory(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
|
||||
}
|
||||
curr++;
|
||||
prev = curr;
|
||||
|
||||
+146
-82
@@ -1,4 +1,4 @@
|
||||
/* $Id: finfo.c,v 1.38 2004/11/06 13:44:57 ekohl Exp $
|
||||
/* $Id: finfo.c,v 1.39 2004/12/05 16:31:51 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -6,6 +6,7 @@
|
||||
* PURPOSE: VFAT Filesystem
|
||||
* PROGRAMMER: Jason Filby ([email protected])
|
||||
* Hartmut Birr
|
||||
* Herve Poussineau ([email protected])
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -106,26 +107,47 @@ VfatSetBasicInformation(PFILE_OBJECT FileObject,
|
||||
ASSERT(NULL != DeviceExt);
|
||||
ASSERT(NULL != BasicInfo);
|
||||
/* Check volume label bit */
|
||||
ASSERT(0 == (FCB->entry.Attrib & 0x08));
|
||||
ASSERT(0 == (*FCB->Attributes & 0x08));
|
||||
|
||||
FsdSystemTimeToDosDateTime(&BasicInfo->CreationTime,
|
||||
&FCB->entry.CreationDate,
|
||||
&FCB->entry.CreationTime);
|
||||
FsdSystemTimeToDosDateTime(&BasicInfo->LastAccessTime,
|
||||
&FCB->entry.AccessDate,
|
||||
if (FCB->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
FsdSystemTimeToDosDateTime(DeviceExt,
|
||||
&BasicInfo->CreationTime,
|
||||
&FCB->entry.FatX.CreationDate,
|
||||
&FCB->entry.FatX.CreationTime);
|
||||
FsdSystemTimeToDosDateTime(DeviceExt,
|
||||
&BasicInfo->LastAccessTime,
|
||||
&FCB->entry.FatX.AccessDate,
|
||||
&FCB->entry.FatX.AccessTime);
|
||||
FsdSystemTimeToDosDateTime(DeviceExt,
|
||||
&BasicInfo->LastWriteTime,
|
||||
&FCB->entry.FatX.UpdateDate,
|
||||
&FCB->entry.FatX.UpdateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
FsdSystemTimeToDosDateTime(DeviceExt,
|
||||
&BasicInfo->CreationTime,
|
||||
&FCB->entry.Fat.CreationDate,
|
||||
&FCB->entry.Fat.CreationTime);
|
||||
FsdSystemTimeToDosDateTime(DeviceExt,
|
||||
&BasicInfo->LastAccessTime,
|
||||
&FCB->entry.Fat.AccessDate,
|
||||
NULL);
|
||||
FsdSystemTimeToDosDateTime(&BasicInfo->LastWriteTime,
|
||||
&FCB->entry.UpdateDate,
|
||||
&FCB->entry.UpdateTime);
|
||||
FsdSystemTimeToDosDateTime(DeviceExt,
|
||||
&BasicInfo->LastWriteTime,
|
||||
&FCB->entry.Fat.UpdateDate,
|
||||
&FCB->entry.Fat.UpdateTime);
|
||||
}
|
||||
|
||||
FCB->entry.Attrib = (unsigned char)((FCB->entry.Attrib &
|
||||
*FCB->Attributes = (unsigned char)((*FCB->Attributes &
|
||||
(FILE_ATTRIBUTE_DIRECTORY | 0x48)) |
|
||||
(BasicInfo->FileAttributes &
|
||||
(FILE_ATTRIBUTE_ARCHIVE |
|
||||
FILE_ATTRIBUTE_SYSTEM |
|
||||
FILE_ATTRIBUTE_HIDDEN |
|
||||
FILE_ATTRIBUTE_READONLY)));
|
||||
DPRINT("Setting attributes 0x%02x\n", FCB->entry.Attrib);
|
||||
DPRINT("Setting attributes 0x%02x\n", *FCB->Attributes);
|
||||
|
||||
VfatUpdateEntry(FCB);
|
||||
|
||||
@@ -139,23 +161,48 @@ VfatGetBasicInformation(PFILE_OBJECT FileObject,
|
||||
PFILE_BASIC_INFORMATION BasicInfo,
|
||||
PULONG BufferLength)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
DPRINT("VfatGetBasicInformation()\n");
|
||||
|
||||
DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
||||
FsdDosDateTimeToSystemTime(FCB->entry.CreationDate,
|
||||
FCB->entry.CreationTime,
|
||||
if (FCB->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
FCB->entry.FatX.CreationDate,
|
||||
FCB->entry.FatX.CreationTime,
|
||||
&BasicInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime(FCB->entry.AccessDate,
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
FCB->entry.FatX.AccessDate,
|
||||
FCB->entry.FatX.AccessTime,
|
||||
&BasicInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
FCB->entry.FatX.UpdateDate,
|
||||
FCB->entry.FatX.UpdateTime,
|
||||
&BasicInfo->LastWriteTime);
|
||||
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
FCB->entry.Fat.CreationDate,
|
||||
FCB->entry.Fat.CreationTime,
|
||||
&BasicInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
FCB->entry.Fat.AccessDate,
|
||||
0,
|
||||
&BasicInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime(FCB->entry.UpdateDate,
|
||||
FCB->entry.UpdateTime,
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
FCB->entry.Fat.UpdateDate,
|
||||
FCB->entry.Fat.UpdateTime,
|
||||
&BasicInfo->LastWriteTime);
|
||||
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
|
||||
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
|
||||
}
|
||||
|
||||
BasicInfo->FileAttributes = FCB->entry.Attrib & 0x3f;
|
||||
BasicInfo->FileAttributes = *FCB->Attributes & 0x3f;
|
||||
/* Synthesize FILE_ATTRIBUTE_NORMAL */
|
||||
if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
|
||||
FILE_ATTRIBUTE_ARCHIVE |
|
||||
@@ -188,7 +235,7 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
|
||||
ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
|
||||
ASSERT(FCB != NULL);
|
||||
|
||||
if (FCB->entry.Attrib & FILE_ATTRIBUTE_READONLY)
|
||||
if (*FCB->Attributes & FILE_ATTRIBUTE_READONLY)
|
||||
{
|
||||
return STATUS_CANNOT_DELETE;
|
||||
}
|
||||
@@ -259,7 +306,7 @@ VfatGetNameInformation(PFILE_OBJECT FileObject,
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
||||
NameInfo->FileNameLength = FCB->PathNameU.Length;
|
||||
memcpy(NameInfo->FileName, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
|
||||
RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
|
||||
NameInfo->FileName[FCB->PathNameU.Length / sizeof(WCHAR)] = 0;
|
||||
|
||||
*BufferLength -= (sizeof(FILE_NAME_INFORMATION) + FCB->PathNameU.Length + sizeof(WCHAR));
|
||||
@@ -286,6 +333,7 @@ VfatGetInternalInformation(PVFATFCB Fcb,
|
||||
|
||||
static NTSTATUS
|
||||
VfatGetNetworkOpenInformation(PVFATFCB Fcb,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
|
||||
PULONG BufferLength)
|
||||
/*
|
||||
@@ -298,16 +346,38 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb,
|
||||
if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
FsdDosDateTimeToSystemTime(Fcb->entry.CreationDate,
|
||||
Fcb->entry.CreationTime,
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
Fcb->entry.FatX.CreationDate,
|
||||
Fcb->entry.FatX.CreationTime,
|
||||
&NetworkInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime(Fcb->entry.AccessDate,
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
Fcb->entry.FatX.AccessDate,
|
||||
Fcb->entry.FatX.AccessTime,
|
||||
&NetworkInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
Fcb->entry.FatX.UpdateDate,
|
||||
Fcb->entry.FatX.UpdateTime,
|
||||
&NetworkInfo->LastWriteTime);
|
||||
NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
Fcb->entry.Fat.CreationDate,
|
||||
Fcb->entry.Fat.CreationTime,
|
||||
&NetworkInfo->CreationTime);
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
Fcb->entry.Fat.AccessDate,
|
||||
0,
|
||||
&NetworkInfo->LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime(Fcb->entry.UpdateDate,
|
||||
Fcb->entry.UpdateTime,
|
||||
FsdDosDateTimeToSystemTime(DeviceExt,
|
||||
Fcb->entry.Fat.UpdateDate,
|
||||
Fcb->entry.Fat.UpdateTime,
|
||||
&NetworkInfo->LastWriteTime);
|
||||
NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
|
||||
NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
|
||||
}
|
||||
if (vfatFCBIsDirectory(Fcb))
|
||||
{
|
||||
NetworkInfo->EndOfFile.QuadPart = 0L;
|
||||
@@ -318,7 +388,7 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb,
|
||||
NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
|
||||
NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
|
||||
}
|
||||
NetworkInfo->FileAttributes = Fcb->entry.Attrib & 0x3f;
|
||||
NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f;
|
||||
|
||||
*BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
|
||||
return STATUS_SUCCESS;
|
||||
@@ -328,12 +398,16 @@ VfatGetNetworkOpenInformation(PVFATFCB Fcb,
|
||||
static NTSTATUS
|
||||
VfatGetAllInformation(PFILE_OBJECT FileObject,
|
||||
PVFATFCB Fcb,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PFILE_ALL_INFORMATION Info,
|
||||
PULONG BufferLength)
|
||||
/*
|
||||
* FUNCTION: Retrieve the all file information
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG InitialBufferLength = *BufferLength;
|
||||
|
||||
ASSERT(Info);
|
||||
ASSERT(Fcb);
|
||||
|
||||
@@ -341,60 +415,28 @@ VfatGetAllInformation(PFILE_OBJECT FileObject,
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
/* Basic Information */
|
||||
FsdDosDateTimeToSystemTime(Fcb->entry.CreationDate,
|
||||
Fcb->entry.CreationTime,
|
||||
&Info->BasicInformation.CreationTime);
|
||||
FsdDosDateTimeToSystemTime(Fcb->entry.AccessDate,
|
||||
0,
|
||||
&Info->BasicInformation.LastAccessTime);
|
||||
FsdDosDateTimeToSystemTime(Fcb->entry.UpdateDate,
|
||||
Fcb->entry.UpdateTime,
|
||||
&Info->BasicInformation.LastWriteTime);
|
||||
Info->BasicInformation.ChangeTime.QuadPart = Info->BasicInformation.LastWriteTime.QuadPart;
|
||||
Info->BasicInformation.FileAttributes = Fcb->entry.Attrib & 0x3f;
|
||||
|
||||
Status = VfatGetBasicInformation(FileObject, Fcb, DeviceObject, &Info->BasicInformation, BufferLength);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
/* Standard Information */
|
||||
if (vfatFCBIsDirectory(Fcb))
|
||||
{
|
||||
Info->StandardInformation.AllocationSize.QuadPart = 0LL;
|
||||
Info->StandardInformation.EndOfFile.QuadPart = 0LL;
|
||||
Info->StandardInformation.Directory = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
|
||||
Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
|
||||
Info->StandardInformation.Directory = FALSE;
|
||||
}
|
||||
Info->StandardInformation.NumberOfLinks = 0;
|
||||
Info->StandardInformation.DeletePending = Fcb->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
|
||||
|
||||
Status = VfatGetStandardInformation(Fcb, &Info->StandardInformation, BufferLength);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
/* Internal Information */
|
||||
/* FIXME: get a real index, that can be used in a create operation */
|
||||
Info->InternalInformation.IndexNumber.QuadPart = 0;
|
||||
|
||||
Status = VfatGetInternalInformation(Fcb, &Info->InternalInformation, BufferLength);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
/* EA Information */
|
||||
Info->EaInformation.EaSize = 0;
|
||||
|
||||
/* Access Information */
|
||||
/* The IO-Manager adds this information */
|
||||
|
||||
/* Access Information: The IO-Manager adds this information */
|
||||
/* Position Information */
|
||||
Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
|
||||
|
||||
/* Mode Information */
|
||||
/* The IO-Manager adds this information */
|
||||
|
||||
/* Alignment Information */
|
||||
/* The IO-Manager adds this information */
|
||||
|
||||
Status = VfatGetPositionInformation(FileObject, Fcb, DeviceObject, &Info->PositionInformation, BufferLength);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
/* Mode Information: The IO-Manager adds this information */
|
||||
/* Alignment Information: The IO-Manager adds this information */
|
||||
/* Name Information */
|
||||
Info->NameInformation.FileNameLength = Fcb->PathNameU.Length;
|
||||
RtlCopyMemory(Info->NameInformation.FileName, Fcb->PathNameU.Buffer, Fcb->PathNameU.Length);
|
||||
Info->NameInformation.FileName[Fcb->PathNameU.Length / sizeof(WCHAR)] = 0;
|
||||
|
||||
*BufferLength -= (sizeof(FILE_ALL_INFORMATION) + Fcb->PathNameU.Length + sizeof(WCHAR));
|
||||
|
||||
Status = VfatGetNameInformation(FileObject, Fcb, DeviceObject, &Info->NameInformation, BufferLength);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
*BufferLength = InitialBufferLength - (sizeof(FILE_ALL_INFORMATION) + Fcb->PathNameU.Length + sizeof(WCHAR));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -410,7 +452,10 @@ VOID UpdateFileSize(PFILE_OBJECT FileObject, PVFATFCB Fcb, ULONG Size, ULONG Clu
|
||||
}
|
||||
if (!vfatFCBIsDirectory(Fcb))
|
||||
{
|
||||
Fcb->entry.FileSize = Size;
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
Fcb->entry.FatX.FileSize = Size;
|
||||
else
|
||||
Fcb->entry.Fat.FileSize = Size;
|
||||
}
|
||||
Fcb->RFCB.FileSize.QuadPart = Size;
|
||||
Fcb->RFCB.ValidDataLength.QuadPart = Size;
|
||||
@@ -438,7 +483,10 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
||||
|
||||
DPRINT("VfatSetAllocationSizeInformation()\n");
|
||||
|
||||
OldSize = Fcb->entry.FileSize;
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
OldSize = Fcb->entry.FatX.FileSize;
|
||||
else
|
||||
OldSize = Fcb->entry.Fat.FileSize;
|
||||
if (AllocationSize->u.HighPart > 0)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
@@ -482,8 +530,15 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
||||
}
|
||||
return STATUS_DISK_FULL;
|
||||
}
|
||||
Fcb->entry.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
|
||||
Fcb->entry.FirstClusterHigh = (unsigned short)((FirstCluster & 0xFFFF0000) >> 16);
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
Fcb->entry.FatX.FirstCluster = FirstCluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
|
||||
Fcb->entry.Fat.FirstClusterHigh = (unsigned short)((FirstCluster & 0xFFFF0000) >> 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -547,8 +602,15 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
||||
}
|
||||
else
|
||||
{
|
||||
Fcb->entry.FirstCluster = 0;
|
||||
Fcb->entry.FirstClusterHigh = 0;
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
Fcb->entry.FatX.FirstCluster = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fcb->entry.Fat.FirstCluster = 0;
|
||||
Fcb->entry.Fat.FirstClusterHigh = 0;
|
||||
}
|
||||
|
||||
NCluster = Cluster = FirstCluster;
|
||||
Status = STATUS_SUCCESS;
|
||||
@@ -640,12 +702,14 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
|
||||
break;
|
||||
case FileNetworkOpenInformation:
|
||||
RC = VfatGetNetworkOpenInformation(FCB,
|
||||
IrpContext->DeviceExt,
|
||||
SystemBuffer,
|
||||
&BufferLength);
|
||||
break;
|
||||
case FileAllInformation:
|
||||
RC = VfatGetAllInformation(IrpContext->FileObject,
|
||||
FCB,
|
||||
IrpContext->DeviceObject,
|
||||
SystemBuffer,
|
||||
&BufferLength);
|
||||
break;
|
||||
|
||||
+175
-81
@@ -16,7 +16,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: fsctl.c,v 1.36 2004/11/06 13:44:57 ekohl Exp $
|
||||
/* $Id: fsctl.c,v 1.37 2004/12/05 16:31:51 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -55,6 +55,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
||||
ULONG Sectors;
|
||||
LARGE_INTEGER Offset;
|
||||
struct _BootSector* Boot;
|
||||
struct _BootSectorFatX* BootFatX;
|
||||
BOOL PartitionInfoIsValid = FALSE;
|
||||
|
||||
DPRINT("VfatHasFileSystem\n");
|
||||
@@ -92,17 +93,15 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
||||
return Status;
|
||||
}
|
||||
PartitionInfoIsValid = TRUE;
|
||||
#if defined(DBG) && !defined(NDEBUG)
|
||||
DbgPrint("Partition Information:\n");
|
||||
DbgPrint("StartingOffset %u\n", PartitionInfo.StartingOffset.QuadPart / 512);
|
||||
DbgPrint("PartitionLength %u\n", PartitionInfo.PartitionLength.QuadPart / 512);
|
||||
DbgPrint("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
|
||||
DbgPrint("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
|
||||
DbgPrint("PartitionType %u\n", PartitionInfo.PartitionType);
|
||||
DbgPrint("BootIndicator %u\n", PartitionInfo.BootIndicator);
|
||||
DbgPrint("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
|
||||
DbgPrint("RewritePartition %u\n", PartitionInfo.RewritePartition);
|
||||
#endif
|
||||
DPRINT("Partition Information:\n");
|
||||
DPRINT("StartingOffset %u\n", PartitionInfo.StartingOffset.QuadPart / 512);
|
||||
DPRINT("PartitionLength %u\n", PartitionInfo.PartitionLength.QuadPart / 512);
|
||||
DPRINT("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
|
||||
DPRINT("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
|
||||
DPRINT("PartitionType %u\n", PartitionInfo.PartitionType);
|
||||
DPRINT("BootIndicator %u\n", PartitionInfo.BootIndicator);
|
||||
DPRINT("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
|
||||
DPRINT("RewritePartition %u\n", PartitionInfo.RewritePartition);
|
||||
if (PartitionInfo.PartitionType)
|
||||
{
|
||||
if (PartitionInfo.PartitionType == PARTITION_FAT_12 ||
|
||||
@@ -151,20 +150,28 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
||||
}
|
||||
|
||||
Offset.QuadPart = 0;
|
||||
|
||||
|
||||
/* Try to recognize FAT12/FAT16/FAT32 partitions */
|
||||
Status = VfatReadDisk(DeviceToMount, &Offset, DiskGeometry.BytesPerSector, (PUCHAR) Boot, FALSE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
if (Boot->Signatur1 != 0xaa55)
|
||||
{
|
||||
DPRINT1("Signature %04x\n", Boot->Signatur1);
|
||||
BootFatX = (struct _BootSectorFatX *) Boot;
|
||||
if (BootFatX->SysType[0] != 'F' ||
|
||||
BootFatX->SysType[1] != 'A' ||
|
||||
BootFatX->SysType[2] != 'T' ||
|
||||
BootFatX->SysType[3] != 'X')
|
||||
{
|
||||
DPRINT1("Signature %04x\n", Boot->Signatur1);
|
||||
}
|
||||
*RecognizedFS=FALSE;
|
||||
}
|
||||
if (*RecognizedFS &&
|
||||
Boot->BytesPerSector != 512 &&
|
||||
Boot->BytesPerSector != 1024 &&
|
||||
Boot->BytesPerSector != 512 &&
|
||||
Boot->BytesPerSector != 1024 &&
|
||||
Boot->BytesPerSector != 2048 &&
|
||||
Boot->BytesPerSector != 4096)
|
||||
Boot->BytesPerSector != 4096)
|
||||
{
|
||||
DPRINT1("BytesPerSector %d\n", Boot->BytesPerSector);
|
||||
*RecognizedFS=FALSE;
|
||||
@@ -172,7 +179,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
||||
|
||||
if (*RecognizedFS &&
|
||||
Boot->FATCount != 1 &&
|
||||
Boot->FATCount != 2)
|
||||
Boot->FATCount != 2)
|
||||
{
|
||||
DPRINT1("FATCount %d\n", Boot->FATCount);
|
||||
*RecognizedFS=FALSE;
|
||||
@@ -180,28 +187,28 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
||||
|
||||
if (*RecognizedFS &&
|
||||
Boot->Media != 0xf0 &&
|
||||
Boot->Media != 0xf8 &&
|
||||
Boot->Media != 0xf9 &&
|
||||
Boot->Media != 0xfa &&
|
||||
Boot->Media != 0xfb &&
|
||||
Boot->Media != 0xfc &&
|
||||
Boot->Media != 0xfd &&
|
||||
Boot->Media != 0xfe &&
|
||||
Boot->Media != 0xff)
|
||||
Boot->Media != 0xf8 &&
|
||||
Boot->Media != 0xf9 &&
|
||||
Boot->Media != 0xfa &&
|
||||
Boot->Media != 0xfb &&
|
||||
Boot->Media != 0xfc &&
|
||||
Boot->Media != 0xfd &&
|
||||
Boot->Media != 0xfe &&
|
||||
Boot->Media != 0xff)
|
||||
{
|
||||
DPRINT1("Media %02x\n", Boot->Media);
|
||||
*RecognizedFS=FALSE;
|
||||
}
|
||||
|
||||
if (*RecognizedFS &&
|
||||
Boot->SectorsPerCluster != 1 &&
|
||||
Boot->SectorsPerCluster != 2 &&
|
||||
Boot->SectorsPerCluster != 1 &&
|
||||
Boot->SectorsPerCluster != 2 &&
|
||||
Boot->SectorsPerCluster != 4 &&
|
||||
Boot->SectorsPerCluster != 8 &&
|
||||
Boot->SectorsPerCluster != 8 &&
|
||||
Boot->SectorsPerCluster != 16 &&
|
||||
Boot->SectorsPerCluster != 32 &&
|
||||
Boot->SectorsPerCluster != 32 &&
|
||||
Boot->SectorsPerCluster != 64 &&
|
||||
Boot->SectorsPerCluster != 128)
|
||||
Boot->SectorsPerCluster != 128)
|
||||
{
|
||||
DPRINT1("SectorsPerCluster %02x\n", Boot->SectorsPerCluster);
|
||||
*RecognizedFS=FALSE;
|
||||
@@ -247,12 +254,12 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
||||
DPRINT("FAT16\n");
|
||||
FatInfo.FatType = FAT16;
|
||||
}
|
||||
if (PartitionInfoIsValid &&
|
||||
FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
*RecognizedFS = FALSE;
|
||||
}
|
||||
if (PartitionInfoIsValid &&
|
||||
FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
*RecognizedFS = FALSE;
|
||||
}
|
||||
|
||||
if (pFatInfo && *RecognizedFS)
|
||||
{
|
||||
@@ -262,6 +269,81 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
||||
}
|
||||
|
||||
ExFreePool(Boot);
|
||||
|
||||
if (!*RecognizedFS && PartitionInfoIsValid)
|
||||
{
|
||||
BootFatX = ExAllocatePool(NonPagedPool, sizeof(struct _BootSectorFatX));
|
||||
if (BootFatX == NULL)
|
||||
{
|
||||
*RecognizedFS=FALSE;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Offset.QuadPart = 0;
|
||||
|
||||
/* Try to recognize FATX16/FATX32 partitions (Xbox) */
|
||||
Status = VfatReadDisk(DeviceToMount, &Offset, sizeof(struct _BootSectorFatX), (PUCHAR) BootFatX, FALSE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*RecognizedFS = TRUE;
|
||||
if (BootFatX->SysType[0] != 'F' ||
|
||||
BootFatX->SysType[1] != 'A' ||
|
||||
BootFatX->SysType[2] != 'T' ||
|
||||
BootFatX->SysType[3] != 'X')
|
||||
{
|
||||
DPRINT1("SysType %c%c%c%c\n", BootFatX->SysType[0], BootFatX->SysType[1], BootFatX->SysType[2], BootFatX->SysType[3]);
|
||||
*RecognizedFS=FALSE;
|
||||
}
|
||||
|
||||
if (*RecognizedFS &&
|
||||
BootFatX->SectorsPerCluster != 1 &&
|
||||
BootFatX->SectorsPerCluster != 2 &&
|
||||
BootFatX->SectorsPerCluster != 4 &&
|
||||
BootFatX->SectorsPerCluster != 8 &&
|
||||
BootFatX->SectorsPerCluster != 16 &&
|
||||
BootFatX->SectorsPerCluster != 32 &&
|
||||
BootFatX->SectorsPerCluster != 64 &&
|
||||
BootFatX->SectorsPerCluster != 128)
|
||||
{
|
||||
DPRINT1("SectorsPerCluster %lu\n", BootFatX->SectorsPerCluster);
|
||||
*RecognizedFS=FALSE;
|
||||
}
|
||||
|
||||
if (*RecognizedFS)
|
||||
{
|
||||
FatInfo.BytesPerSector = DiskGeometry.BytesPerSector;
|
||||
FatInfo.SectorsPerCluster = BootFatX->SectorsPerCluster;
|
||||
FatInfo.rootDirectorySectors = BootFatX->SectorsPerCluster;
|
||||
FatInfo.BytesPerCluster = BootFatX->SectorsPerCluster * DiskGeometry.BytesPerSector;
|
||||
FatInfo.NumberOfClusters = PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerCluster;
|
||||
if (FatInfo.NumberOfClusters < 65525)
|
||||
{
|
||||
DPRINT("FATX16\n");
|
||||
FatInfo.FatType = FATX16;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("FATX32\n");
|
||||
FatInfo.FatType = FATX32;
|
||||
}
|
||||
FatInfo.VolumeID = BootFatX->VolumeID;
|
||||
FatInfo.FATStart = sizeof(struct _BootSectorFatX) / DiskGeometry.BytesPerSector;
|
||||
FatInfo.FATCount = BootFatX->FATCount;
|
||||
FatInfo.FATSectors =
|
||||
ROUND_UP(FatInfo.NumberOfClusters * (FatInfo.FatType == FATX16 ? 2 : 4), 4096) /
|
||||
FatInfo.BytesPerSector;
|
||||
FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
|
||||
FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
|
||||
FatInfo.Sectors = PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector;
|
||||
if (pFatInfo && *RecognizedFS)
|
||||
{
|
||||
*pFatInfo = FatInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
ExFreePool(BootFatX);
|
||||
}
|
||||
|
||||
DPRINT("VfatHasFileSystem done\n");
|
||||
return Status;
|
||||
}
|
||||
@@ -357,31 +439,65 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
DbgPrint("BytesPerSector: %d\n", DeviceExt->FatInfo.BytesPerSector);
|
||||
DbgPrint("SectorsPerCluster: %d\n", DeviceExt->FatInfo.SectorsPerCluster);
|
||||
DbgPrint("FATCount: %d\n", DeviceExt->FatInfo.FATCount);
|
||||
DbgPrint("FATSectors: %d\n", DeviceExt->FatInfo.FATSectors);
|
||||
DbgPrint("RootStart: %d\n", DeviceExt->FatInfo.rootStart);
|
||||
DbgPrint("DataStart: %d\n", DeviceExt->FatInfo.dataStart);
|
||||
DPRINT("BytesPerSector: %d\n", DeviceExt->FatInfo.BytesPerSector);
|
||||
DPRINT("SectorsPerCluster: %d\n", DeviceExt->FatInfo.SectorsPerCluster);
|
||||
DPRINT("FATCount: %d\n", DeviceExt->FatInfo.FATCount);
|
||||
DPRINT("FATSectors: %d\n", DeviceExt->FatInfo.FATSectors);
|
||||
DPRINT("RootStart: %d\n", DeviceExt->FatInfo.rootStart);
|
||||
DPRINT("DataStart: %d\n", DeviceExt->FatInfo.dataStart);
|
||||
if (DeviceExt->FatInfo.FatType == FAT32)
|
||||
{
|
||||
DbgPrint("RootCluster: %d\n", DeviceExt->FatInfo.RootCluster);
|
||||
DPRINT("RootCluster: %d\n", DeviceExt->FatInfo.RootCluster);
|
||||
}
|
||||
#endif
|
||||
|
||||
DeviceExt->StorageDevice = DeviceToMount;
|
||||
DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
|
||||
DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
|
||||
DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
|
||||
DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
|
||||
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
switch (DeviceExt->FatInfo.FatType)
|
||||
{
|
||||
case FAT12:
|
||||
DeviceExt->GetNextCluster = FAT12GetNextCluster;
|
||||
DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
|
||||
DeviceExt->WriteCluster = FAT12WriteCluster;
|
||||
break;
|
||||
|
||||
DPRINT("FsDeviceObject %lx\n", DeviceObject);
|
||||
case FAT16:
|
||||
case FATX16:
|
||||
DeviceExt->GetNextCluster = FAT16GetNextCluster;
|
||||
DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
|
||||
DeviceExt->WriteCluster = FAT16WriteCluster;
|
||||
break;
|
||||
|
||||
case FAT32:
|
||||
case FATX32:
|
||||
DeviceExt->GetNextCluster = FAT32GetNextCluster;
|
||||
DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
|
||||
DeviceExt->WriteCluster = FAT32WriteCluster;
|
||||
break;
|
||||
}
|
||||
|
||||
if (DeviceExt->FatInfo.FatType == FATX16
|
||||
|| DeviceExt->FatInfo.FatType == FATX32)
|
||||
{
|
||||
DeviceExt->Flags |= VCB_IS_FATX;
|
||||
DeviceExt->GetNextDirEntry = FATXGetNextDirEntry;
|
||||
DeviceExt->BaseDateYear = 2000;
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceExt->GetNextDirEntry = FATGetNextDirEntry;
|
||||
DeviceExt->BaseDateYear = 1980;
|
||||
}
|
||||
|
||||
DeviceExt->StorageDevice = DeviceToMount;
|
||||
DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
|
||||
DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
|
||||
DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
|
||||
DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
|
||||
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
DPRINT("FsDeviceObject %lx\n", DeviceObject);
|
||||
|
||||
DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
|
||||
RtlRosInitUnicodeStringFromLiteral(&NameU, L"\\$$Fat$$");
|
||||
Fcb = vfatNewFCB(&NameU);
|
||||
Fcb = vfatNewFCB(DeviceExt, &NameU);
|
||||
if (Fcb == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
@@ -394,7 +510,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
memset(Ccb, 0, sizeof (VFATCCB));
|
||||
RtlZeroMemory(Ccb, sizeof (VFATCCB));
|
||||
DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
|
||||
DeviceExt->FATFileObject->FsContext = Fcb;
|
||||
DeviceExt->FATFileObject->FsContext2 = Ccb;
|
||||
@@ -403,7 +519,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||
DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
|
||||
Fcb->FileObject = DeviceExt->FATFileObject;
|
||||
|
||||
Fcb->Flags = FCB_IS_FAT;
|
||||
Fcb->Flags |= FCB_IS_FAT;
|
||||
|
||||
Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
|
||||
Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
|
||||
@@ -419,38 +535,17 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||
}
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
DbgPrint ("CcRosInitializeFileCache failed\n");
|
||||
DPRINT1 ("CcRosInitializeFileCache failed\n");
|
||||
goto ByeBye;
|
||||
}
|
||||
DeviceExt->LastAvailableCluster = 2;
|
||||
ExInitializeResourceLite(&DeviceExt->DirResource);
|
||||
ExInitializeResourceLite(&DeviceExt->FatResource);
|
||||
|
||||
switch (DeviceExt->FatInfo.FatType)
|
||||
{
|
||||
case FAT12:
|
||||
DeviceExt->GetNextCluster = FAT12GetNextCluster;
|
||||
DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
|
||||
DeviceExt->WriteCluster = FAT12WriteCluster;
|
||||
break;
|
||||
|
||||
case FAT16:
|
||||
DeviceExt->GetNextCluster = FAT16GetNextCluster;
|
||||
DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
|
||||
DeviceExt->WriteCluster = FAT16WriteCluster;
|
||||
break;
|
||||
|
||||
case FAT32:
|
||||
DeviceExt->GetNextCluster = FAT32GetNextCluster;
|
||||
DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
|
||||
DeviceExt->WriteCluster = FAT32WriteCluster;
|
||||
break;
|
||||
}
|
||||
|
||||
InitializeListHead(&DeviceExt->FcbListHead);
|
||||
RtlRosInitUnicodeStringFromLiteral(&NameU, L"\\$$Volume$$");
|
||||
|
||||
VolumeFcb = vfatNewFCB(&NameU);
|
||||
VolumeFcb = vfatNewFCB(DeviceExt, &NameU);
|
||||
if (VolumeFcb == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
@@ -471,7 +566,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||
|
||||
/* read volume label */
|
||||
ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
|
||||
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
ByeBye:
|
||||
|
||||
@@ -737,4 +832,3 @@ NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
||||
VfatFreeIrpContext(IrpContext);
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: misc.c,v 1.14 2004/11/06 13:44:57 ekohl Exp $
|
||||
/* $Id: misc.c,v 1.15 2004/12/05 16:31:51 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -41,7 +41,7 @@ NTSTATUS VfatLockControl(
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Fail;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/* $Id: rw.c,v 1.71 2004/11/06 13:44:57 ekohl Exp $
|
||||
/* $Id: rw.c,v 1.72 2004/12/05 16:31:51 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -592,7 +592,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
|
||||
BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
|
||||
|
||||
/* fail if file is a directory and no paged read */
|
||||
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
|
||||
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto ByeBye;
|
||||
@@ -821,7 +821,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
|
||||
}
|
||||
|
||||
/* fail if file is a directory and no paged read */
|
||||
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
|
||||
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto ByeBye;
|
||||
@@ -1020,14 +1020,26 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
|
||||
if (!(IrpContext->Irp->Flags & IRP_PAGING_IO) &&
|
||||
!(Fcb->Flags & (FCB_IS_FAT|FCB_IS_VOLUME)))
|
||||
{
|
||||
if(!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||
if(!(*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
// set dates and times
|
||||
KeQuerySystemTime (&SystemTime);
|
||||
FsdSystemTimeToDosDateTime (&SystemTime, &Fcb->entry.UpdateDate,
|
||||
&Fcb->entry.UpdateTime);
|
||||
Fcb->entry.AccessDate = Fcb->entry.UpdateDate;
|
||||
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
|
||||
{
|
||||
FsdSystemTimeToDosDateTime (IrpContext->DeviceExt,
|
||||
&SystemTime, &Fcb->entry.FatX.UpdateDate,
|
||||
&Fcb->entry.FatX.UpdateTime);
|
||||
Fcb->entry.FatX.AccessDate = Fcb->entry.FatX.UpdateDate;
|
||||
Fcb->entry.FatX.AccessTime = Fcb->entry.FatX.UpdateTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
FsdSystemTimeToDosDateTime (IrpContext->DeviceExt,
|
||||
&SystemTime, &Fcb->entry.Fat.UpdateDate,
|
||||
&Fcb->entry.Fat.UpdateTime);
|
||||
Fcb->entry.Fat.AccessDate = Fcb->entry.Fat.UpdateDate;
|
||||
}
|
||||
/* set date and times to dirty */
|
||||
Fcb->Flags |= FCB_IS_DIRTY;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: shutdown.c,v 1.8 2003/10/11 17:51:56 hbirr Exp $
|
||||
/* $Id: shutdown.c,v 1.9 2004/12/05 16:31:51 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -48,9 +48,9 @@ VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
Irp->IoStatus.Status = Status;
|
||||
}
|
||||
/* FIXME: Unmount the logical volume */
|
||||
|
||||
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
|
||||
}
|
||||
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
|
||||
|
||||
/* FIXME: Free all global acquired resources */
|
||||
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: vfat.h,v 1.69 2004/11/06 13:44:57 ekohl Exp $ */
|
||||
/* $Id: vfat.h,v 1.70 2004/12/05 16:31:51 gvg Exp $ */
|
||||
|
||||
#include <ddk/ntifs.h>
|
||||
|
||||
@@ -52,6 +52,16 @@ struct _BootSector32
|
||||
unsigned short Signature1; // 510
|
||||
} __attribute__((packed));
|
||||
|
||||
struct _BootSectorFatX
|
||||
{
|
||||
unsigned char SysType[4]; // 0
|
||||
unsigned long VolumeID; // 4
|
||||
unsigned long SectorsPerCluster; // 8
|
||||
unsigned short FATCount; // 12
|
||||
unsigned long Unknown; // 14
|
||||
unsigned char Unused[4078]; // 18
|
||||
} __attribute__((packed));
|
||||
|
||||
struct _FsInfoSector
|
||||
{
|
||||
unsigned long ExtBootSignature2; // 0
|
||||
@@ -68,10 +78,22 @@ typedef struct _BootSector BootSector;
|
||||
#define VFAT_CASE_LOWER_BASE 8 // base is lower case
|
||||
#define VFAT_CASE_LOWER_EXT 16 // extension is lower case
|
||||
|
||||
#define ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
|
||||
#define ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
|
||||
#define ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
|
||||
#define ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
|
||||
#define ENTRY_DELETED(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))
|
||||
#define ENTRY_VOLUME(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))
|
||||
#define ENTRY_END(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))
|
||||
|
||||
#define FAT_ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
|
||||
#define FAT_ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
|
||||
#define FAT_ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
|
||||
#define FAT_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
|
||||
|
||||
#define FATX_ENTRY_DELETED(DirEntry) ((DirEntry)->FilenameLength == 0xe5)
|
||||
#define FATX_ENTRY_END(DirEntry) ((DirEntry)->FilenameLength == 0xff)
|
||||
#define FATX_ENTRY_LONG(DirEntry) (FALSE)
|
||||
#define FATX_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
|
||||
|
||||
#define FAT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FAT_DIR_ENTRY))
|
||||
#define FATX_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATX_DIR_ENTRY))
|
||||
|
||||
struct _FATDirEntry
|
||||
{
|
||||
@@ -87,7 +109,32 @@ struct _FATDirEntry
|
||||
unsigned long FileSize;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
|
||||
typedef struct _FATDirEntry FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
|
||||
|
||||
struct _FATXDirEntry
|
||||
{
|
||||
unsigned char FilenameLength; // 0
|
||||
unsigned char Attrib; // 1
|
||||
unsigned char Filename[42]; // 2
|
||||
unsigned long FirstCluster; // 44
|
||||
unsigned long FileSize; // 48
|
||||
unsigned short UpdateTime; // 52
|
||||
unsigned short UpdateDate; // 54
|
||||
unsigned short CreationTime; // 56
|
||||
unsigned short CreationDate; // 58
|
||||
unsigned short AccessTime; // 60
|
||||
unsigned short AccessDate; // 62
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _FATXDirEntry FATX_DIR_ENTRY, *PFATX_DIR_ENTRY;
|
||||
|
||||
union _DIR_ENTRY
|
||||
{
|
||||
FAT_DIR_ENTRY Fat;
|
||||
FATX_DIR_ENTRY FatX;
|
||||
};
|
||||
|
||||
typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY;
|
||||
|
||||
struct _slot
|
||||
{
|
||||
@@ -106,12 +153,15 @@ typedef struct _slot slot;
|
||||
|
||||
#define BLOCKSIZE 512
|
||||
|
||||
#define FAT16 (1)
|
||||
#define FAT12 (2)
|
||||
#define FAT32 (3)
|
||||
#define FAT16 (1)
|
||||
#define FAT12 (2)
|
||||
#define FAT32 (3)
|
||||
#define FATX16 (4)
|
||||
#define FATX32 (5)
|
||||
|
||||
#define VCB_VOLUME_LOCKED 0x0001
|
||||
#define VCB_DISMOUNT_PENDING 0x0002
|
||||
#define VCB_IS_FATX 0x0004
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -133,6 +183,7 @@ typedef struct
|
||||
} FATINFO, *PFATINFO;
|
||||
|
||||
struct _VFATFCB;
|
||||
struct _VFAT_DIRENTRY_CONTEXT;
|
||||
|
||||
typedef struct _HASHENTRY
|
||||
{
|
||||
@@ -150,6 +201,8 @@ typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG);
|
||||
typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
|
||||
typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
|
||||
|
||||
typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
|
||||
|
||||
typedef struct DEVICE_EXTENSION
|
||||
{
|
||||
ERESOURCE DirResource;
|
||||
@@ -172,6 +225,11 @@ typedef struct DEVICE_EXTENSION
|
||||
PGET_NEXT_CLUSTER GetNextCluster;
|
||||
PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
|
||||
PWRITE_CLUSTER WriteCluster;
|
||||
|
||||
/* Pointers to functions for manipulating directory entries. */
|
||||
PGET_NEXT_DIR_ENTRY GetNextDirEntry;
|
||||
|
||||
ULONG BaseDateYear;
|
||||
|
||||
LIST_ENTRY VolumeListEntry;
|
||||
} DEVICE_EXTENSION, VCB, *PVCB;
|
||||
@@ -195,7 +253,8 @@ extern PVFAT_GLOBAL_DATA VfatGlobalData;
|
||||
#define FCB_IS_FAT 0x0004
|
||||
#define FCB_IS_PAGE_FILE 0x0008
|
||||
#define FCB_IS_VOLUME 0x0010
|
||||
#define FCB_IS_DIRTY 0x0020
|
||||
#define FCB_IS_DIRTY 0x0020
|
||||
#define FCB_IS_FATX_ENTRY 0x0040
|
||||
|
||||
typedef struct _VFATFCB
|
||||
{
|
||||
@@ -207,7 +266,10 @@ typedef struct _VFATFCB
|
||||
/* end FCB header required by ROS/NT */
|
||||
|
||||
/* directory entry for this file or directory */
|
||||
FATDirEntry entry;
|
||||
DIR_ENTRY entry;
|
||||
|
||||
/* Pointer to attributes in entry */
|
||||
PUCHAR Attributes;
|
||||
|
||||
/* long file name, points into PathNameBuffer */
|
||||
UNICODE_STRING LongNameU;
|
||||
@@ -330,7 +392,7 @@ typedef struct _VFAT_DIRENTRY_CONTEXT
|
||||
{
|
||||
ULONG StartIndex;
|
||||
ULONG DirIndex;
|
||||
FAT_DIR_ENTRY FatDirEntry;
|
||||
DIR_ENTRY DirEntry;
|
||||
UNICODE_STRING LongNameU;
|
||||
UNICODE_STRING ShortNameU;
|
||||
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
|
||||
@@ -379,11 +441,13 @@ NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
|
||||
|
||||
NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
|
||||
|
||||
BOOL FsdDosDateTimeToSystemTime (WORD wDosDate,
|
||||
BOOL FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt,
|
||||
WORD wDosDate,
|
||||
WORD wDosTime,
|
||||
PLARGE_INTEGER SystemTime);
|
||||
|
||||
BOOL FsdSystemTimeToDosDateTime (PLARGE_INTEGER SystemTime,
|
||||
BOOL FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt,
|
||||
PLARGE_INTEGER SystemTime,
|
||||
WORD *pwDosDate,
|
||||
WORD *pwDosTime);
|
||||
|
||||
@@ -451,6 +515,12 @@ NTSTATUS VfatUpdateEntry (PVFATFCB pFcb);
|
||||
|
||||
NTSTATUS VfatDelEntry(PDEVICE_EXTENSION, PVFATFCB);
|
||||
|
||||
BOOLEAN
|
||||
vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||
PVFATFCB pDirFcb,
|
||||
ULONG nbSlots,
|
||||
PULONG start);
|
||||
|
||||
/* -------------------------------------------------------- string.c */
|
||||
|
||||
VOID
|
||||
@@ -529,11 +599,17 @@ WriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||
/* ------------------------------------------------------ direntry.c */
|
||||
|
||||
ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
|
||||
PFAT_DIR_ENTRY pDirEntry);
|
||||
PDIR_ENTRY pDirEntry);
|
||||
|
||||
BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb);
|
||||
|
||||
NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
NTSTATUS FATGetNextDirEntry(PVOID * pContext,
|
||||
PVOID * pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
IN PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
BOOLEAN First);
|
||||
|
||||
NTSTATUS FATXGetNextDirEntry(PVOID * pContext,
|
||||
PVOID * pPage,
|
||||
IN PVFATFCB pDirFcb,
|
||||
IN PVFAT_DIRENTRY_CONTEXT DirContext,
|
||||
@@ -541,7 +617,8 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
|
||||
|
||||
/* ----------------------------------------------------------- fcb.c */
|
||||
|
||||
PVFATFCB vfatNewFCB (PUNICODE_STRING pFileNameU);
|
||||
PVFATFCB vfatNewFCB (PDEVICE_EXTENSION pVCB,
|
||||
PUNICODE_STRING pFileNameU);
|
||||
|
||||
VOID vfatDestroyFCB (PVFATFCB pFCB);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: volume.c,v 1.27 2004/11/06 13:44:57 ekohl Exp $
|
||||
/* $Id: volume.c,v 1.28 2004/12/05 16:31:51 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -6,6 +6,7 @@
|
||||
* PURPOSE: VFAT Filesystem
|
||||
* PROGRAMMER: Jason Filby ([email protected])
|
||||
* Hartmut Birr
|
||||
* Herve Poussineau ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
@@ -42,7 +43,7 @@ FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
|
||||
/* valid entries */
|
||||
FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
|
||||
FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
|
||||
memcpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel, FsVolumeInfo->VolumeLabelLength);
|
||||
RtlCopyMemory(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel, FsVolumeInfo->VolumeLabelLength);
|
||||
|
||||
/* dummy entries */
|
||||
FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
|
||||
@@ -94,7 +95,7 @@ FsdGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
|
||||
|
||||
FsAttributeInfo->FileSystemNameLength = Length;
|
||||
|
||||
memcpy(FsAttributeInfo->FileSystemName, pName, Length );
|
||||
RtlCopyMemory(FsAttributeInfo->FileSystemName, pName, Length );
|
||||
|
||||
DPRINT("Finished FsdGetFsAttributeInformation()\n");
|
||||
|
||||
@@ -162,9 +163,140 @@ static NTSTATUS
|
||||
FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
|
||||
PFILE_FS_LABEL_INFORMATION FsLabelInfo)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
PVOID Context = NULL;
|
||||
ULONG DirIndex = 0;
|
||||
PDIR_ENTRY Entry;
|
||||
PVFATFCB pRootFcb;
|
||||
LARGE_INTEGER FileOffset;
|
||||
BOOL LabelFound = FALSE;
|
||||
DIR_ENTRY VolumeLabelDirEntry;
|
||||
ULONG VolumeLabelDirIndex;
|
||||
ULONG LabelLen;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
OEM_STRING StringO;
|
||||
UNICODE_STRING StringW;
|
||||
CHAR cString[43];
|
||||
ULONG SizeDirEntry;
|
||||
ULONG EntriesPerPage;
|
||||
|
||||
DPRINT("FsdSetFsLabelInformation()\n");
|
||||
|
||||
return(STATUS_NOT_IMPLEMENTED);
|
||||
|
||||
DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (sizeof(DeviceObject->Vpb->VolumeLabel) < FsLabelInfo->VolumeLabelLength)
|
||||
{
|
||||
CHECKPOINT;
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
if (FsLabelInfo->VolumeLabelLength / sizeof(WCHAR) > 42)
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
SizeDirEntry = sizeof(FATX_DIR_ENTRY);
|
||||
EntriesPerPage = FATX_ENTRIES_PER_PAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FsLabelInfo->VolumeLabelLength / sizeof(WCHAR) > 11)
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
SizeDirEntry = sizeof(FAT_DIR_ENTRY);
|
||||
EntriesPerPage = FAT_ENTRIES_PER_PAGE;
|
||||
}
|
||||
|
||||
/* Create Volume label dir entry */
|
||||
LabelLen = FsLabelInfo->VolumeLabelLength / sizeof(WCHAR);
|
||||
RtlZeroMemory(&VolumeLabelDirEntry, SizeDirEntry);
|
||||
StringW.Buffer = FsLabelInfo->VolumeLabel;
|
||||
StringW.Length = StringW.MaximumLength = FsLabelInfo->VolumeLabelLength;
|
||||
StringO.Buffer = cString;
|
||||
StringO.Length = 0;
|
||||
StringO.MaximumLength = 42;
|
||||
Status = RtlUnicodeStringToOemString(&StringO, &StringW, FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
if (DeviceExt->Flags & VCB_IS_FATX)
|
||||
{
|
||||
RtlCopyMemory(VolumeLabelDirEntry.FatX.Filename, cString, LabelLen);
|
||||
memset(&VolumeLabelDirEntry.FatX.Filename[LabelLen], ' ', 42 - LabelLen);
|
||||
VolumeLabelDirEntry.FatX.Attrib = 0x08;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(VolumeLabelDirEntry.Fat.Filename, cString, LabelLen);
|
||||
memset(&VolumeLabelDirEntry.Fat.Filename[LabelLen], ' ', 11 - LabelLen);
|
||||
VolumeLabelDirEntry.Fat.Attrib = 0x08;
|
||||
}
|
||||
|
||||
pRootFcb = vfatOpenRootFCB(DeviceExt);
|
||||
|
||||
/* Search existing volume entry on disk */
|
||||
FileOffset.QuadPart = 0;
|
||||
if (CcMapData(pRootFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
if (ENTRY_VOLUME(DeviceExt, Entry))
|
||||
{
|
||||
/* Update entry */
|
||||
LabelFound = TRUE;
|
||||
RtlCopyMemory(Entry, &VolumeLabelDirEntry, SizeDirEntry);
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
if (ENTRY_END(DeviceExt, Entry))
|
||||
{
|
||||
break;
|
||||
}
|
||||
DirIndex++;
|
||||
Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
|
||||
if ((DirIndex % EntriesPerPage) == 0)
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
FileOffset.u.LowPart += PAGE_SIZE;
|
||||
if (!CcMapData(pRootFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
|
||||
{
|
||||
Context = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Context)
|
||||
{
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
}
|
||||
if (!LabelFound)
|
||||
{
|
||||
/* Add new entry for label */
|
||||
if (!vfatFindDirSpace(DeviceExt, pRootFcb, 1, &VolumeLabelDirIndex))
|
||||
Status = STATUS_DISK_FULL;
|
||||
else
|
||||
{
|
||||
FileOffset.u.HighPart = 0;
|
||||
FileOffset.u.LowPart = VolumeLabelDirIndex * SizeDirEntry;
|
||||
CcMapData(pRootFcb->FileObject, &FileOffset, SizeDirEntry,
|
||||
TRUE, &Context, (PVOID*)&Entry);
|
||||
RtlCopyMemory(Entry, &VolumeLabelDirEntry, SizeDirEntry);
|
||||
CcSetDirtyPinnedData(Context, NULL);
|
||||
CcUnpinData(Context);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
vfatReleaseFCB(DeviceExt, pRootFcb);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Update volume label in memory */
|
||||
DeviceObject->Vpb->VolumeLabelLength = FsLabelInfo->VolumeLabelLength;
|
||||
RtlCopyMemory(DeviceObject->Vpb->VolumeLabel, FsLabelInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabelLength);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +387,7 @@ NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
|
||||
/* PRECONDITION */
|
||||
ASSERT(IrpContext);
|
||||
|
||||
DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
|
||||
DPRINT ("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
|
||||
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
|
||||
@@ -267,9 +399,9 @@ NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
|
||||
BufferLength = Stack->Parameters.SetVolume.Length;
|
||||
SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
DPRINT1("FsInformationClass %d\n", FsInformationClass);
|
||||
DPRINT1("BufferLength %d\n", BufferLength);
|
||||
DPRINT1("SystemBuffer %x\n", SystemBuffer);
|
||||
DPRINT ("FsInformationClass %d\n", FsInformationClass);
|
||||
DPRINT ("BufferLength %d\n", BufferLength);
|
||||
DPRINT ("SystemBuffer %x\n", SystemBuffer);
|
||||
|
||||
switch(FsInformationClass)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user