Exemplo n.º 1
0
Arquivo: fat.c Projeto: RPG-7/reactos
/*
 * FUNCTION: Retrieve the next FAT16 cluster from the FAT table
 */
NTSTATUS
FAT16GetNextCluster(
    PDEVICE_EXTENSION DeviceExt,
    ULONG CurrentCluster,
    PULONG NextCluster)
{
    PVOID BaseAddress;
    ULONG FATOffset;
    ULONG ChunkSize;
    PVOID Context;
    LARGE_INTEGER Offset;

    ChunkSize = CACHEPAGESIZE(DeviceExt);
    FATOffset = CurrentCluster * 2;
    Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
    if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, MAP_WAIT, &Context, &BaseAddress))
    {
         return STATUS_UNSUCCESSFUL;
    }

    CurrentCluster = *((PUSHORT)((char*)BaseAddress + (FATOffset % ChunkSize)));
    if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
        CurrentCluster = 0xffffffff;
    CcUnpinData(Context);
    *NextCluster = CurrentCluster;
    return STATUS_SUCCESS;
}
Exemplo n.º 2
0
NTSTATUS
FAT32FindAndMarkAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
/*
 * FUNCTION: Finds the first available cluster in a FAT32 table
 */
{
  ULONG FatLength;
  ULONG StartCluster;
  ULONG i, j;
  PVOID BaseAddress;
  ULONG ChunkSize;
  PVOID Context;
  LARGE_INTEGER Offset;
  PULONG Block;
  PULONG BlockEnd;

  ChunkSize = CACHEPAGESIZE(DeviceExt);
  FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);
  *Cluster = 0;
  StartCluster = DeviceExt->LastAvailableCluster;

  for (j = 0; j < 2; j++)
  {
    for (i = StartCluster; i < FatLength;)
    {
      Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
      if(!CcPinRead(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
      {
        DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
        return STATUS_UNSUCCESSFUL;
      }
      Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
      BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);

      /* Now process the whole block */
      while (Block < BlockEnd && i < FatLength)
      {
        if ((*Block & 0x0fffffff) == 0)
        {
          DPRINT("Found available cluster 0x%x\n", i);
          DeviceExt->LastAvailableCluster = *Cluster = i;
          *Block = 0x0fffffff;
          CcSetDirtyPinnedData(Context, NULL);
          CcUnpinData(Context);
          if (DeviceExt->AvailableClustersValid)
            InterlockedDecrement((PLONG)&DeviceExt->AvailableClusters);
          return(STATUS_SUCCESS);
        }

        Block++;
        i++;
      }

      CcUnpinData(Context);
    }
    FatLength = StartCluster;
    StartCluster = 2;
  }
  return (STATUS_DISK_FULL);
}
Exemplo n.º 3
0
NTSTATUS
FAT32GetNextCluster(PDEVICE_EXTENSION DeviceExt,
		    ULONG CurrentCluster,
		    PULONG NextCluster)
/*
 * FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical
 *           disk read
 */
{
  PVOID BaseAddress;
  ULONG FATOffset;
  ULONG ChunkSize;
  PVOID Context;
  LARGE_INTEGER Offset;

  ChunkSize = CACHEPAGESIZE(DeviceExt);
  FATOffset = CurrentCluster * sizeof(ULONG);
  Offset.QuadPart = ROUND_DOWN(FATOffset, ChunkSize);
  if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
  {
    return STATUS_UNSUCCESSFUL;
  }
  CurrentCluster = (*(PULONG)((char*)BaseAddress + (FATOffset % ChunkSize))) & 0x0fffffff;
  if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
    CurrentCluster = 0xffffffff;
  CcUnpinData(Context);
  *NextCluster = CurrentCluster;
  return (STATUS_SUCCESS);
}
Exemplo n.º 4
0
static NTSTATUS
FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
 * FUNCTION: Counts free clusters in a FAT32 table
 */
{
  PULONG Block;
  PULONG BlockEnd;
  PVOID BaseAddress = NULL;
  ULONG ulCount = 0;
  ULONG i;
  ULONG ChunkSize;
  PVOID Context = NULL;
  LARGE_INTEGER Offset;
  ULONG FatLength;

  ChunkSize = CACHEPAGESIZE(DeviceExt);
  FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);

  for (i = 2; i < FatLength; )
  {
    Offset.QuadPart = ROUND_DOWN(i * 4, ChunkSize);
    if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
    {
      DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
      return STATUS_UNSUCCESSFUL;
    }
    Block = (PULONG)((ULONG_PTR)BaseAddress + (i * 4) % ChunkSize);
    BlockEnd = (PULONG)((ULONG_PTR)BaseAddress + ChunkSize);

    /* Now process the whole block */
    while (Block < BlockEnd && i < FatLength)
    {
      if ((*Block & 0x0fffffff) == 0)
        ulCount++;
      Block++;
      i++;
    }

    CcUnpinData(Context);
  }

  DeviceExt->AvailableClusters = ulCount;
  DeviceExt->AvailableClustersValid = TRUE;

  return(STATUS_SUCCESS);
}
Exemplo n.º 5
0
Arquivo: fat.c Projeto: RPG-7/reactos
/*
 * FUNCTION: Counts free clusters in a FAT16 table
 */
static
NTSTATUS
FAT16CountAvailableClusters(
    PDEVICE_EXTENSION DeviceExt)
{
    PUSHORT Block;
    PUSHORT BlockEnd;
    PVOID BaseAddress = NULL;
    ULONG ulCount = 0;
    ULONG i;
    ULONG ChunkSize;
    PVOID Context = NULL;
    LARGE_INTEGER Offset;
    ULONG FatLength;

    ChunkSize = CACHEPAGESIZE(DeviceExt);
    FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2);

    for (i = 2; i < FatLength; )
    {
        Offset.QuadPart = ROUND_DOWN(i * 2, ChunkSize);
        if (!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
        {
            return STATUS_UNSUCCESSFUL;
        }
        Block = (PUSHORT)((ULONG_PTR)BaseAddress + (i * 2) % ChunkSize);
        BlockEnd = (PUSHORT)((ULONG_PTR)BaseAddress + ChunkSize);

        /* Now process the whole block */
        while (Block < BlockEnd && i < FatLength)
        {
            if (*Block == 0)
                ulCount++;
            Block++;
            i++;
        }

        CcUnpinData(Context);
    }

    DeviceExt->AvailableClusters = ulCount;
    DeviceExt->AvailableClustersValid = TRUE;

    return STATUS_SUCCESS;
}