aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Common.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Common.cs')
-rw-r--r--src/WixToolset.Core/Common.cs109
1 files changed, 16 insertions, 93 deletions
diff --git a/src/WixToolset.Core/Common.cs b/src/WixToolset.Core/Common.cs
index 2d8f9509..610bfcaa 100644
--- a/src/WixToolset.Core/Common.cs
+++ b/src/WixToolset.Core/Common.cs
@@ -21,6 +21,12 @@ namespace WixToolset.Core
21 /// </summary> 21 /// </summary>
22 public static class Common 22 public static class Common
23 { 23 {
24 // TODO: Find a place to put all of these so they doesn't have to be public and exposed by WixToolset.Core.dll
25 public const string UpgradeDetectedProperty = "WIX_UPGRADE_DETECTED";
26 public const string UpgradePreventedCondition = "NOT WIX_UPGRADE_DETECTED";
27 public const string DowngradeDetectedProperty = "WIX_DOWNGRADE_DETECTED";
28 public const string DowngradePreventedCondition = "NOT WIX_DOWNGRADE_DETECTED";
29
24 //------------------------------------------------------------------------------------------------- 30 //-------------------------------------------------------------------------------------------------
25 // Layout of an Access Mask (from http://technet.microsoft.com/en-us/library/cc783530(WS.10).aspx) 31 // Layout of an Access Mask (from http://technet.microsoft.com/en-us/library/cc783530(WS.10).aspx)
26 // 32 //
@@ -45,7 +51,8 @@ namespace WixToolset.Core
45 // GENERIC_EXECUTE (0x20000000L) 51 // GENERIC_EXECUTE (0x20000000L)
46 // GENERIC_WRITE (0x40000000L) 52 // GENERIC_WRITE (0x40000000L)
47 // GENERIC_READ (0x80000000L) 53 // GENERIC_READ (0x80000000L)
48 internal static readonly string[] GenericPermissions = { "GenericAll", "GenericExecute", "GenericWrite", "GenericRead" }; 54 // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
55 public static readonly string[] GenericPermissions = { "GenericAll", "GenericExecute", "GenericWrite", "GenericRead" };
49 56
50 // Standard Access Rights (per WinNT.h) 57 // Standard Access Rights (per WinNT.h)
51 // ---------------------- 58 // ----------------------
@@ -54,7 +61,8 @@ namespace WixToolset.Core
54 // WRITE_DAC (0x00040000L) 61 // WRITE_DAC (0x00040000L)
55 // WRITE_OWNER (0x00080000L) 62 // WRITE_OWNER (0x00080000L)
56 // SYNCHRONIZE (0x00100000L) 63 // SYNCHRONIZE (0x00100000L)
57 internal static readonly string[] StandardPermissions = { "Delete", "ReadPermission", "ChangePermission", "TakeOwnership", "Synchronize" }; 64 // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
65 public static readonly string[] StandardPermissions = { "Delete", "ReadPermission", "ChangePermission", "TakeOwnership", "Synchronize" };
58 66
59 // Object-Specific Access Rights 67 // Object-Specific Access Rights
60 // ============================= 68 // =============================
@@ -69,11 +77,13 @@ namespace WixToolset.Core
69 // FILE_DELETE_CHILD ( 0x0040 ) 77 // FILE_DELETE_CHILD ( 0x0040 )
70 // FILE_READ_ATTRIBUTES ( 0x0080 ) 78 // FILE_READ_ATTRIBUTES ( 0x0080 )
71 // FILE_WRITE_ATTRIBUTES ( 0x0100 ) 79 // FILE_WRITE_ATTRIBUTES ( 0x0100 )
72 internal static readonly string[] FolderPermissions = { "Read", "CreateFile", "CreateChild", "ReadExtendedAttributes", "WriteExtendedAttributes", "Traverse", "DeleteChild", "ReadAttributes", "WriteAttributes" }; 80 // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
81 public static readonly string[] FolderPermissions = { "Read", "CreateFile", "CreateChild", "ReadExtendedAttributes", "WriteExtendedAttributes", "Traverse", "DeleteChild", "ReadAttributes", "WriteAttributes" };
73 82
74 // Registry Access Rights (per TODO) 83 // Registry Access Rights (per TODO)
75 // ---------------------- 84 // ----------------------
76 internal static readonly string[] RegistryPermissions = { "Read", "Write", "CreateSubkeys", "EnumerateSubkeys", "Notify", "CreateLink" }; 85 // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
86 public static readonly string[] RegistryPermissions = { "Read", "Write", "CreateSubkeys", "EnumerateSubkeys", "Notify", "CreateLink" };
77 87
78 // File Access Rights (per WinNT.h) 88 // File Access Rights (per WinNT.h)
79 // ------------------ 89 // ------------------
@@ -89,7 +99,8 @@ namespace WixToolset.Core
89 // 99 //
90 // STANDARD_RIGHTS_REQUIRED (0x000F0000L) 100 // STANDARD_RIGHTS_REQUIRED (0x000F0000L)
91 // FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) 101 // FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
92 internal static readonly string[] FilePermissions = { "Read", "Write", "Append", "ReadExtendedAttributes", "WriteExtendedAttributes", "Execute", "FileAllRights", "ReadAttributes", "WriteAttributes" }; 102 // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
103 public static readonly string[] FilePermissions = { "Read", "Write", "Append", "ReadExtendedAttributes", "WriteExtendedAttributes", "Execute", "FileAllRights", "ReadAttributes", "WriteAttributes" };
93 104
94 public static readonly Regex WixVariableRegex = new Regex(@"(\!|\$)\((?<namespace>loc|wix|bind|bindpath)\.(?<fullname>(?<name>[_A-Za-z][0-9A-Za-z_]+)(\.(?<scope>[_A-Za-z][0-9A-Za-z_\.]*))?)(\=(?<value>.+?))?\)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture); 105 public static readonly Regex WixVariableRegex = new Regex(@"(\!|\$)\((?<namespace>loc|wix|bind|bindpath)\.(?<fullname>(?<name>[_A-Za-z][0-9A-Za-z_]+)(\.(?<scope>[_A-Za-z][0-9A-Za-z_\.]*))?)(\=(?<value>.+?))?\)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture);
95 106
@@ -107,58 +118,6 @@ namespace WixToolset.Core
107 private static readonly Regex LegalWildcardShortFilename = new Regex(String.Concat("^", LegalWildcardShortFilenameCharacters, @"{1,16}(\.", LegalWildcardShortFilenameCharacters, "{0,6})?$")); 118 private static readonly Regex LegalWildcardShortFilename = new Regex(String.Concat("^", LegalWildcardShortFilenameCharacters, @"{1,16}(\.", LegalWildcardShortFilenameCharacters, "{0,6})?$"));
108 119
109 /// <summary> 120 /// <summary>
110 /// Cleans up the temp files.
111 /// </summary>
112 /// <param name="path">The temporary directory to delete.</param>
113 /// <param name="messageHandler">The message handler.</param>
114 /// <returns>True if all files were deleted, false otherwise.</returns>
115 internal static bool DeleteTempFiles(string path, IMessaging messageHandler)
116 {
117 // try three times and give up with a warning if the temp files aren't gone by then
118 int retryLimit = 3;
119 bool removedReadOnly = false;
120
121 for (int i = 0; i < retryLimit; i++)
122 {
123 try
124 {
125 Directory.Delete(path, true); // toast the whole temp directory
126 break; // no exception means we got success the first time
127 }
128 catch (UnauthorizedAccessException)
129 {
130 if (!removedReadOnly) // should only need to unmark readonly once - there's no point in doing it again and again
131 {
132 removedReadOnly = true;
133 RecursiveFileAttributes(path, FileAttributes.ReadOnly, false, messageHandler); // toasting will fail if any files are read-only. Try changing them to not be.
134 }
135 else
136 {
137 messageHandler.Write(WarningMessages.AccessDeniedForDeletion(null, path));
138 return false;
139 }
140 }
141 catch (DirectoryNotFoundException)
142 {
143 // if the path doesn't exist, then there is nothing for us to worry about
144 break;
145 }
146 catch (IOException) // directory in use
147 {
148 if (i == (retryLimit - 1)) // last try failed still, give up
149 {
150 messageHandler.Write(WarningMessages.DirectoryInUse(null, path));
151 return false;
152 }
153
154 System.Threading.Thread.Sleep(300); // sleep a bit before trying again
155 }
156 }
157
158 return true;
159 }
160
161 /// <summary>
162 /// Gets a valid code page from the given web name or integer value. 121 /// Gets a valid code page from the given web name or integer value.
163 /// </summary> 122 /// </summary>
164 /// <param name="value">A code page web name or integer value as a string.</param> 123 /// <param name="value">A code page web name or integer value as a string.</param>
@@ -316,30 +275,6 @@ namespace WixToolset.Core
316 } 275 }
317 276
318 /// <summary> 277 /// <summary>
319 /// Get the value of an attribute with type YesNoType.
320 /// </summary>
321 /// <param name="sourceLineNumbers">Source information for the value.</param>
322 /// <param name="elementName">Name of the element for this attribute, used for a possible exception.</param>
323 /// <param name="attributeName">Name of the attribute.</param>
324 /// <param name="value">Value to process.</param>
325 /// <returns>Returns true for a value of 'yes' and false for a value of 'no'.</returns>
326 /// <exception cref="WixException">Thrown when the attribute's value is not 'yes' or 'no'.</exception>
327 internal static bool IsYes(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string value)
328 {
329 switch (value)
330 {
331 case "no":
332 case "false":
333 return false;
334 case "yes":
335 case "true":
336 return true;
337 default:
338 throw new WixException(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, elementName, attributeName, value, "no", "yes"));
339 }
340 }
341
342 /// <summary>
343 /// Verifies the given string is a valid module or bundle version. 278 /// Verifies the given string is a valid module or bundle version.
344 /// </summary> 279 /// </summary>
345 /// <param name="version">The version to verify.</param> 280 /// <param name="version">The version to verify.</param>
@@ -471,18 +406,6 @@ namespace WixToolset.Core
471 } 406 }
472 } 407 }
473 408
474 public static string GetFileHash(string path)
475 {
476 using (SHA1Managed managed = new SHA1Managed())
477 {
478 using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read))
479 {
480 byte[] hash = managed.ComputeHash(stream);
481 return BitConverter.ToString(hash).Replace("-", String.Empty);
482 }
483 }
484 }
485
486 /// <summary> 409 /// <summary>
487 /// Takes an id, and demodularizes it (if possible). 410 /// Takes an id, and demodularizes it (if possible).
488 /// </summary> 411 /// </summary>