diskuv / dkml-installer-ocaml

The Windows-friendly distribution of OCaml
Apache License 2.0
63 stars 2 forks source link

Prior install of MSVC skips to dkml-install-user-runner.exe and fails permissions #4

Closed jonahbeckford closed 2 years ago

jonahbeckford commented 2 years ago

20220801_220132_trimmed

jonahbeckford commented 2 years ago

Problem: Installer Detection Technology

The problem seems to be described at https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works#installer-detection-technology :

Installer detection only applies to:

  • 32-bit executable files.
  • Applications without a requested execution level attribute.
  • Interactive processes running as a standard user with UAC enabled.

Before a 32-bit process is created, the following attributes are checked to determine whether it is an installer:

  • The file name includes keywords such as "install," "setup," or "update."

We are using a 32-bit installer, even with x86_64 in the name:

$ file setup-diskuv-ocaml-windows_x86_64-0.4.0.exe
setup-diskuv-ocaml-windows_x86_64-0.4.0.exe: PE32 executable (console) Intel 80386, for MS Windows

However, the embedded files (the files that will be installed) are 64-bit:

$ file bin/dkml-install-user-runner.exe
bin/dkml-install-user-runner.exe: PE32+ executable (console) x86-64, for MS Windows

We are in a gray area because:

  1. We are clearly in an installer, and the permissions check is in the process that has a special keyword -install- in it; Windows is correctly detecting it is an installer.
  2. The parent process is 32-bit but not the process with -install--.

Either way, it seems the conditions apply.

Resolution

One of the conditions from the Problem description is:

  • Applications without a requested execution level attribute.

We already embedded a manifest for dkml-install-admin-runner.exe using https://docs.microsoft.com/en-us/cpp/build/reference/manifestuac-embeds-uac-information-in-manifest?view=msvc-170 level=requireAdministrator but no manifest was present for dkml-install-user-runner.exe.

So fix is to explicitly embed a manifest with level=asInvoker for dkml-install-user-runner.exe, even though level=asInvoker is the default, because the Installer Detection Technology may require an explicit manifest.

jonahbeckford commented 2 years ago

Code Fix: https://github.com/diskuv/dkml-install-api/commit/df5e7923be31cf1bd5fc797360436fb3cebd3e2d

Available in: https://github.com/diskuv/dkml-installer-ocaml/releases/tag/v0.4.1_r2

jonahbeckford commented 2 years ago

Works. Closing!

jonahbeckford commented 2 years ago

Final comment: This seems like only an issue if dkml-install-admin-runner.exe was not run by setup.exe. That happens if you already have a compatible MSVC, including when you have a previous partial installation that successfully installed MSVC but failed in the non-admin dkml-install-user-runner.exe portion.

The previous partial installation describes #2