Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WindowsTerminal fails to launch elevate=true profiles on new install; elevate-shim does not set dllpath #14501

Closed
jboelter opened this issue Dec 7, 2022 · 11 comments · Fixed by #14637
Labels
Culprit-Centennial Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.

Comments

@jboelter
Copy link
Contributor

jboelter commented Dec 7, 2022

Windows Terminal version

1.15.2875.0

Windows build number

10.0.22621.819

Other Software

N/A - brand new system setup

Steps to reproduce

This should repro on a brand new Windows 11 installation as long as you do not have vcruntime140.dll in your default system %PATH%.

  • Install new Windows 11 System
  • Install Windows Terminal from the App Store
  • Launch Windows Terminal
  • Create a new profile by duplicating the Command Prompt profile and setting the elevate = true flag
  • Launch the new Command Prompt (elevated) profile (or whatever you named it)

Will provide additional details in the comments. I've got procmon traces, dump snapshots and a method to observe this w/o the failure. Issue seems to be related to ShellExecuteExW in elevate-shim not setting the DllPath in the elevated process.

Expected Behavior

New Windows Terminal window launches w/ elevated cmd.exe

Actual Behavior

WindowsTerminal.exe fails to launch w/ "not found" errors for msvcp140.dll, vcruntime140.dll, vcruntime140_1.dll

image

image

image

@jboelter jboelter added Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Dec 7, 2022
@jboelter
Copy link
Contributor Author

jboelter commented Dec 7, 2022

Process Monitor Trace shows the shim launching an elevated WindowsTerminal.exe, however -- note the paths used to resolve DLLs is different than the unelevated process (and fails).

image

WindowsTerminal-ProcMon.zip

@jboelter
Copy link
Contributor Author

jboelter commented Dec 7, 2022

I took dump snapshots (via Task Manager) of WindowsTerminal.exe of unelevated (after initial launch) and the elevated process (while the initial error dialog is on screen). Notable, the DllPath is different between the two.

Unelevated:

0:000> !peb
    CurrentDirectory:  'C:\Windows\system32\'
    WindowTitle:  'C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.15.2875.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe'
    ImageFile:    'C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.15.2875.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe'
    CommandLine:  '"C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.15.2875.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe" '
    DllPath:      'C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.15.2875.0_x64__8wekyb3d8bbwe;C:\Program Files\WindowsApps\Microsoft.VCLibs.140.00.UWPDesktop_14.0.30704.0_x64__8wekyb3d8bbwe;C:\Program Files\WindowsApps\Microsoft.UI.Xaml.2.7_7.2208.15002.0_x64__8wekyb3d8bbwe;'

Elevated:

0:000> !peb

    CurrentDirectory:  'C:\Windows\system32\'
    WindowTitle:  'C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.15.2875.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe'
    ImageFile:    'C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.15.2875.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe'
    CommandLine:  '"C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.15.2875.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe" --profile "{37fcd1f2-c0fc-49bb-8ea7-f5bf41414c0d}"'
    DllPath:      '< Name not readable >'

0:000> dt _peb @$peb
WindowsTerminal!_PEB
   +0x000 Reserved1        : [2]  ""
   +0x002 BeingDebugged    : 0 ''
   +0x003 Reserved2        : [1]  "???"
   +0x008 Reserved3        : [2] 0xffffffff`ffffffff Void
   +0x018 Ldr              : 0x00007ff8`9c254380 _PEB_LDR_DATA
   +0x020 ProcessParameters : 0x00000184`59203760 _RTL_USER_PROCESS_PARAMETERS
   +0x028 Reserved4        : [3] (null) 
   +0x040 AtlThunkSListPtr : (null) 
   +0x048 Reserved5        : (null) 
   +0x050 Reserved6        : 3
   +0x058 Reserved7        : (null) 
   +0x060 Reserved8        : 0
   +0x064 AtlThunkSListPtr32 : 0
   +0x068 Reserved9        : [45] 0x00000184`58f50000 Void
   +0x1d0 Reserved10       : [96]  ""
   +0x230 PostProcessInitRoutine : (null) 
   +0x238 Reserved11       : [128]  "???"
   +0x2b8 Reserved12       : [1] (null) 
   +0x2c0 SessionId        : 1
0:000> dx -r1 ((WindowsTerminal!_RTL_USER_PROCESS_PARAMETERS *)0x18459203760)
((WindowsTerminal!_RTL_USER_PROCESS_PARAMETERS *)0x18459203760)                 : 0x18459203760 [Type: _RTL_USER_PROCESS_PARAMETERS *]
    [+0x000] Reserved1        [Type: unsigned char [16]]
    [+0x010] Reserved2        [Type: void * [10]]
    [+0x060] ImagePathName    [Type: _UNICODE_STRING]
    [+0x070] CommandLine      [Type: _UNICODE_STRING]
0:000> dx -r1 (*((WindowsTerminal!void * (*)[10])0x18459203770))
(*((WindowsTerminal!void * (*)[10])0x18459203770))                 [Type: void * [10]]
    [0]              : 0x0 [Type: void *]
    [1]              : 0x0 [Type: void *]
    [2]              : 0x0 [Type: void *]
    [3]              : 0x0 [Type: void *]
    [4]              : 0x0 [Type: void *]
    [5]              : 0x2080028 [Type: void *]
    [6]              : 0x18459204530 [Type: void *]
    [7]              : 0x4c [Type: void *]
    [8]              : 0x0 [Type: void *]
    [9]              : 0x0 [Type: void *] <---- null 

@jboelter
Copy link
Contributor Author

jboelter commented Dec 7, 2022

Finally; you can verify this on a working system by attaching a debugger to WindowsTerminal.exe and inspecting the loaded modules for an unelevated vs elevated process. Note the image path is different.

Edit: the dll versions are different too, that's interesting from a bug/support perspective.

unelevated:

0:000> lmDvmVCRUNTIME140
Browse full module list
start             end                 module name
00007ffc`36f90000 00007ffc`36fab000   VCRUNTIME140   (deferred)             
    Image path: C:\Program Files\WindowsApps\Microsoft.VCLibs.140.00.UWPDesktop_14.0.30704.0_x64__8wekyb3d8bbwe\VCRUNTIME140.dll
    Image name: VCRUNTIME140.dll
    Browse all global symbols  functions  data
    Timestamp:        Sun Oct  3 22:33:09 2021 (615A9215)
    CheckSum:         000241C0
    ImageSize:        0001B000
    File version:     14.30.30704.0
    Product version:  14.30.30704.0
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    Information from resource tables:
        CompanyName:      Microsoft Corporation
        ProductName:      Microsoft® Visual Studio®
        InternalName:     vcruntime140.dll
        OriginalFilename: vcruntime140.dll
        ProductVersion:   14.30.30704.0
        FileVersion:      14.30.30704.0 built by: vcwrkspc
        FileDescription:  Microsoft® C Runtime Library
        LegalCopyright:   © Microsoft Corporation. All rights reserved.

elevated:

0:000> lmDvmVCRUNTIME140
Browse full module list
start             end                 module name
00007ffc`4e130000 00007ffc`4e14b000   VCRUNTIME140   (deferred)             
    Image path: C:\Windows\System32\VCRUNTIME140.dll
    Image name: VCRUNTIME140.dll
    Browse all global symbols  functions  data
    Image was built with /Brepro flag.
    Timestamp:        8E79CD85 (This is a reproducible build file hash, not a timestamp)
    CheckSum:         000235A7
    ImageSize:        0001B000
    File version:     14.34.31931.0
    Product version:  14.34.31931.0
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    Information from resource tables:
        CompanyName:      Microsoft Corporation
        ProductName:      Microsoft® Visual Studio®
        InternalName:     vcruntime140.dll
        OriginalFilename: vcruntime140.dll
        ProductVersion:   14.34.31931.0
        FileVersion:      14.34.31931.0
        FileDescription:  Microsoft® C Runtime Library
        LegalCopyright:   © Microsoft Corporation. All rights reserved.

@HecticSerenity
Copy link

👍🏼 great collection of details

@zadjii-msft
Copy link
Member

This is wild, and a great collection of details. I'm not entirely sure how we go about actually fixing this. Kinda seems to me like something that the package infrastructure should have taken care of for us, but I can't be sure. We'll need to follow up with some folks and investigate.

