Native BootstrapApplication payloads folder isn't added to LoadLibrary search path #5435

Open
nirbar opened this Issue Nov 15, 2016 · 2 comments

Projects

None yet

3 participants

@nirbar
nirbar commented Nov 15, 2016

When creating a custom native bootstrap application that depends on other shared library (.dll ) files, the payloads folder isn't added to LoadLibrary search paths.
Consequently, loading the custom bootstrap application fails with error:

Error 0x8007007e: Failed to load UX DLL.

This happens with WiX 3.10.3 on Windows 10 but should reproduce on any Windows version

Reproducing:

  1. Create a custom native bootstrap application that depends on non-trivial shared library files. In my case, that's a BootstrapApplication with Qt-based UI
  2. Use the custom BA in the bundle:
    <BootstrapperApplication Id="Qt" SourceFile="$(var.QtBootstrapApplication.TargetPath)">
      
      <!-- Qt DLL -->
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Core.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Cored.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Gui.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Guid.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Network.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Networkd.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Qml.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Qmld.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Quick.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5Quickd.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5QuickControls2.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5QuickControls2d.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5QuickTemplates2.dll"/>
      <Payload SourceFile="C:\Program Files (x86)\Qt\5.7\msvc2015\bin\Qt5QuickTemplates2d.dll"/>

      <!-- QML files -->
      <Payload SourceFile="$(var.QtBootstrapApplication.ProjectDir)main.qml"/>
      <Payload SourceFile="$(var.QtBootstrapApplication.ProjectDir)Page1.qml"/>
      <Payload SourceFile="$(var.QtBootstrapApplication.ProjectDir)Page1Form.ui.qml"/>

    </BootstrapperApplication>
  1. Run the bootstrapper and you'll get the aforementioned failure

The expected behavior is for burn to add the BA payloads folder to DLL default search paths.

Fix

I'll create a pull request soon. The fix attempts to call SetDefaultDllDirectories and AddDllDirectory to add the BA payloads folder to default LoadLibrary's search path.

Since SetDefaultDllDirectories and AddDllDirectory are only supported on Windows 8/Server 2012 and later, the fix doesn't fail if these functions aren't found in Kernel32.dll

@rseanhall
Member

The engine isn't locking down the search paths in the process that loads the BA. Why can't the custom BA be built where those shared DLLs are declared as delay loaded? Then the BA could setup the environment that it needs before loading the shared DLLs.

@nirbar
nirbar commented Nov 15, 2016

By default, the search paths don't include the location of the BA payloads. Default contains the bootstrapper's executable, working directory, PATH folders and system folders.

AFAIK, when you have a depndency written to your PE then you can't change it to delay load, so you just fail to load and there's no other way around it that I'm aware of.

@barnson barnson added this to the v3.11 milestone Nov 22, 2016
@barnson barnson added the burn label Nov 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment