List:Commits« Previous MessageNext Message »
From:Reggie Burnett Date:September 11 2012 6:56pm
Subject:bzr commit into ABSv2 branch (reggie.burnett:20)
View as plain text  
#At file:///C:/work/wex/absv2/ based on revid:reggie.burnett@stripped

   20 Reggie Burnett	2012-09-11
      started build verifier code along with msi interop code

    added:
      AbsUtility/BuildVerifier.cs
      AbsUtility/MSIDatabase.cs
      AbsUtility/MSIInterop.cs
      AbsUtility/MSIRecord.cs
      AbsUtility/MSIView.cs
    modified:
      AbsJobProcessor/AbsJobProcessor.csproj
      AbsJobProcessor/Program.cs
      AbsUtility/AbsUtility.csproj
      AbsUtility/Job.cs
=== modified file 'AbsJobProcessor/AbsJobProcessor.csproj'
=== modified file 'AbsJobProcessor/AbsJobProcessor.csproj'
--- a/AbsJobProcessor/AbsJobProcessor.csproj	2012-08-22 17:36:55 +0000
+++ b/AbsJobProcessor/AbsJobProcessor.csproj	2012-09-11 18:56:18 +0000
@@ -15,7 +15,7 @@
     <FileAlignment>512</FileAlignment>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <PlatformTarget>x86</PlatformTarget>
+    <PlatformTarget>AnyCPU</PlatformTarget>
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>

=== modified file 'AbsJobProcessor/Program.cs'
--- a/AbsJobProcessor/Program.cs	2012-09-04 21:25:29 +0000
+++ b/AbsJobProcessor/Program.cs	2012-09-11 18:56:18 +0000
@@ -16,6 +16,20 @@
 
       try
       {
+        MSIDatabase m = new MSIDatabase(@"c:\\test.msi");
+        m.Open();
+        DataTable dt2 = m.GetTable("File");
+        m.Close();
+      }
+      catch (Exception ex)
+      {
+        Console.WriteLine(ex.Message + ex.StackTrace);
+        Console.ReadLine();
+      }
+      return;
+
+      try
+      {
         if (!Settings.ResolveFolders()) return;
         if (!Utility.ShouldRun()) return;
 

=== modified file 'AbsUtility/AbsUtility.csproj'
--- a/AbsUtility/AbsUtility.csproj	2012-08-28 19:10:02 +0000
+++ b/AbsUtility/AbsUtility.csproj	2012-09-11 18:56:18 +0000
@@ -44,8 +44,13 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="BuildVerifier.cs" />
     <Compile Include="Job.cs" />
     <Compile Include="JobBuild.cs" />
+    <Compile Include="MSIDatabase.cs" />
+    <Compile Include="MSIInterop.cs" />
+    <Compile Include="MSIRecord.cs" />
+    <Compile Include="MSIView.cs" />
     <Compile Include="Product.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Settings.cs" />

=== added file 'AbsUtility/BuildVerifier.cs'
--- a/AbsUtility/BuildVerifier.cs	1970-01-01 00:00:00 +0000
+++ b/AbsUtility/BuildVerifier.cs	2012-09-11 18:56:18 +0000
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Abs
+{
+  internal class BuildVerifier
+  {
+    public BuildVerifier(string series, string license, string file)
+    {
+      BuildFile = file;
+      Series = series;
+      License = license;
+    }
+
+    public string BuildFile { get; private set; }
+    public string Series { get; private set; }
+    public string License { get; private set; }
+
+    public void Verify()
+    {
+      VerifyFileExistsAndSize();
+      VerifyProperFileName();
+      MSIDatabase m = new MSIDatabase(BuildFile);
+      using (m)
+      {
+        m.Open();
+        VerifyProperFilesIncluded(m);
+        VerifyManifest(m);
+      }
+    }
+
+    private void VerifyFileExistsAndSize()
+    {
+      if (!File.Exists(BuildFile))
+        throw new Exception("Installer file does not exist");
+      FileInfo fi = new FileInfo(BuildFile);
+      if (fi.Length < 200 * 1024 * 1024)
+        throw new Exception("Installer is not large enough");
+    }
+
+    private void VerifyProperFileName()
+    {
+
+    }
+
+    private void VerifyProperFilesIncluded(MSIDatabase m)
+    {
+    }
+
+    private void VerifyManifest(MSIDatabase m)
+    {
+    }
+  }
+}

=== modified file 'AbsUtility/Job.cs'
--- a/AbsUtility/Job.cs	2012-09-04 20:04:05 +0000
+++ b/AbsUtility/Job.cs	2012-09-11 18:56:18 +0000
@@ -151,10 +151,19 @@
       // use msbuild to build setup msi
       BuildInstaller(series, license);
 
+      // now verify that the installer is likely valid
+      VerifyInstaller(series, license);
+
       // mark job as done
       RegisterBuild(series, license);
     }
 
