Exemplo n.º 1
0
        } // end InterceptCtrlC()

        protected override void ProcessRecord()
        {
            if (!DbgProvider.IsInGuestMode)
            {
                throw new InvalidOperationException("This command is only intended to be used by the !dbgshell implementation.");
            }

            LogManager.Trace("WaitForBangDbgShellCommandCommand.ProcessRecord: DbgShell is going dormant.");

            using (var disposer = new ExceptionGuard())
            {
                disposer.Protect(SetDebuggerAndContextAndUpdateCallbacks());
                disposer.Protect(InterceptCtrlC());
                disposer.Protect(Debugger.SuspendEventOutput());   // don't want our "modload" output etc. spewing while we are dormant

                base.ProcessRecord();
                // We need to perform the wait on another thread, because we need to "pump"
                // on this thread, so that debug event callbacks can queue WriteObject calls
                // to this thread.
                _RegisterWaitForGuestModeEvent(disposer);

                // Give the user a hint about what's going on.
                var s = new ColorString(ConsoleColor.DarkGray,
                                        "(DbgShell will remain running in the background until you run !dbgshell again)").ToString(true);
                Host.UI.WriteLine(s);

                MsgLoop.Prepare();

                // This will allow the extension command to return (it tells the dbgeng
                // thread that it can return).
                DbgProvider.GuestModePassivate();

                MsgLoop.Run(); // This will complete when the guest mode event gets signaled.
            } // end using( disposer )
        } // end ProcessRecord()
        private void OnOpenStore()
        {
            var selection = this.GetSingleOrDefaultSelection();

            if (selection == null)
            {
                return;
            }

            if (selection.SignatureKind != SignatureKind.Store)
            {
                return;
            }

            var link = $"ms-windows-store://pdp/?PFN={selection.PackageFamilyName}";
            var psi  = new ProcessStartInfo(link)
            {
                UseShellExecute = true
            };

            ExceptionGuard.Guard
            (
                () =>
            {
                Process.Start(psi);
            },
                this.interactionService
            );
        }
Exemplo n.º 3
0
        public void Convert()
        {
            var tempReg = System.Guid.NewGuid().ToString("N") + ".reg";
            var tempDir = "reg-out-" + System.Guid.NewGuid().ToString("N");

            Directory.CreateDirectory(tempDir);
            try
            {
                var mfn = typeof(TestConversion).Assembly.GetManifestResourceNames().First(a => a.EndsWith("team.reg"));
                using (var mf = typeof(TestConversion).Assembly.GetManifestResourceStream(mfn))
                {
                    using (var fs = File.OpenWrite(tempReg))
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        mf.CopyTo(fs);
                        fs.Flush(true);
                    }
                }

                var regConv = new MsixRegistryFileWriter(tempDir);
                var regPars = new RegFileParser();

                regPars.Parse(Path.Combine(tempReg));
                regConv.ImportRegFile(tempReg);
            }
            finally
            {
                ExceptionGuard.Guard(() =>
                {
                    Directory.Delete(tempDir, true);
                    File.Delete(tempReg);
                });
            }
        }
        public async Task <string> GetSubjectFromDeviceGuardSigning(string accessToken, string refreshToken, CancellationToken cancellationToken = default)
        {
            string tempFile = null;

            try
            {
                var cfg = new DeviceGuardConfig
                {
                    AccessToken  = accessToken,
                    RefreshToken = refreshToken
                };

                var helper = new DgssTokenCreator();
                tempFile = await helper.CreateDeviceGuardJsonTokenFile(cfg, cancellationToken).ConfigureAwait(false);

                return(await this.GetSubjectFromDeviceGuardSigning(tempFile, cancellationToken).ConfigureAwait(false));
            }
            finally
            {
                if (tempFile != null && File.Exists(tempFile))
                {
                    ExceptionGuard.Guard(() => File.Delete(tempFile));
                }
            }
        }
