2009-09-29 10:08:43 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS FAT file system driver
|
2009-10-20 10:12:49 +00:00
|
|
|
* LICENSE: GNU GPLv3 as published by the Free Software Foundation
|
2009-09-29 10:08:43 +00:00
|
|
|
* FILE: drivers/filesystems/fastfat/fullfat.c
|
|
|
|
* PURPOSE: FullFAT integration routines
|
|
|
|
* PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include "fastfat.h"
|
|
|
|
|
|
|
|
/* GLOBALS ******************************************************************/
|
|
|
|
|
|
|
|
#define TAG_FULLFAT 'FLUF'
|
|
|
|
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
|
|
|
|
VOID *
|
|
|
|
FF_Malloc(FF_T_UINT32 allocSize)
|
|
|
|
{
|
|
|
|
return ExAllocatePoolWithTag(PagedPool, allocSize, TAG_FULLFAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FF_Free(VOID *pBuffer)
|
|
|
|
{
|
|
|
|
return ExFreePoolWithTag(pBuffer, TAG_FULLFAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
FF_T_SINT32
|
|
|
|
FatWriteBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam)
|
|
|
|
{
|
|
|
|
DPRINT1("FatWriteBlocks %p %d %d %p\n", pBuffer, SectorAddress, Count, pParam);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
FF_T_SINT32
|
|
|
|
FatReadBlocks(FF_T_UINT8 *DestBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam)
|
|
|
|
{
|
|
|
|
LARGE_INTEGER Offset;
|
2009-10-02 10:49:57 +00:00
|
|
|
//PVOID Buffer;
|
2009-09-29 10:08:43 +00:00
|
|
|
PVCB Vcb = (PVCB)pParam;
|
2009-10-02 10:49:57 +00:00
|
|
|
//PBCB Bcb;
|
2009-09-29 10:08:43 +00:00
|
|
|
ULONG SectorSize = 512; // FIXME: hardcoding 512 is bad
|
2009-10-02 10:49:57 +00:00
|
|
|
IO_STATUS_BLOCK IoSb;
|
2009-09-29 10:08:43 +00:00
|
|
|
|
2009-10-01 16:08:11 +00:00
|
|
|
DPRINT("FatReadBlocks %p %d %d %p\n", DestBuffer, SectorAddress, Count, pParam);
|
2009-09-29 10:08:43 +00:00
|
|
|
|
|
|
|
/* Calculate the offset */
|
|
|
|
Offset.QuadPart = Int32x32To64(SectorAddress, SectorSize);
|
2009-10-02 10:49:57 +00:00
|
|
|
#if 0
|
2009-09-29 10:08:43 +00:00
|
|
|
if (!CcMapData(Vcb->StreamFileObject,
|
|
|
|
&Offset,
|
|
|
|
Count * SectorSize,
|
|
|
|
TRUE,
|
|
|
|
&Bcb,
|
|
|
|
&Buffer))
|
|
|
|
{
|
2009-10-01 13:21:28 +00:00
|
|
|
ASSERT(FALSE);
|
2009-09-29 10:08:43 +00:00
|
|
|
/* Mapping failed */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy data to the buffer */
|
|
|
|
RtlCopyMemory(DestBuffer, Buffer, Count * SectorSize);
|
|
|
|
|
|
|
|
/* Unpin unneeded data */
|
|
|
|
CcUnpinData(Bcb);
|
2009-10-02 10:49:57 +00:00
|
|
|
#else
|
|
|
|
CcCopyRead(Vcb->StreamFileObject, &Offset, Count * SectorSize, TRUE, DestBuffer, &IoSb);
|
|
|
|
#endif
|
2009-09-29 10:08:43 +00:00
|
|
|
|
|
|
|
/* Return amount of read data in sectors */
|
|
|
|
return Count;
|
|
|
|
}
|
|
|
|
|
2009-10-17 13:18:29 +00:00
|
|
|
FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR *pError)
|
|
|
|
{
|
|
|
|
OEM_STRING AnsiName;
|
|
|
|
CHAR AnsiNameBuf[512];
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Convert the name to ANSI */
|
|
|
|
AnsiName.Buffer = AnsiNameBuf;
|
|
|
|
AnsiName.Length = 0;
|
|
|
|
AnsiName.MaximumLength = sizeof(AnsiNameBuf);
|
|
|
|
RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf));
|
|
|
|
Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, pathW, FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT1("Opening '%s'\n", AnsiName.Buffer);
|
|
|
|
|
|
|
|
/* Call FullFAT's handler */
|
|
|
|
return FF_Open(pIoman, AnsiName.Buffer, Mode, pError);
|
|
|
|
}
|
|
|
|
|
2009-10-20 10:02:27 +00:00
|
|
|
FORCEINLINE
|
|
|
|
VOID
|
|
|
|
FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime,
|
|
|
|
IN PFAT_DATETIME FatDateTime,
|
|
|
|
IN UCHAR TenMs OPTIONAL)
|
|
|
|
{
|
|
|
|
TIME_FIELDS TimeFields;
|
|
|
|
|
|
|
|
/* Setup time fields */
|
|
|
|
TimeFields.Year = FatDateTime->Date.Year + 1980;
|
|
|
|
TimeFields.Month = FatDateTime->Date.Month;
|
|
|
|
TimeFields.Day = FatDateTime->Date.Day;
|
|
|
|
TimeFields.Hour = FatDateTime->Time.Hour;
|
|
|
|
TimeFields.Minute = FatDateTime->Time.Minute;
|
|
|
|
TimeFields.Second = (FatDateTime->Time.DoubleSeconds << 1);
|
|
|
|
|
|
|
|
/* Adjust up to 10 milliseconds
|
|
|
|
* if the parameter was supplied
|
|
|
|
*/
|
|
|
|
if (ARGUMENT_PRESENT(TenMs))
|
|
|
|
{
|
|
|
|
TimeFields.Second += TenMs / 100;
|
|
|
|
TimeFields.Milliseconds = (TenMs % 100) * 10;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TimeFields.Milliseconds = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fix seconds value that might get beyoud the bound */
|
|
|
|
if (TimeFields.Second > 59) TimeFields.Second = 0;
|
|
|
|
|
|
|
|
/* Perform ceonversion to system time if possible */
|
|
|
|
if (RtlTimeFieldsToTime(&TimeFields, SystemTime))
|
|
|
|
{
|
|
|
|
/* Convert to system time */
|
|
|
|
ExLocalTimeToSystemTime(SystemTime, SystemTime);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Set to default time if conversion failed */
|
|
|
|
*SystemTime = FatGlobalData.DefaultFileTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Make it a helper around FullFAT library
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes,
|
|
|
|
IN PDIR_ENTRY Dirent)
|
|
|
|
{
|
|
|
|
/* Convert LastWriteTime */
|
|
|
|
FatDateTimeToSystemTime(&FileTimes[FileLastWriteTime],
|
|
|
|
&Dirent->LastWriteDateTime,
|
|
|
|
0);
|
|
|
|
/* All other time fileds are valid (according to MS)
|
|
|
|
* only if Win31 compatability mode is set.
|
|
|
|
*/
|
|
|
|
if (FatGlobalData.Win31FileSystem)
|
|
|
|
{
|
|
|
|
/* We can avoid calling conversion routine
|
|
|
|
* if time in dirent is 0 or equals to already
|
|
|
|
* known time (LastWriteTime).
|
|
|
|
*/
|
|
|
|
if (Dirent->CreationDateTime.Value == 0)
|
|
|
|
{
|
|
|
|
/* Set it to default time */
|
|
|
|
FileTimes[FileCreationTime] = FatGlobalData.DefaultFileTime;
|
|
|
|
}
|
|
|
|
else if (Dirent->CreationDateTime.Value
|
|
|
|
== Dirent->LastWriteDateTime.Value)
|
|
|
|
{
|
|
|
|
/* Assign the already known time */
|
|
|
|
FileTimes[FileCreationTime] = FileTimes[FileLastWriteTime];
|
|
|
|
/* Adjust milliseconds from extra dirent field */
|
|
|
|
FileTimes[FileCreationTime].QuadPart
|
|
|
|
+= (ULONG) Dirent->CreationTimeTenMs * 100000;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Perform conversion */
|
|
|
|
FatDateTimeToSystemTime(&FileTimes[FileCreationTime],
|
|
|
|
&Dirent->CreationDateTime,
|
|
|
|
Dirent->CreationTimeTenMs);
|
|
|
|
}
|
|
|
|
if (Dirent->LastAccessDate.Value == 0)
|
|
|
|
{
|
|
|
|
/* Set it to default time */
|
|
|
|
FileTimes[FileLastAccessTime] = FatGlobalData.DefaultFileTime;
|
|
|
|
}
|
|
|
|
else if (Dirent->LastAccessDate.Value
|
|
|
|
== Dirent->LastWriteDateTime.Date.Value)
|
|
|
|
{
|
|
|
|
/* Assign the already known time */
|
|
|
|
FileTimes[FileLastAccessTime] = FileTimes[FileLastWriteTime];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Perform conversion */
|
|
|
|
FAT_DATETIME LastAccessDateTime;
|
|
|
|
|
|
|
|
LastAccessDateTime.Date.Value = Dirent->LastAccessDate.Value;
|
|
|
|
LastAccessDateTime.Time.Value = 0;
|
|
|
|
FatDateTimeToSystemTime(&FileTimes[FileLastAccessTime],
|
|
|
|
&LastAccessDateTime,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-29 10:08:43 +00:00
|
|
|
/* EOF */
|