/// <summary>
 /// Gets the RegistryRootType from an integer representation of the root.
 /// </summary>
 /// <param name="sourceLineNumbers">The source line information for the root.</param>
 /// <param name="tableName">The name of the table containing the field.</param>
 /// <param name="field">The field containing the root value.</param>
 /// <param name="registryRootType">The strongly-typed representation of the root.</param>
 /// <returns>true if the value could be converted; false otherwise.</returns>
 private bool GetRegistryRootType(SourceLineNumberCollection sourceLineNumbers, string tableName, Field field, out Wix.RegistryRootType registryRootType)
 {
     switch (Convert.ToInt32(field.Data))
     {
         case (-1):
             registryRootType = Wix.RegistryRootType.HKMU;
             return true;
         case MsiInterop.MsidbRegistryRootClassesRoot:
             registryRootType = Wix.RegistryRootType.HKCR;
             return true;
         case MsiInterop.MsidbRegistryRootCurrentUser:
             registryRootType = Wix.RegistryRootType.HKCU;
             return true;
         case MsiInterop.MsidbRegistryRootLocalMachine:
             registryRootType = Wix.RegistryRootType.HKLM;
             return true;
         case MsiInterop.MsidbRegistryRootUsers:
             registryRootType = Wix.RegistryRootType.HKU;
             return true;
         default:
             this.core.OnMessage(WixWarnings.IllegalColumnValue(sourceLineNumbers, tableName, field.Column.Name, field.Data));
             registryRootType = Wix.RegistryRootType.HKCR; // assign anything to satisfy the out parameter
             return false;
     }
 }
Exemple #2
0
 /// <summary>
 /// Determine if this field is identical to another field.
 /// </summary>
 /// <param name="field">The other field to compare to.</param>
 /// <returns>true if they are equal; false otherwise.</returns>
 public bool IsIdentical(Field field)
 {
     return (this.columnDefinition.Name == field.columnDefinition.Name &&
         ((null != this.data && this.data.Equals(field.data)) || (null == this.data && null == field.data)));
 }