Exemplo n.º 5
0
        public async Task MountVhd(string vhdPath, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null)
        {
            Logger.Info($"Mounting volume {vhdPath}...");
            var tempFile = Path.Combine(Path.GetTempPath(), "msix-hero-vhd-" + Guid.NewGuid().ToString("N").Substring(0, 10) + ".cfg");

            try
            {
                var content = @"select vdisk file = ""{0}""
attach vdisk";

                await File.WriteAllTextAsync(tempFile, string.Format(content, vhdPath), cancellationToken).ConfigureAwait(false);

                var arguments = $"/S \"{tempFile}\"";

                Logger.Debug($"DISKPART.EXE command in {tempFile}:\r\n{string.Format(content, vhdPath)}");
                await this.RunDiskPart(arguments, cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                if (File.Exists(tempFile))
                {
                    Logger.Debug($"Deleting {tempFile}...");
                    ExceptionGuard.Guard(() => File.Delete(tempFile));
                }
            }
        }
Exemplo n.º 6
0
 // ReSharper disable once UnusedParameter.Local
 private void Dispose(bool disposing)
 {
     if (this.tempDirectory?.Exists == true)
     {
         ExceptionGuard.Guard(() => this.tempDirectory.Delete(true));
         this.tempDirectory = null;
     }
 }
Exemplo n.º 7
0
 private void Hyperlink_OnClick(object sender, RoutedEventArgs e)
 {
     ExceptionGuard.Guard(() =>
     {
         var dir = (string)((Hyperlink)sender).Tag;
         Process.Start("explorer.exe", "/select," + Path.Combine(dir, FileConstants.AppxManifestFile));
     },
                          new InteractionService(new NotificationManager()));
 }
Exemplo n.º 8
0
 // Wait for the "guest mode" event to be signaled.
 private void _RegisterWaitForGuestModeEvent(ExceptionGuard disposer)
 {
     LogManager.Trace("Registering wait for GuestMode event.");
     ThreadPool.RegisterWaitForSingleObject(DbgProvider.GuestModeEvent,
                                            (x, y) => { disposer.Dispose(); SignalDone(); },
                                            null,    // state
                                            -1,      // INFINITE
                                            true);   // executeOnlyOnce
 } // end _RegisterWaitForGuestModeEvent()
Exemplo n.º 9
0
        private void OnOpenReleaseNotes()
        {
            ExceptionGuard.Guard(() =>
            {
                var psi = new ProcessStartInfo("https://msixhero.net/redirect/release-notes/" + this.CurrentVersion)
                {
                    UseShellExecute = true
                };

                Process.Start(psi);
            },
                                 this.interactionService);
        }
Exemplo n.º 10
0
        private void HyperlinkOnClick(object sender, RoutedEventArgs e)
        {
            ExceptionGuard.Guard(() =>
            {
                var psi = new ProcessStartInfo((string)((Hyperlink)sender).Tag)
                {
                    UseShellExecute = true
                };

                Process.Start(psi);
            },
                                 new InteractionService(new NotificationManager()));
        }
Exemplo n.º 11
0
        public async Task Should_return_null_response_if_exception_was_caught(
            Exception exception)
        {
            var logger = Substitute.For <IInternalLogger>();

            async Task <Verdict> DoRequest()
            {
                return(await Task.FromException <Verdict>(exception));
            }

            var result = await ExceptionGuard.Try(DoRequest, logger);

            result.Should().BeNull();
        }
Exemplo n.º 12
0
        public async Task Should_log_exceptions_as_errors(
            Exception exception)
        {
            var logger = Substitute.For <IInternalLogger>();

            async Task <Verdict> DoRequest()
            {
                return(await Task.FromException <Verdict>(exception));
            }

            await ExceptionGuard.Try(DoRequest, logger);

            logger.Received().Error(exception.ToString);
        }
Exemplo n.º 13
0
        public async Task Should_not_rethrow_non_external_exceptions(
            Exception exception)
        {
            var logger = Substitute.For <IInternalLogger>();

            async Task <Verdict> DoRequest()
            {
                return(await Task.FromException <Verdict>(exception));
            }

            Func <Task> act = async() => await ExceptionGuard.Try(DoRequest, logger);

            await act.Should().NotThrowAsync <Exception>();
        }
Exemplo n.º 14
0
        static App()
        {
            var logLevel = MsixHeroLogLevel.Info;

            ExceptionGuard.Guard(() =>
            {
                var service = new LocalConfigurationService();
                var config  = service.GetCurrentConfiguration();

                logLevel = config.VerboseLogging ? MsixHeroLogLevel.Trace : MsixHeroLogLevel.Info;
            });

            LogManager.Initialize(logLevel);
        }
Exemplo n.º 15
0
        private async void OnView()
        {
            var selectedFile = this.SelectedNode;

            if (selectedFile == null)
            {
                return;
            }

            using var reader = FileReaderFactory.CreateFileReader(this.PackageFile);
            var path = await this.fileViewer.GetDiskPath(reader, selectedFile.Path).ConfigureAwait(false);

            ExceptionGuard.Guard(() => { this.fileInvoker.Execute(path, true); });
        }
Exemplo n.º 16
0
        public async Task Should_return_request_response_if_no_exception_is_thrown(
            Verdict response)
        {
            var logger = Substitute.For <IInternalLogger>();

            async Task <Verdict> DoRequest()
            {
                return(await Task.FromResult(response));
            }

            var result = await ExceptionGuard.Try(DoRequest, logger);

            result.Should().Be(response);
        }
Exemplo n.º 17
0
        public async Task<string> GetSubjectFromDeviceGuardSigning(string dgssTokenPath, CancellationToken cancellationToken = default)
        {
            Logger.Info("Getting certificate subject for Device Guard signing...");

            var tempFilePath = Path.Combine(Path.GetTempPath(), "msix-hero-" + Guid.NewGuid().ToString("N") + ".cat");
            try
            {
                var name = typeof(DeviceGuardHelper).Assembly.GetManifestResourceNames().First(n => n.EndsWith("MSIXHeroTest.cat"));
                using (var manifestResourceStream = typeof(DeviceGuardHelper).Assembly.GetManifestResourceStream(name))
                {
                    if (manifestResourceStream == null)
                    {
                        throw new InvalidOperationException("Cannot extract temporary file.");
                    }

                    Logger.Debug($"Creating temporary file path {tempFilePath}");
                    using (var fileStream = File.Create(tempFilePath))
                    {
                        manifestResourceStream.Seek(0L, SeekOrigin.Begin);
                        await manifestResourceStream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
                    }
                }

                var sdk = new MsixSdkWrapper();
                Logger.Debug($"Signing temporary file path {tempFilePath}");
                await sdk.SignPackageWithDeviceGuard(new[] {tempFilePath}, "SHA256", dgssTokenPath, null, cancellationToken).ConfigureAwait(false);

                using (var fromSignedFile = X509Certificate.CreateFromSignedFile(tempFilePath))
                {
                    Logger.Info($"Certificate subject is {tempFilePath}");
                    return fromSignedFile.Subject;
                }
            }
            catch (Exception e)
            {
                Logger.Error("Could not read subject from Device Guard certificate.", e);
                throw;
            }
            finally
            {
                if (File.Exists(tempFilePath))
                {
                    Logger.Debug($"Removing {tempFilePath}");
                    ExceptionGuard.Guard(() => File.Delete(tempFilePath));
                }
            }
        }
Exemplo n.º 18
0
        static Program()
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
            TaskScheduler.UnobservedTaskException      += TaskSchedulerOnUnobservedTaskException;

            var logLevel = MsixHeroLogLevel.Info;

            ExceptionGuard.Guard(() =>
            {
                var service = new LocalConfigurationService();
                var config  = service.GetCurrentConfiguration();

                logLevel = config.VerboseLogging ? MsixHeroLogLevel.Trace : MsixHeroLogLevel.Info;
            });

            LogManager.Initialize(logLevel);
        }
