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);
}