Exemple #3
0
        /// <summary>
        /// Gets the modularized version of the field data.
        /// </summary>
        /// <param name="field">The field to modularize.</param>
        /// <param name="modularizationGuid">String containing the GUID of the Merge Module to append the the field value, if appropriate.</param>
        /// <param name="suppressModularizationIdentifiers">Optional collection of identifiers that should not be modularized.</param>
        /// <remarks>moduleGuid is expected to be null when not being used to compile a Merge Module.</remarks>
        /// <returns>The modularized version of the field data.</returns>
        internal string GetModularizedValue(Field field, string modularizationGuid, Hashtable suppressModularizationIdentifiers)
        {
            Debug.Assert(null != field.Data && 0 < ((string)field.Data).Length);
            string fieldData = Convert.ToString(field.Data, CultureInfo.InvariantCulture);

            if (null != modularizationGuid && ColumnModularizeType.None != field.Column.ModularizeType && !(Util.IsStandardAction(fieldData) || Util.IsStandardProperty(fieldData)))
            {
                StringBuilder sb;
                int start;
                ColumnModularizeType modularizeType = field.Column.ModularizeType;

                // special logic for the ControlEvent table's Argument column
                // this column requires different modularization methods depending upon the value of the Event column
                if (ColumnModularizeType.ControlEventArgument == field.Column.ModularizeType)
                {
                    switch (this[2].ToString())
                    {
                        case "CheckExistingTargetPath": // redirectable property name
                        case "CheckTargetPath":
                        case "DoAction": // custom action name
                        case "NewDialog": // dialog name
                        case "SelectionBrowse":
                        case "SetTargetPath":
                        case "SpawnDialog":
                        case "SpawnWaitDialog":
                            if (CompilerCore.IsIdentifier(fieldData))
                            {
                                modularizeType = ColumnModularizeType.Column;
                            }
                            else
                            {
                                modularizeType = ColumnModularizeType.Property;
                            }
                            break;
                        default: // formatted
                            modularizeType = ColumnModularizeType.Property;
                            break;
                    }
                }
                else if (ColumnModularizeType.ControlText == field.Column.ModularizeType)
                {
                    // icons are stored in the Binary table, so they get column-type modularization
                    if (("Bitmap" == this[2].ToString() || "Icon" == this[2].ToString()) && CompilerCore.IsIdentifier(fieldData))
                    {
                        modularizeType = ColumnModularizeType.Column;
                    }
                    else
                    {
                        modularizeType = ColumnModularizeType.Property;
                    }
                }

                switch (modularizeType)
                {
                    case ColumnModularizeType.Column:
                        // ensure the value is an identifier (otherwise it shouldn't be modularized this way)
                        if (!CompilerCore.IsIdentifier(fieldData))
                        {
                            throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_CannotModularizeIllegalID, fieldData));
                        }

                        // if we're not supposed to suppress modularization of this identifier
                        if (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData))
                        {
                            fieldData = String.Concat(fieldData, ".", modularizationGuid);
                        }
                        break;

                    case ColumnModularizeType.Property:
                    case ColumnModularizeType.Condition:
                        Regex regex;
                        if (ColumnModularizeType.Property == modularizeType)
                        {
                            regex = new Regex(@"\[(?<identifier>[#$!]?[a-zA-Z_][a-zA-Z0-9_\.]*)]", RegexOptions.Singleline | RegexOptions.ExplicitCapture);
                        }
                        else
                        {
                            Debug.Assert(ColumnModularizeType.Condition == modularizeType);

                            // This heinous looking regular expression is actually quite an elegant way
                            // to shred the entire condition into the identifiers that need to be
                            // modularized.  Let's break it down piece by piece:
                            //
                            // 1. Look for the operators: NOT, EQV, XOR, OR, AND, IMP (plus a space).  Note that the
                            //    regular expression is case insensitive so we don't have to worry about
                            //    all the permutations of these strings.
                            // 2. Look for quoted strings.  Quoted strings are just text and are ignored
                            //    outright.
                            // 3. Look for environment variables.  These look like identifiers we might
                            //    otherwise be interested in but start with a percent sign.  Like quoted
                            //    strings these enviroment variable references are ignored outright.
                            // 4. Match all identifiers that are things that need to be modularized.  Note
                            //    the special characters (!, $, ?, &) that denote Component and Feature states.
                            regex = new Regex(@"NOT\s|EQV\s|XOR\s|OR\s|AND\s|IMP\s|"".*?""|%[a-zA-Z_][a-zA-Z0-9_\.]*|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);

                            // less performant version of the above with captures showing where everything lives
                            // regex = new Regex(@"(?<operator>NOT|EQV|XOR|OR|AND|IMP)|(?<string>"".*?"")|(?<environment>%[a-zA-Z_][a-zA-Z0-9_\.]*)|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)",RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
                        }

                        MatchCollection matches = regex.Matches(fieldData);

                        sb = new StringBuilder(fieldData);

                        // notice how this code walks backward through the list
                        // because it modifies the string as we through it
                        for (int i = matches.Count - 1; 0 <= i; i--)
                        {
                            Group group = matches[i].Groups["identifier"];
                            if (group.Success)
                            {
                                string identifier = group.Value;
                                if (!Util.IsStandardProperty(identifier) && (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(identifier)))
                                {
                                    sb.Insert(group.Index + group.Length, '.');
                                    sb.Insert(group.Index + group.Length + 1, modularizationGuid);
                                }
                            }
                        }

                        fieldData = sb.ToString();
                        break;

                    case ColumnModularizeType.CompanionFile:
                        // if we're not supposed to ignore this identifier and the value does not start with
                        // a digit, we must have a companion file so modularize it
                        if ((null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData)) &&
                            0 < fieldData.Length && !Char.IsDigit(fieldData, 0))
                        {
                            fieldData = String.Concat(fieldData, ".", modularizationGuid);
                        }
                        break;

                    case ColumnModularizeType.Icon:
                        if (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData))
                        {
                            start = fieldData.LastIndexOf(".", StringComparison.Ordinal);
                            if (-1 == start)
                            {
                                fieldData = String.Concat(fieldData, ".", modularizationGuid);
                            }
                            else
                            {
                                fieldData = String.Concat(fieldData.Substring(0, start), ".", modularizationGuid, fieldData.Substring(start));
                            }
                        }
                        break;

                    case ColumnModularizeType.SemicolonDelimited:
                        string[] keys = fieldData.Split(';');
                        for (int i = 0; i < keys.Length; ++i)
                        {
                            keys[i] = String.Concat(keys[i], ".", modularizationGuid);
                        }
                        fieldData = String.Join(";", keys);
                        break;
                }
            }

            return fieldData;
        }