Exemplo n.º 19
0
        private async Task <int> SignDeviceGuardInteractive(string timestamp, bool updatePublisherName)
        {
            string            json = null;
            DeviceGuardConfig cfg;

            try
            {
                cfg = await this.DeviceGuardTokenCreator.SignIn().ConfigureAwait(false);

                json = await this.DeviceGuardTokenCreator.CreateDeviceGuardJsonTokenFile(cfg).ConfigureAwait(false);

                if (!this.Verb.NoPublisherUpdate)
                {
                    await this.Console.WriteInfo("Determining publisher name from Device Guard Signing certificate...").ConfigureAwait(false);

                    cfg.Subject = await this.DeviceGuardHelper.GetSubjectFromDeviceGuardSigning(json).ConfigureAwait(false);

                    await this.Console.WriteSuccess("New publisher name is " + cfg.Subject).ConfigureAwait(false);
                }
            }
            catch (SdkException e)
            {
                Logger.Error(e);
                await this.Console.WriteError($"Signing failed with error code 0x{e.ExitCode:X}: {e.Message}");

                return(e.ExitCode);
            }
            catch (Exception e)
            {
                Logger.Error(e);
                await this.Console.WriteError($"Signing failed: {e.Message}");

                return(10);
            }
            finally
            {
                if (json != null && File.Exists(json))
                {
                    ExceptionGuard.Guard(() => File.Delete(json));
                }
            }

            return(await this.SignDeviceGuard(cfg, timestamp, updatePublisherName).ConfigureAwait(false));
        }
