| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 | |
| 7 from grit.format.policy_templates.writers import template_writer | |
| 8 | |
| 9 | |
| 10 NEWLINE = '\r\n' | |
| 11 | |
| 12 | |
| 13 def GetWriter(config): | |
| 14 '''Factory method for creating AdmWriter objects. | |
| 15 See the constructor of TemplateWriter for description of | |
| 16 arguments. | |
| 17 ''' | |
| 18 return AdmWriter(['win'], config) | |
| 19 | |
| 20 | |
| 21 class IndentedStringBuilder: | |
| 22 '''Utility class for building text with indented lines.''' | |
| 23 | |
| 24 def __init__(self): | |
| 25 self.lines = [] | |
| 26 self.indent = '' | |
| 27 | |
| 28 def AddLine(self, string='', indent_diff=0): | |
| 29 '''Appends a string with indentation and a linebreak to |self.lines|. | |
| 30 | |
| 31 Args: | |
| 32 string: The string to print. | |
| 33 indent_diff: the difference of indentation of the printed line, | |
| 34 compared to the next/previous printed line. Increment occurs | |
| 35 after printing the line, while decrement occurs before that. | |
| 36 ''' | |
| 37 indent_diff *= 2 | |
| 38 if indent_diff < 0: | |
| 39 self.indent = self.indent[(-indent_diff):] | |
| 40 if string != '': | |
| 41 self.lines.append(self.indent + string) | |
| 42 else: | |
| 43 self.lines.append('') | |
| 44 if indent_diff > 0: | |
| 45 self.indent += ''.ljust(indent_diff) | |
| 46 | |
| 47 def AddLines(self, other): | |
| 48 '''Appends the content of another |IndentedStringBuilder| to |self.lines|. | |
| 49 Indentation of the added lines will be the sum of |self.indent| and | |
| 50 their original indentation. | |
| 51 | |
| 52 Args: | |
| 53 other: The buffer from which lines are copied. | |
| 54 ''' | |
| 55 for line in other.lines: | |
| 56 self.AddLine(line) | |
| 57 | |
| 58 def ToString(self): | |
| 59 '''Returns |self.lines| as text string.''' | |
| 60 return NEWLINE.join(self.lines) | |
| 61 | |
| 62 | |
| 63 class AdmWriter(template_writer.TemplateWriter): | |
| 64 '''Class for generating policy templates in Windows ADM format. | |
| 65 It is used by PolicyTemplateGenerator to write ADM files. | |
| 66 ''' | |
| 67 | |
| 68 TYPE_TO_INPUT = { | |
| 69 'string': 'EDITTEXT', | |
| 70 'int': 'NUMERIC', | |
| 71 'string-enum': 'DROPDOWNLIST', | |
| 72 'int-enum': 'DROPDOWNLIST', | |
| 73 'list': 'LISTBOX', | |
| 74 'string-enum-list': 'LISTBOX', | |
| 75 'dict': 'EDITTEXT' | |
| 76 } | |
| 77 | |
| 78 def _Escape(self, string): | |
| 79 return string.replace('.', '_') | |
| 80 | |
| 81 def _AddGuiString(self, name, value): | |
| 82 # The |name| must be escaped. | |
| 83 assert name == self._Escape(name) | |
| 84 # Escape newlines in the value. | |
| 85 value = value.replace('\n', '\\n') | |
| 86 if name in self.strings_seen: | |
| 87 err = ('%s was added as "%s" and now added again as "%s"' % | |
| 88 (name, self.strings_seen[name], value)) | |
| 89 assert value == self.strings_seen[name], err | |
| 90 else: | |
| 91 self.strings_seen[name] = value | |
| 92 line = '%s="%s"' % (name, value) | |
| 93 self.strings.AddLine(line) | |
| 94 | |
| 95 def _WriteSupported(self, builder): | |
| 96 builder.AddLine('#if version >= 4', 1) | |
| 97 builder.AddLine('SUPPORTED !!SUPPORTED_WINXPSP2') | |
| 98 builder.AddLine('#endif', -1) | |
| 99 | |
| 100 def _WritePart(self, policy, key_name, builder): | |
| 101 '''Writes the PART ... END PART section of a policy. | |
| 102 | |
| 103 Args: | |
| 104 policy: The policy to write to the output. | |
| 105 key_name: The registry key backing the policy. | |
| 106 builder: Builder to append lines to. | |
| 107 ''' | |
| 108 policy_part_name = self._Escape(policy['name'] + '_Part') | |
| 109 self._AddGuiString(policy_part_name, policy['label']) | |
| 110 | |
| 111 # Print the PART ... END PART section: | |
| 112 builder.AddLine() | |
| 113 adm_type = self.TYPE_TO_INPUT[policy['type']] | |
| 114 builder.AddLine('PART !!%s %s' % (policy_part_name, adm_type), 1) | |
| 115 if policy['type'] in ('list', 'string-enum-list'): | |
| 116 # Note that the following line causes FullArmor ADMX Migrator to create | |
| 117 # corrupt ADMX files. Please use admx_writer to get ADMX files. | |
| 118 builder.AddLine('KEYNAME "%s\\%s"' % (key_name, policy['name'])) | |
| 119 builder.AddLine('VALUEPREFIX ""') | |
| 120 else: | |
| 121 builder.AddLine('VALUENAME "%s"' % policy['name']) | |
| 122 if policy['type'] == 'int': | |
| 123 # The default max for NUMERIC values is 9999 which is too small for us. | |
| 124 builder.AddLine('MIN 0 MAX 2000000000') | |
| 125 if policy['type'] in ('string', 'dict'): | |
| 126 # The default max for EDITTEXT values is 1023, which is too small for | |
| 127 # big JSON blobs and other string policies. | |
| 128 builder.AddLine('MAXLEN 1000000') | |
| 129 if policy['type'] in ('int-enum', 'string-enum'): | |
| 130 builder.AddLine('ITEMLIST', 1) | |
| 131 for item in policy['items']: | |
| 132 if policy['type'] == 'int-enum': | |
| 133 value_text = 'NUMERIC ' + str(item['value']) | |
| 134 else: | |
| 135 value_text = '"' + item['value'] + '"' | |
| 136 string_id = self._Escape(item['name'] + '_DropDown') | |
| 137 builder.AddLine('NAME !!%s VALUE %s' % (string_id, value_text)) | |
| 138 self._AddGuiString(string_id, item['caption']) | |
| 139 builder.AddLine('END ITEMLIST', -1) | |
| 140 builder.AddLine('END PART', -1) | |
| 141 | |
| 142 def _WritePolicy(self, policy, key_name, builder): | |
| 143 if policy['type'] == 'external': | |
| 144 # This type can only be set through cloud policy. | |
| 145 return | |
| 146 | |
| 147 policy_name = self._Escape(policy['name'] + '_Policy') | |
| 148 self._AddGuiString(policy_name, policy['caption']) | |
| 149 builder.AddLine('POLICY !!%s' % policy_name, 1) | |
| 150 self._WriteSupported(builder) | |
| 151 policy_explain_name = self._Escape(policy['name'] + '_Explain') | |
| 152 self._AddGuiString(policy_explain_name, policy['desc']) | |
| 153 builder.AddLine('EXPLAIN !!' + policy_explain_name) | |
| 154 | |
| 155 if policy['type'] == 'main': | |
| 156 builder.AddLine('VALUENAME "%s"' % policy['name']) | |
| 157 builder.AddLine('VALUEON NUMERIC 1') | |
| 158 builder.AddLine('VALUEOFF NUMERIC 0') | |
| 159 else: | |
| 160 self._WritePart(policy, key_name, builder) | |
| 161 | |
| 162 builder.AddLine('END POLICY', -1) | |
| 163 builder.AddLine() | |
| 164 | |
| 165 def WriteComment(self, comment): | |
| 166 self.lines.AddLine('; ' + comment) | |
| 167 | |
| 168 def WritePolicy(self, policy): | |
| 169 if self.CanBeMandatory(policy): | |
| 170 self._WritePolicy(policy, | |
| 171 self.config['win_reg_mandatory_key_name'], | |
| 172 self.policies) | |
| 173 | |
| 174 def WriteRecommendedPolicy(self, policy): | |
| 175 self._WritePolicy(policy, | |
| 176 self.config['win_reg_recommended_key_name'], | |
| 177 self.recommended_policies) | |
| 178 | |
| 179 def BeginPolicyGroup(self, group): | |
| 180 category_name = self._Escape(group['name'] + '_Category') | |
| 181 self._AddGuiString(category_name, group['caption']) | |
| 182 self.policies.AddLine('CATEGORY !!' + category_name, 1) | |
| 183 | |
| 184 def EndPolicyGroup(self): | |
| 185 self.policies.AddLine('END CATEGORY', -1) | |
| 186 self.policies.AddLine('') | |
| 187 | |
| 188 def BeginRecommendedPolicyGroup(self, group): | |
| 189 category_name = self._Escape(group['name'] + '_Category') | |
| 190 self._AddGuiString(category_name, group['caption']) | |
| 191 self.recommended_policies.AddLine('CATEGORY !!' + category_name, 1) | |
| 192 | |
| 193 def EndRecommendedPolicyGroup(self): | |
| 194 self.recommended_policies.AddLine('END CATEGORY', -1) | |
| 195 self.recommended_policies.AddLine('') | |
| 196 | |
| 197 def _CreateTemplate(self, category_path, key_name, policies): | |
| 198 '''Creates the whole ADM template except for the [Strings] section, and | |
| 199 returns it as an |IndentedStringBuilder|. | |
| 200 | |
| 201 Args: | |
| 202 category_path: List of strings representing the category path. | |
| 203 key_name: Main registry key backing the policies. | |
| 204 policies: ADM code for all the policies in an |IndentedStringBuilder|. | |
| 205 ''' | |
| 206 lines = IndentedStringBuilder() | |
| 207 for part in category_path: | |
| 208 lines.AddLine('CATEGORY !!' + part, 1) | |
| 209 lines.AddLine('KEYNAME "%s"' % key_name) | |
| 210 lines.AddLine() | |
| 211 | |
| 212 lines.AddLines(policies) | |
| 213 | |
| 214 for part in category_path: | |
| 215 lines.AddLine('END CATEGORY', -1) | |
| 216 lines.AddLine() | |
| 217 | |
| 218 return lines | |
| 219 | |
| 220 def BeginTemplate(self): | |
| 221 if self._GetChromiumVersionString() is not None: | |
| 222 self.WriteComment(self.config['build'] + ' version: ' + \ | |
| 223 self._GetChromiumVersionString()) | |
| 224 self._AddGuiString(self.config['win_supported_os'], | |
| 225 self.messages['win_supported_winxpsp2']['text']) | |
| 226 category_path = self.config['win_mandatory_category_path'] | |
| 227 recommended_category_path = self.config['win_recommended_category_path'] | |
| 228 recommended_name = '%s - %s' % \ | |
| 229 (self.config['app_name'], self.messages['doc_recommended']['text']) | |
| 230 if self.config['build'] == 'chrome': | |
| 231 self._AddGuiString(category_path[0], 'Google') | |
| 232 self._AddGuiString(category_path[1], self.config['app_name']) | |
| 233 self._AddGuiString(recommended_category_path[1], recommended_name) | |
| 234 elif self.config['build'] == 'chromium': | |
| 235 self._AddGuiString(category_path[0], self.config['app_name']) | |
| 236 self._AddGuiString(recommended_category_path[0], recommended_name) | |
| 237 # All the policies will be written into self.policies. | |
| 238 # The final template text will be assembled into self.lines by | |
| 239 # self.EndTemplate(). | |
| 240 | |
| 241 def EndTemplate(self): | |
| 242 # Copy policies into self.lines. | |
| 243 policy_class = self.config['win_group_policy_class'].upper() | |
| 244 for class_name in ['MACHINE', 'USER']: | |
| 245 if policy_class != 'BOTH' and policy_class != class_name: | |
| 246 continue | |
| 247 self.lines.AddLine('CLASS ' + class_name, 1) | |
| 248 self.lines.AddLines(self._CreateTemplate( | |
| 249 self.config['win_mandatory_category_path'], | |
| 250 self.config['win_reg_mandatory_key_name'], | |
| 251 self.policies)) | |
| 252 self.lines.AddLines(self._CreateTemplate( | |
| 253 self.config['win_recommended_category_path'], | |
| 254 self.config['win_reg_recommended_key_name'], | |
| 255 self.recommended_policies)) | |
| 256 self.lines.AddLine('', -1) | |
| 257 # Copy user strings into self.lines. | |
| 258 self.lines.AddLine('[Strings]') | |
| 259 self.lines.AddLines(self.strings) | |
| 260 | |
| 261 def Init(self): | |
| 262 # String buffer for building the whole ADM file. | |
| 263 self.lines = IndentedStringBuilder() | |
| 264 # String buffer for building the strings section of the ADM file. | |
| 265 self.strings = IndentedStringBuilder() | |
| 266 # Map of strings seen, to avoid duplicates. | |
| 267 self.strings_seen = {} | |
| 268 # String buffer for building the policies of the ADM file. | |
| 269 self.policies = IndentedStringBuilder() | |
| 270 # String buffer for building the recommended policies of the ADM file. | |
| 271 self.recommended_policies = IndentedStringBuilder() | |
| 272 | |
| 273 def GetTemplateText(self): | |
| 274 return self.lines.ToString() | |
| OLD | NEW |