diff --git a/BurnOutSharp/External/libmsi/LibmsiDatabase.cs b/BurnOutSharp/External/libmsi/LibmsiDatabase.cs index b3757390..3ad27930 100644 --- a/BurnOutSharp/External/libmsi/LibmsiDatabase.cs +++ b/BurnOutSharp/External/libmsi/LibmsiDatabase.cs @@ -299,6 +299,14 @@ namespace LibMSI if (!Directory.Exists(path)) Directory.CreateDirectory(path); + // _MsiDigitalSignatureEx + + //Exception err = null; + //string digitalSignaturePath = System.IO.Path.Combine(path, "_MsiDigitalSignatureEx.idt"); + //using (Stream digitalSignatureStream = File.OpenWrite(digitalSignaturePath)) + //{ + // Export("_MsiDigitalSignatureEx", digitalSignatureStream, ref err); + //} // SummaryInfo @@ -669,7 +677,6 @@ namespace LibMSI internal LibmsiResult GetRawStream(string stname, out GsfInput stm) { - string decoded = DecodeStreamName(stname); if (CloneInfileStream(stname, out stm) == LibmsiResult.LIBMSI_RESULT_SUCCESS) return LibmsiResult.LIBMSI_RESULT_SUCCESS; @@ -1457,7 +1464,7 @@ namespace LibMSI for (int i = 0; i < MSI_MAX_PROPS; i++) { - if (si.Property[i].VariantType != LibmsiOLEVariantType.OLEVT_EMPTY) + if (si.Properties[i] != null && si.Properties[i].VariantType != LibmsiOLEVariantType.OLEVT_EMPTY) { string val = si.SummaryInfoAsString(i); if (val == null) @@ -1491,7 +1498,7 @@ namespace LibMSI return ExportSummaryInfo(fd, ref error); } - string query = $"select * from {table}"; + string query = $"SELECT * FROM `{table}`"; LibmsiResult r = QueryOpen(this, out LibmsiQuery view, query); if (r == LibmsiResult.LIBMSI_RESULT_SUCCESS) { @@ -1642,7 +1649,7 @@ namespace LibMSI if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS) return null; - string query = $"SELECT * FROM {table} WHERE "; + string query = $"SELECT * FROM `{table}` WHERE "; int count = keys.GetFieldCount(); for (int i = 1; i <= count; i++) { @@ -1789,7 +1796,7 @@ namespace LibMSI table.Labels = labels; table.NumLabels = num_labels; - string query = $"SELECT * FROM {name}"; + string query = $"SELECT * FROM `{name}`"; r = QueryOpen(this, out LibmsiQuery mergeview, query); if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS) goto err; @@ -1828,7 +1835,7 @@ namespace LibMSI MERGEDATA data = param as MERGEDATA; string name = rec.GetStringRaw(1); - string query = $"SELECT * FROM {name}"; + string query = $"SELECT * FROM `{name}`"; LibmsiResult r = QueryOpen(data.Merge, out LibmsiQuery mergeview, query); if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS) return r; @@ -1869,7 +1876,7 @@ namespace LibMSI private LibmsiResult GatherMergeData(LibmsiDatabase merge, MERGETABLE tabledata) { - string query = "SELECT * FROM _Tables"; + string query = "SELECT * FROM `_Tables`"; LibmsiResult r = DatabaseOpenQuery(merge, query, out LibmsiQuery view); if (r != LibmsiResult.LIBMSI_RESULT_SUCCESS) return r; diff --git a/BurnOutSharp/External/libmsi/LibmsiQuery.cs b/BurnOutSharp/External/libmsi/LibmsiQuery.cs index 879d0746..b74d3e83 100644 --- a/BurnOutSharp/External/libmsi/LibmsiQuery.cs +++ b/BurnOutSharp/External/libmsi/LibmsiQuery.cs @@ -39,7 +39,7 @@ namespace LibMSI internal string Query { get; set; } - internal LinkedList Mem { get; set; } + internal LinkedList Mem { get; set; } = new LinkedList(); #endregion @@ -245,7 +245,7 @@ namespace LibMSI internal static LibmsiResult QueryOpen(LibmsiDatabase db, out LibmsiQuery view, string query) { Exception err = null; - view = LibmsiQuery.Create(db, query, ref err); + view = Create(db, query, ref err); if (err != null) return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED; diff --git a/BurnOutSharp/External/libmsi/LibmsiSummaryInfo.cs b/BurnOutSharp/External/libmsi/LibmsiSummaryInfo.cs index 7bd31faa..b7d010a6 100644 --- a/BurnOutSharp/External/libmsi/LibmsiSummaryInfo.cs +++ b/BurnOutSharp/External/libmsi/LibmsiSummaryInfo.cs @@ -28,6 +28,7 @@ using static LibMSI.Internal.MsiPriv; namespace LibMSI { + // TODO: Make this a proper variant type OR split it meaningfully internal class LibmsiOLEVariant { public LibmsiOLEVariantType VariantType { get; set; } @@ -70,6 +71,7 @@ namespace LibMSI #region Constants private static readonly string szSumInfo = (char)0x05 + "SummaryInformation"; + private static readonly byte[] fmtid_SummaryInformation = new byte[] { 0xe0, 0x85, 0x9f, 0xf2, 0xf9, 0x4f, 0x68, 0x10, 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9}; @@ -79,9 +81,12 @@ namespace LibMSI internal LibmsiDatabase Database { get; set; } + /// + /// Number of changes allowed + /// internal int UpdateCount { get; set; } - internal LibmsiOLEVariant[] Property { get; set; } = new LibmsiOLEVariant[MSI_MAX_PROPS]; + internal LibmsiOLEVariant[] Properties { get; set; } = new LibmsiOLEVariant[MSI_MAX_PROPS]; #endregion @@ -92,6 +97,8 @@ namespace LibMSI /// private LibmsiSummaryInfo() { } + // TODO: Investigate why Create isn't populating the properties + /// /// If @database is provided, the summary informations will be /// populated during creation, and the libmsi_summary_info_persist() @@ -133,7 +140,7 @@ namespace LibMSI { for (int i = 0; i < MSI_MAX_PROPS; i++) { - FreeProp(Property[i]); + FreeProp(Properties[i]); } } @@ -155,7 +162,7 @@ namespace LibMSI return LibmsiPropertyType.LIBMSI_PROPERTY_TYPE_EMPTY; } - switch (Property[(int)prop].VariantType) + switch (Properties[(int)prop].VariantType) { case LibmsiOLEVariantType.OLEVT_I2: case LibmsiOLEVariantType.OLEVT_I4: @@ -167,7 +174,7 @@ namespace LibMSI case LibmsiOLEVariantType.OLEVT_EMPTY: return LibmsiPropertyType.LIBMSI_PROPERTY_TYPE_EMPTY; default: - error = new Exception($"Unknown type: {Property[(int)prop].VariantType}"); + error = new Exception($"Unknown type: {Properties[(int)prop].VariantType}"); return LibmsiPropertyType.LIBMSI_PROPERTY_TYPE_EMPTY; } } @@ -342,7 +349,7 @@ namespace LibMSI List props = new List(); for (int i = 0; i < MSI_MAX_PROPS; i++) { - if (Property[i].VariantType != LibmsiOLEVariantType.OLEVT_EMPTY) + if (Properties[i].VariantType != LibmsiOLEVariantType.OLEVT_EMPTY) props.Add(i); } @@ -355,7 +362,7 @@ namespace LibMSI internal string SummaryInfoAsString(int uiProperty) { - LibmsiOLEVariant prop = Property[uiProperty]; + LibmsiOLEVariant prop = Properties[uiProperty]; switch (prop.VariantType) { @@ -639,7 +646,7 @@ namespace LibMSI int ofs = 0; if (ReadWORD(data, ref ofs) != 0xfffe) { - Console.Error.WriteLine("property set not little-endian\n"); + Console.Error.WriteLine("Property set not little-endian"); return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED; } @@ -647,7 +654,7 @@ namespace LibMSI // Check the format id is correct ofs = 28; - if (fmtid_SummaryInformation.SequenceEqual(data.Skip(ofs).Take(16))) + if (fmtid_SummaryInformation.SequenceEqual(new ReadOnlySpan(data, ofs, 16).ToArray())) return LibmsiResult.LIBMSI_RESULT_FUNCTION_FAILED; // Seek to the location of the section @@ -666,7 +673,7 @@ namespace LibMSI } // Read all the data in one go - ReadPropertiesFromData(Property, data.Skip(dwOffset).ToArray(), cbSection, cProperties); + ReadPropertiesFromData(Properties, data.Skip(dwOffset).ToArray(), cbSection, cProperties); return LibmsiResult.LIBMSI_RESULT_SUCCESS; } @@ -746,11 +753,11 @@ namespace LibMSI private LibmsiResult Persist(LibmsiDatabase database) { // Add up how much space the data will take and calculate the offsets - int cProperties = GetPropertyCount(Property); + int cProperties = GetPropertyCount(Properties); int cbSection = 8 + cProperties * 8; for (int i = 0; i < MSI_MAX_PROPS; i++) { - cbSection += WritePropertyToData(Property[i], null, 0); + cbSection += WritePropertyToData(Properties[i], null, 0); } int sz = 28 + 20 + cbSection; @@ -779,7 +786,7 @@ namespace LibMSI int dwOffset = 8 + cProperties * 8; for (int i = 0; i < MSI_MAX_PROPS; i++) { - int propsz = WritePropertyToData(Property[i], null, 0); + int propsz = WritePropertyToData(Properties[i], null, 0); if (propsz == 0) continue; @@ -793,7 +800,7 @@ namespace LibMSI // Write out the data for (int i = 0; i < MSI_MAX_PROPS; i++) { - sz += WritePropertyToData(Property[i], data, sz); + sz += WritePropertyToData(Properties[i], data, sz); } //assert(sz == 28 + 20 + cbSection); @@ -819,7 +826,7 @@ namespace LibMSI return; } - LibmsiOLEVariant prop = Property[(int)uiProperty]; + LibmsiOLEVariant prop = Properties[(int)uiProperty]; LibmsiPropertyType type; switch (prop.VariantType) { @@ -867,7 +874,7 @@ namespace LibMSI if (type == LibmsiOLEVariantType.OLEVT_FILETIME && pftValue == 0) return LibmsiResult.LIBMSI_RESULT_INVALID_PARAMETER; - LibmsiOLEVariant prop = Property[(int)uiProperty]; + LibmsiOLEVariant prop = Properties[(int)uiProperty]; if (prop.VariantType == LibmsiOLEVariantType.OLEVT_EMPTY) {