Exemplo n.º 20
0
        } // end BeginProcessing()

        protected override void ProcessRecord()
        {
            var inputCallbacks = Debugger.GetInputCallbacks() as DebugInputCallbacks;

            if (null != inputCallbacks)
            {
                inputCallbacks.UpdateCmdlet(this);
            }

            //var outputCallbacks = Debugger.GetOutputCallbacks() as DebugOutputCallbacks;
            //if( null != outputCallbacks )
            //    outputCallbacks.UpdateCmdlet( this );

            using (var disposer = new ExceptionGuard())
            {
                disposer.Protect(Debugger.SetCurrentCmdlet(this));
                disposer.Protect(InterceptCtrlC());

                MsgLoop.Prepare();

                string actualCommand = string.Join(" ", Command);
                Task   t             = Debugger.InvokeDbgEngCommandAsync(actualCommand, OutputPrefix, _ConsumeLine);
                Task   t2            = t.ContinueWith(async(x) =>
                {
                    DEBUG_STATUS execStatus = Debugger.GetExecutionStatus();
                    if (_StatusRequiresWait(execStatus))
                    {
                        LogManager.Trace("InvokeDbgExtensionCommand: Current execution status ({0}) indicates that we should enter a wait.",
                                         execStatus);

                        await WaitForBreakAsync();
                    }

                    disposer.Dispose();
                    SignalDone();
                }).Unwrap();

                MsgLoop.Run();

                Host.UI.WriteLine();
                Util.Await(t);   // in case it threw
                Util.Await(t2);  // in case it threw
            } // end using( disposer )
        } // end ProcessRecord()
Exemplo n.º 21
0
        private void OpenLogsClicked(object sender, RoutedEventArgs e)
        {
            var logFile = LogManager.LogFile;

            if (logFile != null)
            {
                ExceptionGuard.Guard(() =>
                {
                    var psi = new ProcessStartInfo
                    {
                        UseShellExecute = true,
                        FileName        = "explorer.exe",
                        Arguments       = "/e," + Path.GetDirectoryName(logFile)
                    };

                    Process.Start(psi);
                });
            }
        }
Exemplo n.º 22
0
        protected override void ProcessRecord()
        {
            base.ProcessRecord();

            using (var disposer = new ExceptionGuard(Debugger.HandleDbgEngOutput(_ConsumeLine)))
            {
                // Failure to load an extension should be a terminating error.
                //
                // Because the only reason to load an extension is so that you can call
                // commands in it. And if you didn't load it, then none of those commands
                // will work.

                string providerPath = PathOrName;

                if (providerPath.IndexOfAny(sm_dirSeparators) >= 0)
                {
                    // We support PS paths.
                    //
                    // (we don't want to call GetUnresolvedProviderPathFromPSPath if it's
                    // just a bare name, else PS will interpret that as a relative path,
                    // which would be wrong)
                    providerPath = GetUnresolvedProviderPathFromPSPath(PathOrName);
                }

                MsgLoop.Prepare();

                var t = Debugger.AddExtensionAsync(providerPath);
                t.ContinueWith((x) => { disposer.Dispose(); SignalDone(); });

                MsgLoop.Run();

                var elr = Util.Await(t);   // in case it threw
                if (!string.IsNullOrEmpty(elr.LoadOutput))
                {
                    SafeWriteObject(elr.LoadOutput);
                }
                SafeWriteVerbose("Loaded extension: {0}", PathOrName);
            } // end using( disposer )
        }     // end ProcessRecord()
