internal HResult GetDirectoryEnumerationCallback()

in simpleProviderManaged/SimpleProvider.cs [361:435]


        internal HResult GetDirectoryEnumerationCallback(
            int commandId,
            Guid enumerationId,
            string filterFileName,
            bool restartScan,
            IDirectoryEnumerationResults enumResult)
        {
            Log.Information("----> GetDirectoryEnumerationCallback filterFileName [{Filter}]", filterFileName);

            // Find the requested enumeration.  It should have been put there by StartDirectoryEnumeration.
            if (!this.activeEnumerations.TryGetValue(enumerationId, out ActiveEnumeration enumeration))
            {
                Log.Fatal("      GetDirectoryEnumerationCallback {Result}", HResult.InternalError);
                return HResult.InternalError;
            }

            if (restartScan)
            {
                // The caller is restarting the enumeration, so we reset our ActiveEnumeration to the
                // first item that matches filterFileName.  This also saves the value of filterFileName
                // into the ActiveEnumeration, overwriting its previous value.
                enumeration.RestartEnumeration(filterFileName);
            }
            else
            {
                // The caller is continuing a previous enumeration, or this is the first enumeration
                // so our ActiveEnumeration is already at the beginning.  TrySaveFilterString()
                // will save filterFileName if it hasn't already been saved (only if the enumeration
                // is restarting do we need to re-save filterFileName).
                enumeration.TrySaveFilterString(filterFileName);
            }

            HResult hr = HResult.Ok;

            while (enumeration.IsCurrentValid)
            {
                ProjectedFileInfo fileInfo = enumeration.Current;

                if (!TryGetTargetIfReparsePoint(fileInfo, fileInfo.FullName, out string targetPath))
                {
                    hr = HResult.InternalError;
                    break;
                }

                // A provider adds entries to the enumeration buffer until it runs out, or until adding
                // an entry fails. If adding an entry fails, the provider remembers the entry it couldn't
                // add. ProjFS will call the GetDirectoryEnumerationCallback again, and the provider
                // must resume adding entries, starting at the last one it tried to add. SimpleProvider
                // remembers the entry it couldn't add simply by not advancing its ActiveEnumeration.
                if (AddFileInfoToEnum(enumResult, fileInfo, targetPath))
                {
                    enumeration.MoveNext();
                }
                else
                {
                    // If we could not add the very first entry in the enumeration, a provider must
                    // return InsufficientBuffer.
                    if (enumeration.IsCurrentFirst)
                    {
                        hr = HResult.InsufficientBuffer;
                    }
                    break;
                }
            }

            if (hr == HResult.Ok)
            {
                Log.Information("<---- GetDirectoryEnumerationCallback {Result}", hr);
            }
            else
            {
                Log.Error("<---- GetDirectoryEnumerationCallback {Result}", hr);
            }
            return hr;
        }