private void GetPlaceholderInformationAsyncHandler()

in GVFS/GVFS.Platform.Windows/WindowsFileSystemVirtualizer.cs [767:882]


        private void GetPlaceholderInformationAsyncHandler(
            CancellationToken cancellationToken,
            BlobSizes.BlobSizesConnection blobSizesConnection,
            int commandId,
            string virtualPath,
            uint triggeringProcessId,
            string triggeringProcessImageFileName)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            HResult result = HResult.Ok;

            try
            {
                ProjectedFileInfo fileInfo;
                string parentFolderPath;
                try
                {
                    fileInfo = this.FileSystemCallbacks.GitIndexProjection.GetProjectedFileInfo(cancellationToken, blobSizesConnection, virtualPath, out parentFolderPath);
                    if (fileInfo == null)
                    {
                        this.TryCompleteCommand(commandId, HResult.FileNotFound);
                        return;
                    }
                }
                catch (OperationCanceledException)
                {
                    EventMetadata metadata = this.CreateEventMetadata(virtualPath);
                    metadata.Add(TracingConstants.MessageKey.InfoMessage, nameof(this.GetPlaceholderInformationAsyncHandler) + ": Operation cancelled");
                    this.Context.Tracer.RelatedEvent(
                        EventLevel.Informational,
                        $"{nameof(this.GetPlaceholderInformationAsyncHandler)}_{nameof(this.FileSystemCallbacks.GitIndexProjection.GetProjectedFileInfo)}_Cancelled",
                        metadata);
                    return;
                }

                // The file name case in the virtualPath parameter might be different than the file name case in the repo.
                // Build a new virtualPath that preserves the case in the repo so that the placeholder file is created
                // with proper case.
                string gitCaseVirtualPath = Path.Combine(parentFolderPath, fileInfo.Name);

                string sha;
                FileSystemResult fileSystemResult;
                if (fileInfo.IsFolder)
                {
                    sha = string.Empty;
                    fileSystemResult = this.WritePlaceholderDirectory(gitCaseVirtualPath);
                }
                else
                {
                    sha = fileInfo.Sha.ToString();
                    fileSystemResult = this.WritePlaceholderFile(gitCaseVirtualPath, fileInfo.Size, sha);
                }

                result = (HResult)fileSystemResult.RawResult;
                if (result != HResult.Ok)
                {
                    EventMetadata metadata = this.CreateEventMetadata(virtualPath);
                    metadata.Add("gitCaseVirtualPath", gitCaseVirtualPath);
                    metadata.Add("triggeringProcessId", triggeringProcessId);
                    metadata.Add("triggeringProcessImageFileName", triggeringProcessImageFileName);
                    metadata.Add("FileName", fileInfo.Name);
                    metadata.Add("IsFolder", fileInfo.IsFolder);
                    metadata.Add(nameof(sha), sha);
                    metadata.Add(nameof(result), result.ToString("X") + "(" + result.ToString("G") + ")");
                    this.Context.Tracer.RelatedError(metadata, $"{nameof(this.GetPlaceholderInformationAsyncHandler)}: {nameof(this.virtualizationInstance.WritePlaceholderInfo)} failed");
                }
                else
                {
                    if (fileInfo.IsFolder)
                    {
                        this.FileSystemCallbacks.OnPlaceholderFolderCreated(gitCaseVirtualPath, triggeringProcessImageFileName);
                    }
                    else
                    {
                        this.FileSystemCallbacks.OnPlaceholderFileCreated(gitCaseVirtualPath, sha, triggeringProcessImageFileName);
                    }
                }
            }
            catch (SizesUnavailableException e)
            {
                result = (HResult)HResultExtensions.HResultFromNtStatus.FileNotAvailable;

                EventMetadata metadata = this.CreateEventMetadata(virtualPath, e);
                metadata.Add("commandId", commandId);
                metadata.Add("triggeringProcessId", triggeringProcessId);
                metadata.Add("triggeringProcessImageFileName", triggeringProcessImageFileName);
                metadata.Add(nameof(result), result.ToString("X") + "(" + result.ToString("G") + ")");
                this.Context.Tracer.RelatedError(metadata, nameof(this.GetPlaceholderInformationAsyncHandler) + ": caught SizesUnavailableException");
            }
            catch (Win32Exception e)
            {
                result = HResultExtensions.HResultFromWin32(e.NativeErrorCode);

                EventMetadata metadata = this.CreateEventMetadata(virtualPath, e);
                metadata.Add("commandId", commandId);
                metadata.Add("triggeringProcessId", triggeringProcessId);
                metadata.Add("triggeringProcessImageFileName", triggeringProcessImageFileName);
                metadata.Add(nameof(result), result.ToString("X") + "(" + result.ToString("G") + ")");
                metadata.Add("NativeErrorCode", e.NativeErrorCode.ToString("X") + "(" + e.NativeErrorCode.ToString("G") + ")");
                this.Context.Tracer.RelatedWarning(metadata, nameof(this.GetPlaceholderInformationAsyncHandler) + ": caught Win32Exception");
            }
            catch (Exception e)
            {
                EventMetadata metadata = this.CreateEventMetadata(virtualPath, e);
                metadata.Add("commandId", commandId);
                metadata.Add("triggeringProcessId", triggeringProcessId);
                metadata.Add("triggeringProcessImageFileName", triggeringProcessImageFileName);
                this.LogUnhandledExceptionAndExit(nameof(this.GetPlaceholderInformationAsyncHandler), metadata);
            }

            this.TryCompleteCommand(commandId, result);
        }