Exemplo n.º 23
0
        public override async Task <int> Execute()
        {
            var msixSdkWrapper = new MakeAppxWrapper();

            Logger.Info($"Packing [{this.Verb.Directory}] to [{this.Verb.Package}]...");

            try
            {
                await this.Console.WriteInfo($"Packing [{this.Verb.Directory}] to [{this.Verb.Package}]...").ConfigureAwait(false);

                await msixSdkWrapper.PackPackageDirectory(this.Verb.Directory, this.Verb.Package, !this.Verb.NoCompression, !this.Verb.NoValidation).ConfigureAwait(false);

                await this.Console.WriteSuccess($"Package [{this.Verb.Package}] has been created.");

                if (this.Verb.RemoveDirectoryAfterPacking)
                {
                    await this.Console.WriteInfo($"Removing source directory {this.Verb.Directory}...");

                    ExceptionGuard.Guard(() => Directory.Delete(this.Verb.Directory, true));
                }

                return(StandardExitCodes.ErrorSuccess);
            }
            catch (SdkException e)
            {
                Logger.Error(e);
                await this.Console.WriteError(e.Message);

                return(e.ExitCode);
            }
            catch (Exception e)
            {
                Logger.Error(e);
                await this.Console.WriteError(e.Message);

                return(StandardExitCodes.ErrorGeneric);
            }
        }
Exemplo n.º 24
0
        public override async Task <int> Execute()
        {
            var msixSdkWrapper = new MakeAppxWrapper();

            Logger.Info($"Unpacking [{this.Verb.Package}] to [{this.Verb.Directory}]...");

            try
            {
                await this.Console.WriteInfo($"Unpacking [{this.Verb.Package}] to [{this.Verb.Directory}]...").ConfigureAwait(false);

                await msixSdkWrapper.UnpackPackage(this.Verb.Package, this.Verb.Directory, !this.Verb.NoValidation).ConfigureAwait(false);

                await this.Console.WriteSuccess($"The package has been unpacked to [{this.Verb.Directory}].");

                if (this.Verb.RemovePackageAfterExtraction)
                {
                    await this.Console.WriteInfo($"Removing source package {this.Verb.Package}...");

                    ExceptionGuard.Guard(() => File.Delete(this.Verb.Package));
                }

                return(StandardExitCodes.ErrorSuccess);
            }
            catch (SdkException e)
            {
                Logger.Error(e);
                await this.Console.WriteError(e.Message);

                return(e.ExitCode);
            }
            catch (Exception e)
            {
                Logger.Error(e);
                await this.Console.WriteError(e.Message);

                return(StandardExitCodes.ErrorGeneric);
            }
        }
Exemplo n.º 25
0
        static async Task <int> Main(string[] args)
        {
            var logLevel = MsixHeroLogLevel.Trace;

            ExceptionGuard.Guard(() =>
            {
                var service = new LocalConfigurationService();
                var config  = service.GetCurrentConfiguration();

                logLevel = config.VerboseLogging ? MsixHeroLogLevel.Trace : MsixHeroLogLevel.Info;
            });

            LogManager.Initialize(logLevel);

            var console = new ConsoleImpl(Console.Out, Console.Error);

            try
            {
                // First argument is the "edit" verb.
                // Second argument is the path of the package.
                if (args.Length > 1 &&
                    string.Equals(args[0], "edit", StringComparison.OrdinalIgnoreCase) &&
                    !args[1].StartsWith("-", StringComparison.OrdinalIgnoreCase))
                {
                    return(await DoEditVerb(args[1], args.Skip(2), console));
                }

                return(await DoCommonVerbs(args, console));
            }
            catch (Exception e)
            {
                await console.WriteError(e.Message).ConfigureAwait(false);

                Environment.ExitCode = 1;
                return(1);
            }
        }
Exemplo n.º 26
0
        public void Convert()
        {
            var tempReg = System.Guid.NewGuid().ToString("N") + ".reg";
            var tempDir = "reg-out-" + System.Guid.NewGuid().ToString("N");

            Directory.CreateDirectory(tempDir);
            try
            {
                var mfn = typeof(TestConversion).Assembly.GetManifestResourceNames().First(a => a.EndsWith("team.reg"));
                using (var mf = typeof(TestConversion).Assembly.GetManifestResourceStream(mfn))
                {
                    using (var fs = System.IO.File.OpenWrite(tempReg))
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        mf.CopyTo(fs);
                        fs.Flush(true);
                    }
                }

                var regConv = new RegConverter();
                var regPars = new RegFileParser();

                regPars.Parse(Path.Combine(tempReg));
                regConv.ConvertFromRegToDat(tempReg, Path.Combine(tempDir, "Registry.dat"), RegistryRoot.HKEY_LOCAL_MACHINE).GetAwaiter().GetResult();
                regConv.ConvertFromRegToDat(tempReg, Path.Combine(tempDir, "UserClasses.dat"), RegistryRoot.HKEY_CLASSES_ROOT).GetAwaiter().GetResult();
                regConv.ConvertFromRegToDat(tempReg, Path.Combine(tempDir, "User.dat"), RegistryRoot.HKEY_CURRENT_USER).GetAwaiter().GetResult();
            }
            finally
            {
                ExceptionGuard.Guard(() =>
                {
                    System.IO.Directory.Delete(tempDir, true);
                    System.IO.File.Delete(tempReg);
                });
            }
        }
