Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

Why does GetBinaryType() fail (ERROR_ACCESS_DENIED) on the store WindowsTerminal.exe (ERROR_ACCESS_DENIED)? Can I do anything about that?

And how does CMD know it's a GUI app and consequently not wait for it?

You must be logged in to vote

Replies: 3 comments · 7 replies

Comment options

Does CMD call GetBinaryType? I really don't think so.

The main type of file-peeking it does is figuring out if it's GUI or CUI and for that it reads the PE header directly (via CreateFile/ReadFile --> PIMAGE_OPTIONAL_HEADER32/PIMAGE_OPTIONAL_HEADER64). This then forms the decision on whether to wait for the process.

You must be logged in to vote
7 replies
@DHowett
Comment options

Oh, sorry: it needs to map the file for execution. That is the missing permission.

@vefatica
Comment options

I can run it directly ... not the same?

@DHowett
Comment options

Please re-read the part about how CreateProcess works to understand why you can "run it directly."

@vefatica
Comment options

Do you mean it's using the app alias even when I give the fully-qualified name on a command line? Here, if I execute "WT" (TCC or Win+R) I get d:\wt\windowsterminal.exe.

Right now I have the store version, unzips of 1.21, 1.24, 1.25, and a canary version. I'm trying to figure out an unfortunate behavior where output slows down (but only for the first few chars/lines). I'll be back if I can't do anything about it.

@DHowett
Comment options

I'm only talking about the store version, because it seemed like you were only talking about the store version, when you asked "Why does GetBinaryType() fail (ERROR_ACCESS_DENIED) on the store WindowsTerminal.exe" (emphasis mine).

If you try to execute the store-installed version of WindowsTerminal.exe from the WindowsApps directory or any symlink to that executable, CreateProcess internally fails with ERROR_ACCESS_DENIED and this triggers an internal retry after looking up which package identity is required to run it.

The ACL specifies this DACL:

D:AI(XA;ID;0x1200a9;;;BU;(WIN://SYSAPPID Contains "Microsoft.WindowsTerminal_8wekyb3d8bbwe"))

  • AI - inherited
  • XA - Execute Allow
  • ID - inherited (also)
  • 0x1200a9 - access rights
  • BU - BUILTIN\Users group
  • resource attribute WIN://SYSAPPID contains our package name

and this:

(A;ID;FR;;;BU)

which is BU (BUILTIN\Users) and FR (file read) with no execute bit.

Users are not allowed to execute it.

CreateProcess fails, and then sets WIN://SYSAPPID to the package and tries to re-execute it.

Comment options

However, it is somewhat important to know this. This was not my team's choice. This is a "by design" decision that has had endless ramifications on the platform. I have opinions about this.

Windows Store applications are not intended to be accessed directly. The ACLs on the WindowsApps folder and its subfolders are designed to prevent direct access to the application binary or any of its attendant data.

The ERROR_ACCESS_DENIED is a required part of packaged application launch. It is what CreateProcess uses to determine an EXE was launched that should have been launched as part of a package or with package identity.

This is part of why changing the permissions on WindowsApps or its subfolders breaks Windows.


App execution aliases, on the other hand, are also an abomination. CMD is not launching WindowsTerminal.exe, but rather, %LOCALAPPDATA%\WindowsApps\wt.exe. wt.exe is a 0-byte file with a reparse point indicating exactly which package to launch.

CMD uses internal APIs to determine whether it's a console application. It learns that it is not.

PowerShell does not/cannot, and so it assumes that it is and therefore waits for it to exit.

This is why we made wt.exe a shim that calls CreateProcess again on WindowsTerminal.exe and exits immediately. Because PowerShell would erroneously wait for it to complete.

You must be logged in to vote
0 replies
Comment options

FWIW, I do not see code in GetBinaryTypeW which treats IMAGE_SUBSYSTEM_WINDOWS_CUI any differently. A console application is a Win32 application, and therefore will be considered either SCS_64BIT_BINARY or SCS_32BIT_BINARY. It is not usable to make a determination about whether your shell should wait for it.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.