예제 #1
0
 /// <inheritdoc />
 /// <summary>
 /// Sets the next cluster.
 /// </summary>
 /// <param name="cluster">The cluster.</param>
 /// <param name="nextCluster">The next cluster.</param>
 public void SetNextCluster(Cluster cluster, Cluster nextCluster)
 {
     lock (_fatLock)
     {
         // the only point is to avoid writing to virtual hard disk, which may be sparse and handle sparseness more or less efficiently...
         var fatPage       = GetFatPage(cluster);
         var clusterIndex  = (int)(cluster.Value % ClustersPerFatPage);
         var b             = LittleEndian.GetBytes((UInt32)nextCluster.Value);
         var fatPageOffset = clusterIndex * sizeof(UInt32);
         if (b[0] == fatPage[fatPageOffset] && b[1] == fatPage[fatPageOffset + 1] && b[2] == fatPage[fatPageOffset + 2] && b[3] == fatPage[fatPageOffset + 3])
         {
             return;
         }
         Buffer.BlockCopy(b, 0, fatPage, fatPageOffset, sizeof(Int32));
         _fatPageDirty = true;
         if (!_options.HasAny(ExFatOptions.DelayWrite))
         {
             FlushFatPage();
         }
     }
 }
예제 #2
0
        private void UpdateEntry(ExFatFilesystemEntry entry, FileAccess fileAccess, DataDescriptor dataDescriptor)
        {
            if (entry?.MetaEntry == null)
            {
                return;
            }

            DateTimeOffset?now  = null;
            var            file = (FileExFatDirectoryEntry)entry.MetaEntry.Primary;

            // if file was open for reading and the flag is set, the entry is updated
            if (fileAccess.HasAny(FileAccess.Read) && _options.HasAny(ExFatOptions.UpdateLastAccessTime))
            {
                now = DateTimeOffset.Now;
                file.LastAccessDateTimeOffset.Value = now.Value;
            }

            // when it was open for writing, its characteristics may have changed, so we update them
            if (fileAccess.HasAny(FileAccess.Write))
            {
                now = now ?? DateTimeOffset.Now;
                file.FileAttributes.Value         |= ExFatFileAttributes.Archive;
                file.LastWriteDateTimeOffset.Value = now.Value;
                var stream = entry.MetaEntry.SecondaryStreamExtension;
                if (dataDescriptor.Contiguous)
                {
                    stream.GeneralSecondaryFlags.Value |= ExFatGeneralSecondaryFlags.NoFatChain;
                }
                else
                {
                    stream.GeneralSecondaryFlags.Value &= ~ExFatGeneralSecondaryFlags.NoFatChain;
                }
                stream.FirstCluster.Value    = (UInt32)dataDescriptor.FirstCluster.Value;
                stream.ValidDataLength.Value = dataDescriptor.LogicalLength;
                stream.DataLength.Value      = dataDescriptor.PhysicalLength;
            }

            // now has value only if it was used before, so we spare a flag :)
            if (now.HasValue)
            {
                Update(entry);
            }
        }