Exemplo n.º 27
0
 private async Task <T> TryRequest <T>(Func <Task <T> > request)
     where T : class
 {
     return(await ExceptionGuard.Try(request, _logger));
 }
Exemplo n.º 28
0
        static int Main(string[] args)
        {
            // This allows "[Console]::WriteLine( [char] 0x2026 )" to work just as well as
            // "[char] 0x2026".
            Console.OutputEncoding = Encoding.UTF8;

            //
            // We've got four possibilities:
            //
            // 1) Normal mode: somebody just ran DbgShell.exe.
            // 2) Guest mode: DbgShell is being hosted by a debugger extension
            //    (DbgShellExt.dll).
            // 3) Guest mode cleanup: the debugger extension (DbgShellExt) is being
            //    unloaded.
            // 4) GuestAndHost mode: DbgShell.exe is the host, but !DbgShellExt.dbgshell
            //    was called.
            //

            DbgProvider.EntryDepth++;

            ExceptionGuard entryPointStateDisposer = new ExceptionGuard(
                (Disposable)(() => LogManager.Trace("Undoing entry point state changes.")));

            entryPointStateDisposer.Protect((Disposable)(() => DbgProvider.EntryDepth--));

            using ( entryPointStateDisposer )
            {
                if ((null != args) &&
                    (args.Length > 0) &&
                    (0 == StringComparer.Ordinal.Compare(args[0], c_guestMode)))
                {
                    LogManager.Trace("Main: GuestMode");
                    //
                    // In guest mode, the entry thread is used as the DbgEng thread, and a
                    // separate thread is started to run our Main. When the user runs "exit",
                    // we don't actually exit--we "pause" the main thread, and then return
                    // from here (returning control back to the debugger (like windbg)).
                    //

                    args = args.Skip(1).ToArray();

                    return(_GuestModeMainWrapper(entryPointStateDisposer, args));
                }
                else if ((null != args) &&
                         (args.Length > 0) &&
                         (0 == StringComparer.Ordinal.Compare(args[0], c_guestModeCleanup)))
                {
                    Util.Assert(args.Length == 1);   // there shouldn't be any other args

                    LogManager.Trace("Main: GuestModeCleanup");

                    //
                    // We're in guest mode and the debugger extension is being unloaded--time
                    // to clean up.
                    //
                    return(_GuestModeCleanup());
                }
                else if ((null != args) &&
                         (args.Length > 0) &&
                         (0 == StringComparer.Ordinal.Compare(args[0], c_guestAndHostMode)))
                {
                    LogManager.Trace("Main: GuestAndHostMode");
                    //
                    // GuestAndHost mode is pretty much just like the "reentrant" case in
                    // GuestMode. Because DbgShell.exe is already running and owns "main" and
                    // everything, we don't use any of the other guest mode machinery besides
                    // the CurrentActionQueue and EntryDepth.
                    //

                    args = args.Skip(1).ToArray();

                    return(_GuestAndHostModeMainWrapper(entryPointStateDisposer, args));
                }
                else
                {
                    LogManager.Trace("Main: Normal");
                    //
                    // "Normal" (non-guest) mode.
                    //
                    return(_NormalModeMainWrapper(args));
                } // end else "normal" mode

                // The stuff protected by the entryPointStateDisposer may not get disposed
                // here--it may have been transferred to a different thread via
                // entryPointStateDisposer.Transfer().
            } // end using( entryPointStateDisposer )
        }     // end Main()
