summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChun-wei Fan <fanchunwei@src.gnome.org>2021-02-02 15:17:54 +0800
committerChun-wei Fan <fanchunwei@src.gnome.org>2021-02-02 17:01:41 +0800
commit8a898afb7ecaee46aaa7fb77de145c7ed571ae67 (patch)
tree47fbc91e4c8b74c613fe5c9f6a7c2b5601b4435b
parent334201f48a2627b1d4d572ddd23332886cd897a4 (diff)
downloadgtk+-uac.meson.master.tar.gz
tools: Generate the UAC manifest stuff insteaduac.meson.master
This way, we can have the version info and identifier name that would be unique to the release and the utility program(s) that we want to embed this manifest with. This also adds flexibility to what we can do with the resulting executable: -Avoid or enforce UAC requirements
-rw-r--r--tools/generate-uac-manifest.py110
-rw-r--r--tools/meson.build19
-rw-r--r--tools/update-icon-cache.exe.manifest17
-rw-r--r--tools/update-icon-cache.rc3
4 files changed, 128 insertions, 21 deletions
diff --git a/tools/generate-uac-manifest.py b/tools/generate-uac-manifest.py
new file mode 100644
index 0000000000..ede6ba5044
--- /dev/null
+++ b/tools/generate-uac-manifest.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python3
+
+"""
+This script generates a Windows manifest file and optionally a resource file to
+determine whether a specified program requires UAC elevation
+"""
+
+import os
+import argparse
+
+DOMAIN_NAME='gnome'
+
+def main():
+ parser = argparse.ArgumentParser(
+ description=__doc__)
+ parser.add_argument('-p', '--package', required=True,
+ help='package name of the executable')
+ parser.add_argument('-n', '--name', required=True,
+ help='name of executable')
+ parser.add_argument('--pkg-version', required=True, dest='version',
+ help='version of package')
+ parser.add_argument('--require-admin', action='store_true', dest='admin',
+ default=False,
+ help='require admin access to application')
+ parser.add_argument('--input-resource-file', dest='resource',
+ default=None,
+ help='existing .rc file to embed UAC manifest (do not generate a new .rc file), must have included winuser.h in it')
+ parser.add_argument('--output-dir', dest='outdir',
+ default=None,
+ help='directory to output resulting files')
+ args = parser.parse_args()
+
+ if args.resource is not None:
+ if not os.path.isfile(args.resource):
+ raise FileNotFoundError("Specified resource file '%s' does not exist" % args.resource)
+
+ generate_manifest(args.package, args.name, args.version, args.admin, args.outdir)
+ write_rc_file(args.name, args.resource, args.outdir)
+
+def generate_manifest(package, name, version, admin, outdir):
+ if version.count('.') == 0:
+ manifest_package_version = version + '.0.0.0'
+ elif version.count('.') == 1:
+ manifest_package_version = version + '.0.0'
+ elif version.count('.') == 2:
+ manifest_package_version = version + '.0'
+ elif version.count('.') == 3:
+ manifest_package_version = version
+ else:
+ parts = version.split('.')
+ manifest_package_version = ''
+ for x in (0, 1, 2, 3):
+ if x == 0:
+ manifest_package_version += parts[x]
+ else:
+ manifest_package_version += '.' + parts[x]
+
+ if outdir is not None:
+ output_file_base_name = os.path.join(outdir, name)
+ else:
+ output_file_base_name = name
+
+ outfile = open(output_file_base_name + '.exe.manifest', 'w+')
+ outfile.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n')
+ outfile.write('<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\n')
+ outfile.write(' <assemblyIdentity version="%s"\n' % manifest_package_version)
+ outfile.write(' processorArchitecture="*"\n')
+ outfile.write(' name="%s.%s.%s.exe"\n' % (DOMAIN_NAME, package, name))
+ outfile.write(' type="win32" />\n')
+ outfile.write(' <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">\n')
+ outfile.write(' <security>\n')
+ outfile.write(' <requestedPrivileges>\n')
+ outfile.write(' <requestedExecutionLevel\n')
+
+ if admin:
+ outfile.write(' level="requireAdministrator"\n')
+ else:
+ outfile.write(' level="asInvoker"\n')
+
+ outfile.write(' uiAccess="false" />\n')
+ outfile.write(' </requestedPrivileges>\n')
+ outfile.write(' </security>\n')
+ outfile.write(' </trustInfo>\n')
+ outfile.write('</assembly>\n')
+ outfile.close()
+
+def write_rc_file(name, resource, outdir):
+ if outdir is not None:
+ output_file_base_name = os.path.join(outdir, name)
+ else:
+ output_file_base_name = name
+
+ if resource is None:
+ outfile = open(output_file_base_name + '.rc', 'w+')
+ outfile.write('#include <winuser.h>')
+ else:
+ if resource != output_file_base_name + '.rc':
+ outfile = open(output_file_base_name + '.rc', 'w+')
+ else:
+ outfile = open(output_file_base_name + '.final.rc', 'w+')
+ srcfile = open(resource, 'r')
+ outfile.write(srcfile.read())
+ srcfile.close()
+
+ outfile.write('\n')
+ outfile.write('CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "%s.exe.manifest"' % name)
+ outfile.close()
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/meson.build b/tools/meson.build
index 3d2ea2eb78..7b82caf132 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -2,7 +2,24 @@
extra_update_icon_cache_objs = []
if win32_enabled
- extra_update_icon_cache_objs = import('windows').compile_resources('update-icon-cache.rc')
+ gen_uac_manifest = find_program('generate-uac-manifest.py')
+
+ uac_exe_pkg = 'gtk4'
+ uac_exe_name = '@0@-update-icon-cache'.format(uac_exe_pkg)
+
+ # Well, we have to forgo the xxx.exe.manifest in the output listing, since
+ # compile_resources doesn't like to consume targets with multiple outputs,
+ # and the xxx.exe.manifest and xxx.rc are tied together
+ uac_rc = custom_target(
+ 'tools/@0@.rc'.format(uac_exe_name),
+ output: ['@0@.rc'.format(uac_exe_name)],
+ command: [gen_uac_manifest,
+ '-p=@0@'.format(uac_exe_pkg),
+ '-n=@0@'.format(uac_exe_name),
+ '--pkg-version=@0@'.format(meson.project_version()),
+ '--output-dir=@OUTDIR@'],
+ )
+ extra_update_icon_cache_objs = import('windows').compile_resources(uac_rc)
endif
gtk_tools = [
diff --git a/tools/update-icon-cache.exe.manifest b/tools/update-icon-cache.exe.manifest
deleted file mode 100644
index f215634abc..0000000000
--- a/tools/update-icon-cache.exe.manifest
+++ /dev/null
@@ -1,17 +0,0 @@
-<?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"
- processorArchitecture="*"
- name="gtk-update-icon-cache.exe"
- 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>
diff --git a/tools/update-icon-cache.rc b/tools/update-icon-cache.rc
deleted file mode 100644
index 86ab7cd6fe..0000000000
--- a/tools/update-icon-cache.rc
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <winuser.h>
-
-CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "update-icon-cache.exe.manifest"