private void PopulateLargeFile(FileEnumeratorParameters parameters, INode node, bool hasFileReadPermissions)
        {
            IEnumerable <byte[]> fileChunks = node.GetBytes();

            _timingMetrics.Start(TimingMetric.FileHashing);
            this.Sha256 = Hash.ByteEnumerable.Sha256(fileChunks);
            if (hasFileReadPermissions)
            {
                this._peData = PeDataObject.TryGetPeDataObject(FullPath);
                if (_peData != null)
                {
                    this.SHA1 = _peData.SHA1Hash;
                    this.MD5  = _peData.MD5Hash;
                }
                else
                {
                    this.SHA1 = Hash.ByteEnumerable.Sha1(fileChunks);
                    this.MD5  = Hash.ByteEnumerable.MD5(fileChunks);
                }
            }
            _timingMetrics.Stop(TimingMetric.FileHashing);

            if (_peData != null)
            {
                this._authenticode = AuthenticodeData.GetAuthenticodeData(this._peData.Certificate);
            }

            CancellationHelper.ThrowIfCancelled();

            if (hasFileReadPermissions)
            {
                PopulateFileInfoProperties(FullPath);
                PopulateShellFileInfo(FullPath);
                CancellationHelper.ThrowIfCancelled();
            }

            if (hasFileReadPermissions)
            {
                Rules compiledRules = GetCompiledYaraRules(parameters.YaraParameters);
                if (compiledRules != null)
                {
                    _timingMetrics.Start(TimingMetric.YaraScanning);
                    this._yaraRulesMatched = YaraHelper.ScanFile(FullPath, compiledRules);
                    _timingMetrics.Stop(TimingMetric.YaraScanning);
                    compiledRules = null;
                }

                CancellationHelper.ThrowIfCancelled();
            }

            if (parameters.CalculateEntropy)             // Should we calculate entropy on really large files?
            {
                _timingMetrics.Start(TimingMetric.CalculatingEntropy);
                this.Entropy = EntropyHelper.CalculateFileEntropy(fileChunks, this.Length);
                _timingMetrics.Stop(TimingMetric.CalculatingEntropy);
                CancellationHelper.ThrowIfCancelled();
            }
        }
        public void PopulateFileProperties(FileEnumeratorParameters parameters, char driveLetter, INode node, TimingMetrics timingMetrics)
        {
            if (parameters == null)
            {
                return;
            }
            if (node == null)
            {
                return;
            }

            _timingMetrics = timingMetrics;

            CancellationHelper.SetCancellationToken(parameters.CancelToken);
            CancellationHelper.ThrowIfCancelled();

            _timingMetrics.Start(TimingMetric.MiscFileProperties);

            MFTNumber      = node.MFTRecordNumber;
            SequenceNumber = node.SequenceNumber;

            DriveLetter = driveLetter;
            FileName    = node.Name;

            MftTimeAccessed    = node.LastAccessTime;
            MftTimeCreation    = node.CreationTime;
            MftTimeModified    = node.LastChangeTime;
            MftTimeMftModified = node.TimeMftModified;

            DirectoryLocation = Path.GetDirectoryName(node.FullName);
            Extension         = Path.GetExtension(FileName);
            FullPath          = node.FullName;

            this.Length = node.Size;

            CancellationHelper.ThrowIfCancelled();

            if (this.Length == 0)             //Workaround for hard links
            {
                if (File.Exists(FullPath))
                {
                    long length = new FileInfo(FullPath).Length;
                    if (length > 0)
                    {
                        this.Length = (ulong)length;
                        node.Size   = this.Length;
                    }
                }
            }

            bool hasFileReadPermissions = true;
            var  fileIOPermission       = new FileIOPermission(FileIOPermissionAccess.Read, AccessControlActions.View, FullPath);

            if (fileIOPermission.AllFiles == FileIOPermissionAccess.Read)
            {
                hasFileReadPermissions = true;
            }

            _timingMetrics.Stop(TimingMetric.MiscFileProperties);

            if (this.Length != 0)
            {
                // Some entries in the MFT are greater than int.MaxValue !! That or the size is corrupt. Either way, we handle that here.
                if (this.Length > MaxLength)                 //(int.MaxValue - 1))
                {
                    PopulateLargeFile(parameters, node, hasFileReadPermissions);
                }
                else
                {
                    PopulateSmallFile(parameters, node, hasFileReadPermissions);
                }
            }
            else
            {
                this.Sha256 = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";                 // SHA256 hash of a null or zero-length input
                this.SHA1   = "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709";
                this.MD5    = "D41D8CD98F00B204E9800998ECF8427E";
            }

            _timingMetrics.Start(TimingMetric.MiscFileProperties);

            PopulateIsTrusted();
            CancellationHelper.ThrowIfCancelled();

            this._attributes = new Attributes(node);
            _timingMetrics.Stop(TimingMetric.MiscFileProperties);
            CancellationHelper.ThrowIfCancelled();
        }