Exemplo n.º 29
0
        } // end _NormalModeMainWrapper()

        private static int _GuestAndHostModeMainWrapper(ExceptionGuard entryPointStateDisposer,
                                                        string[] args)
        {
            // We should have two things:
            //    args[ 0 ]: "shareConsole"
            //    args[ 1 ]: command args should all should get passed in one big string.
            //
            // Unlike plain guest mode, we know we are "sharing" the console (because
            // DbgShell.exe is the host!), but it's convenient for the caller to still
            // pass the console ownership arg.
            Util.Assert(2 == args.Length);

            if (0 != StringComparer.Ordinal.Compare(args[0], c_guestModeShareConsole))
            {
                var msg = "Unexpected arg: I expected to see \"shareConsole\".";
                Util.Fail(msg);
                throw new Exception(msg);
            }

            //
            // We're getting called on the dbgeng thread, which should be a background
            // thread, but the API we use from DbgShellExt.dll (RunAssembly) causes this
            // thread to get marked as non-background, so we need to put that back.
            //
            Thread.CurrentThread.IsBackground = true;

            try
            {
                // We'll always pretend it's the first time for the purpose of parsing
                // arguments--on the one hand, -NoProfile doesn't make sense (it can't
                // /ever/ make sense in guestAndHostMode; the profile was run or not
                // when DbgShell.exe started), but we don't want to warn about it.
                //
                // TODO: Is that the right decision?

                bool   noProfile;
                bool   inBreakpointCommand;
                string command = _ParseGuestModeArgs(args[1],
                                                     /* firstTime = */ true,
                                                     out noProfile,
                                                     out inBreakpointCommand);

                if (inBreakpointCommand && !DbgProvider.IsInBreakpointCommand)
                {
                    DbgProvider.IsInBreakpointCommand = true;
                    entryPointStateDisposer.Protect((Disposable)(() => DbgProvider.IsInBreakpointCommand = false));
                }

                // Re-entrant case: DbgShell is already running, but something called
                // the debugger "!dbgshell" extension command (for instance, a
                // breakpoint command).
                LogManager.Trace("_GuestAndHostModeMainWrapper: re-entering (entryDepth: {0}).", DbgProvider.EntryDepth);
                if (null == DbgProvider.CurrentActionQueue)
                {
                    var msg = "(_GuestAndHostModeMainWrapper) DbgShell is already running, but I don't have a CurrentActionQueue to inject commands.";
                    Util.Fail(msg);
                    throw new Exception(msg);
                }
                var transferTicket = entryPointStateDisposer.Transfer();
                DbgProvider.CurrentActionQueue.PostCommand((cii) =>
                {
                    // TODO: BUGBUG: I need to do something here to separate CTRL+C
                    // handling for 'command' versus the cmdlet that is running the
                    // CurrentActionQueue. That is, if we post a command here that
                    // does a naked "Get-Content", it will prompt you for a path, and
                    // if you then do a CTRL+C, I want it to only cancel 'command',
                    // not the entire pipeline including the Resume-Exection command
                    // or whatever it is that is running the CurrentActionQueue.
                    //
                    // Besides just to behave as the user wants/expects, it throws a
                    // wrench in things for execution commands to get canceled--it's
                    // very important, so they do their own CTRL+C handling.
                    using (transferTicket.Redeem())
                    {
                        LogManager.Trace("Executing injected (reentrant) commands:");
                        LogManager.Trace(command.Replace("\n", "\n > "));
                        cii.InvokeScript(command,
                                         false,
                                         PipelineResultTypes.Error |
                                         PipelineResultTypes.Output,
                                         sm_noInput);
                    }     // end using( new disposer )
                });
                transferTicket.CommitTransfer();

                LogManager.Trace("_GuestAndHostModeMainWrapper: returning {0}.",
                                 Util.FormatErrorCode(sm_exitCode));
                return(sm_exitCode);
            }
            finally
            {
                LogManager.Trace("_GuestAndHostModeMainWrapper: leaving.");
            }
        } // end _GuestAndHostModeMainWrapper()
