aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Compiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Compiler.cs')
-rw-r--r--src/WixToolset.Core/Compiler.cs199
1 files changed, 112 insertions, 87 deletions
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index 926a46c5..184c5b3e 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -5,7 +5,6 @@ namespace WixToolset.Core
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.Diagnostics; 7 using System.Diagnostics;
8 using System.Diagnostics.CodeAnalysis;
9 using System.Globalization; 8 using System.Globalization;
10 using System.IO; 9 using System.IO;
11 using System.Linq; 10 using System.Linq;
@@ -2107,6 +2106,7 @@ namespace WixToolset.Core
2107 2106
2108 var comPlusBits = CompilerConstants.IntegerNotSet; 2107 var comPlusBits = CompilerConstants.IntegerNotSet;
2109 string condition = null; 2108 string condition = null;
2109 string subdirectory = null;
2110 var encounteredODBCDataSource = false; 2110 var encounteredODBCDataSource = false;
2111 var files = 0; 2111 var files = 0;
2112 var guid = "*"; 2112 var guid = "*";
@@ -2163,16 +2163,16 @@ namespace WixToolset.Core
2163 break; 2163 break;
2164 case "DisableRegistryReflection": 2164 case "DisableRegistryReflection":
2165 disableRegistryReflection = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2165 disableRegistryReflection = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2166 //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2167 //{
2168 // bits |= MsiInterop.MsidbComponentAttributesDisableRegistryReflection;
2169 //}
2170 break; 2166 break;
2171 case "Condition": 2167 case "Condition":
2172 condition = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 2168 condition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2173 break; 2169 break;
2174 case "Directory": 2170 case "Directory":
2175 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId); 2171 directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2172 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2173 break;
2174 case "Subdirectory":
2175 subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2176 break; 2176 break;
2177 case "DiskId": 2177 case "DiskId":
2178 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int16.MaxValue); 2178 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int16.MaxValue);
@@ -2196,14 +2196,12 @@ namespace WixToolset.Core
2196 { 2196 {
2197 case "either": 2197 case "either":
2198 location = ComponentLocation.Either; 2198 location = ComponentLocation.Either;
2199 //bits |= MsiInterop.MsidbComponentAttributesOptional;
2200 break; 2199 break;
2201 case "local": // this is the default 2200 case "local": // this is the default
2202 location = ComponentLocation.LocalOnly; 2201 location = ComponentLocation.LocalOnly;
2203 break; 2202 break;
2204 case "source": 2203 case "source":
2205 location = ComponentLocation.SourceOnly; 2204 location = ComponentLocation.SourceOnly;
2206 //bits |= MsiInterop.MsidbComponentAttributesSourceOnly;
2207 break; 2205 break;
2208 case "": 2206 case "":
2209 break; 2207 break;
@@ -2217,45 +2215,21 @@ namespace WixToolset.Core
2217 break; 2215 break;
2218 case "NeverOverwrite": 2216 case "NeverOverwrite":
2219 neverOverwrite = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2217 neverOverwrite = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2220 //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2221 //{
2222 // bits |= MsiInterop.MsidbComponentAttributesNeverOverwrite;
2223 //}
2224 break; 2218 break;
2225 case "Permanent": 2219 case "Permanent":
2226 permanent = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2220 permanent = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2227 //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2228 //{
2229 // bits |= MsiInterop.MsidbComponentAttributesPermanent;
2230 //}
2231 break; 2221 break;
2232 case "Shared": 2222 case "Shared":
2233 shared = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2223 shared = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2234 //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2235 //{
2236 // bits |= MsiInterop.MsidbComponentAttributesShared;
2237 //}
2238 break; 2224 break;
2239 case "SharedDllRefCount": 2225 case "SharedDllRefCount":
2240 sharedDllRefCount = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2226 sharedDllRefCount = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2241 //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2242 //{
2243 // bits |= MsiInterop.MsidbComponentAttributesSharedDllRefCount;
2244 //}
2245 break; 2227 break;
2246 case "Transitive": 2228 case "Transitive":
2247 transitive = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2229 transitive = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2248 //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2249 //{
2250 // bits |= MsiInterop.MsidbComponentAttributesTransitive;
2251 //}
2252 break; 2230 break;
2253 case "UninstallWhenSuperseded": 2231 case "UninstallWhenSuperseded":
2254 uninstallWhenSuperseded = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2232 uninstallWhenSuperseded = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2255 //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2256 //{
2257 // bits |= MsiInterop.MsidbComponentAttributesUninstallOnSupersedence;
2258 //}
2259 break; 2233 break;
2260 default: 2234 default:
2261 this.Core.UnexpectedAttribute(node, attrib); 2235 this.Core.UnexpectedAttribute(node, attrib);
@@ -2275,17 +2249,22 @@ namespace WixToolset.Core
2275 id = new Identifier(AccessModifier.Section, componentIdPlaceholder); 2249 id = new Identifier(AccessModifier.Section, componentIdPlaceholder);
2276 } 2250 }
2277 2251
2278 if (null == directoryId) 2252 if (String.IsNullOrEmpty(directoryId))
2279 { 2253 {
2280 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Directory")); 2254 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Directory"));
2281 } 2255 }
2282 2256
2283 if (String.IsNullOrEmpty(guid) && shared /*MsiInterop.MsidbComponentAttributesShared == (bits & MsiInterop.MsidbComponentAttributesShared)*/) 2257 if (!String.IsNullOrEmpty(subdirectory))
2258 {
2259 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, directoryId, subdirectory);
2260 }
2261
2262 if (String.IsNullOrEmpty(guid) && shared)
2284 { 2263 {
2285 this.Core.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Shared", "yes", "Guid", "")); 2264 this.Core.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Shared", "yes", "Guid", ""));
2286 } 2265 }
2287 2266
2288 if (String.IsNullOrEmpty(guid) && permanent /*MsiInterop.MsidbComponentAttributesPermanent == (bits & MsiInterop.MsidbComponentAttributesPermanent)*/) 2267 if (String.IsNullOrEmpty(guid) && permanent)
2289 { 2268 {
2290 this.Core.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Permanent", "yes", "Guid", "")); 2269 this.Core.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Permanent", "yes", "Guid", ""));
2291 } 2270 }
@@ -2587,6 +2566,7 @@ namespace WixToolset.Core
2587 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 2566 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2588 Identifier id = null; 2567 Identifier id = null;
2589 string directoryId = null; 2568 string directoryId = null;
2569 string subdirectory = null;
2590 string source = null; 2570 string source = null;
2591 2571
2592 foreach (var attrib in node.Attributes()) 2572 foreach (var attrib in node.Attributes())
@@ -2599,9 +2579,11 @@ namespace WixToolset.Core
2599 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); 2579 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2600 break; 2580 break;
2601 case "Directory": 2581 case "Directory":
2602 // If the inline syntax is invalid it returns null. Use a static error identifier so the null 2582 directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2603 // directory identifier here doesn't trickle down false errors into child elements. 2583 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2604 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null) ?? "ErrorParsingInlineSyntax"; 2584 break;
2585 case "Subdirectory":
2586 subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2605 break; 2587 break;
2606 case "Source": 2588 case "Source":
2607 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 2589 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -2623,6 +2605,8 @@ namespace WixToolset.Core
2623 id = Identifier.Invalid; 2605 id = Identifier.Invalid;
2624 } 2606 }
2625 2607
2608 directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory");
2609
2626 if (!String.IsNullOrEmpty(source) && !source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) 2610 if (!String.IsNullOrEmpty(source) && !source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
2627 { 2611 {
2628 source = String.Concat(source, Path.DirectorySeparatorChar); 2612 source = String.Concat(source, Path.DirectorySeparatorChar);
@@ -2898,18 +2882,24 @@ namespace WixToolset.Core
2898 private string ParseCreateFolderElement(XElement node, string componentId, string directoryId, bool win64Component) 2882 private string ParseCreateFolderElement(XElement node, string componentId, string directoryId, bool win64Component)
2899 { 2883 {
2900 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 2884 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2885 string subdirectory = null;
2886
2901 foreach (var attrib in node.Attributes()) 2887 foreach (var attrib in node.Attributes())
2902 { 2888 {
2903 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) 2889 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
2904 { 2890 {
2905 switch (attrib.Name.LocalName) 2891 switch (attrib.Name.LocalName)
2906 { 2892 {
2907 case "Directory": 2893 case "Directory":
2908 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId); 2894 directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2909 break; 2895 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2910 default: 2896 break;
2911 this.Core.UnexpectedAttribute(node, attrib); 2897 case "Subdirectory":
2912 break; 2898 subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2899 break;
2900 default:
2901 this.Core.UnexpectedAttribute(node, attrib);
2902 break;
2913 } 2903 }
2914 } 2904 }
2915 else 2905 else
@@ -2918,24 +2908,26 @@ namespace WixToolset.Core
2918 } 2908 }
2919 } 2909 }
2920 2910
2911 directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory");
2912
2921 foreach (var child in node.Elements()) 2913 foreach (var child in node.Elements())
2922 { 2914 {
2923 if (CompilerCore.WixNamespace == child.Name.Namespace) 2915 if (CompilerCore.WixNamespace == child.Name.Namespace)
2924 { 2916 {
2925 switch (child.Name.LocalName) 2917 switch (child.Name.LocalName)
2926 { 2918 {
2927 case "Shortcut": 2919 case "Shortcut":
2928 this.ParseShortcutElement(child, componentId, node.Name.LocalName, directoryId, YesNoType.No); 2920 this.ParseShortcutElement(child, componentId, node.Name.LocalName, directoryId, YesNoType.No);
2929 break; 2921 break;
2930 case "Permission": 2922 case "Permission":
2931 this.ParsePermissionElement(child, directoryId, "CreateFolder"); 2923 this.ParsePermissionElement(child, directoryId, "CreateFolder");
2932 break; 2924 break;
2933 case "PermissionEx": 2925 case "PermissionEx":
2934 this.ParsePermissionExElement(child, directoryId, "CreateFolder"); 2926 this.ParsePermissionExElement(child, directoryId, "CreateFolder");
2935 break; 2927 break;
2936 default: 2928 default:
2937 this.Core.UnexpectedElement(node, child); 2929 this.Core.UnexpectedElement(node, child);
2938 break; 2930 break;
2939 } 2931 }
2940 } 2932 }
2941 else 2933 else
@@ -2969,10 +2961,12 @@ namespace WixToolset.Core
2969 Identifier id = null; 2961 Identifier id = null;
2970 var delete = false; 2962 var delete = false;
2971 string destinationDirectory = null; 2963 string destinationDirectory = null;
2964 string destinationSubdirectory = null;
2972 string destinationName = null; 2965 string destinationName = null;
2973 string destinationShortName = null; 2966 string destinationShortName = null;
2974 string destinationProperty = null; 2967 string destinationProperty = null;
2975 string sourceDirectory = null; 2968 string sourceDirectory = null;
2969 string sourceSubdirectory = null;
2976 string sourceFolder = null; 2970 string sourceFolder = null;
2977 string sourceName = null; 2971 string sourceName = null;
2978 string sourceProperty = null; 2972 string sourceProperty = null;
@@ -2990,16 +2984,20 @@ namespace WixToolset.Core
2990 delete = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2984 delete = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2991 break; 2985 break;
2992 case "DestinationDirectory": 2986 case "DestinationDirectory":
2993 destinationDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 2987 destinationDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2988 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, destinationDirectory);
2989 break;
2990 case "DestinationSubdirectory":
2991 destinationSubdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2994 break; 2992 break;
2995 case "DestinationName": 2993 case "DestinationName":
2996 destinationName = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); 2994 destinationName = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib);
2997 break; 2995 break;
2998 case "DestinationProperty": 2996 case "DestinationProperty":
2999 destinationProperty = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 2997 destinationProperty = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3000 break; 2998 break;
3001 case "DestinationShortName": 2999 case "DestinationShortName":
3002 destinationShortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false); 3000 destinationShortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib);
3003 break; 3001 break;
3004 case "FileId": 3002 case "FileId":
3005 if (null != fileId) 3003 if (null != fileId)
@@ -3010,7 +3008,11 @@ namespace WixToolset.Core
3010 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.File, fileId); 3008 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.File, fileId);
3011 break; 3009 break;
3012 case "SourceDirectory": 3010 case "SourceDirectory":
3013 sourceDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 3011 sourceDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3012 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, sourceDirectory);
3013 break;
3014 case "SourceSubdirectory":
3015 sourceSubdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
3014 break; 3016 break;
3015 case "SourceName": 3017 case "SourceName":
3016 sourceName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 3018 sourceName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -3044,11 +3046,15 @@ namespace WixToolset.Core
3044 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceProperty", "SourceDirectory")); 3046 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceProperty", "SourceDirectory"));
3045 } 3047 }
3046 3048
3049 sourceDirectory = this.HandleSubdirectory(sourceLineNumbers, node, sourceDirectory, sourceSubdirectory, "SourceDirectory", "SourceSubdirectory");
3050
3047 if (null != destinationDirectory && null != destinationProperty) // DestinationDirectory and DestinationProperty cannot coexist 3051 if (null != destinationDirectory && null != destinationProperty) // DestinationDirectory and DestinationProperty cannot coexist
3048 { 3052 {
3049 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DestinationProperty", "DestinationDirectory")); 3053 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DestinationProperty", "DestinationDirectory"));
3050 } 3054 }
3051 3055
3056 destinationDirectory = this.HandleSubdirectory(sourceLineNumbers, node, destinationDirectory, destinationSubdirectory, "DestinationDirectory", "DestinationSubdirectory");
3057
3052 if (null == id) 3058 if (null == id)
3053 { 3059 {
3054 id = this.Core.CreateIdentifier("cf", sourceFolder, sourceDirectory, sourceProperty, destinationDirectory, destinationProperty, destinationName); 3060 id = this.Core.CreateIdentifier("cf", sourceFolder, sourceDirectory, sourceProperty, destinationDirectory, destinationProperty, destinationName);
@@ -3139,6 +3145,7 @@ namespace WixToolset.Core
3139 var explicitWin64 = false; 3145 var explicitWin64 = false;
3140 3146
3141 string scriptFile = null; 3147 string scriptFile = null;
3148 string subdirectory = null;
3142 3149
3143 CustomActionSourceType? sourceType = null; 3150 CustomActionSourceType? sourceType = null;
3144 CustomActionTargetType? targetType = null; 3151 CustomActionTargetType? targetType = null;
@@ -3194,8 +3201,9 @@ namespace WixToolset.Core
3194 { 3201 {
3195 this.Core.Write(ErrorMessages.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileRef", "Property", "Script")); 3202 this.Core.Write(ErrorMessages.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileRef", "Property", "Script"));
3196 } 3203 }
3197 source = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 3204 source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3198 sourceType = CustomActionSourceType.Directory; 3205 sourceType = CustomActionSourceType.Directory;
3206 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, source);
3199 break; 3207 break;
3200 case "DllEntry": 3208 case "DllEntry":
3201 if (null != target) 3209 if (null != target)
@@ -3355,6 +3363,9 @@ namespace WixToolset.Core
3355 case "ScriptSourceFile": 3363 case "ScriptSourceFile":
3356 scriptFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 3364 scriptFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3357 break; 3365 break;
3366 case "Subdirectory":
3367 subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
3368 break;
3358 case "SuppressModularization": 3369 case "SuppressModularization":
3359 suppressModularization = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 3370 suppressModularization = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3360 break; 3371 break;
@@ -3399,6 +3410,18 @@ namespace WixToolset.Core
3399 win64 = true; 3410 win64 = true;
3400 } 3411 }
3401 3412
3413 if (!String.IsNullOrEmpty(subdirectory))
3414 {
3415 if (sourceType == CustomActionSourceType.Directory)
3416 {
3417 source = this.HandleSubdirectory(sourceLineNumbers, node, source, subdirectory, "Directory", "Subdirectory");
3418 }
3419 else
3420 {
3421 this.Core.Write(ErrorMessages.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Subdirectory", "Directory"));
3422 }
3423 }
3424
3402 // if we have an in-lined Script CustomAction ensure no source or target attributes were provided 3425 // if we have an in-lined Script CustomAction ensure no source or target attributes were provided
3403 if (inlineScript) 3426 if (inlineScript)
3404 { 3427 {
@@ -4168,7 +4191,6 @@ namespace WixToolset.Core
4168 var fileSourceAttribSet = false; 4191 var fileSourceAttribSet = false;
4169 XAttribute nameAttribute = null; 4192 XAttribute nameAttribute = null;
4170 var name = "."; // default to parent directory. 4193 var name = "."; // default to parent directory.
4171 string inlineSyntax = null;
4172 string shortName = null; 4194 string shortName = null;
4173 string sourceName = null; 4195 string sourceName = null;
4174 string shortSourceName = null; 4196 string shortSourceName = null;
@@ -4194,7 +4216,7 @@ namespace WixToolset.Core
4194 fileSourceAttribSet = true; 4216 fileSourceAttribSet = true;
4195 break; 4217 break;
4196 case "Name": 4218 case "Name":
4197 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 4219 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
4198 nameAttribute = attrib; 4220 nameAttribute = attrib;
4199 break; 4221 break;
4200 case "ShortName": 4222 case "ShortName":
@@ -4268,37 +4290,22 @@ namespace WixToolset.Core
4268 } 4290 }
4269 } 4291 }
4270 4292
4271 // Create the directory rows for the inline. 4293 if (null == id)
4272 if (nameAttribute != null)
4273 { 4294 {
4274 var lastSlash = name.LastIndexOf('\\'); 4295 id = this.Core.CreateIdentifier("d", parentId, name, shortName, sourceName, shortSourceName);
4275 if (lastSlash > 0)
4276 {
4277 inlineSyntax = name;
4278 name = inlineSyntax.Substring(lastSlash + 1);
4279
4280 parentId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, nameAttribute, parentId, inlineSyntax.Substring(0, lastSlash));
4281
4282 if (!this.Core.IsValidLongFilename(name, false, false))
4283 {
4284 this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, nameAttribute.Name.LocalName, nameAttribute.Value, name));
4285 }
4286 }
4287 } 4296 }
4288 4297 else if (WindowsInstallerStandard.IsStandardDirectory(id.Id))
4289 if (null == id)
4290 { 4298 {
4291 id = this.Core.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName); 4299 if (String.IsNullOrEmpty(sourceName))
4292
4293 if (!String.IsNullOrEmpty(inlineSyntax))
4294 { 4300 {
4295 this.Core.AddInlineDirectoryId(inlineSyntax, id.Id); 4301 this.Core.Write(CompilerWarnings.DefiningStandardDirectoryDeprecated(sourceLineNumbers, id.Id));
4296 } 4302 }
4297 } 4303
4298 else if ("TARGETDIR".Equals(id.Id, StringComparison.Ordinal) && !("SourceDir".Equals(name, StringComparison.Ordinal) && shortName == null && shortSourceName == null && sourceName == null)) 4304 if (id.Id == "TARGETDIR" && name != "SourceDir" && shortName == null && shortSourceName == null && sourceName == null)
4299 { 4305 {
4300 this.Core.Write(ErrorMessages.IllegalTargetDirDefaultDir(sourceLineNumbers, name)); 4306 this.Core.Write(ErrorMessages.IllegalTargetDirDefaultDir(sourceLineNumbers, name));
4301 } 4307 }
4308 }
4302 4309
4303 // Update the file source path appropriately. 4310 // Update the file source path appropriately.
4304 if (fileSourceAttribSet) 4311 if (fileSourceAttribSet)
@@ -4761,7 +4768,8 @@ namespace WixToolset.Core
4761 disallowAdvertise = (this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.No); 4768 disallowAdvertise = (this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.No);
4762 break; 4769 break;
4763 case "ConfigurableDirectory": 4770 case "ConfigurableDirectory":
4764 configurableDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null); 4771 configurableDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4772 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, configurableDirectory);
4765 break; 4773 break;
4766 case "Description": 4774 case "Description":
4767 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 4775 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -8403,5 +8411,22 @@ namespace WixToolset.Core
8403 } 8411 }
8404 } 8412 }
8405 } 8413 }
8414
8415 private string HandleSubdirectory(SourceLineNumber sourceLineNumbers, XElement element, string directoryId, string subdirectory, string directoryAttributeName, string subdirectoryAttributename)
8416 {
8417 if (!String.IsNullOrEmpty(subdirectory))
8418 {
8419 if (String.IsNullOrEmpty(directoryId))
8420 {
8421 this.Core.Write(ErrorMessages.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, element.Name.LocalName, subdirectoryAttributename, directoryAttributeName));
8422 }
8423 else
8424 {
8425 directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, directoryId, subdirectory);
8426 }
8427 }
8428
8429 return directoryId;
8430 }
8406 } 8431 }
8407} 8432}