## Window shenanigans, part the first:
This PR enables terminals to tell ConPTY what the owning window for the
pseudo window should be. This allows thigs like MessageBoxes created by
console applications to work. It also enables console apps to use
`GetAncestor(GetConsoleWindow(), GA_ROOT)` to get directly at the HWND
of the Terminal (but _don't please_).
This is tested with our internal partners and seems to work for their
scenario.
See #2988, #12799, #12515, #12570.
## PR Checklist
This is 1/3 of #2988.
## Summary of the Pull Request
Other than the `s_ResizeWindow` function, the `DispatchCommon` class was
just a couple of static functions indirectly calling the `ConGetSet`
interface. So by moving the `s_ResizeWindow` implementation into the
`ConhostInternalGetSet` class, we could easily replace all usage of
`DispatchCommon` with direct calls to `ConGetSet`.
## PR Checklist
* [x] Closes#12253
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number
where discussion took place: #12253
## Validation Steps Performed
I've manually confirmed the resizing operations still work as expected.
The other functions are harder to test, but were trivial replacements.
## Summary of the Pull Request
This PR refactors the `ConGetSet` API, eliminating some of the bloat produced by the `DoSrvPrivateXXXX` functions, simplifying the method naming to more closely match the `ITerminalApi` interface, and making better use of exceptions for error conditions in place of boolean return values.
## References
This is another small step towards merging the `AdaptDispatch` and `TerminalDispatch` classes (#3849).
## PR Checklist
* [x] Closes#12193
* [x] Closes#12194
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. Issue number where discussion took place: #3849
## Detailed Description of the Pull Request / Additional comments
There are two main parts to this. The first step was to get rid of all the `DoSrvPrivateXXX` functions, and move their implementation directly into the `ConhostInternalGetSet` class. For the most part this was just copying and pasting the code, but I also fixed a couple of bugs where we were using the wrong output buffer (the global buffer rather than the one associated with the output handle), and got rid of some unnecessary calls to `GetActiveBuffer`.
The second part was to make better use of exceptions for error conditions. Instead of catching the exceptions at the `ConGetSet` level, we now allow them to fall through all the way to the `StateMachine`. This greatly simplifies the `AdaptDispatch` implementation since it no longer needs to check a boolean return value on every `ConGetSet` call. This also enables the getter methods to return properties directly instead of having to use a reference parameter.
## Validation Steps Performed
A number of the unit tests had to be updated to match the new API. Sometimes this just required changes to method names, but in other cases error conditions that were previously detected with boolean returns now needed to be caught as exceptions.
There were also a few direct calls to `DoSrvPrivateXXX` functions that now needed to be invoked through other means: either by generating an equivalent escape sequence, or calling a lower level API serving the same purpose.
And in the adapter tests, the mock `ConGetSet` implementation required significant refactoring to match the new interface, mostly to account for the changes in error handling.
The only way to notice that LeaveCriticalSection() was called more
often than EnterCriticalSection() is by calling EnterCriticalSection()
again in the future, which will then deadlock.
Since this bug occurs on exit it wasn't noticeable with the old console lock.
With the new, stricter ticket lock this bug causes a fail-fast exit.
## PR Checklist
* [x] Closes#12168
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Launch and then exit Windows Terminal
* OpenConsole cleanly exits ✅
## Summary of the Pull Request

This adds a new action, `clearBuffer`. It accepts 3 values for the `clear` type:
* `"clear": "screen"`: Clear the terminal viewport content. Leaves the scrollback untouched. Moves the cursor row to the top of the viewport (unmodified).
* `"clear": "scrollback"`: Clear the scrollback. Leaves the viewport untouched.
* `"clear": "all"`: (**default**) Clear the scrollback and the visible viewport. Moves the cursor row to the top of the viewport (unmodified).
"Clear Buffer" has also been added to `defaults.json`.
## References
* From microsoft/vscode#75141 originally
## PR Checklist
* [x] Closes#1193
* [x] Closes#1882
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
This is a bit tricky, because we need to plumb it all the way through conpty to clear the buffer. If we don't, then conpty will immediately just redraw the screen. So this sends a signal to the attached conpty, and then waits for conpty to draw the updated, cleared, screen back to us.
## Validation Steps Performed
* works for each of the three clear types as expected
* tests pass.
* works even with `ping -t 8.8.8.8` as you'd hope.
Fix startup race of resizing ConPTY
- Depending on what the timing and ordering is of the message coming in
from the signal thread, it may be applied to the startup structure
after the I/O thread has begun initializing the console buffer
structures but before it has signaled that it is done and the signal
thread is ready to make changes directly. This likely happens because
the end of the I/O thread setup has a weird unlock/lock jog for the
input thread and the signal thread might have been scheduled in the
middle of it.
- My resolution here is to ensure that the signal thread just keeps
storing the latest resize message until it is told that everything is
initialized. Whomever comes in to tell the signal thread this
information (under lock) will pickup and run the resize if one came in
before everything was ready. This should resolve the race.
## Validation Steps Performed
- o-sdn-o confirms this resolves their issue
Closes#10400
Persist inbox conhost; delegate control activities to it via a pipe
## PR Checklist
* [x] Closes#10194 - WSL Debug Tap doesn't work
* [x] Closes#10134 - WSL Parameter is Incorrect
* [x] Closes#10413 - Ctrl+C not passed to client
* [x] Closes#10414 - Leftover processes on abrupt termination
* [x] Might help #10251 - Win+X Powershell sometimes fails to attach
* [x] I work here
* [x] Manually tested with assorted launch scenarios
## Detailed Description of the Pull Request / Additional comments
It turns out that there's a bit of ownership that goes on with the original inbox `conhost.exe` and the operating system/driver. The PID of that original `conhost.exe` is stowed when the initial connection is established and it is verified for several activities. This means that the plan of letting it go completely away and having the `OpenConsole.exe` take over all of its activities must be slightly revised.
I have tested the following two alternatives to keeping `conhost.exe` around and they do not work:
1. Replacing the original owner `conhost.exe` with `OpenConsole.exe` - A.) The driver does not allow this. Once the owner is registered, it cannot be replaced. B.) There's no way of updating this information inside the client process space and it is kept there too in the `kernelbase`/`conclnt` data from its initial connection.
2. Attempting to pick up the first packet (to determine headed/headless and other initial connection information that we use to determine whether handoff is appropriate or not) prior to registering any owner at all. - The driver doesn't allow this either. The owner must be registered prior to a packet coming through.
Put this mental model in your head:
CMD --> Conhost (inbox) --> OpenConsole (WT Package) --> Terminal (WT Package)
So since the `conhost.exe` needs to stick around, here's what I'm doing in this PR:
- `conhost.exe` in the OS will receive back the `OpenConsole.exe` process handle on a successful handoff and is expected to remain alive until the `OpenConsole.exe` exits. It's now waiting on that before it terminates itself.
- `conhost.exe` in the OS will establish a signal channel pipe and listen for control commands from `OpenConsole.exe` in a very similar fashion to how the `ConPTY` signal pipe operates between the Terminal and the PTY (provided by `OpenConsole.exe` in this particular example.) When `OpenConsole.exe` needs to do something that would be verified by the OS and rejected... it will instead signal the original `conhost.exe` to do that thing and it will go through.
- `conhost.exe` will give its own handle through to `OpenConsole.exe` so it can monitor its lifetime and cleanup. If the owner is gone, the session should end.
- Assorted handle cleanup that was leading to improper exits. I was confused between `.reset()` and `.release()` for some of the `wil::unique_any<T>` handling and it lead to leaked handles. The leaked handles meant that threads weren't aware of the other sides collapsing and wouldn't cleanup/terminate appropriately.
How does this fix things?
- For the WSL cases... WSL was specifically looking up the owner PID of the console session from the driver. That was the `conhost.exe` PID. If it exits, that PID isn't valid and is recycled. Thus the parameter is incorrect or other inappropriate WSL setup behaviors.
- Ctrl+C not passed... this is a signal the operating system rejects from a PID that is not the owner. This is now relayed through the original owner and it works.
- Leftover processes... I believe I explained this was both not-enough-monitoring of each others' process lifetimes coupled with mishandling of release/resetting handles and leaking them.
- Powershell sometimes fails to attach... my theory on this one is that it's a race that became upset when the `conhost.exe` disappeared while something about Powershell/.NET was still starting, much like the WSL one. I believe now that it is sticking around, it will be fine.
Also, this WILL require an OS update to complete improvement of functionality and I have revised the interface ID. This is considered an acceptable breaking change with no mitigation because we said this feature was an alpha preview.
## Validation Steps Performed
- Launched WSL with defapp set, it works
- Launched WSL with defapp set and the debug tap on, it works and opens in two tabs
- Launched CMD, ran ping, did Ctrl+C, it now receives it
- Launched Win+X powershell a ton of times. It seems fine now
- Launched cmd, powershell, wsl, etc. Killed assorted processes in the chain (client/conhost/openconsole/windowsterminal) and observed in Process Explorer (with a long delta timer so I could see it) that they all successfully tear down now without leftovers.
Add names to threads to make debugging a slight bit easier.
## PR Checklist
* [x] Closes personal todo item.
* [x] I work here.
* [x] Tested manually.
## Detailed Description of the Pull Request / Additional comments
Thread descriptions show up as names in both the Visual Studio debugger, WinDBG debugger, and Windows Performance Analyzer. This makes it faster and easier to identify threads of interest in our processes.
## Validation Steps Performed
* [x] Checked threads were named in OpenConsole.exe running in classic conhost window mode under VS debug
* [x] Checked threads were named in OpenConsole.exe running in conpty mode under VS debug
* [x] Checked threads were named in WindowsTerminal.exe (for a few of the threads around connections)
* [x] Checked that we could also see it in WinDBG
Many include statements use forward slashes, while others use backwards
slashes. This is inconsistent formatting. For this reason, I changed the
backward slashes to forward slashes since that is the standard.
Generated by https://github.com/jsoref/spelling `f`; to maintain your repo, please consider `fchurn`
I generally try to ignore upstream bits. I've accidentally included some items from the `deps/` directory. I expect someone will give me a list of items to drop, I'm happy to drop whole files/directories, or to split the PR into multiple items (E.g. comments/locals/public).
Closes#4294
Adjusts the startup and shutdown behavior of most threads in the console host to alleviate race conditions that are either exacerbated or introduced by the VT PTY threads.
Almost all functions in the Windows API that open or create objects and return HANDLEs to them return null on failure; only a few (mostly to do with the file system) return INVALID_HANDLE_VALUE on failure. This PR scrubs the repo of a few, but not necessarily all, cases where INVALID_HANDLE_VALUE was mistakenly used or tested against instead of null. In particular, it fixes 2 cases reported in issue #427 where the return value of CreateThread() was compared against INVALID_HANDLE_VALUE against null, causing the error handling code to run at the wrong time.
There are a lot of other uses of INVALID_HANDLE_VALUE I found that looked questionable, but which I left alone. Most of these were used to initialize HANDLE-typed variables and as a sentinel to see if those variables remained unset to a "real" value.
Fixes#427
* Removed using namespace directive from header files and put these in cpp files where they are used
* Fixed tabbing issues by replacing them with spaces.
Also regrouped the using directives.
* Update src/host/exemain.cpp
Co-Authored-By: Mike Griese <migrie@microsoft.com>
* Update src/interactivity/win32/find.cpp
Co-Authored-By: Mike Griese <migrie@microsoft.com>