Exemplo n.º 30
0
        private static int _GuestModeMainWrapper(ExceptionGuard entryPointStateDisposer,
                                                 string[] args)
        {
            // We should have two things:
            //    args[ 0 ]: either "consoleOwner" or "shareConsole" (windbg versus ntsd, for instance)
            //    args[ 1 ]: command args should all should get passed in one big string.
            Util.Assert(2 == args.Length);

            bool shareConsole = false;

            if (0 == StringComparer.Ordinal.Compare(args[0], c_guestModeShareConsole))
            {
                shareConsole = true;
            }
            else
            {
                if (0 != StringComparer.Ordinal.Compare(args[0], c_guestModeConsoleOwner))
                {
                    var msg = "Unexpected arg: I expected to see \"consoleOwner\".";
                    Util.Fail(msg);
                    throw new Exception(msg);
                }
            }

            bool firstTime      = null == sm_altMainThread;
            bool alreadyRunning = DbgProvider.EntryDepth > 1;

            try
            {
                bool   noProfile;
                bool   inBreakpointCommand;
                string command = _ParseGuestModeArgs(args[1],
                                                     firstTime,
                                                     out noProfile,
                                                     out inBreakpointCommand);

                if (inBreakpointCommand && !DbgProvider.IsInBreakpointCommand)
                {
                    DbgProvider.IsInBreakpointCommand = true;
                    entryPointStateDisposer.Protect((Disposable)(() => DbgProvider.IsInBreakpointCommand = false));
                }

                if (firstTime)
                {
                    Util.Assert(!alreadyRunning);
                    ColorConsoleHost.GuestModeInjectCommand(command);

                    LogManager.Trace("_GuestModeMainWrapper: initial entry.");
                    // This is the first time we've been run, so we need to start everything
                    // up, pretty much the same as when running as a normal EXE.
                    sm_altMainThread = new Thread(_AltMainThread);

                    DbgProvider.SetGuestMode(shareConsole);

                    string[] mainArgs = null;
                    if (noProfile)
                    {
                        mainArgs = new string[] { "-NoProfile" }
                    }
                    ;

                    sm_altMainThread.Start(mainArgs);

                    // This will get signaled when things have been initialized enough to
                    // where we can start the guest mode thread activity.
                    DbgProvider.GuestModeEvent.WaitOne();
                    DbgProvider.GuestModeEvent.Reset();
                }
                else
                {
                    if (alreadyRunning)
                    {
                        // Re-entrant case: DbgShell is already running, but something called
                        // the debugger "!dbgshell" extension command (for instance, a
                        // breakpoint command).
                        LogManager.Trace("_GuestModeMainWrapper: re-entering (entryDepth: {0}).", DbgProvider.EntryDepth);
                        if (null == DbgProvider.CurrentActionQueue)
                        {
                            Util.Fail("DbgShell is already running, but I don't have a CurrentActionQueue to inject commands.");
                            throw new Exception("DbgShell is already running, but I don't have a CurrentActionQueue to inject commands.");
                        }
                        var transferTicket = entryPointStateDisposer.Transfer();
                        DbgProvider.CurrentActionQueue.PostCommand((cii) =>
                        {
                            using (transferTicket.Redeem())
                            {
                                LogManager.Trace("Executing injected (reentrant) commands:");
                                LogManager.Trace(command.Replace("\n", "\n > "));
                                cii.InvokeScript(command,
                                                 false,
                                                 PipelineResultTypes.Error |
                                                 PipelineResultTypes.Output,
                                                 sm_noInput);
                            }     // end using( new disposer )
                        });
                        transferTicket.CommitTransfer();
                    }
                    else
                    {
                        LogManager.Trace("_GuestModeMainWrapper: resuming.");
                        ColorConsoleHost.GuestModeInjectCommand(command);

                        // We already have an alternate main thread, which is "paused" (blocked),
                        // waiting to resume.

                        DbgProvider.GuestModeResume();
                    }
                }

                if (!alreadyRunning)
                {
                    LogManager.Trace("_GuestModeMainWrapper: entering GuestModeGuestThreadActivity.");
                    // The guest mode thread activity is to pump the DbgEngThread (this thread is
                    // the thread that the debugger extension was called on, and we need to use
                    // this thread to interact with dbgeng).
                    //
                    // (if alreadyRunning, then we are already running the
                    // GuestModeGuestThreadActivity (it's below us on the stack))
                    DbgProvider.GuestModeGuestThreadActivity();
                }

                LogManager.Trace("_GuestModeMainWrapper: returning {0}.",
                                 Util.FormatErrorCode(sm_exitCode));
                return(sm_exitCode);
            }
            finally
            {
                LogManager.Trace("_GuestModeMainWrapper: leaving.");
            }
        } // end _GuestModeMainWrapper()