public bool UpdateResources(string filename, BuildResults results)
        {
            bool      returnValue              = true;
            int       beginUpdateRetries       = 20;  // Number of retries
            const int beginUpdateRetryInterval = 100; // In milliseconds
            bool      endUpdate = false;              // Only call EndUpdateResource() if this is true

            // Directory.GetCurrentDirectory() has previously been set to the project location
            string filePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename);

            if (_stringResources.Count == 0 && _fileResources.Count == 0)
            {
                return(true);
            }
            IntPtr hUpdate = IntPtr.Zero;

            try
            {
                hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false);
                while (IntPtr.Zero == hUpdate && Marshal.GetHRForLastWin32Error() == ResourceUpdater.ERROR_SHARING_VIOLATION && beginUpdateRetries > 0) // If it equals 0x80070020 (ERROR_SHARING_VIOLATION), sleep & retry
                {
                    // This warning can be useful for debugging, but shouldn't be displayed to an actual user
                    // results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}, trying again after short sleep", filename, Marshal.GetHRForLastWin32Error())));
                    hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false);
                    beginUpdateRetries--;
                    Thread.Sleep(beginUpdateRetryInterval);
                }
                // If after all that we still failed, throw a build error
                if (IntPtr.Zero == hUpdate)
                {
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                    return(false);
                }

                endUpdate = true;

                if (hUpdate != IntPtr.Zero)
                {
                    foreach (StringResource resource in _stringResources)
                    {
                        byte[] data = StringToByteArray(resource.Data);

                        if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)resource.Type, resource.Name, 0, data, data.Length))
                        {
                            results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                            return(false);
                        }
                    }

                    if (_fileResources.Count > 0)
                    {
                        int    index      = 0;
                        byte[] countArray = StringToByteArray(_fileResources.Count.ToString("G", CultureInfo.InvariantCulture));
                        if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, "COUNT", 0, countArray, countArray.Length))
                        {
                            results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                            return(false);
                        }

                        foreach (FileResource resource in _fileResources)
                        {
                            // Read in the file data
                            int    fileLength  = 0;
                            byte[] fileContent = null;
                            using (FileStream fs = System.IO.File.OpenRead(resource.Filename))
                            {
                                fileLength  = (int)fs.Length;
                                fileContent = new byte[fileLength];

                                fs.Read(fileContent, 0, fileLength);
                            }

                            // Update the resources to include this file's data
                            string dataName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", index);

                            if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, dataName, 0, fileContent, fileLength))
                            {
                                results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                                return(false);
                            }

                            // Add this file's key to the resources
                            string keyName = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", index);
                            byte[] data    = StringToByteArray(resource.Key);
                            if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, keyName, 0, data, data.Length))
                            {
                                results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                                return(false);
                            }

                            index++;
                        }
                    }
                }
            }
            finally
            {
                if (endUpdate && !NativeMethods.EndUpdateResource(hUpdate, false))
                {
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                    returnValue = false;
                }
            }

            return(returnValue);
        }
        private void OrderProducts(Hashtable availableProducts, Hashtable buildQueue)
        {
            bool loopDetected = false;
            _loopDependenciesWarnings = new BuildResults();
            StringBuilder productsInLoop = new StringBuilder();
            while (buildQueue.Count > 0)
            {
                List<string> productsToRemove = new List<string>();
                foreach (Product p in buildQueue.Values)
                {
                    if (p.Dependencies.Count == 0)
                    {
                        _products.Add((Product)availableProducts[p.ProductCode]);
                        RemoveDependency(buildQueue, p);
                        productsToRemove.Add(p.ProductCode);
                    }
                }

                foreach (string productCode in productsToRemove)
                {
                    buildQueue.Remove(productCode);
                    if (loopDetected)
                    {
                        productsInLoop.Append(productCode);
                        productsInLoop.Append(", ");
                    }
                }

                // If we could not remove any products and there are still products in the queue
                // there must be a loop in it. We'll break the loop by removing the dependencies 
                // of the first project in the queue;
                if (buildQueue.Count > 0 && productsToRemove.Count == 0)
                {
                    IDictionaryEnumerator enumerator = buildQueue.GetEnumerator();
                    enumerator.MoveNext();
                    ((Product)enumerator.Value).Dependencies.RemoveAll(m => true);
                    loopDetected = true;
                }

                // If we've been in a loop and there are no more products left
                // or no more products can be installed, we have completely walked that loop
                // and now is a good time to show the warning message for the loop
                if (productsInLoop.Length > 0 && (buildQueue.Count == 0 || productsToRemove.Count == 0))
                {
                    productsInLoop.Remove(productsInLoop.Length - 2, 2);
                    _loopDependenciesWarnings.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.CircularDependency", productsInLoop.ToString()));
                    productsInLoop.Remove(0, productsInLoop.Length);
                }
            }
        }
        public bool UpdateResources(string filename, BuildResults results)
        {
            bool returnValue = true;
            int beginUpdateRetries = 20;    // Number of retries
            const int beginUpdateRetryInterval = 100; // In milliseconds
            bool endUpdate = false; // Only call EndUpdateResource() if this is true

            // Directory.GetCurrentDirectory() has previously been set to the project location
            string filePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename);

            if (_stringResources.Count == 0 && _fileResources.Count == 0)
                return true;
            IntPtr hUpdate = IntPtr.Zero;

            try
            {
                hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false);
                while (IntPtr.Zero == hUpdate && Marshal.GetHRForLastWin32Error() == ResourceUpdater.ERROR_SHARING_VIOLATION && beginUpdateRetries > 0) // If it equals 0x80070020 (ERROR_SHARING_VIOLATION), sleep & retry
                {
                    // This warning can be useful for debugging, but shouldn't be displayed to an actual user
                    // results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}, trying again after short sleep", filename, Marshal.GetHRForLastWin32Error())));
                    hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false);
                    beginUpdateRetries--;
                    Thread.Sleep(beginUpdateRetryInterval);
                }
                // If after all that we still failed, throw a build error
                if (IntPtr.Zero == hUpdate)
                {
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                    return false;
                }

                endUpdate = true;

                if (hUpdate != IntPtr.Zero)
                {
                    foreach (StringResource resource in _stringResources)
                    {
                        byte[] data = StringToByteArray(resource.Data);

                        if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)resource.Type, resource.Name, 0, data, data.Length))
                        {
                            results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                            return false;
                        }
                    }

                    if (_fileResources.Count > 0)
                    {
                        int index = 0;
                        byte[] countArray = StringToByteArray(_fileResources.Count.ToString("G", CultureInfo.InvariantCulture));
                        if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, "COUNT", 0, countArray, countArray.Length))
                        {
                            results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                            return false;
                        }

                        foreach (FileResource resource in _fileResources)
                        {
                            // Read in the file data
                            int fileLength = 0;
                            byte[] fileContent = null;
                            using (FileStream fs = System.IO.File.OpenRead(resource.Filename))
                            {
                                fileLength = (int)fs.Length;
                                fileContent = new byte[fileLength];

                                fs.Read(fileContent, 0, fileLength);
                            }

                            // Update the resources to include this file's data
                            string dataName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", index);

                            if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, dataName, 0, fileContent, fileLength))
                            {
                                results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                                return false;
                            }

                            // Add this file's key to the resources
                            string keyName = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", index);
                            byte[] data = StringToByteArray(resource.Key);
                            if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, keyName, 0, data, data.Length))
                            {
                                results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                                return false;
                            }

                            index++;
                        }
                    }
                }
            }
            finally
            {
                if (endUpdate && !NativeMethods.EndUpdateResource(hUpdate, false))
                {
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error())));
                    returnValue = false;
                }
            }

            return returnValue;
        }
        private bool VerifyHomeSiteInformation(XmlNode packageFileNode, ProductBuilder builder, BuildSettings settings, BuildResults results)
        {
            if (settings.ComponentsLocation != ComponentsLocation.HomeSite)
            {
                return true;
            }

            XmlAttribute homesiteAttribute = packageFileNode.Attributes[HOMESITE_ATTRIBUTE];

            if (homesiteAttribute == null && builder.Product.CopyAllPackageFiles != CopyAllFilesType.CopyAllFilesIfNotHomeSite)
            {
                if (results != null)
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.PackageHomeSiteMissing", builder.Name));
                return false;
            }

            return true;
        }
        private bool AddVerificationInformation(XmlNode packageFileNode, string fileSource, string fileName, ProductBuilder builder, BuildSettings settings, BuildResults results)
        {
            XmlAttribute hashAttribute = packageFileNode.Attributes[HASH_ATTRIBUTE];
            XmlAttribute publicKeyAttribute = packageFileNode.Attributes[PUBLICKEY_ATTRIBUTE];

            if (File.Exists(fileSource))
            {
                string publicKey = GetPublicKeyOfFile(fileSource);
                if (hashAttribute == null && publicKeyAttribute == null)
                {
                    // If neither the Hash nor PublicKey attributes were specified in the manifest, add it
                    if (publicKey != null)
                    {
                        AddAttribute(packageFileNode, PUBLICKEY_ATTRIBUTE, publicKey);
                    }
                    else
                    {
                        AddAttribute(packageFileNode, HASH_ATTRIBUTE, GetFileHash(fileSource));
                    }
                }
                if (publicKeyAttribute != null)
                {
                    // Always use the PublicKey of the file on disk
                    if (publicKey != null)
                        ReplaceAttribute(packageFileNode, PUBLICKEY_ATTRIBUTE, publicKey);
                    else
                    {
                        // File on disk is not signed.  Remove the public key info, and make sure the hash is written instead
                        packageFileNode.Attributes.RemoveNamedItem(PUBLICKEY_ATTRIBUTE);
                        if (hashAttribute == null)
                            AddAttribute(packageFileNode, HASH_ATTRIBUTE, GetFileHash(fileSource));
                    }

                    // If the public key in the file doesn't match the public key on disk, issue a build warning
                    if (publicKey == null || !publicKey.ToLowerInvariant().Equals(publicKeyAttribute.Value.ToLowerInvariant()))
                    {
                        if (results != null)
                            results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", PUBLICKEY_ATTRIBUTE, builder.Name, fileSource));
                    }
                }
                if (hashAttribute != null)
                {
                    string fileHash = GetFileHash(fileSource);

                    // Always use the Hash of the file on disk
                    ReplaceAttribute(packageFileNode, HASH_ATTRIBUTE, fileHash);

                    // If the public key in the file doesn't match the public key on disk, issue a build warning
                    if (!fileHash.ToLowerInvariant().Equals(hashAttribute.Value.ToLowerInvariant()))
                    {
                        if (results != null)
                            results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", "Hash", builder.Name, fileSource));
                    }
                }
            }
            else if (settings.ComponentsLocation == ComponentsLocation.HomeSite)
            {
                if (hashAttribute == null && publicKeyAttribute == null)
                {
                    if (results != null)
                    {
                        results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.MissingVerificationInformation", fileName, builder.Name));
                    }
                    return false;
                }
            }

            return true;
        }
        private XmlNode GetResourcesNodeForSettings(BuildSettings settings, BuildResults results, ref int codepage)
        {
            CultureInfo ci = Util.GetCultureInfoFromString(settings.Culture);
            CultureInfo fallbackCI = Util.GetCultureInfoFromString(settings.FallbackCulture);
            XmlNode cultureNode = null;


            if (ci != null)
            {
                // Work through the progression of parent cultures (up until but excluding the invariant culture) -> fallback culture -> parent fallback culture -> default culture -> parent default culture -> any available culture
                cultureNode = GetResourcesNodeForSettings_Helper(ci, ci, results, ref codepage, false);
                if (cultureNode != null) return cultureNode;
                CultureInfo parentCulture = ci.Parent;

                // Keep going up the chain of parents, stopping at the invariant culture
                while (parentCulture != null && parentCulture != CultureInfo.InvariantCulture)
                {
                    cultureNode = GetResourcesNodeForSettings_Helper(ci, parentCulture, results, ref codepage, false);
                    if (cultureNode != null) return cultureNode;

                    parentCulture = parentCulture.Parent;
                }
            }

            if (fallbackCI != null)
            {
                cultureNode = GetResourcesNodeForSettings_Helper(ci, fallbackCI, results, ref codepage, true);
                if (cultureNode != null) return cultureNode;

                if (!fallbackCI.IsNeutralCulture)
                {
                    cultureNode = GetResourcesNodeForSettings_Helper(ci, fallbackCI.Parent, results, ref codepage, true);
                    if (cultureNode != null) return cultureNode;
                }
            }

            cultureNode = GetResourcesNodeForSettings_Helper(ci, Util.DefaultCultureInfo, results, ref codepage, true);
            if (cultureNode != null) return cultureNode;

            if (!Util.DefaultCultureInfo.IsNeutralCulture)
            {
                cultureNode = GetResourcesNodeForSettings_Helper(ci, Util.DefaultCultureInfo.Parent, results, ref codepage, true);
                if (cultureNode != null) return cultureNode;
            }

            IEnumerator keys = _cultures.Keys.GetEnumerator();
            keys.MoveNext();
            string altCulture = (string)keys.Current;
            if (ci != null && results != null)
                results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", ci.Name, altCulture));
            GetCodePage(altCulture, ref codepage);
            return (XmlNode)_cultures[altCulture.ToLowerInvariant()];
        }
        private XmlNode GetResourcesNodeForSettings_Helper(CultureInfo culture, CultureInfo altCulture, BuildResults results, ref int codepage, bool fShowWarning)
        {
            if (altCulture != null && _cultures.Contains(altCulture.Name.ToLowerInvariant()))
            {
                if (fShowWarning && culture != null && results != null)
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", culture.Name, altCulture.Name));

                codepage = altCulture.TextInfo.ANSICodePage;
                return (XmlNode)_cultures[altCulture.Name.ToLowerInvariant()];
            }

            return null;
        }
        private Package GetPackageForSettings(BuildSettings settings, ProductBuilder builder, BuildResults results)
        {
            CultureInfo ci = Util.GetCultureInfoFromString(settings.Culture);
            CultureInfo fallbackCI = Util.GetCultureInfoFromString(settings.FallbackCulture);
            Package package = null;

            if (builder.Product.Packages.Count == 0)
            {
                if (results != null)
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.ProductCultureNotFound", builder.Name));
                return null;
            }

            if (ci != null)
            {
                package = builder.Product.Packages.Package(ci.Name);
                if (package != null) return package;

                // Target culture not found?  Go through the progression of parent cultures (up until but excluding the invariant culture) -> fallback culture -> parent fallback culture -> default culture -> parent default culture -> any culture available
                // Note: there is no warning if the parent culture of the requested culture is found
                CultureInfo parentCulture = ci.Parent;

                // Keep going up the chain of parents, stopping at the invariant culture
                while (parentCulture != null && parentCulture != CultureInfo.InvariantCulture)
                {
                    package = GetPackageForSettings_Helper(ci, parentCulture, builder, results, false);
                    if (package != null) return package;

                    parentCulture = parentCulture.Parent;
                }
            }


            if (fallbackCI != null)
            {
                package = GetPackageForSettings_Helper(ci, fallbackCI, builder, results, true);
                if (package != null) return package;

                if (!fallbackCI.IsNeutralCulture)
                {
                    package = GetPackageForSettings_Helper(ci, fallbackCI.Parent, builder, results, true);
                    if (package != null) return package;
                }
            }

            package = GetPackageForSettings_Helper(ci, Util.DefaultCultureInfo, builder, results, true);
            if (package != null) return package;

            if (!Util.DefaultCultureInfo.IsNeutralCulture)
            {
                package = GetPackageForSettings_Helper(ci, Util.DefaultCultureInfo.Parent, builder, results, true);
                if (package != null) return package;
            }

            if (results != null && ci != null)
                results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingProductCulture", ci.Name, builder.Name, builder.Product.Packages.Item(0).Culture));
            return builder.Product.Packages.Item(0);
        }
 private Package GetPackageForSettings_Helper(CultureInfo culture, CultureInfo altCulture, ProductBuilder builder, BuildResults results, bool fShowWarning)
 {
     if (altCulture == null)
         return null;
     Package package = builder.Product.Packages.Package(altCulture.Name);
     if (package != null)
     {
         if (fShowWarning && culture != null && results != null)
             results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingProductCulture", culture.Name, builder.Name, altCulture.Name));
         return package;
     }
     return null;
 }
        public bool UpdateResources(string filename, BuildResults results)
        {
            bool flag  = true;
            int  num   = 20;
            bool flag2 = false;

            if ((this.stringResources.Count == 0) && (this.fileResources.Count == 0))
            {
                return(true);
            }
            IntPtr zero = IntPtr.Zero;

            try
            {
                zero = Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.BeginUpdateResourceW(filename, false);
                while (((IntPtr.Zero == zero) && (Marshal.GetHRForLastWin32Error() == -2147024864)) && (num > 0))
                {
                    zero = Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.BeginUpdateResourceW(filename, false);
                    num--;
                    Thread.Sleep(100);
                }
                if (IntPtr.Zero == zero)
                {
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) }));
                    return(false);
                }
                flag2 = true;
                if (!(zero != IntPtr.Zero))
                {
                    return(flag);
                }
                foreach (StringResource resource in this.stringResources)
                {
                    byte[] buffer = this.StringToByteArray(resource.Data);
                    if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)resource.Type, resource.Name, 0, buffer, buffer.Length))
                    {
                        results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) }));
                        return(false);
                    }
                }
                if (this.fileResources.Count <= 0)
                {
                    return(flag);
                }
                int    num2 = 0;
                byte[] data = this.StringToByteArray(this.fileResources.Count.ToString("G", CultureInfo.InvariantCulture));
                if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, "COUNT", 0, data, data.Length))
                {
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) }));
                    return(false);
                }
                foreach (FileResource resource2 in this.fileResources)
                {
                    int    count   = 0;
                    byte[] buffer3 = null;
                    using (FileStream stream = File.OpenRead(resource2.Filename))
                    {
                        count   = (int)stream.Length;
                        buffer3 = new byte[count];
                        stream.Read(buffer3, 0, count);
                    }
                    string lpName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", new object[] { num2 });
                    if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, lpName, 0, buffer3, count))
                    {
                        results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) }));
                        return(false);
                    }
                    string str2    = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", new object[] { num2 });
                    byte[] buffer4 = this.StringToByteArray(resource2.Key);
                    if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, str2, 0, buffer4, buffer4.Length))
                    {
                        results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) }));
                        return(false);
                    }
                    num2++;
                }
            }
            finally
            {
                if (flag2 && !Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.EndUpdateResource(zero, false))
                {
                    results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) }));
                    flag = false;
                }
            }
            return(flag);
        }
        /// <summary>
        /// Generates a bootstrapper based on the specified settings.
        /// </summary>
        /// <param name="settings">The properties used to build this bootstrapper.</param>
        /// <returns>The results of the bootstrapper generation</returns>
        public BuildResults Build(BuildSettings settings)
        {
            _results = new BuildResults();
            try
            {
                if (settings.ApplicationFile == null && (settings.ProductBuilders == null || settings.ProductBuilders.Count == 0))
                {
                    _results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.InvalidInput"));
                    return _results;
                }

                if (String.IsNullOrEmpty(settings.OutputPath))
                {
                    _results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.NoOutputPath"));
                    return _results;
                }

                if (!_fInitialized)
                    Refresh();

                if (String.IsNullOrEmpty(settings.Culture))
                    settings.Culture = MapLCIDToCultureName(settings.LCID);
                if (String.IsNullOrEmpty(settings.FallbackCulture))
                    settings.FallbackCulture = MapLCIDToCultureName(settings.FallbackLCID);

                if (String.IsNullOrEmpty(settings.Culture) || settings.Culture == "*")
                {
                    settings.Culture = settings.FallbackCulture;
                }

                AddBuiltProducts(settings);

                ArrayList componentFilesCopied = new ArrayList();

                // Copy setup.bin to the output directory
                string strOutputExe = System.IO.Path.Combine(settings.OutputPath, SETUP_EXE);
                if (!CopySetupToOutputDirectory(settings, strOutputExe))
                {
                    // Appropriate messages should have been stuffed into the results already
                    return _results;
                }

                ResourceUpdater resourceUpdater = new ResourceUpdater();

                // Build up the String table for setup.exe
                if (!BuildResources(settings, resourceUpdater))
                {
                    // Appropriate messages should have been stuffed into the results already
                    return _results;
                }

                AddStringResourceForUrl(resourceUpdater, "BASEURL", settings.ApplicationUrl, "ApplicationUrl");
                AddStringResourceForUrl(resourceUpdater, "COMPONENTSURL", settings.ComponentsUrl, "ComponentsUrl");
                AddStringResourceForUrl(resourceUpdater, "SUPPORTURL", settings.SupportUrl, "SupportUrl");
                if (settings.ComponentsLocation == ComponentsLocation.HomeSite)
                {
                    resourceUpdater.AddStringResource(40, "HOMESITE", true.ToString());
                }

                XmlElement configElement = _document.CreateElement("Configuration");
                XmlElement applicationElement = CreateApplicationElement(configElement, settings);
                if (applicationElement != null)
                {
                    configElement.AppendChild(applicationElement);
                }

                // Key: File hash, Value: A DictionaryEntry whose Key is "EULAx" and value is a 
                // fully qualified path to a eula. It can be any eula that matches the hash.
                Hashtable eulas = new Hashtable();

                // Copy package files, add each Package config info to the config file
                if (!BuildPackages(settings, configElement, resourceUpdater, componentFilesCopied, eulas))
                    return _results;

                // Transform the configuration xml into something the bootstrapper will understand
                DumpXmlToFile(configElement, "bootstrapper.cfg.xml");
                string config = XmlToConfigurationFile(configElement);
                resourceUpdater.AddStringResource(41, "SETUPCFG", config);
                DumpStringToFile(config, "bootstrapper.cfg", false);

                // Put eulas in the resource stream
                foreach (object obj in eulas.Values)
                {
                    DictionaryEntry de = (DictionaryEntry)obj;
                    string data;
                    FileInfo fi = new System.IO.FileInfo(de.Value.ToString());
                    using (FileStream fs = fi.OpenRead())
                    {
                        data = new StreamReader(fs).ReadToEnd();
                    }

                    resourceUpdater.AddStringResource(44, de.Key.ToString(), data);
                }

                resourceUpdater.AddStringResource(44, "COUNT", eulas.Count.ToString(CultureInfo.InvariantCulture));
                if (!resourceUpdater.UpdateResources(strOutputExe, _results))
                {
                    return _results;
                }

                _results.SetKeyFile(strOutputExe);
                string[] componentFiles = new string[componentFilesCopied.Count];
                componentFilesCopied.CopyTo(componentFiles);
                _results.AddComponentFiles(componentFiles);
                _results.BuildSucceeded();
            }
            catch (Exception ex)
            {
                _results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", ex.Message));
            }
            return _results;
        }
 private bool AddVerificationInformation(XmlNode packageFileNode, string fileSource, string fileName, ProductBuilder builder, BuildSettings settings, BuildResults results)
 {
     XmlAttribute attribute = packageFileNode.Attributes["Hash"];
     XmlAttribute attribute2 = packageFileNode.Attributes["PublicKey"];
     if (File.Exists(fileSource))
     {
         string publicKeyOfFile = this.GetPublicKeyOfFile(fileSource);
         if ((attribute == null) && (attribute2 == null))
         {
             if (publicKeyOfFile != null)
             {
                 this.AddAttribute(packageFileNode, "PublicKey", publicKeyOfFile);
             }
             else
             {
                 this.AddAttribute(packageFileNode, "Hash", this.GetFileHash(fileSource));
             }
         }
         if (attribute2 != null)
         {
             if (publicKeyOfFile != null)
             {
                 this.ReplaceAttribute(packageFileNode, "PublicKey", publicKeyOfFile);
             }
             else
             {
                 packageFileNode.Attributes.RemoveNamedItem("PublicKey");
                 if (attribute == null)
                 {
                     this.AddAttribute(packageFileNode, "Hash", this.GetFileHash(fileSource));
                 }
             }
             if (((publicKeyOfFile == null) || !publicKeyOfFile.ToLowerInvariant().Equals(attribute2.Value.ToLowerInvariant())) && (results != null))
             {
                 results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", new object[] { "PublicKey", builder.Name, fileSource }));
             }
         }
         if (attribute != null)
         {
             string fileHash = this.GetFileHash(fileSource);
             this.ReplaceAttribute(packageFileNode, "Hash", fileHash);
             if (!fileHash.ToLowerInvariant().Equals(attribute.Value.ToLowerInvariant()) && (results != null))
             {
                 results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.DifferingPublicKeys", new object[] { "Hash", builder.Name, fileSource }));
             }
         }
     }
     else if (((settings.ComponentsLocation == ComponentsLocation.HomeSite) && (attribute == null)) && (attribute2 == null))
     {
         if (results != null)
         {
             results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.MissingVerificationInformation", new object[] { fileName, builder.Name }));
         }
         return false;
     }
     return true;
 }
 private bool VerifyHomeSiteInformation(XmlNode packageFileNode, ProductBuilder builder, BuildSettings settings, BuildResults results)
 {
     if (settings.ComponentsLocation != ComponentsLocation.HomeSite)
     {
         return true;
     }
     if ((packageFileNode.Attributes["HomeSite"] != null) || (builder.Product.CopyAllPackageFiles == CopyAllFilesType.CopyAllFilesIfNotHomeSite))
     {
         return true;
     }
     if (results != null)
     {
         results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.PackageHomeSiteMissing", new object[] { builder.Name }));
     }
     return false;
 }
 private XmlNode GetResourcesNodeForSettings_Helper(CultureInfo culture, CultureInfo altCulture, BuildResults results, ref int codepage, bool fShowWarning)
 {
     if ((altCulture == null) || !this.cultures.Contains(altCulture.Name.ToLowerInvariant()))
     {
         return null;
     }
     if ((fShowWarning && (culture != null)) && (results != null))
     {
         results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", new object[] { culture.Name, altCulture.Name }));
     }
     codepage = altCulture.TextInfo.ANSICodePage;
     return (XmlNode) this.cultures[altCulture.Name.ToLowerInvariant()];
 }
 private XmlNode GetResourcesNodeForSettings(BuildSettings settings, BuildResults results, ref int codepage)
 {
     CultureInfo cultureInfoFromString = Util.GetCultureInfoFromString(settings.Culture);
     CultureInfo altCulture = Util.GetCultureInfoFromString(settings.FallbackCulture);
     XmlNode node = null;
     if (cultureInfoFromString != null)
     {
         node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, cultureInfoFromString, results, ref codepage, false);
         if (node != null)
         {
             return node;
         }
         for (CultureInfo info3 = cultureInfoFromString.Parent; (info3 != null) && (info3 != CultureInfo.InvariantCulture); info3 = info3.Parent)
         {
             node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, info3, results, ref codepage, false);
             if (node != null)
             {
                 return node;
             }
         }
     }
     if (altCulture != null)
     {
         node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, altCulture, results, ref codepage, true);
         if (node != null)
         {
             return node;
         }
         if (!altCulture.IsNeutralCulture)
         {
             node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, altCulture.Parent, results, ref codepage, true);
             if (node != null)
             {
                 return node;
             }
         }
     }
     node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo, results, ref codepage, true);
     if (node != null)
     {
         return node;
     }
     if (!Util.DefaultCultureInfo.IsNeutralCulture)
     {
         node = this.GetResourcesNodeForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo.Parent, results, ref codepage, true);
         if (node != null)
         {
             return node;
         }
     }
     IEnumerator enumerator = this.cultures.Keys.GetEnumerator();
     enumerator.MoveNext();
     string current = (string) enumerator.Current;
     if ((cultureInfoFromString != null) && (results != null))
     {
         results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingResourcesCulture", new object[] { cultureInfoFromString.Name, current }));
     }
     this.GetCodePage(current, ref codepage);
     return (XmlNode) this.cultures[current.ToLowerInvariant()];
 }
 private Package GetPackageForSettings(BuildSettings settings, ProductBuilder builder, BuildResults results)
 {
     CultureInfo cultureInfoFromString = Util.GetCultureInfoFromString(settings.Culture);
     CultureInfo altCulture = Util.GetCultureInfoFromString(settings.FallbackCulture);
     Package package = null;
     if (builder.Product.Packages.Count == 0)
     {
         if (results != null)
         {
             results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.ProductCultureNotFound", new object[] { builder.Name }));
         }
         return null;
     }
     if (cultureInfoFromString != null)
     {
         package = builder.Product.Packages.Package(cultureInfoFromString.Name);
         if (package != null)
         {
             return package;
         }
         for (CultureInfo info3 = cultureInfoFromString.Parent; (info3 != null) && (info3 != CultureInfo.InvariantCulture); info3 = info3.Parent)
         {
             package = this.GetPackageForSettings_Helper(cultureInfoFromString, info3, builder, results, false);
             if (package != null)
             {
                 return package;
             }
         }
     }
     if (altCulture != null)
     {
         package = this.GetPackageForSettings_Helper(cultureInfoFromString, altCulture, builder, results, true);
         if (package != null)
         {
             return package;
         }
         if (!altCulture.IsNeutralCulture)
         {
             package = this.GetPackageForSettings_Helper(cultureInfoFromString, altCulture.Parent, builder, results, true);
             if (package != null)
             {
                 return package;
             }
         }
     }
     package = this.GetPackageForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo, builder, results, true);
     if (package != null)
     {
         return package;
     }
     if (!Util.DefaultCultureInfo.IsNeutralCulture)
     {
         package = this.GetPackageForSettings_Helper(cultureInfoFromString, Util.DefaultCultureInfo.Parent, builder, results, true);
         if (package != null)
         {
             return package;
         }
     }
     if ((results != null) && (cultureInfoFromString != null))
     {
         results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.UsingProductCulture", new object[] { cultureInfoFromString.Name, builder.Name, builder.Product.Packages.Item(0).Culture }));
     }
     return builder.Product.Packages.Item(0);
 }