+    private void VerifyInstaller(string series, string license)
+    {
+      BuildVerifier v = new BuildVerifier(series, license, outputFileName);
+      v.Verify();
+    }
+
     private void RegisterBuild(string series, string license)
     {
       MySqlHelper.ExecuteNonQuery(Settings.ConnectionString,

=== added file 'AbsUtility/MSIDatabase.cs'
--- a/AbsUtility/MSIDatabase.cs	1970-01-01 00:00:00 +0000
+++ b/AbsUtility/MSIDatabase.cs	2012-09-11 18:56:18 +0000
@@ -0,0 +1,57 @@
+ï»g System.Data;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Abs
+{
+  public class MSIDatabase : IDisposable
+  {
+    public MSIDatabase(string file)
+    {
+      Filename = file;
+    }
+
+    public string Filename { get; private set; }
+    public IntPtr Handle { get; private set; }
+
+    public void Open()
+    {
+      IntPtr handle = IntPtr.Zero;
+      WindowsErrorCode result = MSIInterop.MsiOpenDatabase(Filename, new IntPtr(MSIInterop.MSIDBOPEN_READONLY), out handle);
+      if (result != WindowsErrorCode.ERROR_SUCCESS)
+        throw new Exception("Unable to open msi database. Return value was: " + result);
+      Handle = handle;
+    }
+
+    public void Close()
+    {
+      if (Handle != IntPtr.Zero)
+        MSIInterop.MsiCloseHandle(Handle);
+      Handle = IntPtr.Zero;
+    }
+
+    public DataTable GetTable(string tableName)
+    {
+      MSIView view = new MSIView(this);
+      using (view)
+      {
+        view.Open("SELECT * FROM " + tableName);
+        return view.GetDataTable();
+      }
+    }
+
+    #region IDisposable Members
+
+    public void Dispose()
+    {
+      Close();
+    }
+
+    #endregion
+
+  }
+
+}

=== added file 'AbsUtility/MSIInterop.cs'
--- a/AbsUtility/MSIInterop.cs	1970-01-01 00:00:00 +0000
+++ b/AbsUtility/MSIInterop.cs	2012-09-11 18:56:18 +0000
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Abs
+{
+  public class MSIInterop
+  {
+    //*********************************** 
+    // DllImports for the MSI API's used.
+    //***********************************
+    [DllImport("msi.dll", SetLastError = true)]
+    public static extern WindowsErrorCode MsiOpenDatabase(string szDatabasePath, IntPtr phPersist, out IntPtr phDatabase);
+
+    [DllImport("msi.dll", ExactSpelling = true)]
+    public static extern WindowsErrorCode MsiCloseHandle(IntPtr hAny);
+
+    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
+    public static extern WindowsErrorCode MsiDatabaseOpenViewW(IntPtr hDatabase, [MarshalAs(UnmanagedType.LPWStr)] string szQuery, out IntPtr phView);
+
+    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
+    public static extern WindowsErrorCode MsiViewExecute(IntPtr hView, IntPtr hRecord);
+
+    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
+    public static extern WindowsErrorCode MsiViewFetch(IntPtr hView, out IntPtr hRecord);
+
+    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
+    public static extern WindowsErrorCode MsiDatabaseCommit(IntPtr hDatabase);
+
+    public const int MSICOLINFO_NAMES = 0;  // return column names
+    public const int MSICOLINFO_TYPES = 1;  // return column definitions, datatype code followed by width
+    [DllImport("msi.dll", ExactSpelling = true)]
+    public static extern WindowsErrorCode MsiViewGetColumnInfo(IntPtr hView, int eColumnInfo, out IntPtr hRecord);
+
+    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
+    public static extern WindowsErrorCode MsiRecordGetString(IntPtr hRecord, int iField, StringBuilder szValueBuf, ref int pcchValueBuf);
+
+    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
+    public static extern uint MsiRecordGetFieldCount(IntPtr record);
+
+    [DllImport("msi.dll")]
+    public static extern WindowsErrorCode MsiViewClose(IntPtr viewhandle);
+
+    //*****************************************
+    // Open mode constants for MsiOpenDatabase.
+    //*****************************************
+    public const int MSIDBOPEN_READONLY = 0;  // database open read-only, no persistent changes
+    public const int MSIDBOPEN_TRANSACT = 1;  // database read/write in transaction mode
+    public const int MSIDBOPEN_DIRECT = 2;  // database direct read/write without transaction
+    public const int MSIDBOPEN_CREATE = 3;  // create new database, transact mode read/write
+    public const int MSIDBOPEN_CREATEDIRECT = 4;  // create new database, direct mode read/write
+  }
+
+  public enum WindowsErrorCode : int
+  {
+    ERROR_SUCCESS = 0,
+    ERROR_INVALID_PARAMETER = 87,
+    ERROR_NO_MORE_ITEMS = 259,
+    ERROR_INSTALL_USEREXIT = 1602,
+    ERROR_INSTALL_FAILURE = 1603,
+    ERROR_BAD_CONFIGURATION = 1610,
+    ERROR_INSTALL_IN_PROGRESS = 1618,
+    ERROR_INSTALL_SOURCE_ABSENT = 1612,
+    ERROR_UNKNOWN_PRODUCT = 1605,
+    ERROR_FUNCTION_FAILED = 1627,
+    ERROR_INVALID_HANDLE_STATE = 1609,
+    ERROR_MORE_DATA = 234,
+    ERROR_UNKNOWN_PROPERTY = 1608,
+    ERROR_CREATE_FAILED = 1631,
+    ERROR_OPEN_FAILED = 110,
+    ERROR_BAD_QUERY_SYNTAX = 1615
+  }
+
+}

=== added file 'AbsUtility/MSIRecord.cs'
--- a/AbsUtility/MSIRecord.cs	1970-01-01 00:00:00 +0000
+++ b/AbsUtility/MSIRecord.cs	2012-09-11 18:56:18 +0000
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Abs
+{
+  public class MSIRecord : IDisposable
+  {
+    public MSIRecord()
+    {
+    }
+
+    public MSIRecord(IntPtr record)
+    {
+        Handle = record;
+    }
+
+    public IntPtr Handle { get; private set; }
+
+    public void Close()
+    {
+      if (Handle != IntPtr.Zero)
+        MSIInterop.MsiCloseHandle(Handle);
+      Handle = IntPtr.Zero;
+    }
+
+    public uint NumberOfFields()
+    {
+      return MSIInterop.MsiRecordGetFieldCount(Handle);
+    }
+
+    public string GetString(int index, int maxSize = 1024)
+    {
+      var builder = new StringBuilder(maxSize);
+      var count = builder.Capacity;
+
+      WindowsErrorCode result = MSIInterop.MsiRecordGetString(Handle, index, builder, ref count);
+      if (result == WindowsErrorCode.ERROR_SUCCESS)
+        return builder.ToString();
+      throw new Exception(String.Format("Error retrieving string value for index {0}", index));
+    }
+
+    #region IDisposable Members
+
+    public void Dispose()
+    {
+      Close();
+    }
+
+    #endregion
+  }
+}

=== added file 'AbsUtility/MSIView.cs'
--- a/AbsUtility/MSIView.cs	1970-01-01 00:00:00 +0000
+++ b/AbsUtility/MSIView.cs	2012-09-11 18:56:18 +0000
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+
+namespace Abs
+{
+  public class MSIView : IDisposable
+  {
+    public MSIView(MSIDatabase db) 
+    {
+      Database = db;
+    }
+
+    public MSIDatabase Database { get; private set; }
+    public string ViewSQL { get; private set; }
+    public IntPtr Handle { get; private set; }
+    public List<string> ColumnNames { get; private set; }
+    public List<string> ColumnTypes { get; private set; }
+
+    public void Open(string sql)
+    {
+      ViewSQL = sql;
+
+      IntPtr view = IntPtr.Zero;
+      WindowsErrorCode result = MSIInterop.MsiDatabaseOpenViewW(Database.Handle, ViewSQL, out view);
+      if (result != WindowsErrorCode.ERROR_SUCCESS)
+        throw new Exception(String.Format("Unable to open view for {0} with error {1}", sql, result));
+      Handle = view;
+      ColumnNames = GetColumnInfo(MSIInterop.MSICOLINFO_NAMES);
+      ColumnTypes = GetColumnInfo(MSIInterop.MSICOLINFO_TYPES);
+    }
+
+    public void Close()
+    {
+      if (Handle != IntPtr.Zero)
+        MSIInterop.MsiCloseHandle(Handle);
+      Handle = IntPtr.Zero;
+    }
+
+    public MSIRecord FetchRecord()
+    {
+      IntPtr recordHandle = IntPtr.Zero;
+
+      WindowsErrorCode result = MSIInterop.MsiViewFetch(Handle, out recordHandle);
+      if (result == WindowsErrorCode.ERROR_NO_MORE_ITEMS) return null;
+      if (result != WindowsErrorCode.ERROR_SUCCESS)
+        throw new Exception(String.Format("Error fetching records for view {0} with error {1}", ViewSQL, result));
+      return new MSIRecord(recordHandle);
+    }
+
+    public DataTable GetDataTable()
+    {
+      DataTable dt = new DataTable();
+      for (int x = 0; x < ColumnNames.Count; x++)
+        dt.Columns.Add(GetColumn(ColumnNames[x], ColumnTypes[x]));
+
+      WindowsErrorCode result = MSIInterop.MsiViewExecute(Handle, IntPtr.Zero);
+      if (result != WindowsErrorCode.ERROR_SUCCESS)
+        throw new Exception(String.Format("Error executing table view for sql {0} with error {1}", ViewSQL, result));
+
+      while (true)
+      {
+        MSIRecord r = FetchRecord();
+        if (r == null) break;
+        DataRow row = dt.NewRow();
+        for (int x = 0; x < dt.Columns.Count; x++)
+          row[x] = r.GetString(x+1);
+        r.Close();
+        dt.Rows.Add(row);
+      }
+      return dt;
+    }
+
+    private List<string> GetColumnInfo(int type)
+    {
+      IntPtr record = IntPtr.Zero;
+      WindowsErrorCode result = MSIInterop.MsiViewGetColumnInfo(Handle, type, out record);
+      MSIRecord r = new MSIRecord(record);
+      uint numFields = r.NumberOfFields();
+
+      List<string> collection = new List<string>();
+      for (int x = 1; x <= numFields; x++)
+        collection.Add(r.GetString(x));
+      return collection;
+    }
+
+    private DataColumn GetColumn(string name, string typeName)
+    {
+      DataColumn c = new DataColumn();
+      c.ColumnName = name;
+      if (typeName.StartsWith("s") || typeName.StartsWith("g"))
+        c.DataType = Type.GetType("System.String");
+      else if (typeName == "i4" || typeName == "j4")
+        c.DataType = Type.GetType("System.Int64");
+      else if (typeName == "i2" || typeName.StartsWith("j"))
+        c.DataType = Type.GetType("System.Int32");
+      else if (typeName == "v0")
+        c.DataType = Type.GetType("byte[]");
+      else if (typeName == "O0")
+        c.DataType = Type.GetType("System.Object");
+      return c;
+    }
+
+    #region IDisposable Members
+
+    public void Dispose()
+    {
+      Close();
+    }
+
+    #endregion
+  }
+}

Attachment: [text/bzr-bundle] bzr/reggie.burnett@oracle.com-20120911185618-86jw1hc9yc9k27kc.bundle
Thread
bzr commit into ABSv2 branch (reggie.burnett:20) Reggie Burnett11 Sep