forked from GNOME/gtk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate-uac-manifest.py
137 lines (118 loc) · 4.38 KB
/
generate-uac-manifest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python3
#
# Copyright © 2021 Chun-wei Fan.
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Original author: Chun-wei Fan <[email protected]>
"""
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 windows.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("#define WIN32_LEAN_AND_MEAN\n")
outfile.write("#include <windows.h>\n")
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()