From 94b941ee95a294228516097c269e27dfa41593ab Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Mon, 13 Jan 2020 09:10:13 -0800 Subject: Provide Record enumerator on View that disposes fetched Records --- .../Inscribe/InscribeMsiPackageCommand.cs | 242 ++++++++++----------- 1 file changed, 109 insertions(+), 133 deletions(-) (limited to 'src/WixToolset.Core.WindowsInstaller/Inscribe') diff --git a/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs b/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs index b91eeeef..ff7472ff 100644 --- a/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs @@ -60,47 +60,39 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe { using (View digitalSignatureView = database.OpenExecuteView("SELECT `Table`, `SignObject`, `DigitalCertificate_`, `Hash` FROM `MsiDigitalSignature` WHERE `Table` <> 'Media'")) { - while (true) + foreach (Record digitalSignatureRecord in digitalSignatureView.Records) { - using (Record digitalSignatureRecord = digitalSignatureView.Fetch()) - { - if (null == digitalSignatureRecord) - { - break; - } + Row digitalSignatureRow = null; + digitalSignatureRow = digitalSignatureTable.CreateRow(null); - Row digitalSignatureRow = null; - digitalSignatureRow = digitalSignatureTable.CreateRow(null); + string table = digitalSignatureRecord.GetString(0); + string signObject = digitalSignatureRecord.GetString(1); - string table = digitalSignatureRecord.GetString(0); - string signObject = digitalSignatureRecord.GetString(1); + digitalSignatureRow[0] = table; + digitalSignatureRow[1] = signObject; + digitalSignatureRow[2] = digitalSignatureRecord.GetString(2); - digitalSignatureRow[0] = table; - digitalSignatureRow[1] = signObject; - digitalSignatureRow[2] = digitalSignatureRecord.GetString(2); + if (false == digitalSignatureRecord.IsNull(3)) + { + // Export to a file, because the MSI API's require us to provide a file path on disk + string hashPath = Path.Combine(this.Context.IntermediateFolder, "MsiDigitalSignature"); + string hashFileName = string.Concat(table, ".", signObject, ".bin"); - if (false == digitalSignatureRecord.IsNull(3)) - { - // Export to a file, because the MSI API's require us to provide a file path on disk - string hashPath = Path.Combine(this.Context.IntermediateFolder, "MsiDigitalSignature"); - string hashFileName = string.Concat(table, ".", signObject, ".bin"); + Directory.CreateDirectory(hashPath); + hashPath = Path.Combine(hashPath, hashFileName); - Directory.CreateDirectory(hashPath); - hashPath = Path.Combine(hashPath, hashFileName); + using (FileStream fs = File.Create(hashPath)) + { + int bytesRead; + byte[] buffer = new byte[1024 * 4]; - using (FileStream fs = File.Create(hashPath)) + while (0 != (bytesRead = digitalSignatureRecord.GetStream(3, buffer, buffer.Length))) { - int bytesRead; - byte[] buffer = new byte[1024 * 4]; - - while (0 != (bytesRead = digitalSignatureRecord.GetStream(3, buffer, buffer.Length))) - { - fs.Write(buffer, 0, bytesRead); - } + fs.Write(buffer, 0, bytesRead); } - - digitalSignatureRow[3] = hashFileName; } + + digitalSignatureRow[3] = hashFileName; } } } @@ -111,145 +103,129 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe { using (View digitalCertificateView = database.OpenExecuteView("SELECT * FROM `MsiDigitalCertificate`")) { - while (true) + foreach (Record digitalCertificateRecord in digitalCertificateView.Records) { - using (Record digitalCertificateRecord = digitalCertificateView.Fetch()) - { - if (null == digitalCertificateRecord) - { - break; - } + string certificateId = digitalCertificateRecord.GetString(1); // get the identifier of the certificate - string certificateId = digitalCertificateRecord.GetString(1); // get the identifier of the certificate + // Export to a file, because the MSI API's require us to provide a file path on disk + string certPath = Path.Combine(this.Context.IntermediateFolder, "MsiDigitalCertificate"); + Directory.CreateDirectory(certPath); + certPath = Path.Combine(certPath, string.Concat(certificateId, ".cer")); - // Export to a file, because the MSI API's require us to provide a file path on disk - string certPath = Path.Combine(this.Context.IntermediateFolder, "MsiDigitalCertificate"); - Directory.CreateDirectory(certPath); - certPath = Path.Combine(certPath, string.Concat(certificateId, ".cer")); + using (FileStream fs = File.Create(certPath)) + { + int bytesRead; + byte[] buffer = new byte[1024 * 4]; - using (FileStream fs = File.Create(certPath)) + while (0 != (bytesRead = digitalCertificateRecord.GetStream(2, buffer, buffer.Length))) { - int bytesRead; - byte[] buffer = new byte[1024 * 4]; - - while (0 != (bytesRead = digitalCertificateRecord.GetStream(2, buffer, buffer.Length))) - { - fs.Write(buffer, 0, bytesRead); - } + fs.Write(buffer, 0, bytesRead); } + } - // Add it to our "add to MsiDigitalCertificate" table dictionary - Row digitalCertificateRow = digitalCertificateTable.CreateRow(null); - digitalCertificateRow[0] = certificateId; + // Add it to our "add to MsiDigitalCertificate" table dictionary + Row digitalCertificateRow = digitalCertificateTable.CreateRow(null); + digitalCertificateRow[0] = certificateId; - // Now set the file path on disk where this binary stream will be picked up at import time - digitalCertificateRow[1] = string.Concat(certificateId, ".cer"); + // Now set the file path on disk where this binary stream will be picked up at import time + digitalCertificateRow[1] = string.Concat(certificateId, ".cer"); - // Load the cert to get it's thumbprint - X509Certificate cert = X509Certificate.CreateFromCertFile(certPath); - X509Certificate2 cert2 = new X509Certificate2(cert); + // Load the cert to get it's thumbprint + X509Certificate cert = X509Certificate.CreateFromCertFile(certPath); + X509Certificate2 cert2 = new X509Certificate2(cert); - certificates.Add(cert2.Thumbprint, certificateId); - } + certificates.Add(cert2.Thumbprint, certificateId); } } } using (View mediaView = database.OpenExecuteView("SELECT * FROM `Media`")) { - while (true) + foreach (Record mediaRecord in mediaView.Records) { - using (Record mediaRecord = mediaView.Fetch()) + X509Certificate2 cert2 = null; + Row digitalSignatureRow = null; + + string cabName = mediaRecord.GetString(4); // get the name of the cab + // If there is no cabinet or it's an internal cab, skip it. + if (String.IsNullOrEmpty(cabName) || cabName.StartsWith("#", StringComparison.Ordinal)) { - if (null == mediaRecord) - { - break; - } + continue; + } - X509Certificate2 cert2 = null; - Row digitalSignatureRow = null; + string cabId = mediaRecord.GetString(1); // get the ID of the cab + string cabPath = Path.Combine(Path.GetDirectoryName(this.Context.InputFilePath), cabName); - string cabName = mediaRecord.GetString(4); // get the name of the cab - // If there is no cabinet or it's an internal cab, skip it. - if (String.IsNullOrEmpty(cabName) || cabName.StartsWith("#", StringComparison.Ordinal)) - { - continue; - } + // If the cabs aren't there, throw an error but continue to catch the other errors + if (!File.Exists(cabPath)) + { + this.Messaging.Write(ErrorMessages.WixFileNotFound(cabPath)); + continue; + } - string cabId = mediaRecord.GetString(1); // get the ID of the cab - string cabPath = Path.Combine(Path.GetDirectoryName(this.Context.InputFilePath), cabName); + try + { + // Get the certificate from the cab + X509Certificate signedFileCert = X509Certificate.CreateFromSignedFile(cabPath); + cert2 = new X509Certificate2(signedFileCert); + } + catch (System.Security.Cryptography.CryptographicException e) + { + uint HResult = unchecked((uint)Marshal.GetHRForException(e)); - // If the cabs aren't there, throw an error but continue to catch the other errors - if (!File.Exists(cabPath)) + // If the file has no cert, continue, but flag that we found at least one so we can later give a warning + if (0x80092009 == HResult) // CRYPT_E_NO_MATCH { - this.Messaging.Write(ErrorMessages.WixFileNotFound(cabPath)); + foundUnsignedExternals = true; continue; } - try + // todo: exactly which HRESULT corresponds to this issue? + // If it's one of these exact platforms, warn the user that it may be due to their OS. + if ((5 == Environment.OSVersion.Version.Major && 2 == Environment.OSVersion.Version.Minor) || // W2K3 + (5 == Environment.OSVersion.Version.Major && 1 == Environment.OSVersion.Version.Minor)) // XP { - // Get the certificate from the cab - X509Certificate signedFileCert = X509Certificate.CreateFromSignedFile(cabPath); - cert2 = new X509Certificate2(signedFileCert); + this.Messaging.Write(ErrorMessages.UnableToGetAuthenticodeCertOfFileDownlevelOS(cabPath, String.Format(CultureInfo.InvariantCulture, "HRESULT: 0x{0:x8}", HResult))); } - catch (System.Security.Cryptography.CryptographicException e) + else // otherwise, generic error { - uint HResult = unchecked((uint)Marshal.GetHRForException(e)); - - // If the file has no cert, continue, but flag that we found at least one so we can later give a warning - if (0x80092009 == HResult) // CRYPT_E_NO_MATCH - { - foundUnsignedExternals = true; - continue; - } - - // todo: exactly which HRESULT corresponds to this issue? - // If it's one of these exact platforms, warn the user that it may be due to their OS. - if ((5 == Environment.OSVersion.Version.Major && 2 == Environment.OSVersion.Version.Minor) || // W2K3 - (5 == Environment.OSVersion.Version.Major && 1 == Environment.OSVersion.Version.Minor)) // XP - { - this.Messaging.Write(ErrorMessages.UnableToGetAuthenticodeCertOfFileDownlevelOS(cabPath, String.Format(CultureInfo.InvariantCulture, "HRESULT: 0x{0:x8}", HResult))); - } - else // otherwise, generic error - { - this.Messaging.Write(ErrorMessages.UnableToGetAuthenticodeCertOfFile(cabPath, String.Format(CultureInfo.InvariantCulture, "HRESULT: 0x{0:x8}", HResult))); - } + this.Messaging.Write(ErrorMessages.UnableToGetAuthenticodeCertOfFile(cabPath, String.Format(CultureInfo.InvariantCulture, "HRESULT: 0x{0:x8}", HResult))); } + } - // If we haven't added this cert to the MsiDigitalCertificate table, set it up to be added - if (!certificates.ContainsKey(cert2.Thumbprint)) - { - // generate a stable identifier - string certificateGeneratedId = Common.GenerateIdentifier("cer", cert2.Thumbprint); - - // Add it to our "add to MsiDigitalCertificate" table dictionary - Row digitalCertificateRow = digitalCertificateTable.CreateRow(null); - digitalCertificateRow[0] = certificateGeneratedId; - - // Export to a file, because the MSI API's require us to provide a file path on disk - string certPath = Path.Combine(this.Context.IntermediateFolder, "MsiDigitalCertificate"); - Directory.CreateDirectory(certPath); - certPath = Path.Combine(certPath, string.Concat(cert2.Thumbprint, ".cer")); - File.Delete(certPath); + // If we haven't added this cert to the MsiDigitalCertificate table, set it up to be added + if (!certificates.ContainsKey(cert2.Thumbprint)) + { + // generate a stable identifier + string certificateGeneratedId = Common.GenerateIdentifier("cer", cert2.Thumbprint); - using (BinaryWriter writer = new BinaryWriter(File.Open(certPath, FileMode.Create))) - { - writer.Write(cert2.RawData); - writer.Close(); - } + // Add it to our "add to MsiDigitalCertificate" table dictionary + Row digitalCertificateRow = digitalCertificateTable.CreateRow(null); + digitalCertificateRow[0] = certificateGeneratedId; - // Now set the file path on disk where this binary stream will be picked up at import time - digitalCertificateRow[1] = string.Concat(cert2.Thumbprint, ".cer"); + // Export to a file, because the MSI API's require us to provide a file path on disk + string certPath = Path.Combine(this.Context.IntermediateFolder, "MsiDigitalCertificate"); + Directory.CreateDirectory(certPath); + certPath = Path.Combine(certPath, string.Concat(cert2.Thumbprint, ".cer")); + File.Delete(certPath); - certificates.Add(cert2.Thumbprint, certificateGeneratedId); + using (BinaryWriter writer = new BinaryWriter(File.Open(certPath, FileMode.Create))) + { + writer.Write(cert2.RawData); + writer.Close(); } - digitalSignatureRow = digitalSignatureTable.CreateRow(null); + // Now set the file path on disk where this binary stream will be picked up at import time + digitalCertificateRow[1] = string.Concat(cert2.Thumbprint, ".cer"); - digitalSignatureRow[0] = "Media"; - digitalSignatureRow[1] = cabId; - digitalSignatureRow[2] = certificates[cert2.Thumbprint]; + certificates.Add(cert2.Thumbprint, certificateGeneratedId); } + + digitalSignatureRow = digitalSignatureTable.CreateRow(null); + + digitalSignatureRow[0] = "Media"; + digitalSignatureRow[1] = cabId; + digitalSignatureRow[2] = certificates[cert2.Thumbprint]; } } @@ -275,7 +251,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe certificates = null; - // If we did find external cabs but none of them were signed, give a warning + // If we did find external cabs but not all of them were signed, give a warning if (foundUnsignedExternals) { this.Messaging.Write(WarningMessages.ExternalCabsAreNotSigned(this.Context.InputFilePath)); -- cgit v1.2.3-55-g6feb