private static bool CheckAcceptResponse(NamedPipeMessages.AcquireLock.Response response, bool checkAvailabilityOnly, out string message) { switch (response.Result) { case NamedPipeMessages.AcquireLock.AcceptResult: if (!checkAvailabilityOnly) { message = null; return(true); } else { message = "Error when acquiring the lock. Unexpected response: " + response.CreateMessage(); return(false); } case NamedPipeMessages.AcquireLock.AvailableResult: if (checkAvailabilityOnly) { message = null; return(true); } else { message = "Error when acquiring the lock. Unexpected response: " + response.CreateMessage(); return(false); } default: message = "Error when acquiring the lock. Not an Accept result: " + response.CreateMessage(); return(false); } }
private void HandleLockRequest(NamedPipeServer.Connection connection, NamedPipeMessages.Message message) { NamedPipeMessages.AcquireLock.Response response; NamedPipeMessages.AcquireLock.Data externalHolder; NamedPipeMessages.AcquireLock.Request request = new NamedPipeMessages.AcquireLock.Request(message); NamedPipeMessages.AcquireLock.Data requester = request.RequestData; if (request == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.UnknownRequest, requester); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult); } else { bool lockAcquired = this.gvfsLock.TryAcquireLock(requester, out externalHolder); if (lockAcquired) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult); } else if (externalHolder == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult); } else { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, externalHolder); } } connection.TrySendResponse(response.CreateMessage()); }
private static void AcquireGVFSLockForProcess(string fullCommand, int pid, Process parentProcess, NamedPipeClient pipeClient) { NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(pid, fullCommand); NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.AcquireLock.AcquireRequest); pipeClient.SendRequest(requestMessage); NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult) { return; } else if (response.Result == NamedPipeMessages.AcquireLock.MountNotReadyResult) { ExitWithError("GVFS has not finished initializing, please wait a few seconds and try again."); } else { string message = string.Empty; switch (response.Result) { case NamedPipeMessages.AcquireLock.AcceptResult: break; case NamedPipeMessages.AcquireLock.DenyGVFSResult: message = "Waiting for GVFS to release the lock"; break; case NamedPipeMessages.AcquireLock.DenyGitResult: message = string.Format("Waiting for '{0}' to release the lock", response.ResponseData.ParsedCommand); break; default: ExitWithError("Error when acquiring the lock. Unrecognized response: " + response.CreateMessage()); break; } ConsoleHelper.ShowStatusWhileRunning( () => { while (response.Result != NamedPipeMessages.AcquireLock.AcceptResult) { Thread.Sleep(250); pipeClient.SendRequest(requestMessage); response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); } return(true); }, message, output: Console.Out, showSpinner: !ConsoleHelper.IsConsoleOutputRedirectedToFile()); } }
private void HandleLockRequest(string messageBody, NamedPipeServer.Connection connection) { NamedPipeMessages.AcquireLock.Response response; NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(messageBody); NamedPipeMessages.LockData requester = request.RequestData; if (this.currentState == MountState.Unmounting) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.UnmountInProgressResult); EventMetadata metadata = new EventMetadata(); metadata.Add("LockRequest", requester.ToString()); metadata.Add(TracingConstants.MessageKey.InfoMessage, "Request denied, unmount in progress"); this.tracer.RelatedEvent(EventLevel.Informational, "HandleLockRequest_UnmountInProgress", metadata); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult); } else { bool lockAcquired = false; NamedPipeMessages.LockData existingExternalHolder = null; string denyGVFSMessage = null; bool lockAvailable = this.context.Repository.GVFSLock.IsLockAvailableForExternalRequestor(out existingExternalHolder); bool isReadyForExternalLockRequests = this.fileSystemCallbacks.IsReadyForExternalAcquireLockRequests(requester, out denyGVFSMessage); if (!requester.CheckAvailabilityOnly && isReadyForExternalLockRequests) { lockAcquired = this.context.Repository.GVFSLock.TryAcquireLockForExternalRequestor(requester, out existingExternalHolder); } if (requester.CheckAvailabilityOnly && lockAvailable && isReadyForExternalLockRequests) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AvailableResult); } else if (lockAcquired) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult); this.tracer.SetGitCommandSessionId(requester.GitCommandSessionId); } else if (existingExternalHolder == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult, responseData: null, denyGVFSMessage: denyGVFSMessage); } else { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, existingExternalHolder); } } connection.TrySendResponse(response.CreateMessage()); }
private void HandleLockRequest(string messageBody, NamedPipeServer.Connection connection) { NamedPipeMessages.AcquireLock.Response response; NamedPipeMessages.LockData externalHolder; NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(messageBody); NamedPipeMessages.LockData requester = request.RequestData; if (request == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.UnknownRequest, requester); } else if (this.currentState == MountState.Unmounting) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.UnmountInProgressResult); EventMetadata metadata = new EventMetadata(); metadata.Add("LockRequest", requester.ToString()); metadata.Add(TracingConstants.MessageKey.InfoMessage, "Request denied, unmount in progress"); this.tracer.RelatedEvent(EventLevel.Informational, "HandleLockRequest_UnmountInProgress", metadata); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult); } else { bool lockAcquired = false; string denyMessage; if (this.gvfltCallbacks.IsReadyForExternalAcquireLockRequests(requester, out denyMessage)) { lockAcquired = this.context.Repository.GVFSLock.TryAcquireLock(requester, out externalHolder); } else { // There might be an external lock holder, and it should be reported to the user externalHolder = this.context.Repository.GVFSLock.GetExternalLockHolder(); } if (lockAcquired) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult); } else if (externalHolder == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult, responseData: null, denyGVFSMessage: denyMessage); } else { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, externalHolder); } } connection.TrySendResponse(response.CreateMessage()); }
private void HandleLockRequest(string messageBody, NamedPipeServer.Connection connection) { NamedPipeMessages.AcquireLock.Response response; NamedPipeMessages.LockData externalHolder; NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(messageBody); NamedPipeMessages.LockData requester = request.RequestData; if (request == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.UnknownRequest, requester); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult); } else { bool lockAcquired = false; if (this.gvfltCallbacks.IsReadyForExternalAcquireLockRequests()) { lockAcquired = this.gvfsLock.TryAcquireLock(requester, out externalHolder); } else { // There might be an external lock holder, and it should be reported to the user externalHolder = this.gvfsLock.GetExternalLockHolder(); } if (lockAcquired) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult); } else if (externalHolder == null) { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult); } else { response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, externalHolder); } } connection.TrySendResponse(response.CreateMessage()); }
private static void HandleRequest(string request, NamedPipeServer.Connection connection) { NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); switch (message.Header) { case NamedPipeMessages.AcquireLock.AcquireRequest: NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult); connection.TrySendResponse(response.CreateMessage()); break; case NamedPipeMessages.ReleaseLock.Request: connection.TrySendResponse(NamedPipeMessages.ReleaseLock.SuccessResult); break; default: connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } }
public static bool TryAcquireGVFSLockForProcess( bool unattended, NamedPipeClient pipeClient, string fullCommand, int pid, bool isElevated, bool checkAvailabilityOnly, string gvfsEnlistmentRoot, out string result) { NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(pid, isElevated, checkAvailabilityOnly, fullCommand); NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.AcquireLock.AcquireRequest); pipeClient.SendRequest(requestMessage); NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); string message = string.Empty; switch (response.Result) { case NamedPipeMessages.AcquireLock.AcceptResult: return(CheckAcceptResponse(response, checkAvailabilityOnly, out result)); case NamedPipeMessages.AcquireLock.AvailableResult: return(CheckAcceptResponse(response, checkAvailabilityOnly, out result)); case NamedPipeMessages.AcquireLock.MountNotReadyResult: result = "GVFS has not finished initializing, please wait a few seconds and try again."; return(false); case NamedPipeMessages.AcquireLock.UnmountInProgressResult: result = "GVFS is unmounting."; return(false); case NamedPipeMessages.AcquireLock.DenyGVFSResult: message = response.DenyGVFSMessage; break; case NamedPipeMessages.AcquireLock.DenyGitResult: message = string.Format("Waiting for '{0}' to release the lock", response.ResponseData.ParsedCommand); break; default: result = "Error when acquiring the lock. Unrecognized response: " + response.CreateMessage(); return(false); } Func <bool> waitForLock = () => { while (true) { Thread.Sleep(250); pipeClient.SendRequest(requestMessage); response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); switch (response.Result) { case NamedPipeMessages.AcquireLock.AcceptResult: return(CheckAcceptResponse(response, checkAvailabilityOnly, out _)); case NamedPipeMessages.AcquireLock.AvailableResult: return(CheckAcceptResponse(response, checkAvailabilityOnly, out _)); case NamedPipeMessages.AcquireLock.UnmountInProgressResult: return(false); default: break; } } }; if (unattended) { waitForLock(); } else { ConsoleHelper.ShowStatusWhileRunning( waitForLock, message, output: Console.Out, showSpinner: !ConsoleHelper.IsConsoleOutputRedirectedToFile(), gvfsLogEnlistmentRoot: gvfsEnlistmentRoot); } result = null; return(true); }
private static void AcquireGlobalLock(string[] args) { try { if (ShouldLock(args)) { GVFSEnlistment enlistment = GVFSEnlistment.CreateFromCurrentDirectory(null, GitProcess.GetInstalledGitBinPath()); if (enlistment == null) { ExitWithError("This hook must be run from a GVFS repo"); } if (EnlistmentIsReady(enlistment)) { string fullCommand = "git " + string.Join(" ", args.Skip(1)); int pid = ProcessHelper.GetParentProcessId("git.exe"); Process parentProcess = null; if (pid == GVFSConstants.InvalidProcessId || !ProcessHelper.TryGetProcess(pid, out parentProcess)) { ExitWithError("GVFS.Hooks: Unable to find parent git.exe process " + "(PID: " + pid + ")."); } using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName)) { if (!pipeClient.Connect()) { ExitWithError("The enlistment does not appear to be mounted. Use 'gvfs status' to check."); } NamedPipeMessages.AcquireLock.Request request = new NamedPipeMessages.AcquireLock.Request(pid, fullCommand, ProcessHelper.GetCommandLine(parentProcess)); NamedPipeMessages.Message requestMessage = request.CreateMessage(); pipeClient.SendRequest(requestMessage); NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult) { return; } else if (response.Result == NamedPipeMessages.AcquireLock.MountNotReadyResult) { ExitWithError("GVFS has not finished initializing, please wait a few seconds and try again."); } else { int retries = 0; char[] waiting = { '\u2014', '\\', '|', '/' }; string message = string.Empty; while (true) { if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult) { if (!Console.IsOutputRedirected) { Console.WriteLine("\r{0}...", message); } return; } else if (response.Result == NamedPipeMessages.AcquireLock.DenyGVFSResult) { message = "Waiting for GVFS to release the lock"; } else if (response.Result == NamedPipeMessages.AcquireLock.DenyGitResult) { message = string.Format("Waiting for '{0}' to release the lock", response.ResponseData.ParsedCommand); } else { ExitWithError("Error when acquiring the lock. Unrecognized response: " + response.CreateMessage()); tracer.RelatedError("Unknown LockRequestResponse: " + response); } if (Console.IsOutputRedirected && retries == 0) { Console.WriteLine("{0}...", message); } else if (!Console.IsOutputRedirected) { Console.Write("\r{0}..{1}", message, waiting[retries % waiting.Length]); } Thread.Sleep(500); pipeClient.SendRequest(requestMessage); response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse()); retries++; } } } } } } catch (Exception e) { EventMetadata metadata = new EventMetadata(); metadata.Add("Error", e.ToString()); tracer.RelatedError(metadata); ExitWithError( "Unable to initialize Git command.", "Ensure that GVFS is running."); } }