Exemple #4
0
        /// <summary>
        /// Returns the field data in a format usable in IDT files.
        /// </summary>
        /// <param name="field">The field to modularize.</param>
        /// <param name="moduleGuid">String containing the GUID of the Merge Module to append the the field value, if appropriate.</param>
        /// <param name="ignoreModularizations">Optional collection of identifers that should not be modularized.</param>
        /// <remarks>moduleGuid is expected to be null when not being used to compile a Merge Module.</remarks>
        /// <returns>Field data in string IDT format.</returns>
        public string GetIdtValue(Field field, string moduleGuid, IgnoreModularizationCollection ignoreModularizations)
        {
            if (field.Column.IsUnreal)
            {
                return null;
            }
            if (null == field.Data)
            {
                return String.Empty;
            }

            string fieldData = Convert.ToString(field.Data);

            // special idt-specific escaping
            if (field.Column.EscapeIdtCharacters)
            {
                fieldData = fieldData.Replace('\t', '\x10');
                fieldData = fieldData.Replace('\r', '\x11');
                fieldData = fieldData.Replace('\n', '\x19');
            }

            string idtValue;
            if (null != moduleGuid && ColumnModularizeType.None != field.Column.ModularizeType && !Common.IsExcludedFromModularization(fieldData))
            {
                StringBuilder sb;
                int start;
                ColumnModularizeType modularizeType = field.Column.ModularizeType;

                // special logic for the ControlEvent table's Argument column
                // this column requires different modularization methods depending upon the value of the Event column
                if (ColumnModularizeType.ControlEventArgument == field.Column.ModularizeType)
                {
                    switch (this.row[2].ToString())
                    {
                        case "CheckExistingTargetPath": // redirectable property name
                        case "CheckTargetPath":
                        case "DoAction": // custom action name
                        case "NewDialog": // dialog name
                        case "SelectionBrowse":
                        case "SetTargetPath":
                        case "SpawnDialog":
                        case "SpawnWaitDialog":
                            if (CompilerCore.IsIdentifier(fieldData))
                            {
                                modularizeType = ColumnModularizeType.Column;
                            }
                            else
                            {
                                modularizeType = ColumnModularizeType.Property;
                            }
                            break;
                        default: // formatted
                            modularizeType = ColumnModularizeType.Property;
                            break;
                    }
                }

                switch (modularizeType)
                {
                    case ColumnModularizeType.Column:
                        // ensure the value is an identifier (otherwise it shouldn't be modularized this way)
                        if (!CompilerCore.IsIdentifier(fieldData))
                        {
                            throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "The value '{0}' is not a legal identifier and therefore cannot be modularized.", fieldData));
                        }

                        // if we're not supposed to ignore this identifier
                        if (null == ignoreModularizations || !ignoreModularizations.ShouldIgnoreModularization(fieldData))
                        {
                            idtValue = String.Concat(fieldData, ".", moduleGuid);
                        }
                        else
                        {
                            idtValue = fieldData;
                        }
                        break;

                    case ColumnModularizeType.Property:
                    case ColumnModularizeType.Condition:
                        Regex regex;
                        if (ColumnModularizeType.Property == modularizeType)
                        {
                            regex = new Regex(@"\[(?<identifier>[#$!]?[a-zA-Z_][a-zA-Z0-9_\.]*)]", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture);
                        }
                        else
                        {
                            Debug.Assert(ColumnModularizeType.Condition == modularizeType);

                            // This heinous looking regular expression is actually quite an elegant way
                            // to shred the entire condition into the identifiers that need to be
                            // modularized.  Let's break it down piece by piece:
                            //
                            // 1. Look for the operators: NOT, EQV, XOR, OR, AND, IMP.  Note that the
                            //    regular expression is case insensitive so we don't have to worry about
                            //    all the permutations of these strings.
                            // 2. Look for quoted strings.  Quoted strings are just text and are ignored
                            //    outright.
                            // 3. Look for environment variables.  These look like identifiers we might
                            //    otherwise be interested in but start with a percent sign.  Like quoted
                            //    strings these enviroment variable references are ignored outright.
                            // 4. Match all identifiers that are things that need to be modularized.  Note
                            //    the special characters (!, $, ?, &) that denote Component and Feature states.
                            regex = new Regex(@"NOT|EQV|XOR|OR|AND|IMP|"".*?""|%[a-zA-Z_][a-zA-Z0-9_\.]*|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);

                            // less performant version of the above with captures showing where everything lives
                            // regex = new Regex(@"(?<operator>NOT|EQV|XOR|OR|AND|IMP)|(?<string>"".*?"")|(?<environment>%[a-zA-Z_][a-zA-Z0-9_\.]*)|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
                        }

                        MatchCollection matches = regex.Matches(fieldData);

                        sb = new StringBuilder(fieldData);

                        // notice how this code walks backward through the list
                        // because it modifies the string as we through it
                        for (int i = matches.Count - 1; 0 <= i; i--)
                        {
                            Group group = matches[i].Groups["identifier"];
                            if (group.Success)
                            {
                                string identifier = group.Value;
                                if (!Common.IsStandardProperty(identifier) && (null == ignoreModularizations || !ignoreModularizations.ShouldIgnoreModularization(identifier)))
                                {
                                    sb.Insert(group.Index + group.Length, '.');
                                    sb.Insert(group.Index + group.Length + 1, moduleGuid);
                                }
                            }
                        }

                        idtValue = sb.ToString();
                        break;

                    case ColumnModularizeType.CompanionFile:
                        // if we're not supposed to ignore this identifier and the value does not start with
                        // a digit, we must have a companion file so modularize it
                        if ((null == ignoreModularizations || !ignoreModularizations.ShouldIgnoreModularization(fieldData)) &&
                            0 < fieldData.Length && !Char.IsDigit(fieldData, 0))
                        {
                            idtValue = String.Concat(fieldData, ".", moduleGuid);
                        }
                        else
                        {
                            idtValue = fieldData;
                        }
                        break;

                    case ColumnModularizeType.Icon:
                        if (null == ignoreModularizations || !ignoreModularizations.ShouldIgnoreModularization(fieldData))
                        {
                            start = fieldData.LastIndexOf(".");
                            if (-1 == start)
                            {
                                idtValue = String.Concat(fieldData, ".", moduleGuid);
                            }
                            else
                            {
                                idtValue = String.Concat(fieldData.Substring(0, start), ".", moduleGuid, fieldData.Substring(start));
                            }
                        }
                        else
                        {
                            idtValue = fieldData;
                        }
                        break;

                    case ColumnModularizeType.SemicolonDelimited:
                        string[] keys = fieldData.Split(";".ToCharArray());
                        for (int i = 0; i < keys.Length; ++i)
                        {
                            keys[i] = String.Concat(keys[i], ".", moduleGuid);
                        }
                        idtValue = String.Join(";", keys);
                        break;

                    default:
                        idtValue = fieldData;
                        break;
                }
            }
            else // no modularization necessary, just use the field data
            {
                idtValue = fieldData;
            }

            return idtValue;
        }
Exemple #5
0
 /// <summary>
 /// Basic constructor for struct
 /// </summary>
 /// <param name="row">Row for the field.</param>
 /// <param name="field">Field needing further resolution.</param>
 public DelayedField(Row row, Field field)
 {
     this.Row = row;
     this.Field = field;
 }
 private static string SafeConvertField(Wix3.Field field)
 {
     return(field?.Data?.ToString());
 }
Exemple #7
0
 /// <summary>
 /// Determine if this field is identical to another field.
 /// </summary>
 /// <param name="field">The other field to compare to.</param>
 /// <returns>true if they are equal; false otherwise.</returns>
 public bool IsIdentical(Field field)
 {
     return (this.columnDefinition.Name == field.columnDefinition.Name) && (this.data.Equals(field.data));
 }