2010-02-21 Yaakov Selkowitz <...> Charles Wilson <...>
[cygwin|mingw] Create UAC manifest files. * libltdl/config/ltmain.m4sh (func_emit_exe_manifest): New function. (func_mode_link) [cygwin|mingw]: Create manifest files for wrapper and target exe when target name matches heuristic that triggers UAC problems for newer win32 OSs. Clean up $cwrapper.manifest on error. Ensure manifest files have executable permission. (func_mode_uninstall): Clean up manifest files. Various reports by Eric Blake, Kai Tietz, and Cesar Strauss. This is a revised version of Yaakov's original patch, that addresses (most of) the comments received previously. Original posted: http://lists.gnu.org/archive/html/libtool-patches/2009-06/msg00058.html The only comment NOT addressed by this version is: Peter Rosin doesn't want this code activated for msvc, but I'm not sure this patch should be modified to guard against a compiler, whose support (in Peter's branch) has not itself yet been merged into master. And I don't know what symbol to use; maybe Peter's branch has a special variable that should be tested? Anyway, IF this patch should be modified to "protect" msvc, I'd sure like somebody to tell me how that should be done: # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then + # Create the UAC manifests first if necessary (but the + # manifest files must have executable permission regardless). like this, maybe: if [ $CC != msvc ]; then + case $output_name in + *instal*|*patch*|*setup*|*update*) Or tell me that such protection should be deferred until Peter's stuff is merged? FYI, Yaakov has submitted all the necessary copyright papers and received acknowledgement from the FSF. -- Chuck
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh index 043d980..1870a79 100644 --- a/libltdl/config/ltmain.m4sh +++ b/libltdl/config/ltmain.m4sh @@ -3733,6 +3733,41 @@ EOF } # end: func_emit_cwrapperexe_src +# func_emit_exe_manifest +# emit a Win32 UAC manifest for executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_exe_manifest () +{ + cat <<EOF +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" +EOF + + case $host in + i?86-*-* ) echo ' processorArchitecture="x86"' ;; + ia64-*-* ) echo ' processorArchitecture="ia64"' ;; + x86_64-*-* ) echo ' processorArchitecture="amd64"' ;; + *) echo ' processorArchitecture="*"' ;; + esac + + cat <<EOF + name="$host_os.$PROGRAM.$outputname" + type="win32"/> + + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> +EOF +} + # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () @@ -7554,7 +7589,7 @@ EOF cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + trap "$RM $cwrappersource $cwrapper $cwrapper.manifest; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource @@ -7574,6 +7609,16 @@ EOF $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then + # Create the UAC manifests first if necessary (but the + # manifest files must have executable permission regardless). + case $output_name in + *instal*|*patch*|*setup*|*update*) + func_emit_exe_manifest > $cwrapper.manifest + func_emit_exe_manifest > $output_path/$objdir/$output_name.exe.manifest + chmod +x $cwrapper.manifest + chmod +x $output_path/$objdir/$output_name.exe.manifest + ;; + esac $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result @@ -8076,8 +8121,9 @@ func_mode_uninstall () # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + rmfiles="$rmfiles ${name}.manifest $objdir/${name}.manifest" if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" + rmfiles="$rmfiles $objdir/lt-$name $objdir/lt-${name}.manifest" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c"