I reckon this is gonna come to something that we could theoretically work around, but we should make sure the rest of the platform team is aware of this.

(@DHowett putting this in your inbox for after vacation - who owns the MSIX bits these days that we should follow up with?)

@zadjii-msft zadjii-msft removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Jan 3, 2023
@ghost ghost added the Needs-Tag-Fix Doesn't match tag requirements label Jan 3, 2023
@jboelter
Copy link
Contributor Author

jboelter commented Jan 4, 2023

I went down quite the rabbit hole exploring how a new process is created with ShellExecuteEx runas. It was also a good excuse to learn more about Time Travel Debug and store apps.

From what I can gather, the ShellExecuteEx call from elevate-shim eventually fires off some RPC COM calls via Explorer.exe to launch the new process WindowsTerminal.exe. However, launching the new process (apparently) does this without any awareness of the store app; and in turn does not set the DllPath in the PEB.

However, launching Terminal via the start menu (elevated or not) seems to follow a different process that is aware of the store app manifest. I can see the AppInfo service (svchost.exe) reading the app manifest file here: C:\ProgramData\Microsoft\Windows\AppRepository\Packages\Microsoft.WindowsTerminal_1.15.3466.0_x64__8wekyb3d8bbwe\S-1-5-21-725345543-602162358-527237240-86197.pckgdep

@jboelter
Copy link
Contributor Author

jboelter commented Jan 4, 2023

It looks like there is a viable path with minimal changes (still uses the shim and ShellExecute); it would require some state to determine if the original process was launched as a store app vs some other means (e.g. developer mode). This state would be passed along to the elevate shim to make a decision to use shell:AppsFolder vs the WindowsTerminal.exe path while it's constructing the call to ShellExecute.

Relevant: PowerToys knows how to launch processes elevated using shell:AppsFolder + runas instead of an executable path.

string command = "shell:AppsFolder\\" + UniqueIdentifier;
command = Environment.ExpandEnvironmentVariables(command.Trim());

var info = ShellCommand.SetProcessStartInfo(command, verb: "runas");
info.UseShellExecute = true;
info.Arguments = queryArguments;
Process.Start(info);
return true;

jboelter added a commit to jboelter/terminal that referenced this issue Jan 5, 2023
Fixes microsoft#14501

This uses `shell:AppsFolder` to launch elevated instances of the app via
`ShellExecuteEx` and `runas` in elevate-shim.exe. The app to launch is
discovered via the `GetCurrentApplicationUserModelId` API.

e.g. `shell:AppsFolder\WindowsTerminalDev_8wekyb3d8bbwe!App`

This will fallback to launching `WindowsTerminal.exe` if it fails to
discover the app user model id to launch.

This also fixes an innocuous bug in elevate-shim where the first
argument of WinMain was lost (e.g. `new-tab`).
@ghost ghost added the In-PR This issue has a related PR label Jan 5, 2023
@ghost ghost closed this as completed in #14637 Jan 19, 2023
ghost pushed a commit that referenced this issue Jan 19, 2023
This uses `shell:AppsFolder` to launch elevated instances of the app via
`ShellExecuteEx` and `runas` in elevate-shim.exe. The app to launch is
discovered via the `GetCurrentApplicationUserModelId` API.

e.g. `shell:AppsFolder\WindowsTerminalDev_8wekyb3d8bbwe!App`

This will fallback to launching `WindowsTerminal.exe` if it fails to
discover the app user model id to launch.

This also fixes a bug in elevate-shim where the first argument of
WinMain was lost (e.g. `new-tab`). 

Curiously, `AppLogic::RunAsUwp()` is never called and
`AppLogic::IsUwp()` is always false when running debug builds locally
(e.g. WindowsTerminalDev). It's not clear if this is an artifact of
development packages or something else.

## Validation Steps Performed

Various manual debug/execution scenarios.

Verified the fallback path by running the unbundled app by extracting
the `CascadiaPackage_0.0.1.0_x64.msix` from the 'drop' build artifact.

Fixes #14501
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Jan 19, 2023
@ghost
Copy link

ghost commented Jan 24, 2023

🎉This issue was addressed in #14637, which has now been successfully released as Windows Terminal Preview v1.17.1023.:tada:

Handy links:

carlos-zamora pushed a commit that referenced this issue Jan 25, 2023
This uses `shell:AppsFolder` to launch elevated instances of the app via
`ShellExecuteEx` and `runas` in elevate-shim.exe. The app to launch is
discovered via the `GetCurrentApplicationUserModelId` API.

e.g. `shell:AppsFolder\WindowsTerminalDev_8wekyb3d8bbwe!App`

This will fallback to launching `WindowsTerminal.exe` if it fails to
discover the app user model id to launch.

This also fixes a bug in elevate-shim where the first argument of
WinMain was lost (e.g. `new-tab`). 

Curiously, `AppLogic::RunAsUwp()` is never called and
`AppLogic::IsUwp()` is always false when running debug builds locally
(e.g. WindowsTerminalDev). It's not clear if this is an artifact of
development packages or something else.

## Validation Steps Performed

Various manual debug/execution scenarios.

Verified the fallback path by running the unbundled app by extracting
the `CascadiaPackage_0.0.1.0_x64.msix` from the 'drop' build artifact.

Fixes #14501
DHowett pushed a commit that referenced this issue Jan 27, 2023
This uses `shell:AppsFolder` to launch elevated instances of the app via
`ShellExecuteEx` and `runas` in elevate-shim.exe. The app to launch is
discovered via the `GetCurrentApplicationUserModelId` API.

e.g. `shell:AppsFolder\WindowsTerminalDev_8wekyb3d8bbwe!App`

This will fallback to launching `WindowsTerminal.exe` if it fails to
discover the app user model id to launch.

This also fixes a bug in elevate-shim where the first argument of
WinMain was lost (e.g. `new-tab`).

Curiously, `AppLogic::RunAsUwp()` is never called and
`AppLogic::IsUwp()` is always false when running debug builds locally
(e.g. WindowsTerminalDev). It's not clear if this is an artifact of
development packages or something else.

## Validation Steps Performed

Various manual debug/execution scenarios.

Verified the fallback path by running the unbundled app by extracting
the `CascadiaPackage_0.0.1.0_x64.msix` from the 'drop' build artifact.

Fixes #14501

(cherry picked from commit eab1c23)
Service-Card-Id: 87690177
Service-Version: 1.16
@ghost
Copy link

ghost commented Jan 27, 2023

🎉This issue was addressed in #14637, which has now been successfully released as Windows Terminal v1.16.1026 (1.16.10261.0 and 1.16.10262.0).:tada:

Handy links:

1 similar comment
@ghost
Copy link

ghost commented Jan 27, 2023

🎉This issue was addressed in #14637, which has now been successfully released as Windows Terminal v1.16.1026 (1.16.10261.0 and 1.16.10262.0).:tada:

Handy links:

@zadjii-msft
Copy link
Member

To close the loop on this, a colleague helped dig into why this regressed recently in the Terminal:

I debugged why the regression occurs. Microsoft.UI.Xaml.dll fails to load because the loader cannot find VCRUNTIME140_1_APP.dll. Normally this comes from the Terminal package directory. However, since the DLL path is empty (due to the Appinfo bug), the loader cannot find it (no package directories in the search path).

But now for the real question: how did it work before? Terminal 1.15 includes Microsoft_Toolkit_Win32_UI_XamlHost.dll, which statically links to VCRUNTIME140_1_APP.dll! Terminal 1.15 loads the toolkit DLL first, which loads VCRUNTIME140_1_API.dll, and then initializes Microsoft.UI.Xaml.dll. It succeeds because VCRUNTIME140_1_APP.dll is already loaded, satisfying the dependency.

The current fix to Terminal seems good. Appinfo should also be fixed, and backported, if possible (though it has always been broken in this way).

There's also now MSFT:43119564 tracking making sure that this is fixed in the OS too, so no one else runs into this.

Big s/o to @johnstep for doing the hard work here, and @jboelter for fixing this before we rolled it out to the whole of the Terminal install base. Thanks again!

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Culprit-Centennial Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants