dir.c

来自「这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统」· C语言 代码 · 共 513 行 · 第 1/2 页

C
513
字号
/*
 * COPYRIGHT:        See COPYING in the top level directory
 * PROJECT:          ReactOS kernel
 * FILE:             drivers/fs/vfat/dir.c
 * PURPOSE:          VFAT Filesystem : directory control
 * UPDATE HISTORY:
     19-12-1998 : created

*/

#define NDEBUG
#include "vfat.h"


// function like DosDateTimeToFileTime
BOOLEAN
FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime)
{
  PDOSTIME pdtime = (PDOSTIME) &DosTime;
  PDOSDATE pddate = (PDOSDATE) &DosDate;
  TIME_FIELDS TimeFields;
  LARGE_INTEGER LocalTime;

  if (SystemTime == NULL)
    return FALSE;

  TimeFields.Milliseconds = 0;
  TimeFields.Second = pdtime->Second * 2;
  TimeFields.Minute = pdtime->Minute;
  TimeFields.Hour = pdtime->Hour;

  TimeFields.Day = pddate->Day;
  TimeFields.Month = pddate->Month;
  TimeFields.Year = (CSHORT)(DeviceExt->BaseDateYear + pddate->Year);

  RtlTimeFieldsToTime (&TimeFields, &LocalTime);
  ExLocalTimeToSystemTime(&LocalTime, SystemTime);

  return TRUE;
}

// function like FileTimeToDosDateTime
BOOLEAN
FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, USHORT *pDosDate, USHORT *pDosTime)
{
  PDOSTIME pdtime = (PDOSTIME) pDosTime;
  PDOSDATE pddate = (PDOSDATE) pDosDate;
  TIME_FIELDS TimeFields;
  LARGE_INTEGER LocalTime;

  if (SystemTime == NULL)
    return FALSE;

  ExSystemTimeToLocalTime (SystemTime, &LocalTime);
  RtlTimeToTimeFields (&LocalTime, &TimeFields);

  if (pdtime)
    {
      pdtime->Second = TimeFields.Second / 2;
      pdtime->Minute = TimeFields.Minute;
      pdtime->Hour = TimeFields.Hour;
    }

  if (pddate)
    {
      pddate->Day = TimeFields.Day;
      pddate->Month = TimeFields.Month;
      pddate->Year = (USHORT) (TimeFields.Year - DeviceExt->BaseDateYear);
    }

  return TRUE;
}

#define ULONG_ROUND_UP(x)   ROUND_UP((x), (sizeof(ULONG)))

static NTSTATUS
VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
			    PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength)
{
  if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
    return STATUS_BUFFER_OVERFLOW;
  pInfo->FileNameLength = DirContext->LongNameU.Length;
  pInfo->NextEntryOffset =
    ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
  RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
  return STATUS_SUCCESS;
}

static NTSTATUS
VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
				 PDEVICE_EXTENSION DeviceExt,
				 PFILE_DIRECTORY_INFORMATION pInfo,
				 ULONG BufferLength)
{
  if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
    return STATUS_BUFFER_OVERFLOW;
  pInfo->FileNameLength = DirContext->LongNameU.Length;
  pInfo->NextEntryOffset =
    ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
  RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
//      pInfo->FileIndex=;
  if (DeviceExt->Flags & VCB_IS_FATX)
  {
    FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
			      DirContext->DirEntry.FatX.CreationTime,
			      &pInfo->CreationTime);
    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;
    if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
      {
        pInfo->EndOfFile.QuadPart = 0;
        pInfo->AllocationSize.QuadPart = 0;
      }
    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
  {
    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 = 0;
        pInfo->AllocationSize.QuadPart = 0;
      }
    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;
}

static NTSTATUS
VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
				     PDEVICE_EXTENSION DeviceExt,
				     PFILE_FULL_DIR_INFORMATION pInfo,
				     ULONG BufferLength)
{
  if ((sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
    return STATUS_BUFFER_OVERFLOW;
  pInfo->FileNameLength = DirContext->LongNameU.Length;
  pInfo->NextEntryOffset =
    ULONG_ROUND_UP (sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length);
  RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
//      pInfo->FileIndex=;
  if (DeviceExt->Flags & VCB_IS_FATX)
  {
    FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
			      DirContext->DirEntry.FatX.CreationTime,
			      &pInfo->CreationTime);
    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->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;
}

static NTSTATUS
VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
			    PDEVICE_EXTENSION DeviceExt,
			    PFILE_BOTH_DIR_INFORMATION pInfo,
			    ULONG BufferLength)
{
  if ((sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
    return STATUS_BUFFER_OVERFLOW;

  if (DeviceExt->Flags & VCB_IS_FATX)
  {
    pInfo->FileNameLength = DirContext->LongNameU.Length;
    RtlCopyMemory(pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
    pInfo->NextEntryOffset =
      ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_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 (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;
    if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
      {
        pInfo->EndOfFile.QuadPart = 0;
        pInfo->AllocationSize.QuadPart = 0;
      }
    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
  {

⌨️ 快捷键说明

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